Topo2: ONOS-5640, ONOS-5641 ONOS-5645 Show details for Hosts, Links, Sub-Regions

Added Links panel
Details panel shared between Details, Link, Hosts and Regions
Refactored List content for panel views
Reference to the PanelService Element had a name change
Added a Base UIView to extend future views from
Extend method was being repeated

Change-Id: I3fa070fc5140e98720e47f4b90e3571cb0347596
This commit is contained in:
Steven Burrows 2016-11-16 18:19:12 -06:00 committed by Gerrit Code Review
parent 878c78cca3
commit 86af435285
21 changed files with 743 additions and 204 deletions

View File

@ -413,6 +413,29 @@
return classes.join(' ');
}
function extend(protoProps, staticProps) {
var parent = this,
child;
child = function () {
return parent.apply(this, arguments);
};
angular.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function and add the prototype properties.
child.prototype = angular.extend({}, parent.prototype, protoProps);
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
}
angular.module('onosUtil')
.factory('FnService',
@ -452,7 +475,8 @@
addToTrie: addToTrie,
removeFromTrie: removeFromTrie,
trieLookup: trieLookup,
classNames: classNames
classNames: classNames,
extend: extend
};
}]);

View File

@ -0,0 +1,60 @@
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Widget -- List Service
*/
(function () {
'use strict';
function addProp(el, label, value) {
var tr = el.append('tr'),
lab;
if (typeof label === 'string') {
lab = label.replace(/_/g, ' ');
} else {
lab = label;
}
function addCell(cls, txt) {
tr.append('td').attr('class', cls).html(txt);
}
addCell('label', lab + ' :');
addCell('value', value);
}
function addSep(el) {
el.append('tr').append('td').attr('colspan', 2).append('hr');
}
function listProps(el, data) {
data.propOrder.forEach(function (p) {
if (p === '-') {
addSep(el);
} else {
addProp(el, p, data.props[p]);
}
});
}
angular.module('onosWidget')
.factory('ListService', [
function () {
return listProps;
}]);
}());

View File

@ -181,7 +181,7 @@
}
#ov-topo2 svg .node.device.selected .node-container {
#ov-topo2 svg .node.selected .node-container {
stroke-width: 2.0;
stroke: #009fdb;
}

View File

@ -22,7 +22,8 @@
(function () {
'use strict';
var Model;
var Model,
extend;
function Collection(models, options) {
@ -91,34 +92,12 @@
}
};
Collection.extend = function (protoProps, staticProps) {
var parent = this;
var child;
child = function () {
return parent.apply(this, arguments);
};
angular.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function and add the prototype properties.
child.prototype = angular.extend({}, parent.prototype, protoProps);
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
};
angular.module('ovTopo2')
.factory('Topo2Collection',
['Topo2Model',
function (_Model_) {
['Topo2Model', 'FnService',
function (_Model_, fn) {
Collection.extend = fn.extend;
Model = _Model_;
return Collection;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Topology View Module.
Module that displays the details panel for selected nodes
*/
(function () {
'use strict';
// Injected Services
var Panel;
// Internal State
var detailsPanel;
// configuration
var id = 'topo2-p-detail',
className = 'topo-p',
panelOpts = {
width: 260 // summary and detail panel width
};
function getInstance() {
if (detailsPanel) {
return detailsPanel;
}
var options = angular.extend({}, panelOpts, {
class: className
});
detailsPanel = new Panel(id, options);
detailsPanel.el.classed(className, true);
return detailsPanel;
}
angular.module('ovTopo2')
.factory('Topo2DetailsPanelService',
['Topo2PanelService',
function (_ps_) {
Panel = _ps_;
return getInstance;
}
]);
})();

View File

@ -74,25 +74,7 @@
},
onClick: function () {
var ev = d3.event;
if (ev.shiftKey) {
// TODO: Multi-Select Details Panel
this.set('selected', true);
} else {
var s = Boolean(this.get('selected'));
// Clear all selected Items
_.each(this.collection.models, function (m) {
m.set('selected', false);
});
this.set('selected', !s);
}
var selected = this.collection.filter(function (m) {
return m.get('selected');
});
var selected = this.select(d3.event);
if (_.isArray(selected) && selected.length > 0) {
if (selected.length === 1) {

View File

@ -23,17 +23,13 @@
'use strict';
// Injected Services
var Panel, gs, wss, flash, bs, fs, ns;
var Panel, gs, wss, flash, bs, fs, ns, listProps;
// Internal State
var detailsPanel;
// configuration
var id = 'topo2-p-detail',
className = 'topo-p',
panelOpts = {
width: 260 // summary and detail panel width
},
handlerMap = {
'showDetails': showDetails
};
@ -69,43 +65,7 @@
function init() {
bindHandlers();
var options = angular.extend({}, panelOpts, {
class: className
});
detailsPanel = new Panel(id, options);
detailsPanel.p.classed(className, true);
}
function addProp(tbody, label, value) {
var tr = tbody.append('tr'),
lab;
if (typeof label === 'string') {
lab = label.replace(/_/g, ' ');
} else {
lab = label;
}
function addCell(cls, txt) {
tr.append('td').attr('class', cls).html(txt);
}
addCell('label', lab + ' :');
addCell('value', value);
}
function addSep(tbody) {
tbody.append('tr').append('td').attr('colspan', 2).append('hr');
}
function listProps(tbody, data) {
data.propOrder.forEach(function (p) {
if (p === '-') {
addSep(tbody);
} else {
addProp(tbody, p, data.props[p]);
}
});
detailsPanel = Panel();
}
function addBtnFooter() {
@ -136,10 +96,6 @@
cb: function () { ns.navTo(path, { devId: devId }); }
});
}
// TODO: Implement Overlay service
// else if (btn = _getButtonDef(id, data)) {
// addAction(btn);
// }
});
}
@ -196,17 +152,17 @@
}
function toggle() {
var on = detailsPanel.p.toggle(),
var on = detailsPanel.el.toggle(),
verb = on ? 'Show' : 'Hide';
flash.flash(verb + ' Details Panel');
}
function show() {
detailsPanel.p.show();
detailsPanel.el.show();
}
function hide() {
detailsPanel.p.hide();
detailsPanel.el.hide();
}
function destroy() {
@ -216,9 +172,9 @@
angular.module('ovTopo2')
.factory('Topo2DeviceDetailsPanel',
['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService',
'ButtonService', 'FnService', 'NavService',
function (_ps_, _gs_, _wss_, _flash_, _bs_, _fs_, _ns_) {
['Topo2DetailsPanelService', 'GlyphService', 'WebSocketService', 'FlashService',
'ButtonService', 'FnService', 'NavService', 'ListService',
function (_ps_, _gs_, _wss_, _flash_, _bs_, _fs_, _ns_, _listService_) {
Panel = _ps_;
gs = _gs_;
@ -227,6 +183,7 @@
bs = _bs_;
fs = _fs_;
ns = _ns_;
listProps = _listService_;
return {
init: init,

View File

@ -48,12 +48,34 @@
angular.module('ovTopo2')
.factory('Topo2HostService', [
'Topo2Collection', 'Topo2NodeModel', 'Topo2ViewService',
'IconService', 'Topo2ZoomService',
function (_Collection_, _NodeModel_, _t2vs_, is, zs) {
'IconService', 'Topo2ZoomService', 'Topo2HostsPanelService',
function (_Collection_, _NodeModel_, _t2vs_, is, zs, t2hds) {
Collection = _Collection_;
Model = _NodeModel_.extend({
initialize: function () {
this.super = this.constructor.__super__;
this.super.initialize.apply(this, arguments);
},
events: {
'click': 'onClick'
},
onChange: function () {
// Update class names when the model changes
if (this.el) {
this.el.attr('class', this.svgClassName());
}
},
onClick: function () {
var selected = this.select(d3.select);
if (selected.length > 0) {
t2hds.displayPanel(this);
} else {
t2hds.hide();
}
},
nodeType: 'host',
icon: function () {
var type = this.get('type');
@ -117,6 +139,7 @@
.attr('text-anchor', 'middle');
this.setScale();
this.setUpEvents();
}
});

View File

@ -0,0 +1,114 @@
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Topology Layout Module.
Module that contains the d3.force.layout logic
*/
(function () {
'use strict';
// Injected Services
var Panel, gs, wss, flash, listProps;
// Internal State
var hostPanel, hostData;
function init() {
hostPanel = Panel();
}
function formatHostData(data) {
return {
title: data.get('id'),
propOrder: ['MAC', 'IP', 'VLAN', '-', 'Latitude', 'Longitude'],
props: {
'-': '',
'MAC': data.get('id'),
'IP': data.get('ips')[0],
'VLAN': 'None', // TODO
'Latitude': data.get('location').lat,
'Longitude': data.get('location').lng,
}
}
};
function displayPanel(data) {
init();
hostData = formatHostData(data);
render();
}
function render() {
hostPanel.el.show();
hostPanel.emptyRegions();
var svg = hostPanel.appendToHeader('div')
.classed('icon', true)
.append('svg'),
title = hostPanel.appendToHeader('h2'),
table = hostPanel.appendToBody('table'),
tbody = table.append('tbody');
title.text(hostData.title);
gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
listProps(tbody, hostData);
}
function show() {
hostPanel.el.show();
}
function hide() {
hostPanel.el.hide();
}
function toggle() {
var on = hostPanel.el.toggle(),
verb = on ? 'Show' : 'Hide';
flash.flash(verb + ' host Panel');
}
function destroy() {
hostPanel.destroy();
}
angular.module('ovTopo2')
.factory('Topo2HostsPanelService',
['Topo2DetailsPanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
function (_ps_, _gs_, _wss_, _flash_, _listService_) {
Panel = _ps_;
gs = _gs_;
wss = _wss_;
flash = _flash_;
listProps = _listService_;
return {
displayPanel: displayPanel,
init: init,
show: show,
hide: hide,
toggle: toggle,
destroy: destroy,
isVisible: function () { return hostPanel.isVisible(); }
};
}
]);
})();

View File

@ -22,7 +22,7 @@
(function () {
'use strict';
var $log, Collection, Model, ts, sus, t2zs, t2vs;
var $log, Collection, Model, ts, sus, t2zs, t2vs, t2lps, fn;
var linkLabelOffset = '0.35em';
@ -124,6 +124,16 @@
type: function () {
return this.get('type');
},
svgClassName: function () {
return fn.classNames('link',
this.nodeType,
this.get('type'),
{
enhanced: this.get('enhanced'),
selected: this.get('selected')
}
);
},
expected: function () {
// TODO: original code is: (s && s.expected) && (t && t.expected);
return true;
@ -137,6 +147,12 @@
return (sourceOnline) && (targetOnline);
},
onChange: function () {
// Update class names when the model changes
if (this.el) {
this.el.attr('class', this.svgClassName());
}
},
enhance: function () {
var data = [],
point;
@ -145,7 +161,7 @@
link.unenhance();
});
this.el.classed('enhanced', true);
this.set('enhanced', true);
if (showPort()) {
point = this.locatePortLabel();
@ -193,9 +209,36 @@
}
},
unenhance: function () {
this.el.classed('enhanced', false);
this.set('enhanced', false);
d3.select('#topo-portLabels').selectAll('.portLabel').remove();
},
select: function () {
var ev = d3.event;
// TODO: if single selection clear selected devices, hosts, sub-regions
var s = Boolean(this.get('selected'));
// Clear all selected Items
_.each(this.collection.models, function (m) {
m.set('selected', false);
});
this.set('selected', !s);
var selected = this.collection.filter(function (m) {
return m.get('selected');
});
return selected;
},
showDetails: function () {
var selected = this.select(d3.event);
if (selected) {
t2lps.displayLink(this);
} else {
t2lps.hide();
}
},
locatePortLabel: function (src) {
var offset = 32 / (labelDim * t2zs.scale()),
@ -259,6 +302,7 @@
// from mouse position.
this.el.on('mouseover', this.enhance.bind(this));
this.el.on('mouseout', this.unenhance.bind(this));
this.el.on('click', this.showDetails.bind(this));
if (this.get('type') === 'hostLink') {
// sus.visible(link, api.showHosts());
@ -277,7 +321,7 @@
},
update: function () {
if (this.el.classed('enhanced')) {
if (this.get('enhanced')) {
this.enhance();
}
}
@ -298,9 +342,9 @@
.factory('Topo2LinkService',
['$log', 'Topo2Collection', 'Topo2Model',
'ThemeService', 'SvgUtilService', 'Topo2ZoomService',
'Topo2ViewService',
'Topo2ViewService', 'Topo2LinkPanelService', 'FnService',
function (_$log_, _Collection_, _Model_, _ts_, _sus_,
_t2zs_, _t2vs_) {
_t2zs_, _t2vs_, _t2lps_, _fn_) {
$log = _$log_;
ts = _ts_;
@ -309,6 +353,8 @@
t2vs = _t2vs_;
Collection = _Collection_;
Model = _Model_;
t2lps = _t2lps_;
fn = _fn_;
return {
createLinkCollection: createLinkCollection

View File

@ -0,0 +1,127 @@
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Topology Layout Module.
Module that contains the d3.force.layout logic
*/
(function () {
'use strict';
// Injected Services
var Panel, gs, wss, flash, listProps;
// Internal State
var linkPanel, linkData;
function init() {
linkPanel = Panel();
}
function formatLinkData(data) {
var source = data.get('source'),
target = data.get('target');
return {
title: 'Link',
propOrder: [
'Type', '-',
'A Type', 'A Id', 'A Label', 'A Port', '-',
'B Type', 'B Id', 'B Label', 'B Port'
],
props: {
'-': '',
'Type': data.get('type'),
'A Type': source.get('nodeType'),
'A Id': source.get('id'),
'A Label': 'Label',
'A Port': data.get('portA') || '',
'B Type': target.get('nodeType'),
'B Id': target.get('id'),
'B Label': 'Label',
'B Port': data.get('portB') || '',
}
}
};
function displayLink(data) {
init();
linkData = formatLinkData(data);
render();
}
function render() {
linkPanel.el.show();
linkPanel.emptyRegions();
var svg = linkPanel.appendToHeader('div')
.classed('icon', true)
.append('svg'),
title = linkPanel.appendToHeader('h2'),
table = linkPanel.appendToBody('table'),
tbody = table.append('tbody');
title.text(linkData.title);
gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
listProps(tbody, linkData);
}
function show() {
linkPanel.el.show();
}
function hide() {
linkPanel.el.hide();
}
function toggle() {
var on = linkPanel.el.toggle(),
verb = on ? 'Show' : 'Hide';
flash.flash(verb + ' Link Panel');
}
function destroy() {
wss.unbindHandlers(handlerMap);
linkPanel.destroy();
}
angular.module('ovTopo2')
.factory('Topo2LinkPanelService',
['Topo2DetailsPanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
function (_ps_, _gs_, _wss_, _flash_, _listService_) {
Panel = _ps_;
gs = _gs_;
wss = _wss_;
flash = _flash_;
listProps = _listService_;
return {
displayLink: displayLink,
init: init,
show: show,
hide: hide,
toggle: toggle,
destroy: destroy,
isVisible: function () { return linkPanel.isVisible(); }
};
}
]);
})();

View File

@ -22,6 +22,8 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout.
(function () {
'use strict';
var extend;
function Model(attributes) {
var attrs = attributes || {};
@ -118,34 +120,13 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout.
}
};
Model.extend = function (protoProps, staticProps) {
var parent = this;
var child;
child = function () {
return parent.apply(this, arguments);
};
angular.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function and add the prototype properties.
child.prototype = angular.extend({}, parent.prototype, protoProps);
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
};
angular.module('ovTopo2')
.factory('Topo2Model', [
function () {
'FnService',
function (fn) {
Model.extend = fn.extend;
return Model;
}
]);
})();

View File

@ -76,6 +76,31 @@
'mouseout': 'mouseoutHandler'
};
},
select: function () {
var ev = d3.event;
// TODO: if single selection clear selected devices, hosts, sub-regions
if (ev.shiftKey) {
// TODO: Multi-Select Details Panel
this.set('selected', true);
} else {
var s = Boolean(this.get('selected'));
// Clear all selected Items
_.each(this.collection.models, function (m) {
m.set('selected', false);
});
this.set('selected', !s);
}
var selected = this.collection.filter(function (m) {
return m.get('selected');
});
return selected;
},
createNode: function () {
this.set('svgClass', this.svgClassName());
t2nps.positionNode(this);

View File

@ -22,30 +22,24 @@
(function () {
'use strict';
var ps;
// Injected Services
var flash, ps;
var Panel = function (id, options) {
this.id = id;
this.p = ps.createPanel(this.id, options);
this.setup();
var panel = {
initialize: function (id, options) {
this.id = id;
this.el = ps.createPanel(id, options);
this.setup();
if (options.show) {
this.p.show();
}
};
Panel.prototype = {
if (options.show) {
this.el.show();
}
},
setup: function () {
var panel = this.p;
panel.empty();
panel.append('div').classed('header', true);
panel.append('div').classed('body', true);
panel.append('div').classed('footer', true);
this.header = panel.el().select('.header');
this.body = panel.el().select('.body');
this.footer = panel.el().select('.body');
this.el.empty();
this.header = this.el.append('div').classed('header', true);
this.body = this.el.append('div').classed('body', true);
this.footer = this.el.append('div').classed('footer', true);
},
appendToHeader: function (x) {
return this.header.append(x);
@ -65,15 +59,19 @@
ps.destroyPanel(this.id);
},
isVisible: function () {
return this.p.isVisible();
return this.el.isVisible();
}
};
}
angular.module('ovTopo2')
.factory('Topo2PanelService', ['PanelService',
function (_ps_) {
.factory('Topo2PanelService',
['Topo2UIView', 'FlashService', 'PanelService',
function (View, _flash_, _ps_) {
flash = _flash_;
ps = _ps_;
return Panel;
return View.extend(panel);
}
]);

View File

@ -54,8 +54,6 @@
link.createLink();
});
console.log(region.get('id'));
// TEMP Map Zoom
var regionPanZooms = {
"(root)": {

View File

@ -41,9 +41,9 @@
angular.module('ovTopo2')
.factory('Topo2SubRegionService',
['WebSocketService', 'Topo2Collection', 'Topo2NodeModel',
'ThemeService', 'Topo2ViewService',
'ThemeService', 'Topo2ViewService', 'Topo2SubRegionPanelService',
function (_wss_, _c_, _NodeModel_, _ts_, _t2vs_) {
function (_wss_, _c_, _NodeModel_, _ts_, _t2vs_m, _t2srp_) {
wss = _wss_;
Collection = _c_;
@ -54,13 +54,29 @@
this.super.initialize.apply(this, arguments);
},
events: {
'dblclick': 'navigateToRegion'
'dblclick': 'navigateToRegion',
'click': 'onClick'
},
onChange: function () {
// Update class names when the model changes
if (this.el) {
this.el.attr('class', this.svgClassName());
}
},
nodeType: 'sub-region',
icon: function () {
var type = this.get('type');
return remappedDeviceTypes[type] || type || 'm_cloud';
},
onClick: function () {
var selected = this.select(d3.event);
if (selected.length > 0) {
_t2srp_.displayPanel(this);
} else {
_t2srp_.hide();
}
},
navigateToRegion: function () {
if (d3.event.defaultPrevented) return;

View File

@ -0,0 +1,112 @@
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Topology Layout Module.
Module that contains the d3.force.layout logic
*/
(function () {
'use strict';
// Injected Services
var Panel, gs, wss, flash, listProps;
// Internal State
var subRegionPanel, subRegionData;
function init() {
subRegionPanel = Panel();
}
function formatSubRegionData(data) {
return {
title: data.get('name'),
propOrder: ['Id', 'Type', '-', 'Number of Devices', 'Number of Hosts'],
props: {
'-': '',
'Id': data.get('id'),
'Type': data.get('nodeType'),
'Number of Devices': data.get('nDevs'),
'Number of Hosts': data.get('nHosts')
}
}
};
function displayPanel(data) {
init();
subRegionData = formatSubRegionData(data);
render();
}
function render() {
subRegionPanel.el.show();
subRegionPanel.emptyRegions();
var svg = subRegionPanel.appendToHeader('div')
.classed('icon', true)
.append('svg'),
title = subRegionPanel.appendToHeader('h2'),
table = subRegionPanel.appendToBody('table'),
tbody = table.append('tbody');
title.text(subRegionData.title);
gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
listProps(tbody, subRegionData);
}
function show() {
subRegionPanel.el.show();
}
function hide() {
subRegionPanel.el.hide();
}
function toggle() {
var on = subRegionPanel.el.toggle(),
verb = on ? 'Show' : 'Hide';
flash.flash(verb + ' subRegion Panel');
}
function destroy() {
subRegionPanel.destroy();
}
angular.module('ovTopo2')
.factory('Topo2SubRegionPanelService',
['Topo2DetailsPanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
function (_ps_, _gs_, _wss_, _flash_, _listService_) {
Panel = _ps_;
gs = _gs_;
wss = _wss_;
flash = _flash_;
listProps = _listService_;
return {
displayPanel: displayPanel,
init: init,
show: show,
hide: hide,
toggle: toggle,
destroy: destroy,
isVisible: function () { return subRegionPanel.isVisible(); }
};
}
]);
})();

View File

@ -23,7 +23,7 @@
'use strict';
// Injected Services
var Panel, gs, wss, flash;
var Panel, gs, wss, flash, listProps;
// Internal State
var summaryPanel, summaryData;
@ -33,7 +33,7 @@
className = 'topo-p',
panelOpts = {
show: true,
width: 260 // summary and detail panel width
width: 260 // summary and detail panel width
},
handlerMap = {
showSummary: handleSummaryData
@ -49,37 +49,7 @@
});
summaryPanel = new Panel(id, options);
summaryPanel.p.classed(className, true);
}
function addProp(tbody, label, value) {
var tr = tbody.append('tr'),
lab;
if (typeof label === 'string') {
lab = label.replace(/_/g, ' ');
} else {
lab = label;
}
function addCell(cls, txt) {
tr.append('td').attr('class', cls).html(txt);
}
addCell('label', lab + ' :');
addCell('value', value);
}
function addSep(tbody) {
tbody.append('tr').append('td').attr('colspan', 2).append('hr');
}
function listProps(tbody, data) {
summaryData.propOrder.forEach(function (p) {
if (p === '-') {
addSep(tbody);
} else {
addProp(tbody, p, summaryData.props[p]);
}
});
summaryPanel.el.classed(className, true);
}
function render() {
@ -94,7 +64,7 @@
title.text(summaryData.title);
gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
listProps(tbody);
listProps(tbody, summaryData);
}
function handleSummaryData(data) {
@ -107,7 +77,7 @@
}
function toggle() {
var on = summaryPanel.p.toggle(),
var on = summaryPanel.el.toggle(),
verb = on ? 'Show' : 'Hide';
flash.flash(verb + ' Summary Panel');
}
@ -119,17 +89,17 @@
angular.module('ovTopo2')
.factory('Topo2SummaryPanelService',
['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService',
function (_ps_, _gs_, _wss_, _flash_) {
['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
function (_ps_, _gs_, _wss_, _flash_, _listService_) {
Panel = _ps_;
gs = _gs_;
wss = _wss_;
flash = _flash_;
listProps = _listService_;
return {
init: init,
toggle: toggle,
destroy: destroy,
isVisible: function () { return summaryPanel.isVisible(); }

View File

@ -0,0 +1,58 @@
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Base UIView class.
A base class for UIViews to extend from
*/
(function () {
'use strict';
function View(options) {
if (options && options.el) {
this.el = options.el;
this.$el = angular.element(this.el);
}
this.initialize.apply(this, arguments);
}
angular.module('ovTopo2')
.factory('Topo2UIView',
['FnService',
function (fn) {
_.extend(View.prototype, {
el: null,
empty: function () {
if (this.$el) {
this.$el.empty();
}
},
destroy: function () {
// TODO: Unbind Events
this.empty();
return this;
}
});
View.extend = fn.extend;
return View;
}
]);
})();

View File

@ -83,6 +83,7 @@
<script src="app/fw/widget/button.js"></script>
<script src="app/fw/widget/tableBuilder.js"></script>
<script src="app/fw/widget/chartBuilder.js"></script>
<script src="app/fw/widget/listBuilder.js"></script>
<script src="app/fw/layer/layer.js"></script>
<script src="app/fw/layer/panel.js"></script>
@ -127,20 +128,23 @@
<link rel="stylesheet" href="app/fw/widget/table-theme.css">
<!-- Under development for Region support. -->
<!-- <script src="app/view/topo2/topo2.js"></script>
<!--<script src="app/view/topo2/topo2.js"></script>
<script src="app/view/topo2/topo2Breadcrumb.js"></script>
<script src="app/view/topo2/topo2Collection.js"></script>
<script src="app/view/topo2/topo2D3.js"></script>
<script src="app/view/topo2/topo2Dialog.js"></script>
<script src="app/view/topo2/topo2DetailsPanel.js"></script>
<script src="app/view/topo2/topo2Device.js"></script>
<script src="app/view/topo2/topo2DeviceDetailsPanel.js"></script>
<script src="app/view/topo2/topo2Event.js"></script>
<script src="app/view/topo2/topo2Force.js"></script>
<script src="app/view/topo2/topo2Host.js"></script>
<script src="app/view/topo2/topo2HostsPanel.js"></script>
<script src="app/view/topo2/topo2Instance.js"></script>
<script src="app/view/topo2/topo2KeyCommands.js"></script>
<script src="app/view/topo2/topo2Layout.js"></script>
<script src="app/view/topo2/topo2Link.js"></script>
<script src="app/view/topo2/topo2LinkPanel.js"></script>
<script src="app/view/topo2/topo2Map.js"></script>
<script src="app/view/topo2/topo2MapCountryFilters.js"></script>
<script src="app/view/topo2/topo2MapConfig.js"></script>
@ -154,9 +158,11 @@
<script src="app/view/topo2/topo2Select.js"></script>
<script src="app/view/topo2/topo2SummaryPanel.js"></script>
<script src="app/view/topo2/topo2SubRegion.js"></script>
<script src="app/view/topo2/topo2SubRegionPanel.js"></script>
<script src="app/view/topo2/topo2Theme.js"></script>
<script src="app/view/topo2/topo2View.js"></script>
<script src="app/view/topo2/topo2Zoom.js"></script>
<script src="app/view/topo2/uiView.js"></script>
<link rel="stylesheet" href="app/view/topo2/topo2.css">
<link rel="stylesheet" href="app/view/topo2/topo2-theme.css">-->

View File

@ -212,12 +212,12 @@ describe('factory: fw/util/fn.js', function() {
it('should define api functions', function () {
expect(fs.areFunctions(fs, [
'isF', 'isA', 'isS', 'isO', 'contains',
'areFunctions', 'areFunctionsNonStrict', 'windowSize',
'areFunctions', 'areFunctionsNonStrict', 'windowSize',
'isMobile', 'isChrome', 'isSafari', 'isFirefox',
'debugOn', 'debug',
'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'sameObjProps', 'containsObj', 'cap',
'eecode', 'noPx', 'noPxStyle', 'endsWith', 'parseBitRate', 'addToTrie', 'removeFromTrie', 'trieLookup',
'classNames'
'classNames', 'extend'
])).toBeTruthy();
});