ONOS-4733: Simplified Settings Table view (removed redundant data)
- Now shows just simple class name for component
- Removed default value column
- Values that are *not* the same as the default are highlighted (emboldened)
- Table rows now selectable and show details panel
- panel shows component fully qualified class name
- panel currently read-only
- in future, user will be able to change the property value from here
Change-Id: I01a2af727dcfad82c6b7d2378701a5cb3e24e43a
diff --git a/web/gui/src/main/webapp/app/view/settings/settings.js b/web/gui/src/main/webapp/app/view/settings/settings.js
index 00c102e..3197ff0 100644
--- a/web/gui/src/main/webapp/app/view/settings/settings.js
+++ b/web/gui/src/main/webapp/app/view/settings/settings.js
@@ -21,16 +21,215 @@
(function () {
'use strict';
- angular.module('ovSettings', [])
- .controller('OvSettingsCtrl',
- ['$log', '$scope', 'TableBuilderService',
+ // injected refs
+ var $log, $scope, wss, fs, ks, ps, is;
- function ($log, $scope, tbs) {
+ // internal state
+ var detailsPanel,
+ panelData,
+ top,
+ pStartY,
+ pHeight,
+ wSize = false;
+
+ // constants
+ var pName = 'settings-details-panel',
+ panelWidth = 540,
+ topPdg = 60,
+ propOrder = ['fqComponent', 'id', 'type', 'value', 'defValue', 'desc'],
+ friendlyProps = [
+ 'Component', 'Property', 'Type', 'Value', 'Default Value',
+ 'Description'
+ ];
+
+ function createDetailsPanel() {
+ detailsPanel = ps.createPanel(pName, {
+ width: wSize.width,
+ margin: 0,
+ hideMargin: 0
+ });
+
+ detailsPanel.el().style({
+ position: 'absolute',
+ top: pStartY + 'px'
+ });
+
+ detailsPanel.hide();
+ }
+
+ function closePanel() {
+ if (detailsPanel.isVisible()) {
+ $scope.selId = null;
+ panelData = null;
+ detailsPanel.hide();
+ return true;
+ }
+ return false;
+ }
+
+ function addCloseBtn(div) {
+ is.loadEmbeddedIcon(div, 'close', 26);
+ div.on('click', closePanel);
+ }
+
+ function setUpPanel() {
+ var container, closeBtn, div;
+
+ detailsPanel.empty();
+ detailsPanel.width(panelWidth);
+
+ container = detailsPanel.append('div').classed('container', true);
+
+ top = container.append('div').classed('top', true);
+ closeBtn = top.append('div').classed('close-btn', true);
+ addCloseBtn(closeBtn);
+
+ div = top.append('div').classed('top-content', true);
+
+ function ndiv(cls, addTable) {
+ var d = div.append('div').classed(cls, true);
+ if (addTable) {
+ d.append('table');
+ }
+ }
+
+ ndiv('settings-title');
+ ndiv('settings-props', true);
+ }
+
+ function addProp(tbody, index, value) {
+ var tr = tbody.append('tr');
+
+ function addCell(cls, txt) {
+ tr.append('td').attr('class', cls).html(txt);
+ }
+
+ addCell('label', friendlyProps[index] + ':');
+ addCell('value', value);
+ }
+
+ function populateTop(details) {
+ var propsBody = top.select('.settings-props').append('tbody');
+
+ top.select('.settings-title').text(details.id);
+
+ propOrder.forEach(function (prop, i) {
+ addProp(propsBody, i, details[prop]);
+ });
+ }
+
+ function populateDetails() {
+ setUpPanel();
+ populateTop(panelData);
+ detailsPanel.height(pHeight);
+ }
+
+ angular.module('ovSettings', [])
+ .controller('OvSettingsCtrl',
+ ['$log', '$scope',
+ 'WebSocketService', 'FnService', 'KeyService', 'PanelService',
+ 'IconService', 'TableBuilderService',
+
+ function (_$log_, _$scope_, _wss_, _fs_, _ks_, _ps_, _is_, tbs) {
+ $log = _$log_;
+ $scope = _$scope_;
+ wss = _wss_;
+ fs = _fs_;
+ ks = _ks_;
+ ps = _ps_;
+ is = _is_;
+ $scope.panelData = {};
+
+ function selCb($event, row) {
+ if ($scope.selId) {
+ panelData = row;
+ populateDetails();
+ detailsPanel.show();
+ } else {
+ panelData = null;
+ detailsPanel.hide();
+ }
+ }
+
tbs.buildTable({
scope: $scope,
- tag: 'setting'
+ tag: 'setting',
+ selCb: selCb
+ });
+
+ ks.keyBindings({
+ esc: [$scope.selectCallback, 'Deselect property'],
+ _helpFormat: ['esc']
+ });
+ ks.gestureNotes([
+ ['click row', 'Select / deselect settings property'],
+ ['scroll down', 'See more settings']
+ ]);
+
+ $scope.$on('$destroy', function () {
+ ks.unbindKeys();
});
$log.log('OvSettingsCtrl has been created');
- }]);
+ }])
+
+ .directive('settingsDetailsPanel',
+ ['$rootScope', '$window', '$timeout', 'KeyService',
+ function ($rootScope, $window, $timeout, ks) {
+ return function (scope) {
+ var unbindWatch;
+
+ function heightCalc() {
+ pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
+ + topPdg;
+ wSize = fs.windowSize(pStartY);
+ pHeight = wSize.height;
+ }
+
+ function initPanel() {
+ heightCalc();
+ createDetailsPanel();
+ $log.debug('start to initialize panel!');
+ }
+
+ // Safari has a bug where it renders the fixed-layout table wrong
+ // if you ask for the window's size too early
+ if (scope.onos.browser === 'safari') {
+ $timeout(initPanel);
+ } else {
+ initPanel();
+ }
+ // create key bindings to handle panel
+ ks.keyBindings({
+ esc: [closePanel, 'Close the details panel'],
+ _helpFormat: ['esc']
+ });
+ ks.gestureNotes([
+ ['click', 'Select a row to show property details'],
+ ['scroll down', 'See more properties']
+ ]);
+
+ // if the window size changes
+ unbindWatch = $rootScope.$watchCollection(
+ function () {
+ return {
+ h: $window.innerHeight,
+ w: $window.innerWidth
+ };
+ }, function () {
+ if (panelData) {
+ heightCalc();
+ populateDetails();
+ }
+ }
+ );
+
+ scope.$on('$destroy', function () {
+ panelData = null;
+ unbindWatch();
+ ks.unbindKeys();
+ ps.destroyPanel(pName);
+ });
+ };
+ }]);
}());