Adding server-side user preferences.
More work still needs to get done to allow client to process
server-pushed preferences updates.
Change-Id: I6e80e3f3677285cb19cfa3b6240c1b13aac56622
diff --git a/web/gui/src/main/webapp/app/fw/layer/loading.js b/web/gui/src/main/webapp/app/fw/layer/loading.js
index 86dd56d..a9e141eb 100644
--- a/web/gui/src/main/webapp/app/fw/layer/loading.js
+++ b/web/gui/src/main/webapp/app/fw/layer/loading.js
@@ -122,9 +122,9 @@
angular.module('onosLayer')
.factory('LoadingService',
- ['$log', '$timeout', 'ThemeService', 'FnService',
+ ['$log', '$timeout', 'ThemeService', 'FnService', 'WebSocketService',
- function (_$log_, _$timeout_, _ts_, _fs_) {
+ function (_$log_, _$timeout_, _ts_, _fs_, wss) {
$log = _$log_;
$timeout = _$timeout_;
ts = _ts_;
@@ -132,11 +132,13 @@
preloadImages();
- return {
+ var self = {
start: start,
stop: stop,
waiting: waiting
};
+ wss._setLoadingDelegate(self);
+ return self;
}]);
}());
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/app/fw/layer/veil.js b/web/gui/src/main/webapp/app/fw/layer/veil.js
index fc0530a..fddfe7f 100644
--- a/web/gui/src/main/webapp/app/fw/layer/veil.js
+++ b/web/gui/src/main/webapp/app/fw/layer/veil.js
@@ -79,21 +79,23 @@
angular.module('onosLayer')
.factory('VeilService',
- ['$log', '$route', 'FnService', 'KeyService', 'GlyphService',
+ ['$log', '$route', 'FnService', 'KeyService', 'GlyphService', 'WebSocketService',
- function (_$log_, _$route_, _fs_, _ks_, _gs_) {
+ function (_$log_, _$route_, _fs_, _ks_, _gs_, wss) {
$log = _$log_;
$route = _$route_;
fs = _fs_;
ks = _ks_;
gs = _gs_;
- return {
+ var self = {
init: init,
show: show,
hide: hide,
lostServer: lostServer
};
+ wss._setVeilDelegate(self);
+ return self;
}]);
}());
diff --git a/web/gui/src/main/webapp/app/fw/remote/websocket.js b/web/gui/src/main/webapp/app/fw/remote/websocket.js
index e39a7f9..92d2d2e 100644
--- a/web/gui/src/main/webapp/app/fw/remote/websocket.js
+++ b/web/gui/src/main/webapp/app/fw/remote/websocket.js
@@ -59,7 +59,7 @@
function handleOpen() {
$log.info('Web socket open - ', url);
- vs.hide();
+ vs && vs.hide();
if (fs.debugOn('txrx')) {
$log.debug('Sending ' + pendingEvents.length + ' pending event(s)...');
@@ -105,14 +105,14 @@
var gsucc;
$log.info('Web socket closed');
- ls.stop();
+ ls && ls.stop();
wsUp = false;
if (gsucc = findGuiSuccessor()) {
createWebSocket(webSockOpts, gsucc);
} else {
// If no controllers left to contact, show the Veil...
- vs.show([
+ vs && vs.show([
'Oops!',
'Web-socket connection to server closed...',
'Try refreshing the page.'
@@ -296,22 +296,29 @@
}
}
+ // Binds the veil service as a delegate
+ function setVeilDelegate(vd) {
+ vs = vd;
+ }
+
+ // Binds the loading service as a delegate
+ function setLoadingDelegate(ld) {
+ ls = ld;
+ }
+
// ============================
// ===== Definition of module
angular.module('onosRemote')
.factory('WebSocketService',
['$log', '$location', 'FnService', 'UrlFnService', 'WSock',
- 'VeilService', 'LoadingService',
- function (_$log_, _$loc_, _fs_, _ufs_, _wsock_, _vs_, _ls_) {
+ function (_$log_, _$loc_, _fs_, _ufs_, _wsock_) {
$log = _$log_;
$loc = _$loc_;
fs = _fs_;
ufs = _ufs_;
wsock = _wsock_;
- vs = _vs_;
- ls = _ls_;
bindHandlers(builtinHandlers);
@@ -324,7 +331,10 @@
addOpenListener: addOpenListener,
removeOpenListener: removeOpenListener,
sendEvent: sendEvent,
- isConnected: function () { return wsUp; }
+ isConnected: function () { return wsUp; },
+
+ _setVeilDelegate: setVeilDelegate,
+ _setLoadingDelegate: setLoadingDelegate
};
}
]);
diff --git a/web/gui/src/main/webapp/app/fw/util/prefs.js b/web/gui/src/main/webapp/app/fw/util/prefs.js
index 02a2390..ad3dc04 100644
--- a/web/gui/src/main/webapp/app/fw/util/prefs.js
+++ b/web/gui/src/main/webapp/app/fw/util/prefs.js
@@ -21,54 +21,14 @@
'use strict';
// injected refs
- var $log, $cookies, fs;
+ var $log, fs, wss;
// internal state
var cache = {};
- // NOTE: in Angular 1.3.5, $cookies is just a simple object, and
- // cookie values are just strings. From the 1.3.5 docs:
- //
- // "Only a simple Object is exposed and by adding or removing
- // properties to/from this object, new cookies are created/deleted
- // at the end of current $eval. The object's properties can only
- // be strings."
- //
- // We may want to upgrade the version of Angular sometime soon
- // since later version support objects as cookie values.
-
- // NOTE: prefs represented as simple name/value pairs
- // => a temporary restriction while we are encoding into cookies
- /*
- {
- foo: 1,
- bar: 0,
- goo: 2
- }
-
- stored as "foo:1,bar:0,goo:2"
- */
-
- // reads cookie with given name and returns an object rep of its value
- // or null if no such cookie is set
- function getPrefs(name) {
- var cook = $cookies[name],
- bits,
- obj = {};
-
- if (cook) {
- bits = cook.split(',');
- bits.forEach(function (value) {
- var x = value.split(':');
- obj[x[0]] = x[1];
- });
-
- // update the cache
- cache[name] = obj;
- return obj;
- }
- // perhaps we have a cached copy..
- return cache[name];
+ // returns the preference by the specified name
+ function getPrefs(name, defaults) {
+ return cache[name] || defaults;
}
// converts string values to numbers for selected (or all) keys
@@ -89,34 +49,28 @@
}
function setPrefs(name, obj) {
- var bits = [],
- str;
-
- angular.forEach(obj, function (value, key) {
- bits.push(key + ':' + value);
- });
- str = bits.join(',');
-
- // keep a cached copy of the object
+ // keep a cached copy of the object and send an update to server
cache[name] = obj;
-
- // The angular way of doing this...
- // $cookies[name] = str;
- // ...but it appears that this gets delayed, and doesn't 'stick' ??
-
- // FORCE cookie to be set by writing directly to document.cookie...
- document.cookie = name + '=' + encodeURIComponent(str);
- if (fs.debugOn('prefs')) {
- $log.debug('<<>> Wrote cookie <'+name+'>:', str);
- }
+ wss.sendEvent('updatePrefReq', { key: name, value: obj });
+ }
+
+ function updatePrefs(data) {
+ $log.info('User properties updated');
+ cache[data.key] = data.value;
}
angular.module('onosUtil')
- .factory('PrefsService', ['$log', '$cookies', 'FnService',
- function (_$log_, _$cookies_, _fs_) {
+ .factory('PrefsService', ['$log', 'FnService', 'WebSocketService',
+ function (_$log_, _fs_, _wss_) {
$log = _$log_;
- $cookies = _$cookies_;
fs = _fs_;
+ wss = _wss_;
+
+ cache = userPrefs;
+
+ wss.bindHandlers({
+ updatePrefs: updatePrefs
+ });
return {
getPrefs: getPrefs,
diff --git a/web/gui/src/main/webapp/app/fw/util/theme.js b/web/gui/src/main/webapp/app/fw/util/theme.js
index 0e0ee64..4441402 100644
--- a/web/gui/src/main/webapp/app/fw/util/theme.js
+++ b/web/gui/src/main/webapp/app/fw/util/theme.js
@@ -20,7 +20,7 @@
(function () {
'use strict';
- var $log, fs;
+ var $log, fs, ps;
var themes = ['light', 'dark'],
themeStr = themes.join(' '),
@@ -29,7 +29,7 @@
nextListenerId = 1;
function init() {
- thidx = 0;
+ thidx = ps.getPrefs('theme', { idx: 0 }).idx;
updateBodyClass();
}
@@ -37,10 +37,11 @@
return themes[thidx];
}
- function setTheme(t) {
+ function setTheme(t, force) {
var idx = themes.indexOf(t);
- if (idx > -1 && idx !== thidx) {
+ if (force || idx > -1 && idx !== thidx) {
thidx = idx;
+ ps.setPrefs('theme', { idx: thidx });
updateBodyClass();
themeEvent('set');
}
@@ -49,6 +50,7 @@
function toggleTheme() {
var i = thidx + 1;
thidx = (i===themes.length) ? 0 : i;
+ ps.setPrefs('theme', { idx: thidx });
updateBodyClass();
themeEvent('toggle');
return getTheme();
@@ -97,11 +99,11 @@
}
angular.module('onosUtil')
- .factory('ThemeService', ['$log', 'FnService',
- function (_$log_, _fs_) {
+ .factory('ThemeService', ['$log', 'FnService', 'PrefsService',
+ function (_$log_, _fs_, _ps_) {
$log = _$log_;
fs = _fs_;
- thidx = 0;
+ ps = _ps_;
return {
init: init,
diff --git a/web/gui/src/main/webapp/app/fw/widget/toolbar.js b/web/gui/src/main/webapp/app/fw/widget/toolbar.js
index 050afd0..3b9e5ed 100644
--- a/web/gui/src/main/webapp/app/fw/widget/toolbar.js
+++ b/web/gui/src/main/webapp/app/fw/widget/toolbar.js
@@ -219,6 +219,10 @@
}
}
+ function isVisible() {
+ return panel.isVisible();
+ }
+
return {
addButton: addButton,
addToggle: addToggle,
@@ -228,7 +232,8 @@
show: show,
hide: hide,
- toggle: toggle
+ toggle: toggle,
+ isVisible: isVisible
};
}
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 9b532f6..069fa42 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -30,7 +30,7 @@
// references to injected services
var $scope, $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss, ps, th,
- tds, tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, tspr, ttip, tov;
+ tds, t3s, tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, tspr, ttip, tov;
// DOM elements
var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
@@ -369,16 +369,14 @@
function setUpMap($loc) {
var qp = $loc.search(),
- pr = ps.getPrefs('topo_mapid'),
- mi1 = qp.mapid,
- mi2 = pr && pr.id,
- mapId = mi1 || mi2 || 'usa',
- ms1 = qp.mapscale,
- ms2 = pr && pr.scale,
- mapScale = ms1 || ms2 || 1,
- t1 = qp.tint,
- t2 = pr && pr.tint,
- tint = t1 || t2 || 'off',
+ pr = ps.getPrefs('topo_mapid', {
+ id: qp.mapid || 'usa',
+ scale: qp.mapscale || 1,
+ tint: qp.tint || 'off'
+ }),
+ mapId = pr.id,
+ mapScale = pr.scale,
+ tint = pr.tint,
promise,
cfilter;
@@ -441,8 +439,8 @@
function setUpSprites($loc, tspr) {
var s1 = $loc.search().sprites,
- s2 = ps.getPrefs('topo_sprites'),
- sprId = s1 || (s2 && s2.id);
+ s2 = ps.getPrefs('topo_sprites', { id: s1 }),
+ sprId = s2.id;
spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites');
if (sprId) {
@@ -463,7 +461,7 @@
function restoreConfigFromPrefs() {
// NOTE: toolbar will have set this for us..
- prefsState = ps.asNumbers(ps.getPrefs('topo_prefs'));
+ prefsState = ps.asNumbers(ps.getPrefs('topo_prefs', ttbs.defaultPrefs));
$log.debug('TOPO- Prefs State:', prefsState);
@@ -476,6 +474,7 @@
togglePorts(prefsState.porthl);
toggleMap(prefsState.bg);
toggleSprites(prefsState.spr);
+ t3s.setDevLabIndex(prefsState.dlbls);
flash.enable(true);
}
@@ -484,7 +483,7 @@
// have opened the websocket to the server; hence this extra function
// invoked after tes.start()
function restoreSummaryFromPrefs() {
- prefsState = ps.asNumbers(ps.getPrefs('topo_prefs'));
+ prefsState = ps.asNumbers(ps.getPrefs('topo_prefs', ttbs.defaultPrefs));
$log.debug('TOPO- Prefs SUMMARY State:', prefsState.summary);
flash.enable(false);
@@ -506,7 +505,7 @@
'$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
'WebSocketService', 'PrefsService', 'ThemeService',
- 'TopoDialogService',
+ 'TopoDialogService', 'TopoD3Service',
'TopoEventService', 'TopoForceService', 'TopoPanelService',
'TopoInstService', 'TopoSelectService', 'TopoLinkService',
'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
@@ -515,7 +514,7 @@
function (_$scope_, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
_zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _th_,
- _tds_, _tes_,
+ _tds_, _t3s_, _tes_,
_tfs_, _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_,
_ttbs_, _tspr_, _ttip_, _tov_) {
var params = $loc.search(),
@@ -545,6 +544,7 @@
ps = _ps_;
th = _th_;
tds = _tds_;
+ t3s = _t3s_;
tes = _tes_;
tfs = _tfs_;
// TODO: consider funnelling actions through TopoForceService...
@@ -601,7 +601,7 @@
setUpNoDevs();
setUpMap($loc).then(
function (proj) {
- var z = ps.getPrefs('topo_zoom') || {tx:0, ty:0, sc:1};
+ var z = ps.getPrefs('topo_zoom', { tx:0, ty:0, sc:1 });
zoomer.panZoom([z.tx, z.ty], z.sc);
$log.debug('** Zoom restored:', z);
diff --git a/web/gui/src/main/webapp/app/view/topo/topoD3.js b/web/gui/src/main/webapp/app/view/topo/topoD3.js
index a14ccbe..ef704c7 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoD3.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoD3.js
@@ -23,7 +23,7 @@
'use strict';
// injected refs
- var $log, fs, sus, is, ts;
+ var $log, fs, sus, is, ts, ps, ttbs;
// api to topoForce
var api;
@@ -159,7 +159,7 @@
// ====
function incDevLabIndex() {
- deviceLabelIndex = (deviceLabelIndex+1) % 3;
+ setDevLabIndex(deviceLabelIndex+1);
switch(deviceLabelIndex) {
case 0: return 'Hide device labels';
case 1: return 'Show friendly device labels';
@@ -167,6 +167,13 @@
}
}
+ function setDevLabIndex(mode) {
+ deviceLabelIndex = mode % 3;
+ var p = ps.getPrefs('topo_prefs', ttbs.defaultPrefs);
+ p.dlbls = deviceLabelIndex;
+ ps.setPrefs('topo_prefs', p);
+ }
+
// Returns the newly computed bounding box of the rectangle
function adjustRectToFitText(n) {
var text = n.select('text'),
@@ -599,13 +606,16 @@
angular.module('ovTopo')
.factory('TopoD3Service',
['$log', 'FnService', 'SvgUtilService', 'IconService', 'ThemeService',
+ 'PrefsService', 'TopoToolbarService',
- function (_$log_, _fs_, _sus_, _is_, _ts_) {
+ function (_$log_, _fs_, _sus_, _is_, _ts_, _ps_, _ttbs_) {
$log = _$log_;
fs = _fs_;
sus = _sus_;
is = _is_;
ts = _ts_;
+ ps = _ps_;
+ ttbs = _ttbs_;
icfg = is.iconConfig();
@@ -620,6 +630,7 @@
destroyD3: destroyD3,
incDevLabIndex: incDevLabIndex,
+ setDevLabIndex: setDevLabIndex,
adjustRectToFitText: adjustRectToFitText,
hostLabel: hostLabel,
deviceLabel: deviceLabel,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoPanel.js b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
index 34e85f3..e1cef91 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
@@ -529,6 +529,7 @@
showSummary: showSummary,
toggleSummary: toggleSummary,
+ hideSummary: hideSummaryPanel,
toggleUseDetailsFlag: toggleUseDetailsFlag,
displaySingle: displaySingle,
@@ -538,8 +539,6 @@
displaySomething: displaySomething,
addAction: addAction,
- hideSummaryPanel: hideSummaryPanel,
-
detailVisible: function () { return detail.panel().isVisible(); },
summaryVisible: function () { return summary.panel().isVisible(); }
};
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
index deb49a5..535cd17 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -70,11 +70,12 @@
// initial toggle state: default settings and tag to key mapping
var defaultPrefsState = {
- summary: 1,
insts: 1,
+ summary: 1,
detail: 1,
hosts: 0,
offdev: 1,
+ dlbls: 0,
porthl: 1,
bg: 0,
spr: 0,
@@ -104,7 +105,7 @@
}
function setInitToggleState() {
- cachedState = ps.asNumbers(ps.getPrefs(cooktag));
+ cachedState = ps.asNumbers(ps.getPrefs(cooktag, defaultPrefsState));
$log.debug('TOOLBAR---- read prefs state:', cachedState);
if (!cachedState) {
@@ -264,6 +265,9 @@
function toggleToolbar() {
toolbar.toggle();
+ var prefs = ps.getPrefs(cooktag, defaultPrefsState);
+ prefs.toolbar = !prefs.toolbar;
+ ps.setPrefs('topo_prefs', prefs);
}
function setDefaultOverlay() {
@@ -298,6 +302,7 @@
keyListener: keyListener,
toggleToolbar: toggleToolbar,
setDefaultOverlay: setDefaultOverlay,
+ defaultPrefs: defaultPrefsState,
fnkey: fnkey
};
}]);