");
30 | $stat_name_cell = $("").text(field);
31 | $row.append($stat_name_cell);
32 | for (port_name in ports_stats) {
33 | stats = ports_stats[port_name];
34 | var $stat_cell = $(" | ").text(stats[field]);
35 | $row.append($stat_cell);
36 | $container.append($row);
37 | }
38 | }
39 | init_custom_scroller($("#port_stats").parent(), true);
40 | });
41 | }
42 |
43 | function init_custom_scroller(selector, horizontal) {
44 | $(selector).scroller('reset').scroller({
45 | horizontal : horizontal
46 | });
47 | }
48 |
49 | update_custom_scroller = init_custom_scroller;
50 |
51 | function draw_switch_view(selector) {
52 |
53 | var position = 0;
54 | var led = {
55 | width : 30,
56 | height : 20
57 | };
58 |
59 | // clear tips if any
60 | $(".d3-tip").remove();
61 |
62 | var tip = d3.tip().attr('class', 'd3-tip').offset([ -10, 0 ]).html(
63 | function(intf) {
64 | var tip_html = "Interface: " + intf.name + " Port: "
65 | + intf.port + "";
66 |
67 |
68 | var statistics = (intf.statistics && intf.statistics[0] == "map") ? intf.statistics[1] : [];
69 | var is_err = statistics.filter(function(element) {
70 | return (((element[0].indexOf('err') != -1) || (element[0].indexOf('drop') != -1)) && (element[1] > 0));
71 | });
72 |
73 | if (is_err.length)
74 | tip_html += " Error detected on this interface: see statistics for details "
75 | return tip_html
76 | });
77 |
78 | var redirect = function(intf, index) {
79 | // TODO: change a redirect principle
80 | window.location.replace('/Interface/' + intf.name);
81 | };
82 |
83 | $.getJSON('/_switch_view', {/* no data */}, function(bridges) {
84 | // clear data
85 | var start_x = 3;
86 | var start_y = 3;
87 |
88 | for (var bridge_idx = 0; bridge_idx < bridges.length; bridge_idx++) {
89 |
90 | var bridge = bridges[bridge_idx];
91 | var bridge_selector = ".switch_view#br_" + bridge.name;
92 | if (!$(bridge_selector).length)
93 | continue;
94 |
95 | d3.select(bridge_selector).selectAll("svg").remove();
96 |
97 | for (var port_idx = 0; port_idx < bridge.ports.length; port_idx++) {
98 | var port = bridge.ports[port_idx];
99 | // add port name to each interface in a group
100 | for (var intf_idx = 0; intf_idx < port.interfaces.length; intf_idx++) {
101 | port.interfaces[intf_idx].port = port.name;
102 | }
103 |
104 | var max_width = $(bridge_selector).prop('clientWidth');
105 | var num_of_rows = 1;
106 |
107 | var svg_container = d3.select(bridge_selector).append("svg").attr({
108 | "width" : "100%",
109 | "height" : "1px" // increased after drawing whole switch_view
110 | });
111 |
112 | svg_container.call(tip);
113 |
114 | var max_width = $(bridge_selector).prop('clientWidth');
115 | var row = 0;
116 | var prev_x = start_x;
117 | var real_width = start_x;
118 |
119 | var ports = svg_container.selectAll("rect").data(port.interfaces).enter().append("rect").attr({
120 | "x" : function() {
121 | var x = start_x;
122 | if (start_x > (max_width - (led.width + 3))) {
123 | x = start_x = 3;
124 | row++;
125 | } else {
126 | start_x += (led.width + 3);
127 | }
128 | if (x > real_width) {
129 | real_width = x + led.width + 1;
130 | }
131 | return x;
132 | },
133 | "y" : function() {
134 | var x = this.x.animVal.value;
135 | if (x < prev_x) {
136 | start_y += row * led.height + 3;
137 | }
138 | prev_x = x;
139 | return start_y;
140 | }, /* + led.width */
141 | "width" : led.width,
142 | "height" : led.height,
143 | "class" : function(intf) {
144 | var c = "iface ";
145 | if (intf.admin_state !== "up") {
146 | c += "down ";
147 | } else {
148 | c += (intf.link_state === "up") ? "up" : "fail";
149 | };
150 |
151 | var statistics = (intf.statistics && intf.statistics[0] == "map") ? intf.statistics[1] : [];
152 | var is_err = statistics.filter(function(element) {
153 | return (((element[0].indexOf('err') != -1) || (element[0].indexOf('drop') != -1)) && (element[1] > 0));
154 | });
155 |
156 | if (is_err.length) {
157 | c += " error";
158 | }
159 |
160 | return c;
161 | },
162 | }).on({
163 | "mouseover" : tip.show,
164 | "mouseout" : tip.hide,
165 | "click" : redirect
166 | });
167 |
168 | start_x = 3;
169 | var real_hight = start_y + led.height;
170 | if (real_width == start_x) {
171 | real_width = start_x + led.width + 1;
172 | }
173 |
174 | svg_container.attr({
175 | 'height' : real_hight + 3 + "px",
176 | 'width' : real_width + 3 + "px"
177 | });
178 |
179 | svg_container.append("rect").attr({
180 | "x" : start_x - 2,
181 | "y" : 1,
182 | "width" : real_width,
183 | "height" : 1 + real_hight,
184 | "style" : "fill:none; stroke:black;"
185 | });
186 | start_y = 3;
187 | }
188 | }
189 | });
190 | }
191 |
192 | function retrieve_updates() {
193 | var $alerts = $('.dropdown-alerts');
194 | var $updates = $('#num-of-updates');
195 |
196 | $.getJSON('/updates', function(updates) {
197 | $('li', $alerts).remove();
198 |
199 | var len = updates.length < 10 ? updates.length : 10;
200 |
201 | for (var int = 0; int < len; int++) {
202 | var update = updates[int];
203 | var key = Object.keys(update);
204 | var uuid = Object.keys(update[key]);
205 | var msg;
206 | var subkey;
207 | var action;
208 | var icon;
209 |
210 | if ((uuid instanceof Array) && (uuid.length > 1)) {
211 | msg = 'Multiple changes';
212 | action = 'changes';
213 | icon = 'fa-warning';
214 | } else {
215 | if (update[key][uuid].old) {
216 | // removed
217 | msg = update[key][uuid]['old'];
218 | action = 'removed';
219 | icon = 'fa-warning';
220 | } else {
221 | // added
222 | msg = update[key][uuid]['new'];
223 | action = 'created';
224 | icon = 'fa-comment';
225 | }
226 | // TODO: foreach key in subkeys should be here
227 | subkey = Object.keys(msg)[0];
228 | msg = msg[subkey];
229 | }
230 |
231 | $alerts.append($('').append($('', {
232 | href : "#"
233 | }).append($('').append($('', {
234 | class : 'fa ' + icon + ' fa-fw'
235 | })).append(key + ': "' + msg + '"').append($('', {
236 | 'class' : 'pull-right text-muted small'
237 | }).append(action)))).append($('', {
238 | class : 'divider'
239 | })));
240 | }
241 |
242 | $alerts.append($('').append($('', {
243 | href : "/alerts",
244 | class : 'text-center'
245 | }).append($('').text('See All Alerts').append($('', {
246 | class : 'fa fa-angle-right fa-fw'
247 | })))));
248 |
249 | // See All Alerts
250 | $updates.text(updates.length || '');
251 | });
252 | }
253 |
254 | function select_menu_item(selector) {
255 | $item = $(selector);
256 | if (!$item.length) {
257 | return;
258 | }
259 |
260 | $(".nav.collapse.in").removeClass("in");
261 | $item.addClass("active");
262 | $parents = $item.parents(".nav.collapse");
263 | $parents.addClass("in");
264 | }
265 |
266 | function submit_raw_json() {
267 | var data = $("#raw_content > textarea").val();
268 | var bridge = window.location.pathname.substring(1);
269 | var index = bridge.indexOf('/');
270 | if (index != -1) {
271 | bridge = bridge.substring(0, bridge.lastIndexOf('/'));
272 | }
273 |
274 | $.post('/' + bridge + '/raw_json', {
275 | request : data
276 | }, function(data) {
277 | console.log(data);
278 | $("#raw_reply").val(data);
279 | });
280 | }
281 |
--------------------------------------------------------------------------------
/public/js/d3.tip.v0.6.3.js:
--------------------------------------------------------------------------------
1 | // d3.tip
2 | // Copyright (c) 2013 Justin Palmer
3 | //
4 | // Tooltips for d3.js SVG visualizations
5 |
6 | // Public - contructs a new tooltip
7 | //
8 | // Returns a tip
9 | d3.tip = function() {
10 | var direction = d3_tip_direction,
11 | offset = d3_tip_offset,
12 | html = d3_tip_html,
13 | node = initNode(),
14 | svg = null,
15 | point = null,
16 | target = null
17 |
18 | function tip(vis) {
19 | svg = getSVGNode(vis)
20 | point = svg.createSVGPoint()
21 | document.body.appendChild(node)
22 | }
23 |
24 | // Public - show the tooltip on the screen
25 | //
26 | // Returns a tip
27 | tip.show = function() {
28 | var args = Array.prototype.slice.call(arguments)
29 | if(args[args.length - 1] instanceof SVGElement) target = args.pop()
30 |
31 | var content = html.apply(this, args),
32 | poffset = offset.apply(this, args),
33 | dir = direction.apply(this, args),
34 | nodel = d3.select(node), i = 0,
35 | coords
36 |
37 | nodel.html(content)
38 | .style({ opacity: 1, 'pointer-events': 'all' })
39 |
40 | while(i--) nodel.classed(directions[i], false)
41 | coords = direction_callbacks.get(dir).apply(this)
42 | nodel.classed(dir, true).style({
43 | top: (coords.top + poffset[0]) + 'px',
44 | left: (coords.left + poffset[1]) + 'px'
45 | })
46 |
47 | return tip
48 | }
49 |
50 | // Public - hide the tooltip
51 | //
52 | // Returns a tip
53 | tip.hide = function() {
54 | nodel = d3.select(node)
55 | nodel.style({ opacity: 0, 'pointer-events': 'none' })
56 | return tip
57 | }
58 |
59 | // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value.
60 | //
61 | // n - name of the attribute
62 | // v - value of the attribute
63 | //
64 | // Returns tip or attribute value
65 | tip.attr = function(n, v) {
66 | if (arguments.length < 2 && typeof n === 'string') {
67 | return d3.select(node).attr(n)
68 | } else {
69 | var args = Array.prototype.slice.call(arguments)
70 | d3.selection.prototype.attr.apply(d3.select(node), args)
71 | }
72 |
73 | return tip
74 | }
75 |
76 | // Public: Proxy style calls to the d3 tip container. Sets or gets a style value.
77 | //
78 | // n - name of the property
79 | // v - value of the property
80 | //
81 | // Returns tip or style property value
82 | tip.style = function(n, v) {
83 | if (arguments.length < 2 && typeof n === 'string') {
84 | return d3.select(node).style(n)
85 | } else {
86 | var args = Array.prototype.slice.call(arguments)
87 | d3.selection.prototype.style.apply(d3.select(node), args)
88 | }
89 |
90 | return tip
91 | }
92 |
93 | // Public: Set or get the direction of the tooltip
94 | //
95 | // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
96 | // sw(southwest), ne(northeast) or se(southeast)
97 | //
98 | // Returns tip or direction
99 | tip.direction = function(v) {
100 | if (!arguments.length) return direction
101 | direction = v == null ? v : d3.functor(v)
102 |
103 | return tip
104 | }
105 |
106 | // Public: Sets or gets the offset of the tip
107 | //
108 | // v - Array of [x, y] offset
109 | //
110 | // Returns offset or
111 | tip.offset = function(v) {
112 | if (!arguments.length) return offset
113 | offset = v == null ? v : d3.functor(v)
114 |
115 | return tip
116 | }
117 |
118 | // Public: sets or gets the html value of the tooltip
119 | //
120 | // v - String value of the tip
121 | //
122 | // Returns html value or tip
123 | tip.html = function(v) {
124 | if (!arguments.length) return html
125 | html = v == null ? v : d3.functor(v)
126 |
127 | return tip
128 | }
129 |
130 | function d3_tip_direction() { return 'n' }
131 | function d3_tip_offset() { return [0, 0] }
132 | function d3_tip_html() { return ' ' }
133 |
134 | var direction_callbacks = d3.map({
135 | n: direction_n,
136 | s: direction_s,
137 | e: direction_e,
138 | w: direction_w,
139 | nw: direction_nw,
140 | ne: direction_ne,
141 | sw: direction_sw,
142 | se: direction_se
143 | }),
144 |
145 | directions = direction_callbacks.keys()
146 |
147 | function direction_n() {
148 | var bbox = getScreenBBox()
149 | return {
150 | top: bbox.n.y - node.offsetHeight,
151 | left: bbox.n.x - node.offsetWidth / 2
152 | }
153 | }
154 |
155 | function direction_s() {
156 | var bbox = getScreenBBox()
157 | return {
158 | top: bbox.s.y,
159 | left: bbox.s.x - node.offsetWidth / 2
160 | }
161 | }
162 |
163 | function direction_e() {
164 | var bbox = getScreenBBox()
165 | return {
166 | top: bbox.e.y - node.offsetHeight / 2,
167 | left: bbox.e.x
168 | }
169 | }
170 |
171 | function direction_w() {
172 | var bbox = getScreenBBox()
173 | return {
174 | top: bbox.w.y - node.offsetHeight / 2,
175 | left: bbox.w.x - node.offsetWidth
176 | }
177 | }
178 |
179 | function direction_nw() {
180 | var bbox = getScreenBBox()
181 | return {
182 | top: bbox.nw.y - node.offsetHeight,
183 | left: bbox.nw.x - node.offsetWidth
184 | }
185 | }
186 |
187 | function direction_ne() {
188 | var bbox = getScreenBBox()
189 | return {
190 | top: bbox.ne.y - node.offsetHeight,
191 | left: bbox.ne.x
192 | }
193 | }
194 |
195 | function direction_sw() {
196 | var bbox = getScreenBBox()
197 | return {
198 | top: bbox.sw.y,
199 | left: bbox.sw.x - node.offsetWidth
200 | }
201 | }
202 |
203 | function direction_se() {
204 | var bbox = getScreenBBox()
205 | return {
206 | top: bbox.se.y,
207 | left: bbox.e.x
208 | }
209 | }
210 |
211 | function initNode() {
212 | var node = d3.select(document.createElement('div'))
213 | node.style({
214 | position: 'absolute',
215 | opacity: 0,
216 | pointerEvents: 'none',
217 | boxSizing: 'border-box'
218 | })
219 |
220 | return node.node()
221 | }
222 |
223 | function getSVGNode(el) {
224 | el = el.node()
225 | if(el.tagName.toLowerCase() == 'svg')
226 | return el
227 |
228 | return el.ownerSVGElement
229 | }
230 |
231 | // Private - gets the screen coordinates of a shape
232 | //
233 | // Given a shape on the screen, will return an SVGPoint for the directions
234 | // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
235 | // sw(southwest).
236 | //
237 | // +-+-+
238 | // | |
239 | // + +
240 | // | |
241 | // +-+-+
242 | //
243 | // Returns an Object {n, s, e, w, nw, sw, ne, se}
244 | function getScreenBBox() {
245 | var targetel = target || d3.event.target,
246 | bbox = {},
247 | matrix = targetel.getScreenCTM(),
248 | tbbox = targetel.getBBox(),
249 | width = tbbox.width,
250 | height = tbbox.height,
251 | x = tbbox.x,
252 | y = tbbox.y,
253 | scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
254 | scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
255 |
256 |
257 | point.x = x + scrollLeft
258 | point.y = y + scrollTop
259 | bbox.nw = point.matrixTransform(matrix)
260 | point.x += width
261 | bbox.ne = point.matrixTransform(matrix)
262 | point.y += height
263 | bbox.se = point.matrixTransform(matrix)
264 | point.x -= width
265 | bbox.sw = point.matrixTransform(matrix)
266 | point.y -= height / 2
267 | bbox.w = point.matrixTransform(matrix)
268 | point.x += width
269 | bbox.e = point.matrixTransform(matrix)
270 | point.x -= width / 2
271 | point.y -= height / 2
272 | bbox.n = point.matrixTransform(matrix)
273 | point.y += height
274 | bbox.s = point.matrixTransform(matrix)
275 |
276 | return bbox
277 | }
278 |
279 | return tip
280 | };
281 |
--------------------------------------------------------------------------------
/public/js/event_emitter.js:
--------------------------------------------------------------------------------
1 | // Generated by CommonJS Everywhere 0.9.7
2 | (function (global) {
3 | function require(file, parentModule) {
4 | if ({}.hasOwnProperty.call(require.cache, file))
5 | return require.cache[file];
6 | var resolved = require.resolve(file);
7 | if (!resolved)
8 | throw new Error('Failed to resolve module ' + file);
9 | var module$ = {
10 | id: file,
11 | require: require,
12 | filename: file,
13 | exports: {},
14 | loaded: false,
15 | parent: parentModule,
16 | children: []
17 | };
18 | if (parentModule)
19 | parentModule.children.push(module$);
20 | var dirname = file.slice(0, file.lastIndexOf('/') + 1);
21 | require.cache[file] = module$.exports;
22 | resolved.call(module$.exports, module$, module$.exports, dirname, file);
23 | module$.loaded = true;
24 | return require.cache[file] = module$.exports;
25 | }
26 | require.modules = {};
27 | require.cache = {};
28 | require.resolve = function (file) {
29 | return {}.hasOwnProperty.call(require.modules, file) ? require.modules[file] : void 0;
30 | };
31 | require.define = function (file, fn) {
32 | require.modules[file] = fn;
33 | };
34 | require.define('/index.js', function (module, exports, __dirname, __filename) {
35 | var util = {};
36 | util.isObject = function isObject(arg) {
37 | return typeof arg === 'object' && arg !== null;
38 | };
39 | util.isNumber = function isNumber(arg) {
40 | return typeof arg === 'number';
41 | };
42 | util.isUndefined = function isUndefined(arg) {
43 | return arg === void 0;
44 | };
45 | util.isFunction = function isFunction(arg) {
46 | return typeof arg === 'function';
47 | };
48 | function EventEmitter() {
49 | EventEmitter.init.call(this);
50 | }
51 | module.exports = EventEmitter;
52 | EventEmitter.EventEmitter = EventEmitter;
53 | EventEmitter.prototype._events = undefined;
54 | EventEmitter.prototype._maxListeners = undefined;
55 | EventEmitter.defaultMaxListeners = 10;
56 | EventEmitter.init = function () {
57 | this._events = this._events || {};
58 | this._maxListeners = this._maxListeners || undefined;
59 | };
60 | EventEmitter.prototype.setMaxListeners = function (n) {
61 | if (!util.isNumber(n) || n < 0 || isNaN(n))
62 | throw TypeError('n must be a positive number');
63 | this._maxListeners = n;
64 | return this;
65 | };
66 | EventEmitter.prototype.emit = function (type) {
67 | var er, handler, len, args, i, listeners;
68 | if (!this._events)
69 | this._events = {};
70 | if (type === 'error' && !this._events.error) {
71 | er = arguments[1];
72 | if (er instanceof Error) {
73 | throw er;
74 | } else {
75 | throw Error('Uncaught, unspecified "error" event.');
76 | }
77 | return false;
78 | }
79 | handler = this._events[type];
80 | if (util.isUndefined(handler))
81 | return false;
82 | if (util.isFunction(handler)) {
83 | switch (arguments.length) {
84 | case 1:
85 | handler.call(this);
86 | break;
87 | case 2:
88 | handler.call(this, arguments[1]);
89 | break;
90 | case 3:
91 | handler.call(this, arguments[1], arguments[2]);
92 | break;
93 | default:
94 | len = arguments.length;
95 | args = new Array(len - 1);
96 | for (i = 1; i < len; i++)
97 | args[i - 1] = arguments[i];
98 | handler.apply(this, args);
99 | }
100 | } else if (util.isObject(handler)) {
101 | len = arguments.length;
102 | args = new Array(len - 1);
103 | for (i = 1; i < len; i++)
104 | args[i - 1] = arguments[i];
105 | listeners = handler.slice();
106 | len = listeners.length;
107 | for (i = 0; i < len; i++)
108 | listeners[i].apply(this, args);
109 | }
110 | return true;
111 | };
112 | EventEmitter.prototype.addListener = function (type, listener) {
113 | var m;
114 | if (!util.isFunction(listener))
115 | throw TypeError('listener must be a function');
116 | if (!this._events)
117 | this._events = {};
118 | if (this._events.newListener)
119 | this.emit('newListener', type, util.isFunction(listener.listener) ? listener.listener : listener);
120 | if (!this._events[type])
121 | this._events[type] = listener;
122 | else if (util.isObject(this._events[type]))
123 | this._events[type].push(listener);
124 | else
125 | this._events[type] = [
126 | this._events[type],
127 | listener
128 | ];
129 | if (util.isObject(this._events[type]) && !this._events[type].warned) {
130 | var m;
131 | if (!util.isUndefined(this._maxListeners)) {
132 | m = this._maxListeners;
133 | } else {
134 | m = EventEmitter.defaultMaxListeners;
135 | }
136 | if (m && m > 0 && this._events[type].length > m) {
137 | this._events[type].warned = true;
138 | if (util.isFunction(console.error)) {
139 | console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length);
140 | }
141 | if (util.isFunction(console.trace))
142 | console.trace();
143 | }
144 | }
145 | return this;
146 | };
147 | EventEmitter.prototype.on = EventEmitter.prototype.addListener;
148 | EventEmitter.prototype.once = function (type, listener) {
149 | if (!util.isFunction(listener))
150 | throw TypeError('listener must be a function');
151 | var fired = false;
152 | function g() {
153 | this.removeListener(type, g);
154 | if (!fired) {
155 | fired = true;
156 | listener.apply(this, arguments);
157 | }
158 | }
159 | g.listener = listener;
160 | this.on(type, g);
161 | return this;
162 | };
163 | EventEmitter.prototype.removeListener = function (type, listener) {
164 | var list, position, length, i;
165 | if (!util.isFunction(listener))
166 | throw TypeError('listener must be a function');
167 | if (!this._events || !this._events[type])
168 | return this;
169 | list = this._events[type];
170 | length = list.length;
171 | position = -1;
172 | if (list === listener || util.isFunction(list.listener) && list.listener === listener) {
173 | delete this._events[type];
174 | if (this._events.removeListener)
175 | this.emit('removeListener', type, listener);
176 | } else if (util.isObject(list)) {
177 | for (i = length; i-- > 0;) {
178 | if (list[i] === listener || list[i].listener && list[i].listener === listener) {
179 | position = i;
180 | break;
181 | }
182 | }
183 | if (position < 0)
184 | return this;
185 | if (list.length === 1) {
186 | list.length = 0;
187 | delete this._events[type];
188 | } else {
189 | list.splice(position, 1);
190 | }
191 | if (this._events.removeListener)
192 | this.emit('removeListener', type, listener);
193 | }
194 | return this;
195 | };
196 | EventEmitter.prototype.removeAllListeners = function (type) {
197 | var key, listeners;
198 | if (!this._events)
199 | return this;
200 | if (!this._events.removeListener) {
201 | if (arguments.length === 0)
202 | this._events = {};
203 | else if (this._events[type])
204 | delete this._events[type];
205 | return this;
206 | }
207 | if (arguments.length === 0) {
208 | for (key in this._events) {
209 | if (key === 'removeListener')
210 | continue;
211 | this.removeAllListeners(key);
212 | }
213 | this.removeAllListeners('removeListener');
214 | this._events = {};
215 | return this;
216 | }
217 | listeners = this._events[type];
218 | if (util.isFunction(listeners)) {
219 | this.removeListener(type, listeners);
220 | } else if (Array.isArray(listeners)) {
221 | while (listeners.length)
222 | this.removeListener(type, listeners[listeners.length - 1]);
223 | }
224 | delete this._events[type];
225 | return this;
226 | };
227 | EventEmitter.prototype.listeners = function (type) {
228 | var ret;
229 | if (!this._events || !this._events[type])
230 | ret = [];
231 | else if (util.isFunction(this._events[type]))
232 | ret = [this._events[type]];
233 | else
234 | ret = this._events[type].slice();
235 | return ret;
236 | };
237 | EventEmitter.listenerCount = function (emitter, type) {
238 | var ret;
239 | if (!emitter._events || !emitter._events[type])
240 | ret = 0;
241 | else if (util.isFunction(emitter._events[type]))
242 | ret = 1;
243 | else
244 | ret = emitter._events[type].length;
245 | return ret;
246 | };
247 | });
248 | global.EventEmitter = require('/index.js');
249 | }.call(this, this));
250 |
--------------------------------------------------------------------------------
/public/js/loading.js:
--------------------------------------------------------------------------------
1 | Navigation.on("loading", function() {
2 | $('#loading-indicator').show();
3 | var left_pos = ($(window).width() - $('#loading-indicator').width()) / 2;
4 | $('#loading-indicator').css("left", left_pos);
5 |
6 | /* hide left panel on mobile phones */
7 | $("#wrapper").removeClass("sidebar-shown");
8 | $(".navbar-collapse").toggleClass("in", $("#wrapper").hasClass("sidebar-shown"));
9 | });
10 |
11 | Navigation.on("loaded", function() {
12 | $('#loading-indicator').hide();
13 | });
14 |
--------------------------------------------------------------------------------
/public/js/navigation.js:
--------------------------------------------------------------------------------
1 | (function (global, $, undefined) {
2 |
3 | function Navigation(options) {
4 | // Singleton
5 | if (arguments.callee.instance)
6 | return arguments.callee.instance;
7 | this.init(options);
8 | arguments.callee.instance = this;
9 |
10 | //event emmiter
11 | EventEmitter.call(this);
12 | }
13 |
14 | Navigation.prototype.__proto__ = EventEmitter.prototype;
15 |
16 | Navigation.prototype.init = function(options) {
17 | var self = this;
18 |
19 | var defaults = this.options || {
20 | container: "body",
21 | landing_page: "/",
22 | params : {xhr: true}
23 | };
24 |
25 | options = options || {};
26 | this.options = $.extend(defaults, options);
27 |
28 | this.lastpage = this.options.landing_page;
29 | //history.pushState(this.options.landing_page, null, this.options.landing_page);
30 | this.event_handlers = {};
31 |
32 | this.$container = $(this.options.container);
33 |
34 | $(window).off("popstate").on("popstate", function(e) {
35 | var url = e.originalEvent.state || global.location.pathname;
36 | self.go(url, null, true);
37 | });
38 | $(window).on("load", function() {
39 | self.emit("loaded", global.location.pathname);
40 | });
41 | };
42 |
43 | Navigation.getInstance = function(options) {
44 | var instance = new Navigation(options);
45 | return instance;
46 | };
47 |
48 | Navigation.prototype.go = function(url, params, no_history) {
49 | var self = this;
50 | if (url === self.lastpage) {
51 | return;
52 | }
53 |
54 | if (!url) {
55 |
56 | url = self.options.landing_page;
57 | no_history = true;
58 | }
59 | if (url.substr(0,1) !== "/"){
60 | url = '/' + url.replace('#',''); //strip the #page part of the hash and leave only the page number
61 | }
62 |
63 | self.emit("loading");
64 |
65 | params = $.extend(this.options.params, params);
66 |
67 |
68 | $.get(url, params, function(data) {
69 | self.$container.html(data);
70 | self.lastpage = url;
71 | self.emit("loaded", url);
72 | }).error(function(xhr, status, e) {
73 | if (xhr.status == 404) {
74 | var data = xhr.responseText;
75 | self.$container.html(data);
76 | };
77 | self.emit("loaded",xhr);
78 | });
79 |
80 | //push page change to history
81 | if (! no_history) {
82 | history.pushState(url, null, url);
83 | }
84 | };
85 |
86 |
87 | $.fn.navigation = function(options) {
88 | var chain = this;
89 | var defaults = {url : "href"};
90 | options = $.extend(defaults, options);
91 | this.each( function() {
92 | if ($(this).data("navigation")) return;
93 |
94 | $(this).data("navigation", true);
95 | $(this).on("click.navig", function(e) {
96 | var $this = $(this);
97 | e.preventDefault();
98 | var addr = $this.attr("data-addr");
99 | var url;
100 | if (options.url instanceof Function) {
101 | url = options.url($this);
102 | } else {
103 | url = $this.attr(options.url);
104 | }
105 |
106 | global.Navigation.go(url, {addr : addr});
107 | return true;
108 | });
109 | });
110 | return chain;
111 | };
112 |
113 | global.Navigation = Navigation.getInstance({});
114 | }(this, $, undefined));
115 |
--------------------------------------------------------------------------------
/public/js/plugins/jquery.cookie.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Cookie Plugin v1.4.1
3 | * https://github.com/carhartl/jquery-cookie
4 | *
5 | * Copyright 2006, 2014 Klaus Hartl
6 | * Released under the MIT license
7 | */
8 | (function (factory) {
9 | if (typeof define === 'function' && define.amd) {
10 | // AMD
11 | define(['jquery'], factory);
12 | } else if (typeof exports === 'object') {
13 | // CommonJS
14 | factory(require('jquery'));
15 | } else {
16 | // Browser globals
17 | factory(jQuery);
18 | }
19 | }(function ($) {
20 |
21 | var pluses = /\+/g;
22 |
23 | function encode(s) {
24 | return config.raw ? s : encodeURIComponent(s);
25 | }
26 |
27 | function decode(s) {
28 | return config.raw ? s : decodeURIComponent(s);
29 | }
30 |
31 | function stringifyCookieValue(value) {
32 | return encode(config.json ? JSON.stringify(value) : String(value));
33 | }
34 |
35 | function parseCookieValue(s) {
36 | if (s.indexOf('"') === 0) {
37 | // This is a quoted cookie as according to RFC2068, unescape...
38 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
39 | }
40 |
41 | try {
42 | // Replace server-side written pluses with spaces.
43 | // If we can't decode the cookie, ignore it, it's unusable.
44 | // If we can't parse the cookie, ignore it, it's unusable.
45 | s = decodeURIComponent(s.replace(pluses, ' '));
46 | return config.json ? JSON.parse(s) : s;
47 | } catch(e) {}
48 | }
49 |
50 | function read(s, converter) {
51 | var value = config.raw ? s : parseCookieValue(s);
52 | return $.isFunction(converter) ? converter(value) : value;
53 | }
54 |
55 | var config = $.cookie = function (key, value, options) {
56 |
57 | // Write
58 |
59 | if (arguments.length > 1 && !$.isFunction(value)) {
60 | options = $.extend({}, config.defaults, options);
61 |
62 | if (typeof options.expires === 'number') {
63 | var days = options.expires, t = options.expires = new Date();
64 | t.setTime(+t + days * 864e+5);
65 | }
66 |
67 | return (document.cookie = [
68 | encode(key), '=', stringifyCookieValue(value),
69 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
70 | options.path ? '; path=' + options.path : '',
71 | options.domain ? '; domain=' + options.domain : '',
72 | options.secure ? '; secure' : ''
73 | ].join(''));
74 | }
75 |
76 | // Read
77 |
78 | var result = key ? undefined : {};
79 |
80 | // To prevent the for loop in the first place assign an empty array
81 | // in case there are no cookies at all. Also prevents odd result when
82 | // calling $.cookie().
83 | var cookies = document.cookie ? document.cookie.split('; ') : [];
84 |
85 | for (var i = 0, l = cookies.length; i < l; i++) {
86 | var parts = cookies[i].split('=');
87 | var name = decode(parts.shift());
88 | var cookie = parts.join('=');
89 |
90 | if (key && key === name) {
91 | // If second argument (value) is a function it's a converter...
92 | result = read(cookie, value);
93 | break;
94 | }
95 |
96 | // Prevent storing a cookie that we couldn't decode.
97 | if (!key && (cookie = read(cookie)) !== undefined) {
98 | result[name] = cookie;
99 | }
100 | }
101 |
102 | return result;
103 | };
104 |
105 | config.defaults = {};
106 |
107 | $.removeCookie = function (key, options) {
108 | if ($.cookie(key) === undefined) {
109 | return false;
110 | }
111 |
112 | // Must not alter options, thus extending a fresh object...
113 | $.cookie(key, '', $.extend({}, options, { expires: -1 }));
114 | return !$.cookie(key);
115 | };
116 |
117 | }));
118 |
--------------------------------------------------------------------------------
/public/js/plugins/metisMenu.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * metismenu - v1.0.3
3 | * Easy menu jQuery plugin for Twitter Bootstrap 3
4 | * https://github.com/onokumus/metisMenu
5 | *
6 | * Made by Osman Nuri Okumuş
7 | * Under MIT License
8 | */
9 | !function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document);
--------------------------------------------------------------------------------
/public/js/plugins/scroller.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Scroller v3.0.4 - 2014-04-08
3 | * A jQuery plugin for replacing default browser scrollbars. Part of the Formstone Library.
4 | * http://formstone.it/scroller/
5 | *
6 | * Copyright 2014 Ben Plum; MIT Licensed
7 | */
8 |
9 | !function(a,b){"use strict";function c(b){b=a.extend({},l,b||{}),null===k&&(k=a("body"));for(var c=a(this),e=0,f=c.length;f>e;e++)d(c.eq(e),b);return c}function d(c,d){if(!c.hasClass("scroller")){d=a.extend({},d,c.data("scroller-options"));var h="";h+='",d.paddingRight=parseInt(c.css("padding-right"),10),d.paddingBottom=parseInt(c.css("padding-bottom"),10),c.addClass(d.customClass+" scroller").wrapInner('').prepend(h),d.horizontal&&c.addClass("scroller-horizontal");var i=a.extend({$scroller:c,$content:c.find(".scroller-content"),$bar:c.find(".scroller-bar"),$track:c.find(".scroller-track"),$handle:c.find(".scroller-handle")},d);i.trackMargin=parseInt(i.trackMargin,10),i.$content.on("scroll.scroller",i,e),i.$scroller.on("touchstart.scroller mousedown.scroller",".scroller-track",i,f).on("touchstart.scroller mousedown.scroller",".scroller-handle",i,g).data("scroller",i),m.reset.apply(c),a(b).one("load",function(){m.reset.apply(c)})}}function e(a){a.preventDefault(),a.stopPropagation();var b=a.data;if(b.horizontal){var c=b.$content.scrollLeft();0>c&&(c=0);var d=c/b.scrollRatio;d>b.handleBounds.right&&(d=b.handleBounds.right),b.$handle.css({left:d})}else{var e=b.$content.scrollTop();0>e&&(e=0);var f=e/b.scrollRatio;f>b.handleBounds.bottom&&(f=b.handleBounds.bottom),b.$handle.css({top:f})}}function f(a){a.preventDefault(),a.stopPropagation();var b=a.data,c=a.originalEvent,d=b.$track.offset(),e="undefined"!=typeof c.targetTouches?c.targetTouches[0]:null,f=e?e.pageX:a.clientX,g=e?e.pageY:a.clientY;b.horizontal?(b.mouseStart=f,b.handleLeft=f-d.left-b.handleWidth/2,j.apply(b.$scroller,[b,b.handleLeft])):(b.mouseStart=g,b.handleTop=g-d.top-b.handleHeight/2,j.apply(b.$scroller,[b,b.handleTop])),b.$content.off(".scroller"),k.on("touchmove.scroller mousemove.scroller",b,h).on("touchend.scroller mouseup.scroller",b,i)}function g(a){a.preventDefault(),a.stopPropagation();var b=a.data,c=a.originalEvent,d="undefined"!=typeof c.targetTouches?c.targetTouches[0]:null,e=d?d.pageX:a.clientX,f=d?d.pageY:a.clientY;b.horizontal?(b.mouseStart=e,b.handleLeft=parseInt(b.$handle.css("left"),10)):(b.mouseStart=f,b.handleTop=parseInt(b.$handle.css("top"),10)),b.$content.off(".scroller"),k.on("touchmove.scroller mousemove.scroller",b,h).on("touchend.scroller mouseup.scroller",b,i)}function h(a){a.preventDefault(),a.stopPropagation();var b=a.data,c=a.originalEvent,d=0,e=0,f="undefined"!=typeof c.targetTouches?c.targetTouches[0]:null,g=f?f.pageX:a.clientX,h=f?f.pageY:a.clientY;b.horizontal?(e=b.mouseStart-g,d=b.handleLeft-e):(e=b.mouseStart-h,d=b.handleTop-e),j.apply(b.$scroller,[b,d])}function i(a){a.preventDefault(),a.stopPropagation();var b=a.data;b.$content.on("scroll.scroller",b,e),k.off(".scroller")}function j(a,b){if(a.horizontal){ba.handleBounds.right&&(b=a.handleBounds.right);var c=Math.round(b*a.scrollRatio);a.$handle.css({left:b}),a.$content.scrollLeft(c)}else{ba.handleBounds.bottom&&(b=a.handleBounds.bottom);var d=Math.round(b*a.scrollRatio);a.$handle.css({top:b}),a.$content.scrollTop(d)}}var k=null,l={customClass:"",duration:0,handleSize:0,horizontal:!1,trackMargin:0},m={defaults:function(b){return l=a.extend(l,b||{}),a(this)},destroy:function(){return a(this).each(function(b,c){var d=a(c).data("scroller");d&&(d.$scroller.removeClass(d.customClass).removeClass("scroller").removeClass("scroller-active"),d.$bar.remove(),d.$content.contents().unwrap(),d.$content.off(".scroller"),d.$scroller.off(".scroller").removeData("scroller"))})},scroll:function(b,c){return a(this).each(function(){var d=a(this).data("scroller"),e=c||l.duration;if("number"!=typeof b){var f=a(b);if(f.length>0){var g=f.position();b=d.horizontal?g.left+d.$content.scrollLeft():g.top+d.$content.scrollTop()}else b=d.$content.scrollTop()}d.horizontal?d.$content.stop().animate({scrollLeft:b},e):d.$content.stop().animate({scrollTop:b},e)})},reset:function(){return a(this).each(function(){var b=a(this).data("scroller");if(b){if(b.$scroller.addClass("scroller-setup"),b.horizontal){b.barHeight=b.$content[0].offsetHeight-b.$content[0].clientHeight,b.frameWidth=b.$content.outerWidth(),b.trackWidth=b.frameWidth-2*b.trackMargin,b.scrollWidth=b.$content[0].scrollWidth,b.ratio=b.trackWidth/b.scrollWidth,b.trackRatio=b.trackWidth/b.scrollWidth,b.handleWidth=b.handleSize>0?b.handleSize:b.trackWidth*b.trackRatio,b.scrollRatio=(b.scrollWidth-b.frameWidth)/(b.trackWidth-b.handleWidth),b.handleBounds={left:0,right:b.trackWidth-b.handleWidth},b.$content.css({paddingBottom:b.barHeight+b.paddingBottom});var c=b.$content.scrollLeft(),d=c*b.ratio;b.scrollWidth<=b.frameWidth?b.$scroller.removeClass("scroller-active"):b.$scroller.addClass("scroller-active"),b.$bar.css({width:b.frameWidth}),b.$track.css({width:b.trackWidth,marginLeft:b.trackMargin,marginRight:b.trackMargin}),b.$handle.css({width:b.handleWidth}),j.apply(b.$scroller,[b,d])}else{b.barWidth=b.$content[0].offsetWidth-b.$content[0].clientWidth,b.frameHeight=b.$content.outerHeight(),b.trackHeight=b.frameHeight-2*b.trackMargin,b.scrollHeight=b.$content[0].scrollHeight,b.ratio=b.trackHeight/b.scrollHeight,b.trackRatio=b.trackHeight/b.scrollHeight,b.handleHeight=b.handleSize>0?b.handleSize:b.trackHeight*b.trackRatio,b.scrollRatio=(b.scrollHeight-b.frameHeight)/(b.trackHeight-b.handleHeight),b.handleBounds={top:0,bottom:b.trackHeight-b.handleHeight};var e=b.$content.scrollTop(),f=e*b.ratio;b.scrollHeight<=b.frameHeight?b.$scroller.removeClass("scroller-active"):b.$scroller.addClass("scroller-active"),b.$bar.css({height:b.frameHeight}),b.$track.css({height:b.trackHeight,marginBottom:b.trackMargin,marginTop:b.trackMargin}),b.$handle.css({height:b.handleHeight}),j.apply(b.$scroller,[b,f])}b.$scroller.removeClass("scroller-setup")}})}};a.fn.scroller=function(a){return m[a]?m[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?this:c.apply(this,arguments)},a.scroller=function(a){"defaults"===a&&m.defaults.apply(this,Array.prototype.slice.call(arguments,1))}}(jQuery);
--------------------------------------------------------------------------------
/public/js/sb-admin-2.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
3 | * Code licensed under the Apache License v2.0.
4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5 | */
6 |
7 | $(function() {
8 |
9 | $('#side-menu').metisMenu();
10 |
11 | });
12 |
13 | // Loads the correct sidebar on window load,
14 | // collapses the sidebar on window resize.
15 | // Sets the min-height of #page-wrapper to window size
16 | $(function() {
17 | $(window).bind("load resize", function() {
18 | topOffset = 50;
19 | width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
20 | if (width < 768) {
21 | $('div.navbar-collapse').addClass('collapse')
22 | topOffset = 100; // 2-row-menu
23 | } else {
24 | $('div.navbar-collapse').removeClass('collapse')
25 | }
26 |
27 | height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
28 | height = height - topOffset;
29 | if (height < 1)
30 | height = 1;
31 | if (height > topOffset) {
32 | $("#page-wrapper").css("min-height", (height) + "px");
33 | }
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/public/js/sweet-alert.min.js:
--------------------------------------------------------------------------------
1 | !function(e,t){function n(){var e='',n=t.createElement("div");n.innerHTML=e,t.body.appendChild(n)}function o(t){var n=m(),o=n.querySelector("h2"),r=n.querySelector("p"),a=n.querySelector("button.cancel"),c=n.querySelector("button.confirm");if(o.innerHTML=b(t.title).split("\n").join(" "),r.innerHTML=b(t.text||"").split("\n").join(" "),t.text&&w(r),x(n.querySelectorAll(".icon")),t.type){for(var l=!1,s=0;sr;r++)o=parseInt(e.substr(2*r,2),16),o=Math.round(Math.min(Math.max(0,o+o*t),255)).toString(16),n+=("00"+o).substr(o.length);return n}function a(e){var t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?parseInt(t[1],16)+", "+parseInt(t[2],16)+", "+parseInt(t[3],16):null}function i(e,t){var n=a(t);e.style.boxShadow="0 0 2px rgba("+n+", 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)"}function c(){var e=m();B(g(),10),w(e),p(e,"showSweetAlert"),v(e,"hideSweetAlert"),O=t.activeElement;var n=e.querySelector("button.confirm");n.focus(),setTimeout(function(){p(e,"visible")},500)}function l(){var n=m();T(g(),5),T(n,5),v(n,"showSweetAlert"),p(n,"hideSweetAlert"),v(n,"visible");var o=n.querySelector(".icon.success");v(o,"animate"),v(o.querySelector(".tip"),"animateSuccessTip"),v(o.querySelector(".long"),"animateSuccessLong");var r=n.querySelector(".icon.error");v(r,"animateErrorIcon"),v(r.querySelector(".x-mark"),"animateXMark");var a=n.querySelector(".icon.warning");v(a,"pulseWarning"),v(a.querySelector(".body"),"pulseWarningIns"),v(a.querySelector(".dot"),"pulseWarningIns"),e.onkeydown=A,t.onclick=I,O&&O.focus(),M=void 0}function s(){var e=m();e.style.marginTop=k(m())}var u=".sweet-alert",f=".sweet-overlay",d=["error","warning","info","success"],m=function(){return t.querySelector(u)},g=function(){return t.querySelector(f)},y=function(e,t){return new RegExp(" "+t+" ").test(" "+e.className+" ")},p=function(e,t){y(e,t)||(e.className+=" "+t)},v=function(e,t){var n=" "+e.className.replace(/[\t\r\n]/g," ")+" ";if(y(e,t)){for(;n.indexOf(" "+t+" ")>=0;)n=n.replace(" "+t+" "," ");e.className=n.replace(/^\s+|\s+$/g,"")}},b=function(e){var n=t.createElement("div");return n.appendChild(t.createTextNode(e)),n.innerHTML},h=function(e){e.style.opacity="",e.style.display="block"},w=function(e){if(e&&!e.length)return h(e);for(var t=0;t0?setTimeout(o,t):e.style.display="none"};o()},E=function(n){if(MouseEvent){var o=new MouseEvent("click",{view:e,bubbles:!1,cancelable:!0});n.dispatchEvent(o)}else if(t.createEvent){var r=t.createEvent("MouseEvents");r.initEvent("click",!1,!1),n.dispatchEvent(r)}else t.createEventObject?n.fireEvent("onclick"):"function"==typeof n.onclick&&n.onclick()},q=function(t){"function"==typeof t.stopPropagation?(t.stopPropagation(),t.preventDefault()):e.event&&e.event.hasOwnProperty("cancelBubble")&&(e.event.cancelBubble=!0)},O,I,A,M;e.sweetAlert=e.swal=function(){function n(e){var t=e.keyCode||e.which;if(-1!==[9,13,32,27].indexOf(t)){for(var n=e.target||e.srcElement,o=-1,r=0;r.btn{width:100%;padding-right:25px}.error .bootstrap-select .btn{border:1px solid #b94a48}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .btn:focus{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row-fluid .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-group .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.form-inline .bootstrap-select.btn-group .form-control{width:100%}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group .btn .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group[class*=col-] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;z-index:1035;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled) a small{color:#64b1d8;color:rgba(100,177,216,.4)}.bootstrap-select.btn-group .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.btn{z-index:1035+1}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom-width:7px;border-bottom-style:solid;border-bottom-color:#ccc;border-bottom-color:rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-bottom:0;border-top-width:7px;border-top-style:solid;border-top-color:#ccc;border-top-color:rgba(204,204,204,.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bs-searchbox,.bs-actionsbox{padding:4px 8px}.bs-actionsbox{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox input.form-control{margin-bottom:0;width:100%}.mobile-device{position:absolute;top:0;left:0;display:block!important;width:100%;height:100%!important;opacity:0}
--------------------------------------------------------------------------------
/public/stylesheets/default.css:
--------------------------------------------------------------------------------
1 | #wrapper {
2 | padding-left: 0;
3 | }
4 |
5 | #wrapper.toggled {
6 | padding-left: 250px;
7 | }
8 |
9 | #sidebar_wrapper {
10 | font-size: 18px;
11 | z-index: 1000;
12 | position: fixed;
13 | /*left: 460px;*/
14 | width: 0;
15 | height: 100%;
16 | margin-left: -460px;
17 | overflow-y: none;
18 | background-color: #29272c;
19 | background: url('/images/bg_login.jpg') bottom;
20 | }
21 |
22 | #sidebar_wrapper {
23 | color: #555;
24 | padding-left: 0px;
25 | padding-right: 0px;
26 | height: 100%;
27 | }
28 |
29 | #sidebar_wrapper .well {
30 | background-color: transparent;
31 | text-align: right;
32 | border: none;
33 | box-shadow: none;
34 | }
35 |
36 | #sidebar_wrapper .well.well-sm {
37 | line-height: 30px;
38 | }
39 |
40 | #wrapper.toggled #sidebar_wrapper {
41 | width: 460px;
42 | }
43 |
44 | #page_content_wrapper {
45 | width: 100%;
46 | }
47 |
48 | #sidebar_wrapper > div {
49 | position: absolute;
50 | width: 100%;
51 | padding-right: 40px;
52 | text-align: right;
53 | }
54 |
55 | .sidebar-welcome {
56 | position: absolute;
57 | bottom: 70%;
58 | color: #007da5;
59 | font-size: 24px;
60 | font-weight: bold;
61 | }
62 |
63 | .sidebar-welcome.mobile-version {
64 | visibility: visible;
65 | }
66 |
67 | #sidebar_choose_ip {
68 | top: 30%;
69 | }
70 |
71 | .sidebar-welcome div {
72 | width: 100%;
73 | }
74 |
75 | .sidebar-welcome .project-name {
76 | font-size: 42px;
77 | font-weight: normal;
78 | }
79 |
80 | .bottom-line {
81 | font-size: 14px;
82 | color: #999792;
83 | position: absolute;
84 | bottom: 3%;
85 | }
86 |
87 | .links-navbar {
88 | list-style-type: none;
89 | margin: 0;
90 | }
91 |
92 | .links-navbar li {
93 | display: inline-block;
94 | }
95 |
96 | .links-navbar li:not(:first-child):before {
97 | content: "|";
98 | margin: 0 15px;
99 | }
100 |
101 | .links-navbar a {
102 | color: #99979c;
103 | }
104 |
105 | .links-navbar a:hover {
106 | text-decoration: none;
107 | }
108 |
109 | .btn {
110 | color: #ffffff;
111 | /*background-color: #3372f2;*/
112 | background-color: #00a3d8;
113 | font-weight: normal;
114 | font-family: sans;
115 | }
116 |
117 | .btn:hover, .btn:active, .btn:focus {
118 | color: #ffffff;
119 | /*background-color: #1352e2;*/
120 | background-color: #00a3d8;
121 | }
122 |
123 | .btn.disabled, .btn[disabled] {
124 | background-color: #c9c7cc !important;
125 | }
126 |
127 | .btn.loading {
128 | /* temporarily hack: change to lada-spinner in future */
129 | background-image: url("/images/spinner.gif");
130 | background-position: center;
131 | background-repeat: no-repeat;
132 | text-indent: -1000px;
133 | }
134 |
135 | #connect_btn {
136 | width: 120px;
137 | margin-left: 14px;
138 | }
139 |
140 | .nice {
141 | margin-bottom: 0px;
142 | border-radius: 0px;
143 | height: 50px;
144 | }
145 |
146 | .font18 {
147 | font-size: 18px;
148 | }
149 |
150 | .radius-fixed {
151 | border-radius: 0px;
152 | }
153 |
154 | #row {
155 | position: absolute;
156 | top: 30%;
157 | }
158 |
159 | body {
160 | background-color: #e7e9ec;
161 | background: url('/images/bg_login.jpg') bottom right;
162 | }
163 |
164 | .arrow-right {
165 | margin-top: 16px;
166 | position: absolute;
167 | top: 30%;
168 | width: 0;
169 | height: 0;
170 | border-top: 8px solid transparent;
171 | border-bottom: 8px solid transparent;
172 | border-left: 8px solid #99979c;
173 | }
174 |
175 | #add_connection {
176 | text-align: center;
177 | padding-top: 70px;
178 |
179 | }
180 |
181 | .btn-enter {
182 | padding-top: 6px;
183 | vertical-align: bottom;
184 | padding-bottom: 32px;
185 | }
186 |
187 | .icon {
188 | background-image: url("/images/icons_16x16px.png");
189 | width: 16px;
190 | height: 16px;
191 | display: inline-block;
192 | }
193 |
194 | .icon.icon-add, .icon.icon-add {
195 | background-position: 0px 112px;
196 | }
197 |
198 | .icon.icon-add.disabled, .icon.icon-add[disabled] {
199 | background-position: 0px 32px;
200 | }
201 |
202 | label.mobile-version {
203 | color: #D3E4FF;
204 | }
205 |
206 | @media(min-width:768px) {
207 | body {
208 | /*background-image: none;*/
209 | background-color: #e7e9ec;
210 | }
211 |
212 | #wrapper {
213 | padding-left: 460px;
214 | }
215 |
216 | #wrapper.toggled {
217 | padding-left: 0;
218 | }
219 |
220 | #sidebar_wrapper {
221 | width: 460px;
222 | }
223 |
224 | #wrapper.toggled #sidebar_wrapper {
225 | width: 0;
226 | }
227 |
228 | #page_content_wrapper {
229 | /* padding: 20px; */
230 | }
231 |
232 | #wrapper.toggled #page_content_wrapper {
233 | position: relative;
234 | margin-right: 0;
235 | }
236 |
237 | .sidebar-welcome.mobile-version {
238 | visibility:hidden;
239 | }
240 |
241 | label.mobile-version {
242 | color: #99979C;
243 | }
244 |
245 | .arrow-right {
246 | border-left-color: black;
247 | }
248 |
249 | #row {
250 | position: absolute;
251 | top: 30%;
252 | width: 100%;
253 | left: 0px;
254 | padding-left: 475px;
255 | }
256 | }
257 |
--------------------------------------------------------------------------------
/public/stylesheets/plugins/metisMenu.min.css:
--------------------------------------------------------------------------------
1 | .arrow{float:right}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"}
--------------------------------------------------------------------------------
/public/stylesheets/plugins/scroller.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Scroller v3.0.4 - 2014-04-08
3 | * A jQuery plugin for replacing default browser scrollbars. Part of the Formstone Library.
4 | * http://formstone.it/scroller/
5 | *
6 | * Copyright 2014 Ben Plum; MIT Licensed
7 | */
8 |
9 | .scroller { overflow: hidden; overflow-x: hidden; overflow-y: hidden; position: relative; }
10 | .scroller-content { height: 100%; overflow: auto; overflow-x: hidden; overflow-y: auto; position: relative; z-index: 1;
11 | -webkit-overflow-scrolling: touch;
12 | }
13 | .scroller-bar { background: #FBFBFB; border-left: 1px solid #EEEEEE; display: none; height: 100%; position: absolute; right: 0; top: 0; width: 20px; z-index: 2; }
14 | .scroller-track { background: #FBFBFB; height: 100%; overflow: hidden; position: relative; width: 100%; }
15 | .scroller-handle { background: #EEEEEE; border: 1px solid #D5D5D5; border-radius: 5px; cursor: pointer; height: 20px; overflow: hidden; position: absolute; right: 5px; top: 0; width: 10px; z-index: 2;
16 | -webkit-transition: right 0.1s linear, width 0.1s linear;
17 | -moz-transition: right 0.1s linear, width 0.1s linear;
18 | -ms-transition: right 0.1s linear, width 0.1s linear;
19 | -o-transition: right 0.1s linear, width 0.1s linear;
20 | transition: right 0.1s linear, width 0.1s linear;
21 | }
22 |
23 | /* Webkit Fix */
24 | .scroller-content::-webkit-scrollbar,
25 | .scroller-content::-webkit-scrollbar-button,
26 | .scroller-content::-webkit-scrollbar-track,
27 | .scroller-content::-webkit-scrollbar-track-piece,
28 | .scroller-content::-webkit-scrollbar-thumb,
29 | .scroller-content::-webkit-scrollbar-corner,
30 | .scroller-content::-webkit-resizer { background: transparent; opacity: 0; }
31 |
32 | /* Active Scrollbar */
33 | .scroller-active .scroller-content { padding: 20px; }
34 | .scroller-active .scroller-bar { display: block; }
35 |
36 | /* Setup Scrollbar - Should match 'active' styles for proper sizing */
37 | .scroller-active .scroller-content { padding: 20px; }
38 | .scroller-active .scroller-bar { display: block; }
39 |
40 | /* Horizontal */
41 | .scroller-horizontal .scroller-content { overflow: auto; overflow-x: auto; overflow-y: hidden; padding: 0 0 10px 0; }
42 | .scroller-horizontal .scroller-bar { border-left: none; border-top: 1px solid #EEEEEE; bottom: 0; height: 20px; top: auto; width: 100%; }
43 | .scroller-horizontal .scroller-handle { bottom: 5px; height: 10px; right: auto; top: auto; width: 20px; }
--------------------------------------------------------------------------------
/public/stylesheets/sb-admin-2.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
3 | * Code licensed under the Apache License v2.0.
4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5 | */
6 |
7 | body {
8 | background-color: #f8f8f8;
9 | }
10 |
11 | #wrapper {
12 | width: 100%;
13 | }
14 |
15 | #page-wrapper {
16 | padding: 0 15px;
17 | min-height: 568px;
18 | background-color: #fff;
19 | }
20 |
21 | @media(min-width:768px) {
22 | #page-wrapper {
23 | position: inherit;
24 | margin: 0 0 0 250px;
25 | /*padding: 0 30px;*/
26 | border-left: 1px solid #e7e7e7;
27 | }
28 | }
29 |
30 | .navbar-top-links li {
31 | display: inline-block;
32 | }
33 |
34 | .navbar-top-links li:last-child {
35 | margin-right: 15px;
36 | }
37 |
38 | .navbar-top-links li a {
39 | padding: 15px;
40 | min-height: 50px;
41 | }
42 |
43 | .navbar-top-links .dropdown-menu li {
44 | display: block;
45 | }
46 |
47 | .navbar-top-links .dropdown-menu li:last-child {
48 | margin-right: 0;
49 | }
50 |
51 | .navbar-top-links .dropdown-menu li a {
52 | padding: 3px 20px;
53 | min-height: 0;
54 | }
55 |
56 | .navbar-top-links .dropdown-menu li a div {
57 | white-space: normal;
58 | }
59 |
60 | .navbar-top-links .dropdown-messages,
61 | .navbar-top-links .dropdown-tasks,
62 | .navbar-top-links .dropdown-alerts {
63 | width: 310px;
64 | min-width: 0;
65 | }
66 |
67 | .navbar-top-links .dropdown-messages {
68 | margin-left: 5px;
69 | }
70 |
71 | .navbar-top-links .dropdown-tasks {
72 | margin-left: -59px;
73 | }
74 |
75 | .navbar-top-links .dropdown-alerts {
76 | margin-left: -123px;
77 | }
78 |
79 | .navbar-top-links .dropdown-user {
80 | right: 0;
81 | /* left: auto; */
82 | margin-left: 5px;
83 | }
84 |
85 | .sidebar .sidebar-nav.navbar-collapse {
86 | padding-right: 0;
87 | padding-left: 0;
88 | }
89 |
90 | .sidebar .sidebar-search {
91 | padding: 15px;
92 | }
93 |
94 | .sidebar ul li {
95 | border-bottom: 1px solid #e7e7e7;
96 | }
97 |
98 | .sidebar ul li a.active {
99 | background-color: #eee;
100 | }
101 |
102 | .sidebar .arrow {
103 | float: right;
104 | }
105 |
106 | .sidebar .fa.arrow:before {
107 | content: "\f104";
108 | }
109 |
110 | .sidebar .active>a>.fa.arrow:before {
111 | content: "\f107";
112 | }
113 |
114 | .sidebar .nav-second-level li,
115 | .sidebar .nav-third-level li {
116 | border-bottom: 0!important;
117 | }
118 |
119 | .sidebar .nav-second-level li a {
120 | padding-left: 37px;
121 | }
122 |
123 | .sidebar .nav-third-level li a {
124 | padding-left: 52px;
125 | }
126 |
127 | @media(min-width:768px) {
128 | .sidebar {
129 | z-index: 1;
130 | position: absolute;
131 | width: 250px;
132 | margin-top: 51px;
133 | }
134 |
135 | .navbar-top-links .dropdown-messages,
136 | .navbar-top-links .dropdown-tasks,
137 | .navbar-top-links .dropdown-alerts {
138 | margin-left: auto;
139 | }
140 | }
141 |
142 | .btn-outline {
143 | color: inherit;
144 | background-color: transparent;
145 | transition: all .5s;
146 | }
147 |
148 | .btn-primary.btn-outline {
149 | color: #428bca;
150 | }
151 |
152 | .btn-success.btn-outline {
153 | color: #5cb85c;
154 | }
155 |
156 | .btn-info.btn-outline {
157 | color: #5bc0de;
158 | }
159 |
160 | .btn-warning.btn-outline {
161 | color: #f0ad4e;
162 | }
163 |
164 | .btn-danger.btn-outline {
165 | color: #d9534f;
166 | }
167 |
168 | .btn-primary.btn-outline:hover,
169 | .btn-success.btn-outline:hover,
170 | .btn-info.btn-outline:hover,
171 | .btn-warning.btn-outline:hover,
172 | .btn-danger.btn-outline:hover {
173 | color: #fff;
174 | }
175 |
176 | .chat {
177 | margin: 0;
178 | padding: 0;
179 | list-style: none;
180 | }
181 |
182 | .chat li {
183 | margin-bottom: 10px;
184 | padding-bottom: 5px;
185 | border-bottom: 1px dotted #999;
186 | }
187 |
188 | .chat li.left .chat-body {
189 | margin-left: 60px;
190 | }
191 |
192 | .chat li.right .chat-body {
193 | margin-right: 60px;
194 | }
195 |
196 | .chat li .chat-body p {
197 | margin: 0;
198 | }
199 |
200 | .panel .slidedown .glyphicon,
201 | .chat .glyphicon {
202 | margin-right: 5px;
203 | }
204 |
205 | .chat-panel .panel-body {
206 | height: 350px;
207 | overflow-y: scroll;
208 | }
209 |
210 | .login-panel {
211 | margin-top: 25%;
212 | }
213 |
214 | .flot-chart {
215 | display: block;
216 | height: 400px;
217 | }
218 |
219 | .flot-chart-content {
220 | width: 100%;
221 | height: 100%;
222 | }
223 |
224 | table.dataTable thead .sorting,
225 | table.dataTable thead .sorting_asc,
226 | table.dataTable thead .sorting_desc,
227 | table.dataTable thead .sorting_asc_disabled,
228 | table.dataTable thead .sorting_desc_disabled {
229 | background: 0 0;
230 | }
231 |
232 | table.dataTable thead .sorting_asc:after {
233 | content: "\f0de";
234 | float: right;
235 | font-family: fontawesome;
236 | }
237 |
238 | table.dataTable thead .sorting_desc:after {
239 | content: "\f0dd";
240 | float: right;
241 | font-family: fontawesome;
242 | }
243 |
244 | table.dataTable thead .sorting:after {
245 | content: "\f0dc";
246 | float: right;
247 | font-family: fontawesome;
248 | color: rgba(50,50,50,.5);
249 | }
250 |
251 | .btn-circle {
252 | width: 30px;
253 | height: 30px;
254 | padding: 6px 0;
255 | border-radius: 15px;
256 | text-align: center;
257 | font-size: 12px;
258 | line-height: 1.428571429;
259 | }
260 |
261 | .btn-circle.btn-lg {
262 | width: 50px;
263 | height: 50px;
264 | padding: 10px 16px;
265 | border-radius: 25px;
266 | font-size: 18px;
267 | line-height: 1.33;
268 | }
269 |
270 | .btn-circle.btn-xl {
271 | width: 70px;
272 | height: 70px;
273 | padding: 10px 16px;
274 | border-radius: 35px;
275 | font-size: 24px;
276 | line-height: 1.33;
277 | }
278 |
279 | .show-grid [class^=col-] {
280 | padding-top: 10px;
281 | padding-bottom: 10px;
282 | border: 1px solid #ddd;
283 | background-color: #eee!important;
284 | }
285 |
286 | .show-grid {
287 | margin: 15px 0;
288 | }
289 |
290 | .huge {
291 | font-size: 40px;
292 | }
293 |
294 | .panel-green {
295 | border-color: #5cb85c;
296 | }
297 |
298 | .panel-green .panel-heading {
299 | border-color: #5cb85c;
300 | color: #fff;
301 | background-color: #5cb85c;
302 | }
303 |
304 | .panel-green a {
305 | color: #5cb85c;
306 | }
307 |
308 | .panel-green a:hover {
309 | color: #3d8b3d;
310 | }
311 |
312 | .panel-red {
313 | border-color: #d9534f;
314 | }
315 |
316 | .panel-red .panel-heading {
317 | border-color: #d9534f;
318 | color: #fff;
319 | background-color: #d9534f;
320 | }
321 |
322 | .panel-red a {
323 | color: #d9534f;
324 | }
325 |
326 | .panel-red a:hover {
327 | color: #b52b27;
328 | }
329 |
330 | .panel-yellow {
331 | border-color: #f0ad4e;
332 | }
333 |
334 | .panel-yellow .panel-heading {
335 | border-color: #f0ad4e;
336 | color: #fff;
337 | background-color: #f0ad4e;
338 | }
339 |
340 | .panel-yellow a {
341 | color: #f0ad4e;
342 | }
343 |
344 | .panel-yellow a:hover {
345 | color: #df8a13;
346 | }
347 |
--------------------------------------------------------------------------------
/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | .glyphicon {
2 | color: #99979c;
3 | }
4 |
5 | #loading-indicator {
6 | position: fixed;
7 | left: 50%;
8 | top: 50%;
9 | z-index: 100;
10 | }
11 |
12 | #wrapper.sidebar-shown {
13 | overflow-x : hidden;
14 | }
15 | .sidebar-shown .sidebar {
16 | z-index: 1;
17 | position: absolute;
18 | width: 250px;
19 | display: block;
20 | }
21 |
22 | .sidebar-shown #page-wrapper {
23 | margin-left: 250px;
24 | width: 100%;
25 | }
26 |
27 | .sidebar-shown .sidebar {
28 | width: 250px;
29 | }
30 |
31 | .modal-body .table {
32 | word-break: break-all;
33 | }
34 |
35 | #page_overlay {
36 | width: 100%;
37 | height: 150%;
38 | background: #000;
39 | position: fixed;
40 | top: 0;
41 | left: 0;
42 | z-index: 50;
43 | opacity: 0.6;
44 | display: none;
45 | }
46 |
47 | .data-table td.Empty:before, .data-table td:Empty:before {
48 | content: "Not specified";
49 | color: #999;
50 | }
51 |
52 | .table-wrapper {
53 | border-left: 1px solid #ddd;
54 | border-right: 1px solid #ddd;
55 | overflow-x: auto;
56 | }
57 |
58 | .table-wrapper .table {
59 | margin-bottom: 0px;
60 | border-left: 0px;
61 | border-right: 0px;
62 | }
63 |
64 | .table-wrapper td:first-child, .table-wrapper th:first-child {
65 | border-left: 0px;
66 | }
67 |
68 | .table-wrapper td:last-child, .table-wrapper th:last-child {
69 | border-right: 0px;
70 | }
71 |
72 | .stats-table {
73 | font-size: 11px;
74 | }
75 |
76 | .stats-table td:empty:before {
77 | content: "N/A";
78 | color: #999;
79 | }
80 |
81 | .no-border {
82 | border: none;
83 | }
84 |
85 | /* device view */
86 | .panel-default>.panel-heading {
87 | background-color: inherit;
88 | }
89 |
90 | .panel {
91 | margin-bottom: 15px;
92 | }
93 |
94 | .panel-general {
95 | border: none;
96 | }
97 |
98 | .panel-body {
99 | /* padding-top: 10px;
100 | padding-bottom: 10px; */
101 | overflow-x: auto;
102 | }
103 |
104 | .sidebar-nav a {
105 | cursor: pointer;
106 | }
107 |
108 | /* for d3 */
109 |
110 | .switch_view {
111 | border: 1px solid #dddddd;
112 | padding: 7px;
113 | }
114 |
115 | .switch_view svg {
116 | margin-right: 7px;
117 | }
118 |
119 | .d3-tip.n {
120 | background-color: black;
121 | padding: 6px;
122 | border-radius: 3px;
123 | }
124 |
125 | .d3-tip {
126 | line-height: 1;
127 | font-weight: bold;
128 | padding: 12px;
129 | background: rgba(0, 0, 0, 0.5);
130 | color: #fff;
131 | border-radius: 2px;
132 | }
133 |
134 | /* Creates a small triangle extender for the tooltip */
135 | .d3-tip:after {
136 | box-sizing: border-box;
137 | display: inline;
138 | font-size: 10px;
139 | width: 100%;
140 | line-height: 1;
141 | color: rgba(0, 0, 0, 0.8);
142 | content: "\25BC";
143 | position: absolute;
144 | text-align: center;
145 | }
146 |
147 | /* Style northward tooltips differently */
148 | .d3-tip.n:after {
149 | margin: -1px 0 0 0;
150 | top: 100%;
151 | left: 0;
152 | }
153 |
154 |
155 | .uuid-links-list .uuid-link:not(:last-child):after {
156 | content: ", ";
157 | }
158 |
159 | .uuid-links-list:not(:empty) + .uuid-list-details:before {
160 | content: ", ";
161 | }
162 |
163 | .uuid-list-details a {
164 | font-weight: bold;
165 | }
166 |
167 | .iface {
168 | cursor : pointer;
169 | }
170 |
171 | .iface.up {
172 | fill : green;
173 | }
174 |
175 | .iface.down {
176 | fill : grey;
177 | }
178 |
179 | .iface.fail {
180 | fill : red;
181 | }
182 |
183 | .iface.error {
184 | stroke: orange;
185 | stroke-width: 2px;
186 | }
187 |
188 | /* axilera style */
189 | .nav>li {
190 | background: #3c3c3c !important;
191 | }
192 |
193 | .nav>li>a {
194 | color: #d9d9d9 !important;
195 | }
196 |
197 | .nav>li :hover {
198 | background: #303030 !important;
199 | }
200 |
201 | .nav.nav-tabs>li>a:active,
202 | .nav>li>a.active {
203 | background: #00a3d8 !important;
204 | }
205 |
206 | .nav-tabs>li.active>a, .nav-tabs>li.active>a:hover, .nav-tabs>li.active>a:focus {
207 | background: #00a3d8 !important;
208 | }
209 |
210 | .nav>li:active,
211 | .nav>li>a:focus {
212 | background: #00a3d8 !important;
213 | }
214 |
215 | .panel-info {
216 | border-color: #007da5;
217 | }
218 | .panel-info>.panel-heading {
219 | background-color: #00a3d8 !important;
220 | color: #d9d9d9 !important;
221 | }
222 |
223 | a:focus,
224 | li.selected:focus {
225 | outline-color: #007da5 !important;
226 | }
227 |
--------------------------------------------------------------------------------
/routes/bridge_stats_route.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | * Copyright (C) 2014-2016 PLVision
4 | * Ihor Chumak, Roman Gotsiy
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 |
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 |
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see .
18 |
19 | * PLVision, developers@plvision.eu
20 | */
21 |
22 | var client_manager = require("../lib/client-manager.js")();
23 | var utils = require("../lib/utils.js");
24 | var extend = require("../lib/extend.js");
25 | //var extend = require("extend")
26 |
27 | module.exports.stats_route = function (req, res, next) {
28 | var db_name = req.session.db_name;
29 | var addr = req.session.connection;
30 | var bridge_name = req.params.bridge_name;
31 |
32 | var userid = "test";
33 | client_manager.client(userid, addr, function (err, client) {
34 | var stats = {};
35 | client.database(db_name).tableByName("Bridge").find_by_name(bridge_name).ports().each(function (port, next_port) {
36 | port.data(["name", "statistics", "interfaces"], function (err, port_data) {
37 | if (err) {
38 | return next_port(err);
39 | }
40 | if (port_data.statistics[1].length) {
41 | stats[port_data.name] = utils.map_array2map(port_data.statistics);
42 | };
43 | // TODO: bound port is temporary skipped
44 | if (port_data.interfaces[0] !== "uuid") {
45 | return next_port();
46 | }
47 |
48 | var uuid = port_data.interfaces[1];
49 | port.interfaces().get(uuid).data(["statistics"], function (err, iface_data) {
50 | if (err)
51 | return next_port(err);
52 | stats[port_data.name] = extend(stats[port_data.name],
53 | utils.map_array2map(iface_data.statistics));
54 | next_port();
55 | });
56 | }
57 | );
58 | }, function (err) {
59 | res.send(JSON.stringify(stats)).end();
60 | });
61 | });
62 | };
63 |
--------------------------------------------------------------------------------
/routes/custom_data_loaders.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | * Copyright (C) 2014-2016 PLVision
4 | * Ihor Chumak, Roman Gotsiy
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 |
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 |
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see .
18 |
19 | * PLVision, developers@plvision.eu
20 | */
21 |
22 |
23 | /*
24 | * file with extra-data loaders for some tables
25 | * USED BY: table_routes_info.js
26 | */
27 | var utils = require("../lib/utils.js");
28 | var asyncForEach = require("async").forEach;
29 |
30 | /* extra-data loader for bridge table. Loads bridge controllers info */
31 | var object_bridge_data_loader = function (bridge_data, db, callback) {
32 | var additiona_data = {};
33 | if (bridge_data instanceof Array) {
34 | bridge_data = bridge_data[0];
35 | }
36 | db.bridges().get(bridge_data._uuid).controllers().data(["is_connected", "target", "status"], function (err, controllers) {
37 | if (err) return callback(err);
38 | for (var i = 0; i < controllers.length; i++) {
39 | controllers[i].status = utils.map_array2map(controllers[i].status);
40 | }
41 | additiona_data.controllers = controllers;
42 | callback(null, additiona_data);
43 | });
44 | };
45 |
46 | /* extra-data loader for port/ports table. Loads interfaces and qoses info */
47 | var ports_data_loader = function (ports_data, db, callback) {
48 | var additional_data = { interfaces: {} };
49 | if (!(ports_data instanceof Array)) {
50 | ports_data = [ports_data];
51 | }
52 |
53 | asyncForEach(ports_data, function (port, next_port) {
54 | db.ports().get(port._uuid).interfaces().data(["name", "statistics"], function (err, interface_data) {
55 | if (err) return next_port(err);
56 | additional_data.interfaces[port.name] = interface_data;
57 | next_port();
58 | });
59 | }, function (err) {
60 | callback(err, additional_data);
61 | });
62 |
63 | };
64 |
65 | var bridges_data_loader = function (bridges_data, db, callback) {
66 | var additional_data = { controllers: {} };
67 | if (!(bridges_data instanceof Array)) {
68 | bridges_data = [bridges_data];
69 | }
70 |
71 | asyncForEach(bridges_data, function (bridge, next_bridge) {
72 | db.bridges().get(bridge._uuid).controllers().data(["is_connected", "target", "status"], function (err, controller_data) {
73 | if (err) return next_bridge(err);
74 | additional_data.controllers[bridge.name] = controller_data;
75 | next_bridge();
76 | });
77 | }, function (err) {
78 | callback(err, additional_data);
79 | });
80 |
81 | };
82 |
83 |
84 | module.exports = {
85 | object_bridge_data_loader: object_bridge_data_loader,
86 | ports_data_loader: ports_data_loader,
87 | bridges_data_loader: bridges_data_loader
88 | };
89 |
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | * Copyright (C) 2014-2016 PLVision
4 | * Ihor Chumak, Roman Gotsiy
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 |
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 |
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see .
18 |
19 | * PLVision, developers@plvision.eu
20 | */
21 |
22 | //var extend = require("extend");
23 | var extend = require("../lib/extend.js");
24 | var table_routes = require("./table_routes.js");
25 | var bridge_stats_route = require("./bridge_stats_route.js");
26 |
27 | extend(module.exports, table_routes, bridge_stats_route);
28 |
--------------------------------------------------------------------------------
/routes/table_routes.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | * Copyright (C) 2014-2016 PLVision
4 | * Ihor Chumak, Roman Gotsiy
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 |
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 |
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see .
18 |
19 | * PLVision, developers@plvision.eu
20 | */
21 |
22 | var client_manager = require("../lib/client-manager.js")();
23 | var utils = require("../lib/utils.js");
24 | var custom_data_loaders = require("./custom_data_loaders.js");
25 | var routes_info = require("./table_routes_info.js");
26 |
27 |
28 | /* Abstract table route.
29 | * basic routine for rendering entities from db
30 | * is customisated by parameters:
31 | * - load_data: async function that loads data
32 | * - get_table_title: function that build table title
33 | * - is_table: bool responsible for search table details if routes_info
34 | */
35 | var AbstractTableRoute = function (load_data, get_table_title, is_table) {
36 | this.load_data = load_data;
37 | this.get_table_title = get_table_title;
38 | this.is_table = is_table;
39 | };
40 |
41 | AbstractTableRoute.prototype.route = function (req, res, next) {
42 | var self = this;
43 | var addr = req.session.connection;
44 | var db_name = req.session.db_name;
45 | var table = req.params.table;
46 | var userid = req.session.userid;
47 |
48 | client_manager.client(userid, addr, function (err, client) {
49 | if (err) {
50 | return next(err);
51 | }
52 | var db = client.database(db_name);
53 | try {
54 | self.load_data(db, req, function (err, data) {
55 | if (err)
56 | return next(err);
57 |
58 | var table_schema = client.db_schema(db_name).tables[table];
59 | var custom_tmpl;
60 | if (self.is_table)
61 | custom_tmpl = routes_info.custom_templates.tables[table];
62 | else
63 | custom_tmpl = routes_info.custom_templates.objects[table];
64 |
65 | var additional_data_loader;
66 | var template;
67 | if (custom_tmpl) {
68 | template = custom_tmpl.template;
69 | additional_data_loader = custom_tmpl.additional_data_loader;
70 | }
71 |
72 | if (!template)
73 | template = ((!self.is_table) || routes_info.vtables.includes(table)) ? "vtable" : "htable";
74 |
75 | var title = self.get_table_title(req);
76 | var additional_data;
77 |
78 | var render = function () {
79 | res.renderView(template, {
80 | title: title,
81 | data: data,
82 | table_schema: table_schema,
83 | table: table,
84 | additional_data: additional_data
85 | });
86 | };
87 |
88 | if (additional_data_loader) {
89 | additional_data_loader(data, client.database(db_name), function (err, extra_data) {
90 | if (err) {
91 | return next(err);
92 | }
93 | additional_data = extra_data;
94 | render();
95 | });
96 | } else {
97 | render();
98 | }
99 | });
100 | } catch (e) {
101 | next(e);
102 | }
103 | });
104 | };
105 |
106 | /* route for some table */
107 | var table_route = function (req, res, next) {
108 | var table = req.params.table;
109 |
110 | var load_data_strategy = function (db, req, callback) {
111 | db.tableByName(table).data(callback);
112 | };
113 |
114 | var get_table_title_strategy = function (req) {
115 | return table + "s list";
116 | };
117 |
118 | (new AbstractTableRoute(load_data_strategy, get_table_title_strategy, true)).route(req, res, next);
119 |
120 | };
121 |
122 | /* route for special object from some table */
123 | var table_object_route = function (req, res, next) {
124 | var obj_name = req.params.row_name;
125 | var table = req.params.table;
126 |
127 | var load_data_strategy = function (db, req, callback) {
128 | db.tableByName(table).find_by_name(obj_name).data(callback);
129 | };
130 |
131 | var get_table_title_strategy = function (req) {
132 | return table + " " + obj_name;
133 | };
134 |
135 | (new AbstractTableRoute(load_data_strategy, get_table_title_strategy, false)).route(req, res, next);
136 |
137 | };
138 |
139 | /* route for children of special object from some parent table */
140 | var table_object_subtable_route = function (req, res, next) {
141 | var parent_obj_name = req.params.parent_obj_name;
142 | var parent_table = req.params.parent_table;
143 | var table = req.params.table;
144 |
145 | var load_data_strategy = function (db, req, callback) {
146 | db.tableByName(parent_table).find_by_name(parent_obj_name).tableByName(table).data(callback);
147 | };
148 |
149 | var get_table_title_strategy = function (req) {
150 | return table + "s of " + parent_table + " " + parent_obj_name;
151 | };
152 |
153 | (new AbstractTableRoute(load_data_strategy, get_table_title_strategy, true)).route(req, res, next);
154 |
155 | };
156 |
157 | module.exports = {
158 | table_route: table_route,
159 | table_object_route: table_object_route,
160 | table_object_subtable_route: table_object_subtable_route
161 | };
162 |
--------------------------------------------------------------------------------
/routes/table_routes_info.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | * Copyright (C) 2014-2016 PLVision
4 | * Ihor Chumak, Roman Gotsiy
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 |
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 |
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see .
18 |
19 | * PLVision, developers@plvision.eu
20 | */
21 |
22 | /*
23 | * Contains informations that specify some features of concrete table route
24 | */
25 |
26 | var custom_data_loaders = require("./custom_data_loaders.js");
27 |
28 | /* list of tables that should be vertical */
29 | var vtables = ["Open_vSwitch", "SSL", "IPFIX", "NetFlow", "sFlow"];
30 |
31 | /* specify for table custom template and if need loader of additional date needed by that template */
32 | var custom_templates = {
33 | tables: {
34 | "Open_vSwitch": {
35 | template: "custom/table_openvswitch"
36 | },
37 | "Bridge": {
38 | template: "custom/table_bridge",
39 | additional_data_loader: custom_data_loaders.bridges_data_loader
40 | },
41 | "Manager": {
42 | template: "custom/table_manager"
43 | },
44 | "Port": {
45 | template: "custom/table_port",
46 | additional_data_loader: custom_data_loaders.ports_data_loader
47 | },
48 | /* bug #89
49 | "SSL" : {
50 | template : "custom/table_ssl"
51 | }, */
52 | "Controller": {
53 | template: "custom/table_controller"
54 | },
55 | "Interface": {
56 | template: "custom/table_interface"
57 | }
58 | },
59 | objects: {
60 | "Bridge": {
61 | template: "custom/object_bridge",
62 | additional_data_loader: custom_data_loaders.object_bridge_data_loader
63 | },
64 | }
65 | };
66 |
67 | module.exports = {
68 | vtables: vtables,
69 | custom_templates: custom_templates
70 | };
71 |
--------------------------------------------------------------------------------
/views/404.jade:
--------------------------------------------------------------------------------
1 | //
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends general_table
22 |
23 | block tablecontent
24 | .row
25 | .col-lg-12
26 | h1.text-warning.page-header 404 Not found
27 | h4 Route
28 | strong #{route}
29 | | was not found
30 |
--------------------------------------------------------------------------------
/views/500.jade:
--------------------------------------------------------------------------------
1 | //
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | h1 500 Internal Server Error
22 |
23 | h4 Reload button may correct the error. If the error persists, connection to ovsdb-server may be lost: try to
24 | a(href="/logout") disconnect
25 | | and connect again.
26 |
--------------------------------------------------------------------------------
/views/alerts.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends general_table
22 |
23 | block tablecontent
24 | .row
25 | .col-lg-12
26 | h1.page-header Alerts
27 | ul.nav.nav-tabs(role='tablist')
28 | li.active
29 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
30 | //li
31 | a(href='#table', role='tab', data-toggle='tab') Table view
32 | div.tab-content
33 | div#plates.tab-pane.active(style="padding-top:10px;")
34 | .panel.panel-info
35 | .panel-heading
36 | strong Alerts
37 | .panel-body
38 | .row
39 | .col-lg-12
40 | h4 Available only in Full Version
41 | table.table.data-table.table-bordered
42 | tbody
43 | - var idx = 0
44 | each update in updates
45 | - var key = Object.keys(update)[0];
46 | - var record = update[key]
47 | - var actions = '';
48 | - var uuids = Object.keys(record);
49 | tr
50 | td #{idx}
51 | td
52 | each uuid in uuids
53 | - var name = record[uuid].old ? record[uuid].old.name : record[uuid].new.name;
54 | - var method = record[uuid].old ? 'removed' : 'created';
55 | - actions += "\"" + name + "\" " + method + " ";
56 | | #{key}: #{actions}
57 | - idx++;
58 | //.panel-footer
59 | //a(href='/alerts/clear') Clear
60 | div#table.tab-pane
61 | .table-wrapper
62 |
--------------------------------------------------------------------------------
/views/custom/object_bridge.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | - bridge = data
26 | if (bridge instanceof Array)
27 | - bridge = bridge[0]
28 |
29 | .row
30 | .col-lg-12
31 | h1.page-header Bridge: #{bridge.name}
32 | ul.nav.nav-tabs(role='tablist')
33 | li.active
34 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
35 | li
36 | a(href='#table', role='tab', data-toggle='tab') Table view
37 |
38 | div.tab-content
39 | div#plates.tab-pane.active(style="padding-top:10px;")
40 | .row
41 | .col-lg-5
42 | .row
43 | .col-lg-12
44 | .panel.panel-info
45 | .panel-heading
46 | strong Info
47 | .panel-body
48 | .row
49 | .col-lg-12
50 | table.table.data-table
51 | tbody
52 | tr
53 | td Datapath ID
54 | td #{bridge['datapath_id']}
55 | tr
56 | td Fail mode
57 | +comma_separated_set_td(bridge['fail_mode'])
58 | tr
59 | td OpenFlow Versions
60 | +comma_separated_set_td(bridge['protocols'])
61 | tr
62 | td Flood VLANs
63 | +comma_separated_set_td(bridge['flood_vlans'])
64 | tr
65 | td STP Enable
66 | td #{bridge['stp_enable']}
67 | .row
68 | .col-lg-12
69 | .panel.panel-info
70 | - controllers = additional_data.controllers
71 | .panel-heading
72 | strong Bridge Controllers
73 | .panel-body
74 | .row
75 | .col-lg-12
76 | table.table.data-table
77 | thead
78 | th Target
79 | th Connected
80 | th State
81 | th
82 | |Connected time
83 | h6 (in seconds)
84 | th Last error
85 | tbody
86 | each controller in controllers
87 | tr
88 | td #{controller.target}
89 | - var cls = (controller.is_connected) ? "text-success" : "text-danger"
90 | td(class="#{cls}") #{controller.is_connected}
91 | td #{controller.status.state}
92 | td #{controller.status.sec_since_connect}
93 | td.text-danger #{controller.status.last_error}
94 | .col-lg-7
95 | .panel.panel-info
96 | .panel-heading
97 | strong Ports
98 | .panel-body
99 | .row
100 | .col-lg-6
101 | .row
102 | .col-lg-6
103 | +children_list("Ports", bridge.ports, "Bridge", "Port", bridge.name)
104 | .row
105 | .col-lg-12
106 | h4 Switch view
107 | .switch_view(id="br_#{bridge.name}")
108 | .col-lg-6
109 | .row
110 | .col-lg-12
111 | h4 Ports statistics
112 | div.scrollbar
113 | table.table#port_stats.stats-table
114 | div#table.tab-pane
115 | .table-wrapper
116 | include ../include/vtable_inc
117 |
118 | script.
119 | $(document).ready(function() {
120 | draw_switch_view(".switch_view", function(){});
121 | display_port_stats("#port_stats", "#{bridge.name}");
122 | });
123 |
--------------------------------------------------------------------------------
/views/custom/table_bridge.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header Bridges list
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | - for (var row = 0; row < data.length / 3; row++)
36 | .row
37 | - for (var index = row * 3; index < row*3+3 && index < data.length; index++)
38 | - bridge = data[index];
39 | .col-lg-4
40 | .panel.panel-info
41 | .panel-heading
42 | strong #{bridge.name}
43 | .panel-body
44 | .row
45 | .col-lg-12
46 | h4 Basic info
47 | table.table.data-table
48 | tbody
49 | tr
50 | td Datapath ID
51 | td #{bridge['datapath_id']}
52 | tr
53 | td Fail mode
54 | +comma_separated_set_td(bridge['fail_mode'])
55 | tr
56 | td OpenFlow Versions
57 | +comma_separated_set_td(bridge['protocols'])
58 | tr
59 | td Ports
60 | td
61 | +comma_separated_uuids_links(bridge['ports'])
62 | tr
63 | td Mirrors
64 | td
65 | +comma_separated_uuids_links(bridge['mirrors'])
66 | .row
67 | .col-lg-12
68 | h4 Switch view
69 | .switch_view(id="br_#{bridge.name}")
70 | .row
71 | .col-lg-12
72 | h4 Controllers
73 | table.table.data-table
74 | - controllers = additional_data.controllers[bridge.name]
75 | each controller in controllers
76 | tr
77 | td #{controller.target}
78 | - var cls = (controller.is_connected) ? "text-success" : "text-danger"
79 | td(class="#{cls}") #{controller.is_connected ? "Connected" : "Disconected"}
80 | -//.row
81 | -//.col-lg-6
82 | -//+children_list("Ports", bridge.ports, "Bridge", "Port", bridge.name)
83 | -//.col-lg-6
84 | -//+children_list("Mirrors", bridge.mirrors, "Bridge", "Mirror", bridge.name)
85 |
86 | .panel-footer
87 | a(href="/Bridge/#{bridge.name}") Details
88 | div#table.tab-pane
89 | .table-wrapper
90 | include ../include/htable_inc
91 |
92 | script.
93 | $(document).ready(function() {
94 | draw_switch_view(".switch_view");
95 | });
96 |
--------------------------------------------------------------------------------
/views/custom/table_controller.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header #{title}
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | each controller in data
37 | .col-lg-4
38 | .panel.panel-info
39 | .panel-heading
40 | strong Controller
41 | .panel-body
42 | .row
43 | .col-lg-12
44 | h4 Basic info
45 | table.table.data-table
46 | tbody
47 | tr
48 | td Target
49 | td #{controller['target']}
50 | tr
51 | td Connected
52 | td #{controller['is_connected']}
53 | tr
54 | td Local Network Mask
55 | +comma_separated_set_td(controller['local_netmask'])
56 | tr
57 | td Local Gateway
58 | +comma_separated_set_td(controller['local_gateway'])
59 | tr
60 | td Maximum Back-off
61 | +comma_separated_set_td(controller['max_backoff'])
62 | tr
63 | td Local IP
64 | +comma_separated_set_td(controller['local_ip'])
65 | .row
66 | .col-lg-12
67 | h4 Status (
68 | +set_length(controller['status'])
69 | |)
70 | +comma_separated_list_map(controller['status'])
71 | .row
72 | .col-lg-12
73 | h4 External IDs(
74 | +set_length(controller['external_ids'])
75 | |)
76 | +comma_separated_list_map(controller['external_ids'])
77 | .row
78 | .col-lg-12
79 | h4 Other Configuration(
80 | +set_length(controller['other_config'])
81 | |)
82 | +comma_separated_list_map(controller['other_config'])
83 | .panel-footer
84 | a(href="/Controller#table") Details
85 | div#table.tab-pane
86 | .table-wrapper
87 | include ../include/htable_inc
88 |
89 | script
90 |
--------------------------------------------------------------------------------
/views/custom/table_interface.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header All Interfaces
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | each interface in data
37 | .col-lg-4
38 | .panel.panel-info
39 | .panel-heading
40 | strong Interface
41 | .panel-body
42 | .row
43 | .col-lg-12
44 | h4 Basic info
45 | table.table.data-table
46 | tbody
47 | tr
48 | td Name
49 | td #{interface['name']}
50 | tr
51 | td MAC
52 | td #{interface['mac_in_use']}
53 | tr
54 | td Link State
55 | td #{interface['link_state']}
56 | tr
57 | td Link Speed
58 | if (interface['link_speed'] instanceof Array)
59 | +comma_separated_set_td(interface['link_speed'])
60 | else
61 | td #{interface['link_speed']}
62 | tr
63 | td Duplex
64 | if (interface['duplex'] instanceof Array)
65 | +comma_separated_set_td(interface['duplex'])
66 | else
67 | td #{interface['duplex']}
68 | tr
69 | td MTU
70 | td #{interface['mtu']}
71 | -//+comma_separated_set_td(interface['connection_mode'])
72 | -//tr
73 | -//td Status
74 | -//td
75 | -//+comma_separated_list_map(interface['statistics'])
76 | .row
77 | .col-lg-12
78 | h4 Status(
79 | +set_length(interface['status'])
80 | |)
81 | +comma_separated_list_map(interface['status'])
82 | .row
83 | .col-lg-12
84 | h4 Statistics(
85 | +set_length(interface['statistics'])
86 | |)
87 | +comma_separated_list_map(interface['statistics'])
88 |
89 | .panel-footer
90 | a(href="/Interface/#{interface['name']}") Details
91 | div#table.tab-pane
92 | .table-wrapper
93 | include ../include/htable_inc
94 |
--------------------------------------------------------------------------------
/views/custom/table_manager.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header Managers
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | each manager in data
37 | .col-lg-4
38 | .panel.panel-info
39 | .panel-heading
40 | - var state = manager['status'][1].filter(function(element, index) { if (element[0] == 'state') return element[1] })[0];
41 | - state = state ? state[1] : 'INACTIVE'
42 | - // should be in lowercase
43 | strong Manager (#{state.toLowerCase()})
44 | .panel-body
45 | .row
46 | .col-lg-12
47 | h4 Basic info
48 | table.table.data-table
49 | tbody
50 | tr
51 | td Target
52 | td #{manager['target']}
53 | tr
54 | td Connection Status
55 | - var connection_status = (manager['is_connected'] == false ? 'Disconnected' : 'Connected');
56 | td #{connection_status}
57 |
58 | tr
59 | td Maximum Back-off
60 | +comma_separated_set_td(manager['max_backoff'])
61 | tr
62 | td Connection Mode
63 | +comma_separated_set_td(manager['connection_mode'])
64 | tr
65 | td Status
66 | td
67 | +comma_separated_list_map(manager['status'])
68 | .row
69 | .col-lg-12
70 | h4 External IDs(
71 | +set_length(manager['external_ids'])
72 | |)
73 | +comma_separated_list_map(manager['external_ids'])
74 | .row
75 | .col-lg-12
76 | h4 Other Configurations(
77 | +set_length(manager['other_config'])
78 | |)
79 | +comma_separated_list_map(manager['other_config'])
80 | div#table.tab-pane
81 | .table-wrapper
82 | include ../include/htable_inc
83 |
--------------------------------------------------------------------------------
/views/custom/table_openvswitch.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header Open_vSwitch
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | - openvswitch = data[0];
37 | .col-lg-6
38 | .panel.panel-info
39 | .panel-heading
40 | strong Open_vSwitch
41 | .panel-body
42 | .row
43 | .col-lg-12
44 | h4 Basic info
45 | table.table.data-table
46 | tbody
47 | tr
48 | td System Version
49 | +comma_separated_set_td(openvswitch['system_version'])
50 | tr
51 | td System Type
52 | +comma_separated_set_td(openvswitch['system_type'])
53 | tr
54 | td Bridges
55 | td
56 | +comma_separated_uuids_links(openvswitch['bridges'])
57 | tr
58 | td Manager Options
59 | td
60 | +comma_separated_uuids_links(openvswitch['manager_options'])
61 | tr
62 | td OVS Version
63 | +comma_separated_set_td(openvswitch['ovs_version'])
64 | tr
65 | td SSL
66 | td
67 | +comma_separated_uuids_links(openvswitch['ssl'], true)
68 | tr
69 | td Database Version
70 | +comma_separated_set_td(openvswitch['db_version'])
71 | tr
72 | td Current Configuration
73 | td #{openvswitch['cur_cfg']}
74 |
75 | -//+children_list("Bridges", openvswitch.bridges, "Open_vSwitch", "Bridge")
76 | -//+children_list("Managers", openvswitch.manager_options, "Manager", "Manager")
77 |
78 | .row
79 | .col-lg-6
80 | -//+children_list("Mirrors", undefined, "Bridge", "Mirror", openvswitch.name)
81 | .row
82 | .col-lg-6
83 | -//+children_list("Controllers", openvswitch.controller, "Bridge", "Controller", openvswitch.name)
84 | //.panel-footer
85 | //a(href="/Bridge")
86 | div#table.tab-pane
87 | .table-wrapper
88 | include ../include/vtable_inc
89 |
--------------------------------------------------------------------------------
/views/custom/table_port.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header #{title}
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | .col-lg-6
37 | - ports_general_info_cols = { "name" : {"caption" : "Port name"}, "vlan_mode" : {"caption" : "VLAN mode"}, "trunks": { "caption": "Trunks"}, "tag" : {"caption": "Tag"}, "lacp" : {"caption" : "LACP"}, "mac" : {"caption" : "MAC"} }
38 | .panel.panel-info
39 | .panel-heading
40 | strong General info
41 | .panel-body
42 | div.table-wrapper
43 | table.table.table-bordered.data-table
44 | thead
45 | tr
46 | each col_detail, col in ports_general_info_cols
47 | th #{col_detail.caption}
48 | tbody
49 | each port, idx in data
50 | tr
51 | each col_detail, col in ports_general_info_cols
52 | td
53 | +display_complex_data(port[col], col_detail.caption)
54 | .col-lg-6
55 | .panel.panel-info
56 | - port_interfaces = additional_data.interfaces
57 | .panel-heading
58 | strong Interfaces of ports
59 | .panel-body
60 | div.table-wrapper
61 | table.table.table-bordered.data-table
62 | thead
63 | tr
64 | th Port
65 | th Interfaces
66 | tbody
67 | each port, idx in data
68 | tr
69 | td #{port.name}
70 | td
71 | +comma_separated_uuids_links(port.interfaces)
72 | .row
73 | .col-lg-6
74 | .panel.panel-info
75 | .panel-heading
76 | strong Ports statistics
77 | .panel-body
78 | div.scrollbar
79 | table.table#port_stats.stats-table
80 |
81 | div#table.tab-pane
82 | .table-wrapper
83 | include ../include/htable_inc
84 |
85 | script.
86 | $(document).ready(function() {
87 | display_port_stats("#port_stats");
88 | });
89 |
--------------------------------------------------------------------------------
/views/custom/table_ssl.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends ../general_table
22 | include ../include/mixins
23 |
24 | block tablecontent
25 | .row
26 | .col-lg-12
27 | h1.page-header SSL
28 | ul.nav.nav-tabs(role='tablist')
29 | li.active
30 | a(href='#plates', role='tab', data-toggle='tab') Tiles view
31 | li
32 | a(href='#table', role='tab', data-toggle='tab') Table view
33 | div.tab-content
34 | div#plates.tab-pane.active(style="padding-top:10px;")
35 | .row
36 | each ssl in data
37 | .col-lg-6
38 | .panel.panel-info
39 | .panel-heading
40 | strong SSL
41 | .panel-body
42 | .row
43 | .col-lg-12
44 | h4 Basic info
45 | table.table.data-table
46 | tbody
47 | tr
48 | td CA Cert
49 | td #{ssl['ca_cert']}
50 | tr
51 | td Bootstrap CA Cert
52 | - var is_empty = ssl['bootstrap_ca_cert'] === false
53 | td
54 | - if (is_empty)
55 | | false
56 | - else
57 | | #{ssl['bootstrap_ca_cert']}
58 | tr
59 | td Private Key
60 | td #{ssl['private_key']}
61 | tr
62 | td Certificate
63 | td #{ssl['certificate']}
64 |
65 | .row
66 | .col-lg-12
67 | h4 External IDs(
68 | +set_length(ssl['external_ids'])
69 | |)
70 | +comma_separated_list_map(ssl['external_ids'])
71 | //.panel-footer
72 | //a(href="/SSL#table") Details
73 | div#table.tab-pane
74 | .table-wrapper
75 | include ../include/vtable_inc
76 |
77 | script
78 |
--------------------------------------------------------------------------------
/views/dashboard.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends index
22 | block maincontent
23 | .devices
24 | each br in bridges
25 | - //var led_dimensions = { width : 16, height : 8 };
26 | - //var len = br.ports.length < 10 ? 10 : br.ports.length % 2 ? br.ports.length + 1 : br.ports.length;
27 | - //var panel_dimensions = { width : ((len / 2 >> 0) + 1 )*3 + (len / 2 >> 0)*led_dimensions.width + 2, height : 2*3 + 2*led_dimensions.height + 8 + 2 };
28 | - //var view_dimensions = { width : panel_dimensions.width + 2*8, height : panel_dimensions.height + 2*12 };
29 |
30 | .panel.panel-default
31 | .panel-heading
32 | |Bridge: #{br.name}
33 | .panel-body
34 | .switch_view(id="#{br.name}")
35 | - //svg(height="#{view_dimensions.height}", width="#{view_dimensions.width}")
36 | - //rect(x=0, y=0, width=view_dimensions.width, height=view_dimensions.height, style="fill:rgb(247,244,251); stroke: black;")
37 | - //rect(x=8, y=12, width=panel_dimensions.width, height=panel_dimensions.height, style="fill:rgb(247,244,251); stroke: black;")
38 | - //var x = 12
39 | - //var y = 16
40 | - //num = 0
41 | - //var line = (len / 2 >> 0);
42 | - //each port in br.ports
43 | - //if (num == line)
44 | - //num = 0;
45 | - //y += 2*led_dimensions.height;
46 | - //x = 12;
47 | - //else
48 | - //var color = port.link_state == "up" ? "rgb(118,181,18)" : "rgb(228,77,58)";
49 | - //rect.led(x=x, y=y, width=led_dimensions.width, height=led_dimensions.height, style="fill: #{color}; stroke: black;")
50 | - //title
51 | - //|#{port}
52 | - //x += led_dimensions.width + 3;
53 | - //num++;
54 | script.
55 | $(document).ready(function() {
56 | draw_switch_view(".switch_view");
57 | });
58 |
--------------------------------------------------------------------------------
/views/enter.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | doctype html
22 | html(lang="en")
23 | head
24 | meta(charset="utf-8")
25 | meta(http-equiv="X-UA-Compatible", content="IE=edge")
26 | meta(name="viewport", content="width=device-width, initial-scale=1")
27 | meta(name="description", content="")
28 | meta(name="author", content="")
29 | title= title
30 | link(rel='stylesheet', href='/stylesheets/bootstrap.min.css')
31 | link(rel='stylesheet', href='/stylesheets/default.css')
32 | link(rel='stylesheet', href='/stylesheets/sweet-alert.css')
33 | script(src="/js/jquery-1.11.1.min.js")
34 | script(src="/js/bootstrap.min.js")
35 | script(src="/js/sweet-alert.min.js")
36 |
37 | body.cable
38 | #wrapper
39 | #sidebar_wrapper
40 | .sidebar-welcome
41 | div PLVision
42 | .project-name Open_vMonitor
43 | #sidebar_choose_ip.well.well-sm.nice Enter Credentials
44 | .well.well-sm.nice(style="margin-top: 72px; padding-right: 0px;") Enter OVSDB IP
45 | .bottom-line
46 | -// copyright here
47 |
48 | #page_content_wrapper
49 | .arrow-right
50 | .container-fluid
51 | .sidebar-welcome.mobile-version.col-lg-6
52 | div PLVision
53 | .project-name OVS Open_vMonitor
54 | .row-fluid#row
55 | .col-lg-6
56 | .row
57 | .col-lg-12
58 | .input-group
59 | input.form-control.nice.font18#username(type="text", placeholder="login", value="#{username}")
60 | input.form-control.nice.font18#password(type="password", placeholder="password", style="margin-top: 2px;")
61 | input.form-control.nice.font18#database_ip_address(type="text", value="#{connection}", placeholder="Database IP Address", style="margin-top: 6px;")
62 | label.mobile-version
63 | //input#secure(type="checkbox")
64 | //| Use secured connection
65 | button.btn.btn-default.font18.radius-fixed.pull-right#connect_btn(type="submit", style="margin-top: 6px;") Connect
66 |
67 | ul.bottom-line.links-navbar
68 | li
69 | a(href="http://plvision.eu", target="_blank") About
70 | li
71 | a(href="http://plvision.eu/contact-us/", target="_blank") Contacts
72 | script.
73 | $(document).ready(function() {
74 | $("#database_ip_address, #username, #password, #secure").bind("keypress", {}, function(event) {
75 | var code = (event.keyCode ? event.keyCode : event.which);
76 |
77 | if (code == 13) { /* Enter keycode */
78 | event.preventDefault();
79 |
80 | $("#connect_btn").click();
81 | }
82 | });
83 |
84 | $("#connect_btn").click(function() {
85 | var db_ip = $("#database_ip_address").val();
86 | var username = $("#username").val();
87 | var password = $("#password").val();
88 | var secure = $("#secure").prop("checked");
89 |
90 | $("#connect_btn").addClass("loading").attr("disabled", true);
91 |
92 | $.ajax( {
93 | type : "POST",
94 | url: "/enter",
95 | data: {
96 | "database_ip_address" : db_ip,
97 | "username" : username,
98 | "password" : password,
99 | "secure" : secure
100 | },
101 | timeout : 15000
102 | })
103 | .done(function() {
104 | window.location.href = "/";
105 | })
106 | .fail(function(e, t, m) {
107 | var error_text;
108 |
109 | switch (e.status) {
110 | case 403:
111 | error_text = "Authentication error.";
112 | break;
113 | default:
114 | error_text = "Can not connect to server.";
115 | if (t === "timeout") {
116 | error_text += " Timeout error.";
117 | }
118 | break;
119 | }
120 |
121 | if (e.responseJSON && e.responseJSON.message) {
122 | error_text += " " + e.responseJSON.message;
123 | }
124 |
125 | swal({
126 | title: "Error!",
127 | text: error_text,
128 | // type: "error"
129 | });
130 | })
131 | .always(function() {
132 | $("#connect_btn").removeClass("loading").removeAttr("disabled");
133 | })
134 | });
135 | })
136 |
--------------------------------------------------------------------------------
/views/error.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | doctype html
22 | html(lang="en")
23 | head
24 | meta(charset="utf-8")
25 | meta(http-equiv="X-UA-Compatible", content="IE=edge")
26 | meta(name="viewport", content="width=device-width, initial-scale=1")
27 | meta(name="description", content="")
28 | meta(name="author", content="")
29 | title= title
30 | link(rel='stylesheet', href='/stylesheets/bootstrap.min.css')
31 | script(src="/js/bootstrap.min.js")
32 |
33 | body
34 | #page_content_wrapper
35 | .container-fluid
36 | h1= message
37 | h2= error.status
38 | h4= error.message
39 | if showStack
40 | pre #{error.stack}
41 |
--------------------------------------------------------------------------------
/views/general_table.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends index
22 | block maincontent
23 | block tablecontent
24 |
25 | block scripts
26 | script.
27 | $(document).ready(function() {
28 | $("a.multiple", maincontent).click(function(event) {
29 | event.preventDefault();
30 |
31 | var title = $(this).attr('modal-title');
32 | $("#modal .modal-header > .modal-title").text(title);
33 | var html = $(this).children().html();
34 | $("#modal .modal-body > table").html(html);
35 | $('#modal').modal({
36 | backdrop: true,
37 | });
38 | });
39 |
40 | document.title = "#{table} - " + "Open_vMonitor";
41 |
42 | // navigate to tabs
43 | var idx = document.location.href.lastIndexOf('#');
44 |
45 | if (idx != -1) {
46 | var tab = document.location.href.substr(idx);
47 | $('.nav.nav-tabs a[href=' + tab + ']').tab('show');
48 | }
49 |
50 | $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
51 | window.location.hash = e.target.hash;
52 | window.scroll(0, 0); // FIXME: small workaround
53 | init_custom_scroller(".scrollbar", true);
54 | });
55 |
56 | // update scoller on window resize
57 | $(window).resize(function() {
58 | update_custom_scroller(".scroller");
59 | });
60 |
61 | //$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
62 | //e.target // activated tab
63 | //e.relatedTarget // previous tab
64 | //init_custom_scroller(".scrollbar", true);
65 | //});
66 | });
67 |
--------------------------------------------------------------------------------
/views/htable.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends general_table
22 |
23 | block tablecontent
24 | include include/htable_inc
25 |
--------------------------------------------------------------------------------
/views/include/htable_inc.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | include mixins
22 | if data.length == 0
23 | h3 #{title}: no data here
24 | else
25 | h3 #{title}
26 | - var rows = data
27 | div.scrollbar
28 | - var columns = Object.keys(table_schema.columns).sort();
29 | table.table.table-bordered.table-hover.table-striped#use_datatable
30 | thead
31 | tr
32 | th
33 | +title("Uuid")
34 | each key, index in columns
35 | th(nowrap)
36 | +title(key)
37 | tbody
38 | each value, row_idx in rows
39 | tr
40 | //- displaying row uuid
41 | td(nowrap)
42 | +display_complex_data(rows[row_idx]["_uuid"], "", false, true)
43 | each _key, _index in columns
44 | td(nowrap)
45 | - var title = _key.substr(0, 1).toUpperCase() + _key.substr(1).toLowerCase()
46 | - title = title.split('_').join(' ');
47 |
48 | +display_complex_data(rows[row_idx][_key], title)
49 |
--------------------------------------------------------------------------------
/views/include/mixins.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | mixin title(value)
22 | -// handle 0 and false
23 | if typeof(value) !== 'undefined'
24 | if typeof(value) === 'number'
25 | |#{value}
26 | else
27 | - var words = value.split('_')
28 | - var res = []
29 | each word in words
30 | - res.push(word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase())
31 | - res = res.join(' ')
32 | |#{res}
33 |
34 | mixin display_complex_data(col, title, inline, is_row_uuid)
35 | - var type = col[0]
36 |
37 | case type
38 | when "map"
39 | - // this is a map object
40 | - var len = col.length - 1
41 | if len
42 | if col[1].length > 1
43 | if !inline
44 | a.multiple(href="#", modal-title="#{title}") Multiple values
45 | table.hidden
46 | tbody
47 | each value, idx in col[1]
48 | tr
49 | td(nowrap)
50 | +title(value[0])
51 | td
52 | - // need to check on named-uuid here
53 | if value[1][0] && value[1][0] == 'uuid'
54 | +display_complex_data(value[1], '', true)
55 | else
56 | |#{value[1]}
57 | else
58 | -// do not generate popup
59 | - col = col[1]
60 | each value, idx in col
61 | |#{value[0]} #{value[1]}
62 | br
63 | else
64 | - for (var x = 1; x < col.length; x++)
65 | - for (var y = 0; y < col[x].length; y++)
66 | | #{col[x][y][0]} :
67 | if (col[x][y][1] instanceof Array)
68 | +display_complex_data(col[x][y][1], '', true)
69 | else
70 | | #{col[x][y][1]}
71 | when "set"
72 | - // this is a set of values
73 | - var len = col.length - 1
74 | if len && (col[1] != '')
75 | a.multiple(href="#", modal-title="#{title}") Multiple values
76 | table.hidden
77 | tbody
78 | - var c = col[1][0];
79 | if (col[1] instanceof Array) && (c && c[0] == "uuid")
80 | each value, idx in col[1]
81 | tr
82 | td
83 | +title(value[3])
84 | td
85 | - //display uuid as link
86 | +display_complex_data(value, '', true)
87 | else
88 | - // e.g. vlans
89 | tr
90 | td
91 | |#{title}
92 | td
93 | |#{col[1]}
94 |
95 | when "uuid"
96 | -// have to handle named-uuid
97 | if (col[2] instanceof Array) && (col[2][0] == "map")
98 | - col[0] = col[2][1], col[1] = col[3]
99 | - var res = ''
100 | each value, idx in col[0]
101 | - res += value[0] + ': ' + value[1]
102 | a.uuid(href="/#{col[1]}", data-page="#{col[1]}") #{res}
103 | else if (col[2] instanceof Array) && (col[2][0] == "uuid")
104 | - col[2] = col[2][1]
105 | a.uuid(href="/#{col[3]}/#{col[2]}", data-page="#{col[3]}") #{col[2]}
106 | else
107 | //- FIXME: hardcode (workaround to fix bug 68: bad link on SSL page)
108 | - var link = col[3] + "/" + col[2]
109 | - var title = col[2]
110 | if (col[3] === "SSL")
111 | - link = col[3]
112 |
113 | - // if this is uuid of the current row, then in title should be exact uuid value
114 | if (is_row_uuid)
115 | - title = col[1]
116 |
117 | a.uuid(href="/#{link}", data-page="#{col[3]}") #{title}
118 | default
119 | - // should not be here
120 | - if (col !== "")
121 | | #{col}
122 | - else
123 | | Empty
124 |
125 | mixin comma_separated_list_map(map)
126 | if map instanceof Array
127 | if map[0] === "map"
128 | - map = map[1]
129 |
130 | - var value = ''
131 | each element in map
132 | b #{element[0]}:
133 | | #{element[1]}
134 | br
135 | |#{value}
136 |
137 | mixin comma_separated_set_td(set)
138 | - var value;
139 | if (set && (set instanceof Array))
140 | if set[0] === "set"
141 | - set = set[1]
142 | else
143 | - set = [set]
144 | - value = set.join(", ")
145 | else
146 | - value = set
147 | - cls = (!value ? "Empty" : "")
148 | td(class="#{cls}") #{value}
149 |
150 |
151 | mixin comma_separated_uuids_links(set, link_to_table)
152 | if set[0] === "set"
153 | - uuids = set[1]
154 | else
155 | - uuids = [set]
156 |
157 | span.uuid-links-list
158 | each uuid, idx in uuids
159 | span.uuid-link
160 | - var link = uuid[3] + "/" + uuid[2]
161 | if (link_to_table)
162 | - link = uuid[3]
163 | a(href="/#{link}", data-page="#{uuid[3]}") #{uuid[2]}
164 |
165 | mixin set_length(set)
166 | if set[0] === "set" || set[0] === "map"
167 | - uuids = set[1]
168 | else
169 | - uuids = [set]
170 | |#{uuids.length}
171 |
172 | mixin children_list(caption, children, table, refTable, object_name)
173 | h4 #{caption} (
174 | +set_length(children)
175 | |)
176 | .row
177 | .col-lg-12
178 | +comma_separated_uuids_links(children)
179 | br
180 | if (!object_name)
181 | span.uuid-list-details
182 | a(href="/#{refTable}" data-page="#{refTable}" class="text-info") Detailed view
183 | else
184 | span.uuid-list-details
185 | a(href="/#{table}/#{object_name}/#{refTable}" data-page="#{refTable}") Detailed view
186 |
--------------------------------------------------------------------------------
/views/include/vtable_inc.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | include mixins
22 | if data.length == 0
23 | h3 #{title}: no data here
24 | else
25 | h3 #{title}
26 | - var row = data
27 | if (row instanceof Array)
28 | - row = data[0]
29 | table.table.table-bordered.table-hover.table-striped#use_datatable
30 | thead
31 | tr
32 | th.col-lg-2(nowrap) Option
33 | th(nowrap) Value(s)
34 | tbody
35 | - var keys = Object.keys(table_schema.columns).sort();
36 | //- displaying row (record) uuid
37 | tr
38 | td Uuid
39 | td
40 | +display_complex_data(row["_uuid"], "", false, true)
41 | each key in keys
42 | tr
43 | td
44 | +title(key)
45 | td
46 | - var title = key.substr(0, 1).toUpperCase() + key.substr(1).toLowerCase()
47 | +display_complex_data(row[key], title)
48 |
--------------------------------------------------------------------------------
/views/index.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends layout
22 |
23 | mixin list_objects(table, list, sub_items)
24 | each obj, key in list
25 | li
26 | - var id = obj.name + "_submenu"
27 | a.link(data-toggle="collapse",data-target="##{id}") #{obj.name}
28 | span.fa.arrow
29 | ul.nav.nav-third-level.collapse(id="#{id}")
30 | each item_details, item_link in sub_items
31 | li
32 | a.link(href="/#{table}/#{obj.name}/#{item_link}" data-page="#{item_details.caption}") #{item_details.caption}
33 |
34 | block sidebar
35 | - var c = ""
36 | - var auth_error_text = ""
37 | if authorized !== undefined
38 | - c = (authorized === true ? "bg-success" : "bg-danger");
39 | - auth_error_text = auth_error ? "Server is unauthorized: " + auth_error : "Server is authorized";
40 | // li(class="disabled #{c}" title="#{auth_error_text}")
41 | a Connection: #{connection}
42 | li(class="disabled")
43 | a #{connection}/Open_vSwitch
44 | // .btn-group
45 | //label.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown')
46 | div
47 | | #{selected_db}
48 | //span.caret
49 |
50 | ul.dropdown-menu(role='menu', aria-labelledby='dLabel')
51 | each db in databases
52 | - var cls = (db===selected_db) ? "active" : ""
53 | li(role='presentation', class="#{cls}")
54 | a(role='menuitem', tabindex='-1', href='#', value="#{db}") #{db}
55 | -//li
56 | -//a(href="/", data-page="dashboard") Dashboard
57 | li
58 | a.link(href="/Open_vSwitch" data-page="Open_vSwitch") General info
59 | li
60 | a(href='#')
61 | -//i.fa.fa-bar-chart-o.fa-fw
62 | | Bridges
63 | span.fa.arrow
64 | - var bridge_subitems = { "" : { caption: "Bridge Details" }, "Port" : { caption : "Ports" }, "NetFlow" : { caption : "NetFlow" }, "Mirror" : { caption : "Mirrors" }, "Controller" : { caption : "Controller" }, "IPFIX" : { caption : "IPFIX" }, "sFlow" : {caption : "sFlow"} }
65 | ul.nav.nav-second-level.collapse
66 | li
67 | a.link(href="/Bridge", data-page="Bridge") Bridges List
68 | +list_objects("Bridge", bridges, bridge_subitems)
69 | li
70 | a.link(href="/Manager" data-page="Manager") Manager
71 | li
72 | a.link(href='/QoS' data-page="QoS") QoS
73 | li
74 | a.link(href='/Queue' data-page="Queue") Queues
75 | li
76 | a.link(href='/Flow_Table' data-page="Flow_Table") Flow Table
77 | li
78 | a.link(href='/Flow_Sample_Collector_Set' data-page="Flow_Sample_Collector_Set") Flow Sample Collector Set
79 | // li
80 | // a.link(href='/alerts' data-page="Alerts") Alerts
81 | // a.link(href="/SSL" data-page="SSL") SSL
82 | // li
83 |
84 | block content
85 | - if(!isAjax)
86 | .row
87 | .col-lg-12#maincontent
88 | block maincontent
89 | block scripts
90 | - else
91 | block maincontent
92 | block scripts
93 |
--------------------------------------------------------------------------------
/views/layout.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | mixin list_db(obj, db)
22 | if obj
23 | - var isArray = obj instanceof Array;
24 | - var isObject = obj instanceof Object;
25 |
26 | if isArray
27 | each val, index in obj
28 | +list_db(val, db)
29 | else if isObject
30 | each val, index in obj
31 | li
32 | a.link(href="/#{index}" data-page="#{index}") #{index}
33 | ul.collapse.in
34 | +list_db(val, db)
35 | else
36 | li
37 | a.link(href="/#{obj}" data-page="#{obj}", data-addr="#{db}") #{obj}
38 |
39 | - if(!isAjax)
40 | doctype html
41 | html(lang="en")
42 | head
43 | meta(charset="utf-8")
44 | meta(http-equiv="X-UA-Compatible", content="IE=edge")
45 | meta(name="viewport", content="width=device-width, initial-scale=1")
46 | meta(name="description", content="")
47 | meta(name="author", content="")
48 | title= title
49 | link(rel='stylesheet', href='/stylesheets/bootstrap.min.css')
50 | link(rel='stylesheet', href='/stylesheets/style.css')
51 | link(rel='stylesheet', href='/stylesheets/sb-admin-2.css')
52 | link(rel='stylesheet', href='/stylesheets/plugins/metisMenu.min.css')
53 | link(rel='stylesheet', href='/stylesheets/font-awesome.min.css')
54 | link(rel='stylesheet', href='/stylesheets/plugins/scroller.css')
55 | link(rel='stylesheet', href='/stylesheets/sweet-alert.css')
56 | link(rel='stylesheet', href='/stylesheets/bootstrap-select.min.css')
57 | script(src="/js/jquery-1.11.1.min.js")
58 | script(src="/js/bootstrap.min.js")
59 | script(src="/js/plugins/metisMenu.min.js")
60 | script(src="/js/sb-admin-2.js")
61 | script(src="/js/d3.v3.min.js")
62 | script(src="/js/d3.tip.v0.6.3.js")
63 | script(src="/js/event_emitter.js")
64 | script(src="/js/plugins/scroller.js")
65 | script(src="/js/navigation.js")
66 | script(src="/js/assets.js")
67 | script(src="/js/loading.js")
68 | script(src="/js/sweet-alert.min.js")
69 | script(src="/js/bootstrap-select.min.js")
70 | script(src="/js/plugins/jquery.cookie.js")
71 |
72 | style(type='text/css').
73 | th.rotate {
74 | /* Something you can count on */
75 | height: 140px;
76 | white-space: nowrap;
77 | }
78 |
79 | th.rotate > div {
80 | transform: rotate(-90deg);
81 | -webkit-transform:rotate(-90deg);
82 | width: 30px;
83 | }
84 | th.rotate > div > span {
85 |
86 | }
87 |
88 | body
89 | #wrapper
90 | nav.navbar.navbar-default.navbar-static-top(role="navigation", style="margin-bottom: 0px;")
91 | .navbar-header
92 | button.navbar-toggle(type='button')
93 | span.sr-only Toggle navigation
94 | span.icon-bar
95 | span.icon-bar
96 | span.icon-bar
97 |
98 | a.navbar-brand(href="/") Open_vMonitor
99 | ul.nav.navbar-top-links.navbar-right
100 | label(style="color: #fff; margin-right: 5px;")
101 | | Automatic refresh:
102 | select.selectpicker.show-tick(data-width="auto")
103 | optgroup(label="Refresh timeout")
104 | option(value="-1")
105 | | Off
106 | option(value="10")
107 | | 10 secs
108 | option(value="20")
109 | | 20 secs
110 | option(value="30")
111 | | 30 secs
112 | option(value="60")
113 | | 1 minute
114 | -//li.dropdown
115 | -//a.dropdown-toggle(data-toggle='dropdown', href='#')
116 | -//i.fa.fa-envelope.fa-fw
117 | -//i.fa.fa-caret-down
118 | -//ul.dropdown-menu.dropdown-messages
119 | -//li
120 | -//a(href='#')
121 | -//div
122 | -//strong John Smith
123 | -//span.pull-right.text-muted
124 | -//em Yesterday
125 | -//div
126 | -//| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...
127 | -//li.divider
128 | -//li
129 | -//a.text-center(href='/log')
130 | -//strong Read All Messages
131 | -//i.fa.fa-angle-right
132 | li.dropdown
133 | a.dropdown-toggle(data-toggle='dropdown', href='#')
134 | span.badge#num-of-updates
135 | i.fa.fa-bell.fa-fw
136 | i.fa.fa-caret-down
137 | ul.dropdown-menu.dropdown-alerts
138 | //li
139 | a(href='#')
140 | i.fa.fa-gear.fa-fw
141 | | Settings
142 | //li.divider
143 | li
144 | a(href="#")
145 | | Available only in Full Version
146 | //i.fa.fa-angle-right
147 | li.dropdown
148 | a.dropdown-toggle(data-toggle='dropdown', href='#')
149 | i.fa.fa-user.fa-fw
150 | i.fa.fa-caret-down
151 | ul.dropdown-menu.dropdown-user
152 | //li
153 | a(href='#')
154 | i.fa.fa-gear.fa-fw
155 | | Settings
156 | //li.divider
157 | li
158 | a(href='/logout')
159 | i.fa.fa-sign-out.fa-fw
160 | | Logout
161 | .navbar-default.sidebar(role="navigation")
162 | .sidebar-nav.navbar-collapse
163 | ul.nav#side-menu
164 | block sidebar
165 |
166 | #page-wrapper
167 | #page_overlay
168 | block content
169 |
170 | img(src="/images/loading.gif" id="loading-indicator" style="display:none")
171 |
172 | .modal#modal(tabindex="-1", role="dialog", aria-labelledby="", aria-hidden="true")
173 | .modal-dialog.modal-sm
174 | .modal-content
175 | .modal-header
176 | button.close(type="button", data-dismiss="modal")
177 | span(area-hidden="true") ×
178 | span.sr-only Close
179 | h4.modal-title#modal-title
180 | .modal-body
181 | table.table.table-bordered.table-hover.table-striped
182 | .modal-footer
183 | button.btn.btn-default(type="button", data-dismiss="modal") Close
184 |
185 | script.
186 | $(document).ready(function() {
187 | var auto_refresh_interval = undefined;
188 |
189 | //var addr = $("[data-connection]").first().attr("data-connection");
190 | Navigation.init({
191 | container : "#maincontent",
192 | landing_page : window.location.pathname
193 | });
194 | //Navigation.go(windo.location.pathname)
195 |
196 | Navigation.on("loaded", function(url) {
197 | if ((typeof url === "string") || (url instanceof String)) {
198 | var $all_items = $('a[data-page]', $("#side-menu"));
199 | $all_items.removeClass('active');
200 | select_menu_item('[href="' + url + '"]');
201 | $("a[data-page]").navigation();
202 | init_custom_scroller(".scrollbar", true);
203 |
204 | } else {
205 | /* we have error here */
206 | var xhr = url;
207 | if (xhr.status == 500) {
208 | swal({
209 | title: "Error!",
210 | text: "Something went wrong. Try again. If the error persists, connection to ovsdb-server may be lost: try to log out and connect again",
211 | // type: "error"
212 | });
213 | }
214 | }
215 | });
216 |
217 |
218 | $(window).on('hashchange', function(e) {
219 | $("a[href='" + window.location.hash + "']").click();
220 | });
221 |
222 | $('.navbar-toggle').click(function() {
223 | $("#wrapper").toggleClass("sidebar-shown");
224 | $(".navbar-collapse").toggleClass("in", $("#wrapper").hasClass("sidebar-shown"));
225 | });
226 |
227 | // initialize update notifications with selected interval
228 | $('.selectpicker').change(function(e) {
229 | var value = $(this).find('option:selected').val();
230 |
231 | if (typeof auto_refresh_interval !== "undefined") {
232 | clearInterval(auto_refresh_interval);
233 | $.cookie("refresh_interval", "-1");
234 | }
235 |
236 | if (value != -1) {
237 | auto_refresh_interval = setInterval(function() {
238 | window.location.reload();
239 | }, value + "000");
240 | $.cookie("refresh_interval", value);
241 | }
242 | });
243 |
244 | var value = $.cookie("refresh_interval");
245 | if ((typeof value === "undefined") || value == 0) {
246 | value = -1;
247 | }
248 |
249 | if (value != '-1') {
250 | $('.selectpicker').val(value).change();
251 | }
252 |
253 | });
254 | - else
255 | block content
256 |
--------------------------------------------------------------------------------
/views/raw_json.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends index
22 | block maincontent
23 | #raw_packet
24 | .row
25 | .col-lg-12
26 | .panel.panel-default
27 | .panel-body
28 | .row
29 | .col-lg-12#raw_content
30 | h3 Raw JSON OVSDB:
31 | textarea.form-control(rows="3", placeholder="What's up?",required)
32 | textarea.form-control#raw_reply(rows="3", placeholder="What's up?",disabled)
33 | button.btn.btn-default(type="button", onclick="submit_raw_json();") Submit
34 |
--------------------------------------------------------------------------------
/views/vtable.jade:
--------------------------------------------------------------------------------
1 | //-
2 | Open vMonitor is a WEB-based tool for monitoring and troubleshooting Open vSwitch
3 | Copyright (C) 2014-2016 PLVision
4 | Ihor Chumak, Roman Gotsiy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as
8 | published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Affero General Public License for more details.
15 |
16 | You should have received a copy of the GNU Affero General Public License
17 | along with this program. If not, see .
18 |
19 | PLVision, developers@plvision.eu
20 |
21 | extends general_table
22 |
23 | block tablecontent
24 | include include/vtable_inc.jade
25 |
--------------------------------------------------------------------------------
|