ONOS-5579 Refactoring Details Panel
Added an Editable Textfield Component
Refactored Device View
Refactored Host View
Change-Id: I7ca423f6c198f8e09b20ed4e57e352de04b797e9
diff --git a/web/gui/src/main/webapp/app/fw/layer/details-panel.css b/web/gui/src/main/webapp/app/fw/layer/details-panel.css
new file mode 100644
index 0000000..1c41835
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/layer/details-panel.css
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
diff --git a/web/gui/src/main/webapp/app/fw/layer/details-panel.js b/web/gui/src/main/webapp/app/fw/layer/details-panel.js
new file mode 100644
index 0000000..cc72a06
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/layer/details-panel.js
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+(function () {
+
+ var ps, fs, mast, wss, is, EditableTextComponent;
+
+ var panel,
+ pStartY,
+ wSize,
+ wssHandlers = {},
+ options;
+
+ // Constants
+ var topPdg = 28,
+ defaultLabelWidth = 110,
+ defaultValueWidth = 80;
+
+ // Elements
+ var container,
+ top,
+ bottom;
+
+ function createDetailsPanel(name, _options) {
+ options = _options;
+ scope = options.scope;
+
+ panel = ps.createPanel(name, options);
+
+ calculatePositions();
+
+ panel.el().style({
+ position: 'absolute',
+ top: pStartY + 'px',
+ });
+
+ hide();
+
+ return panel;
+ }
+
+ function calculatePositions() {
+ pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
+ + mast.mastHeight() + topPdg;
+ wSize = fs.windowSize(pStartY);
+ pHeight = wSize.height;
+ }
+
+ function hide() {
+ panel.hide();
+ }
+
+ function setResponse(name, callback) {
+ var additionalHandler = {};
+ additionalHandler[name] = callback;
+
+ wss.bindHandlers(additionalHandler);
+ wssHandlers = _.extend({}, wssHandlers, additionalHandler);
+ }
+
+ function addContainers() {
+ container = panel.append('div').classed('container', true);
+ top = container.append('div').classed('top', true);
+ bottom = container.append('div').classed('bottom', true);
+ }
+
+ function addCloseButton(onClose) {
+ var closeBtn = top.append('div').classed('close-btn', true);
+
+ is.loadEmbeddedIcon(closeBtn, 'close', 20);
+ closeBtn.on('click', onClose || function () {});
+ }
+
+ function addHeading(icon) {
+ top.append('div').classed('iconDiv ' + icon, true);
+ new EditableTextComponent(top.append('h2'), {
+ scope: options.scope,
+ nameChangeRequest: options.nameChangeRequest,
+ keyBindings: options.keyBindings,
+ });
+ }
+
+ function addTable(parent, className) {
+ return parent.append('div').classed(className, true).append('table');
+ }
+
+ function addProp(tbody, key, value) {
+ console.log(tbody);
+ var tr = tbody.append('tr');
+
+ function addCell(cls, txt, width) {
+ tr.append('td').attr('class', cls).attr('width', width).text(txt);
+ }
+
+ addCell('label', key + ' :', defaultLabelWidth);
+ addCell('value', value, defaultValueWidth);
+ }
+
+ function addPropsList(el, props) {
+ var tblDiv = el.append('div').classed('top-tables', true);
+ var left = addTable(tblDiv, 'left').append('tbody');
+ var right = addTable(tblDiv, 'right').append('tbody');
+
+ var keys = _.keys(props);
+
+ _.each(props, function (value, key) {
+ var index = keys.indexOf(key);
+
+ if (index < keys.length / 2) {
+ addProp(left, key, value);
+ } else {
+ addProp(right, key, value);
+ }
+ });
+ }
+
+ function empty() {
+ panel.empty();
+ }
+
+ function select(id) {
+ return panel.el().select(id);
+ }
+
+ function destroy() {
+ wss.unbindHandlers(wssHandlers);
+ }
+
+ angular.module('onosLayer')
+ .factory('DetailsPanelService', [
+
+ 'PanelService', 'FnService', 'MastService', 'WebSocketService',
+ 'IconService', 'EditableTextComponent',
+
+ function (_ps_, _fs_, _mast_, _wss_, _is_, _etc_) {
+
+ ps = _ps_;
+ fs = _fs_;
+ mast = _mast_;
+ wss = _wss_;
+ is = _is_;
+ EditableTextComponent = _etc_;
+
+ return {
+ create: createDetailsPanel,
+ setResponse: setResponse,
+
+ addContainers: addContainers,
+ addCloseButton: addCloseButton,
+ addHeading: addHeading,
+ addPropsList: addPropsList,
+
+ // Elements
+ container: function () { return container; },
+ top: function () { return top; },
+ bottom: function () { return bottom; },
+ select: select,
+
+ empty: empty,
+ hide: hide,
+ destroy: destroy,
+ };
+ },
+ ]);
+})();
diff --git a/web/gui/src/main/webapp/app/fw/layer/editable-text.js b/web/gui/src/main/webapp/app/fw/layer/editable-text.js
new file mode 100644
index 0000000..09da1ec
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/layer/editable-text.js
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+(function () {
+
+ var ks, wss;
+
+ var EditableText = function (el, options) {
+ // constructor
+ this.el = el;
+ this.scope = options.scope;
+ this.options = options;
+
+ this.el.classed('editable clickable', true).on('click', this.onEdit.bind(this));
+ this.editingName = false;
+ };
+
+ EditableText.prototype = {
+
+ bindHandlers: function () {
+ ks.keyBindings({
+ 'enter': this.save.bind(this),
+ 'esc': [this.cancel.bind(this), 'Close the details panel']
+ });
+ },
+
+ unbindHandlers: function () {
+ ks.unbindKeys();
+
+ if (this.options.keyBindings) {
+ // Reset to original bindings before editable text
+ ks.keyBindings(this.options.keyBindings);
+ }
+ },
+
+ addTextField: function () {
+ return this.el.append('input').classed('name-input', true)
+ .attr('type', 'text')
+ .attr('value', this.scope.panelData.name)[0][0];
+ },
+
+ onEdit: function () {
+ if (!this.editingName) {
+ this.el.classed('editable clickable', false);
+ this.el.text('');
+
+ var el = this.addTextField();
+ el.focus();
+ el.select();
+ this.editingName = true;
+
+ this.bindHandlers();
+
+ ks.enableGlobalKeys(false);
+ }
+ },
+
+ exit: function (name) {
+ this.el.text(name);
+ this.el.classed('editable clickable', true);
+ this.editingName = false;
+ ks.enableGlobalKeys(true);
+ this.unbindHandlers();
+ },
+
+ cancel: function (a, b, ev) {
+
+ if (this.editingName) {
+ this.exit(this.scope.panelData.name);
+ return true;
+ }
+
+ return false;
+ },
+
+ save: function () {
+ var id = this.scope.panelData.id,
+ val,
+ newVal;
+
+ if (this.editingName) {
+ val = this.el.select('input').property('value').trim();
+ newVal = val || id;
+
+ this.exit(newVal);
+ this.scope.panelData.name = newVal;
+ wss.sendEvent(this.options.nameChangeRequest, { id: id, name: val });
+ }
+ },
+ };
+
+
+ angular.module('onosLayer')
+ .factory('EditableTextComponent', [
+
+ 'KeyService', 'WebSocketService',
+
+ function (_ks_, _wss_) {
+ ks = _ks_;
+ wss = _wss_;
+
+ return EditableText;
+ },
+ ]);
+
+})();
diff --git a/web/gui/src/main/webapp/app/view/device/device.js b/web/gui/src/main/webapp/app/view/device/device.js
index 4fbb0df..6bc66d8 100644
--- a/web/gui/src/main/webapp/app/view/device/device.js
+++ b/web/gui/src/main/webapp/app/view/device/device.js
@@ -22,17 +22,14 @@
'use strict';
// injected refs
- var $log, $scope, $loc, fs, mast, ps, wss, is, ns, ks;
+ var $log, $scope, $loc, fs, mast, ps, wss, is, ns, ks, dps;
// internal state
var detailsPanel,
pStartY,
pHeight,
top,
- bottom,
- iconDiv,
wSize,
- editingName = false,
device;
// constants
@@ -40,19 +37,12 @@
ctnrPdg = 24,
scrollSize = 17,
portsTblPdg = 50,
- defaultLabelWidth = 110,
- defaultValueWidth = 80,
pName = 'device-details-panel',
detailsReq = 'deviceDetailsRequest',
detailsResp = 'deviceDetailsResponse',
nameChangeReq = 'deviceNameChangeRequest',
nameChangeResp = 'deviceNameChangeResponse',
- friendlyProps = [
- 'URI', 'Type', 'Master ID', 'Chassis ID',
- 'Vendor', 'H/W Version', 'S/W Version', 'Protocol', 'Serial #',
- 'Pipeconf',
- ],
portCols = [
'enabled', 'id', 'speed', 'type', 'elinks_dest', 'name',
],
@@ -60,6 +50,11 @@
'Enabled', 'ID', 'Speed', 'Type', 'Egress Links', 'Name',
];
+ var keyBindings = {
+ esc: [closePanel, 'Close the details panel'],
+ _helpFormat: ['esc'],
+ };
+
function closePanel() {
if (detailsPanel.isVisible()) {
$scope.selId = null;
@@ -69,119 +64,44 @@
return false;
}
- function addCloseBtn(div) {
- is.loadEmbeddedIcon(div, 'close', 20);
- div.on('click', closePanel);
- }
-
- function exitEditMode(nameH2, name) {
- nameH2.text(name);
- nameH2.classed('editable clickable', true);
- editingName = false;
- ks.enableGlobalKeys(true);
- }
-
- function editNameSave() {
- var nameH2 = top.select('h2'),
- id = $scope.panelData.id,
- val,
- newVal;
-
- if (editingName) {
- val = nameH2.select('input').property('value').trim();
- newVal = val || id;
-
- exitEditMode(nameH2, newVal);
- $scope.panelData.name = newVal;
- wss.sendEvent(nameChangeReq, { id: id, name: val });
- }
- }
-
- function editNameCancel() {
- if (editingName) {
- exitEditMode(top.select('h2'), $scope.panelData.name);
- return true;
- }
- return false;
- }
-
- function editName() {
- var nameH2 = top.select('h2'),
- tf, el;
-
- if (!editingName) {
- nameH2.classed('editable clickable', false);
- nameH2.text('');
- tf = nameH2.append('input').classed('name-input', true)
- .attr('type', 'text')
- .attr('value', $scope.panelData.name);
- el = tf[0][0];
- el.focus();
- el.select();
- editingName = true;
- ks.enableGlobalKeys(false);
- }
- }
-
- function handleEscape() {
- return editNameCancel() || closePanel();
- }
-
function setUpPanel() {
- var container, closeBtn, tblDiv;
- detailsPanel.empty();
+ // var container, closeBtn, tblDiv;
- container = detailsPanel.append('div').classed('container', true);
+ dps.empty();
+ dps.addContainers();
+ dps.addCloseButton(closePanel);
- top = container.append('div').classed('top', true);
- closeBtn = top.append('div').classed('close-btn', true);
- addCloseBtn(closeBtn);
- iconDiv = top.append('div').classed('dev-icon', true);
- top.append('h2').classed('editable clickable', true).on('click', editName);
+ var top = dps.top();
+ var bottom = dps.bottom();
- tblDiv = top.append('div').classed('top-tables', true);
- tblDiv.append('div').classed('left', true).append('table');
- tblDiv.append('div').classed('right', true).append('table');
+ dps.addHeading('dev-icon');
+ top.append('div').classed('top-content', true);
top.append('hr');
- bottom = container.append('div').classed('bottom', true);
bottom.append('h2').classed('ports-title', true).text('Ports');
bottom.append('table');
}
- function addProp(tbody, index, value) {
- var tr = tbody.append('tr');
-
- function addCell(cls, txt, width) {
- tr.append('td').attr('class', cls).attr('width', width).text(txt);
- }
- addCell('label', friendlyProps[index] + ' :', defaultLabelWidth);
- addCell('value', value, defaultValueWidth);
+ function friendlyPropsList(details) {
+ return {
+ 'URI': device.id,
+ 'Type': device.type,
+ 'Master ID': details['masterid'],
+ 'Chassis ID': details['chassid'],
+ 'Vendor': device.mfr,
+ 'H/W Version': device.hw,
+ 'S/W Version': device.sw,
+ 'Protocol': details['protocol'],
+ 'Serial #': device.serial,
+ 'Pipeconf': details['pipeconf'],
+ };
}
function populateTop(tblDiv, details) {
- var leftTbl = tblDiv.select('.left')
- .select('table')
- .append('tbody'),
- rightTbl = tblDiv.select('.right')
- .select('table')
- .append('tbody');
-
- is.loadEmbeddedIcon(iconDiv, details._iconid_type, 40);
- top.select('h2').text(details.name);
-
- // === demonstrate use of JsonCodec object see ONOS-5976
- addProp(leftTbl, 0, device.id);
- addProp(leftTbl, 1, device.type);
- addProp(leftTbl, 2, details['masterid']);
- addProp(leftTbl, 3, details['chassid']);
- addProp(leftTbl, 4, device.mfr);
- addProp(rightTbl, 5, device.hw);
- addProp(rightTbl, 6, device.sw);
- addProp(rightTbl, 7, details['protocol']);
- addProp(rightTbl, 8, device.serial);
- addProp(rightTbl, 9, details['pipeconf']);
+ is.loadEmbeddedIcon(dps.select('.iconDiv'), details._iconid_type, 40);
+ dps.top().select('h2').text(details.name);
+ dps.addPropsList(tblDiv, friendlyPropsList(details));
}
function addPortRow(tbody, port) {
@@ -193,6 +113,7 @@
}
function populateBottom(table, ports) {
+
var theader = table.append('thead').append('tr'),
tbody = table.append('tbody'),
tbWidth, tbHeight;
@@ -200,16 +121,15 @@
friendlyPortCols.forEach(function (col) {
theader.append('th').text(col);
});
+
ports.forEach(function (port) {
addPortRow(tbody, port);
});
tbWidth = fs.noPxStyle(tbody, 'width') + scrollSize;
tbHeight = pHeight
- - (fs.noPxStyle(detailsPanel.el()
- .select('.top'), 'height')
- + fs.noPxStyle(detailsPanel.el()
- .select('.ports-title'), 'height')
+ - (fs.noPxStyle(detailsPanel.el().select('.top'), 'height')
+ + fs.noPxStyle(detailsPanel.el().select('.ports-title'), 'height')
+ portsTblPdg);
table.style({
@@ -223,15 +143,14 @@
}
function populateDetails(details) {
- var topTbs, btmTbl, ports;
+ var btmTbl, ports;
setUpPanel();
- topTbs = top.select('.top-tables');
- btmTbl = bottom.select('table');
+ btmTbl = dps.bottom().select('table');
ports = details.ports;
- populateTop(topTbs, details);
+ populateTop(dps.select('.top-content'), details);
populateBottom(btmTbl, ports);
detailsPanel.height(pHeight);
@@ -250,18 +169,19 @@
}
}
- function createDetailsPane() {
- detailsPanel = ps.createPanel(pName, {
+ function createDetailsPanel() {
+ detailsPanel = dps.create(pName, {
width: wSize.width,
margin: 0,
hideMargin: 0,
+ scope: $scope,
+ keyBindings: keyBindings,
+ nameChangeRequest: nameChangeReq,
});
- detailsPanel.el().style({
- position: 'absolute',
- top: pStartY + 'px',
- });
+
+ dps.setResponse(detailsResp, respDetailsCb);
+
$scope.hidePanel = function () { detailsPanel.hide(); };
- detailsPanel.hide();
}
// Sample functions for detail panel creation
@@ -283,10 +203,10 @@
['$log', '$scope', '$location', 'TableBuilderService',
'TableDetailService', 'FnService',
'MastService', 'PanelService', 'WebSocketService', 'IconService',
- 'NavService', 'KeyService',
+ 'NavService', 'KeyService', 'DetailsPanelService',
function (_$log_, _$scope_, _$location_,
- tbs, tds, _fs_, _mast_, _ps_, _wss_, _is_, _ns_, _ks_) {
+ tbs, tds, _fs_, _mast_, _ps_, _wss_, _is_, _ns_, _ks_, _dps_) {
var params,
handlers = {};
@@ -300,6 +220,7 @@
is = _is_;
ns = _ns_;
ks = _ks_;
+ dps = _dps_;
params = $loc.search();
@@ -310,7 +231,7 @@
$scope.meterTip = 'Show meter view for selected device';
// details panel handlers
- handlers[detailsResp] = respDetailsCb;
+ // handlers[detailsResp] = respDetailsCb;
handlers[nameChangeResp] = respNameCb;
wss.bindHandlers(handlers);
@@ -352,6 +273,7 @@
};
$scope.$on('$destroy', function () {
+ dps.destroy();
wss.unbindHandlers(handlers);
});
@@ -373,7 +295,7 @@
function initPanel() {
heightCalc();
- createDetailsPane();
+ createDetailsPanel();
}
// Safari has a bug where it renders the fixed-layout table wrong
@@ -384,11 +306,8 @@
initPanel();
}
// create key bindings to handle panel
- ks.keyBindings({
- enter: editNameSave,
- esc: [handleEscape, 'Close the details panel'],
- _helpFormat: ['esc'],
- });
+ ks.keyBindings(keyBindings);
+
ks.gestureNotes([
['click', 'Select a row to show device details'],
['scroll down', 'See more devices'],
diff --git a/web/gui/src/main/webapp/app/view/host/host.js b/web/gui/src/main/webapp/app/view/host/host.js
index b5bf018..37668bb 100644
--- a/web/gui/src/main/webapp/app/view/host/host.js
+++ b/web/gui/src/main/webapp/app/view/host/host.js
@@ -22,16 +22,14 @@
'use strict';
// injected refs
- var $log, $scope, $loc, fs, mast, ps, wss, is, ns, ks;
+ var $log, $scope, $loc, fs, mast, ps, wss, is, ns, ks, dps;
// internal state
var detailsPanel,
pStartY,
pHeight,
top,
- iconDiv,
- wSize,
- editingName = false;
+ wSize;
// constants
var topPdg = 28,
@@ -41,13 +39,10 @@
nameChangeReq = 'hostNameChangeRequest',
nameChangeResp = 'hostNameChangeResponse';
- var propOrder = [
- 'id', 'ip', 'mac', 'vlan', 'configured', 'location',
- ],
- friendlyProps = [
- 'Host ID', 'IP Address', 'MAC Address', 'VLAN',
- 'Configured', 'Location',
- ];
+ var keyBindings = {
+ esc: [closePanel, 'Close the details panel'],
+ _helpFormat: ['esc'],
+ };
function closePanel() {
if (detailsPanel.isVisible()) {
@@ -58,105 +53,41 @@
return false;
}
- function addCloseBtn(div) {
- is.loadEmbeddedIcon(div, 'close', 20);
- div.on('click', closePanel);
- }
-
- function exitEditMode(nameH2, name) {
- nameH2.text(name);
- nameH2.classed('editable clickable', true);
- editingName = false;
- ks.enableGlobalKeys(true);
- }
-
- function editNameSave() {
- var nameH2 = top.select('h2'),
- id = $scope.panelData.id,
- ip = $scope.panelData.ip,
- val,
- newVal;
-
- if (editingName) {
- val = nameH2.select('input').property('value').trim();
- newVal = val || ip;
-
- exitEditMode(nameH2, newVal);
- $scope.panelData.name = newVal;
- wss.sendEvent(nameChangeReq, { id: id, name: val });
- }
- }
-
- function editNameCancel() {
- if (editingName) {
- exitEditMode(top.select('h2'), $scope.panelData.name);
- return true;
- }
- return false;
- }
-
- function editName() {
- var nameH2 = top.select('h2'),
- tf, el;
-
- if (!editingName) {
- nameH2.classed('editable clickable', false);
- nameH2.text('');
- tf = nameH2.append('input').classed('name-input', true)
- .attr('type', 'text')
- .attr('value', $scope.panelData.name);
- el = tf[0][0];
- el.focus();
- el.select();
- editingName = true;
- ks.enableGlobalKeys(false);
- }
- }
-
- function handleEscape() {
- return editNameCancel() || closePanel();
- }
function setUpPanel() {
- var container, closeBtn;
- detailsPanel.empty();
- container = detailsPanel.append('div').classed('container', true);
+ dps.empty();
+ dps.addContainers();
+ dps.addCloseButton(closePanel);
- top = container.append('div').classed('top', true);
- closeBtn = top.append('div').classed('close-btn', true);
- addCloseBtn(closeBtn);
- iconDiv = top.append('div').classed('host-icon', true);
- top.append('h2').classed('editable clickable', true).on('click', editName);
+ var top = dps.top();
- top.append('div').classed('top-tables', true);
+ dps.addHeading('host-icon');
+ top.append('div').classed('top-content', true);
+
top.append('hr');
}
- function addProp(tbody, index, value) {
- var tr = tbody.append('tr');
-
- function addCell(cls, txt) {
- tr.append('td').attr('class', cls).text(txt);
- }
- addCell('label', friendlyProps[index] + ' :');
- addCell('value', value);
+ function friendlyPropsList(details) {
+ return {
+ 'Host ID': details.id,
+ 'IP Address': details.ip[0],
+ 'MAC Address': details.mac,
+ 'VLAN': details.vlan,
+ 'Configured': details.configured,
+ 'Location': details.location,
+ };
}
- function populateTop(details) {
- var tab = top.select('.top-tables').append('table').append('tbody');
-
- is.loadEmbeddedIcon(iconDiv, details._iconid_type, 40);
- top.select('h2').text(details.name);
-
- propOrder.forEach(function (prop, i) {
- addProp(tab, i, details[prop]);
- });
+ function populateTop(tblDiv, details) {
+ is.loadEmbeddedIcon(dps.select('.iconDiv'), details._iconid_type, 40);
+ dps.top().select('h2').text(details.name);
+ dps.addPropsList(tblDiv, friendlyPropsList(details));
}
function populateDetails(details) {
setUpPanel();
- populateTop(details);
+ populateTop(dps.select('.top-content'), details);
detailsPanel.height(pHeight);
// configure width based on content.. for now hardcoded
detailsPanel.width(400);
@@ -174,18 +105,19 @@
}
}
- function createDetailsPane() {
- detailsPanel = ps.createPanel(pName, {
+ function createDetailsPanel() {
+ detailsPanel = dps.create(pName, {
width: wSize.width,
margin: 0,
hideMargin: 0,
+ scope: $scope,
+ keyBindings: keyBindings,
+ nameChangeRequest: nameChangeReq,
});
- detailsPanel.el().style({
- position: 'absolute',
- top: pStartY + 'px',
- });
+
+ dps.setResponse(detailsResp, respDetailsCb);
+
$scope.hidePanel = function () { detailsPanel.hide(); };
- detailsPanel.hide();
}
@@ -196,12 +128,12 @@
'$location',
'TableBuilderService',
'FnService', 'MastService', 'PanelService', 'WebSocketService',
- 'IconService', 'NavService', 'KeyService',
+ 'IconService', 'NavService', 'KeyService', 'DetailsPanelService',
function (_$log_, _$scope_, _$location_,
tbs,
_fs_, _mast_, _ps_, _wss_,
- _is_, _ns_, _ks_) {
+ _is_, _ns_, _ks_, _dps_) {
var params,
handlers = {};
@@ -216,13 +148,13 @@
is = _is_;
ns = _ns_;
ks = _ks_;
+ dps = _dps_;
params = $loc.search();
$scope.panelData = {};
// details panel handlers
- handlers[detailsResp] = respDetailsCb;
handlers[nameChangeResp] = respNameCb;
wss.bindHandlers(handlers);
@@ -254,6 +186,7 @@
};
$scope.$on('$destroy', function () {
+ dps.destroy();
wss.unbindHandlers(handlers);
});
@@ -261,7 +194,7 @@
}])
.directive('hostDetailsPanel',
- ['$rootScope', '$window', '$timeout', 'KeyService',
+ ['$rootScope', '$window', '$timeout', 'KeyService', 'DetailsPanelService',
function ($rootScope, $window, $timeout, ks) {
return function (scope) {
var unbindWatch;
@@ -275,7 +208,7 @@
function initPanel() {
heightCalc();
- createDetailsPane();
+ createDetailsPanel();
}
// Safari has a bug where it renders the fixed-layout table wrong
@@ -286,11 +219,7 @@
initPanel();
}
// create key bindings to handle panel
- ks.keyBindings({
- enter: editNameSave,
- esc: [handleEscape, 'Close the details panel'],
- _helpFormat: ['esc'],
- });
+ ks.keyBindings(keyBindings);
ks.gestureNotes([
['click', 'Select a row to show device details'],
['scroll down', 'See more devices'],