mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-24 05:41:01 +02:00
GUI -- User Prefs written as a service; persistent topo settings updated a bit; still WIP.
Change-Id: I6945dd9eb4b325a8f1637c44e2c4b271126b2bc4
This commit is contained in:
parent
553db17965
commit
c7ae795c31
107
web/gui/src/main/webapp/app/fw/util/prefs.js
Normal file
107
web/gui/src/main/webapp/app/fw/util/prefs.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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 -- Util -- User Preference Service
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// injected refs
|
||||||
|
var $log, $cookies;
|
||||||
|
|
||||||
|
// 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(number) 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]] = Number(x[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// update the cache
|
||||||
|
cache[name] = obj;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
// perhaps we have a cached copy..
|
||||||
|
return cache[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
$log.debug('<<>> Wrote cookie <'+name+'>:', str);
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.module('onosUtil')
|
||||||
|
.factory('PrefsService', ['$log', '$cookies',
|
||||||
|
function (_$log_, _$cookies_) {
|
||||||
|
$log = _$log_;
|
||||||
|
$cookies = _$cookies_;
|
||||||
|
|
||||||
|
return {
|
||||||
|
getPrefs: getPrefs,
|
||||||
|
setPrefs: setPrefs
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
}());
|
||||||
@ -29,7 +29,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
// references to injected services etc.
|
// references to injected services etc.
|
||||||
var $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss,
|
var $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss, ps,
|
||||||
tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs;
|
tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs;
|
||||||
|
|
||||||
// DOM elements
|
// DOM elements
|
||||||
@ -100,7 +100,7 @@
|
|||||||
function toggleInstances(x) {
|
function toggleInstances(x) {
|
||||||
if (x === 'keyev') {
|
if (x === 'keyev') {
|
||||||
tis.toggle();
|
tis.toggle();
|
||||||
updateCookieState('insts', tis.isVisible());
|
updatePrefsState('insts', tis.isVisible());
|
||||||
} else if (x) {
|
} else if (x) {
|
||||||
tis.show();
|
tis.show();
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +112,7 @@
|
|||||||
function toggleMap(x) {
|
function toggleMap(x) {
|
||||||
var on = (x === 'keyev') ? !sus.visible(mapG) : !!x;
|
var on = (x === 'keyev') ? !sus.visible(mapG) : !!x;
|
||||||
sus.visible(mapG, on);
|
sus.visible(mapG, on);
|
||||||
updateCookieState('bg', on);
|
updatePrefsState('bg', on);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need wrapper functions for state changes needed in cookies
|
// TODO: need wrapper functions for state changes needed in cookies
|
||||||
@ -248,22 +248,9 @@
|
|||||||
.attr('opacity', b ? 1 : 0);
|
.attr('opacity', b ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Config from Cookies -------------------------------------------
|
// --- User Preferemces ----------------------------------------------
|
||||||
|
|
||||||
// TODO: write a general purpose cookie service, rather than custom here
|
var defaultPrefsState = {
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
var defaultCookieState = {
|
|
||||||
bg: 1,
|
bg: 1,
|
||||||
insts: 1,
|
insts: 1,
|
||||||
summary: 1,
|
summary: 1,
|
||||||
@ -271,54 +258,27 @@
|
|||||||
hosts: 0
|
hosts: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var cookieState = {};
|
var prefsState = {};
|
||||||
|
|
||||||
function writeCookieState() {
|
function topoDefPrefs() {
|
||||||
var bits = [],
|
return angular.extend({}, defaultPrefsState);
|
||||||
str;
|
|
||||||
angular.forEach(cookieState, function (value, key) {
|
|
||||||
bits.push(key + ':' + value);
|
|
||||||
});
|
|
||||||
str = bits.join(',');
|
|
||||||
|
|
||||||
// The angular way of doing this...
|
|
||||||
// $cookies.topo_state = 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 = 'topo_state=' + encodeURIComponent(str);
|
|
||||||
$log.debug('<<>> Wrote cookie:', str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readCookieState() {
|
function updatePrefsState(what, b) {
|
||||||
var cook = $cookies.topo_state || '',
|
prefsState[what] = b ? 1 : 0;
|
||||||
bits;
|
ps.setPrefs('topo_prefs', prefsState);
|
||||||
|
|
||||||
if (!cook) {
|
|
||||||
cookieState = angular.extend({}, defaultCookieState);
|
|
||||||
writeCookieState(); // seed the pot
|
|
||||||
|
|
||||||
} else {
|
|
||||||
bits = cook.split(',');
|
|
||||||
bits.forEach(function (value) {
|
|
||||||
var x = value.split(':');
|
|
||||||
cookieState[x[0]] = Number(x[1]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCookieState(what, b) {
|
|
||||||
cookieState[what] = b ? 1 : 0;
|
|
||||||
writeCookieState();
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreConfigFromCookies() {
|
function restoreConfigFromPrefs() {
|
||||||
readCookieState();
|
// NOTE: toolbar will have set this for us..
|
||||||
$log.debug('Cookie State:', cookieState);
|
prefsState = ps.getPrefs('topo_prefs');
|
||||||
|
|
||||||
toggleInstances(cookieState.insts);
|
$log.debug('TOPO---- Prefs State:', prefsState);
|
||||||
tps.toggleSummary(cookieState.summary);
|
|
||||||
tps.toggleDetails(cookieState.detail);
|
toggleInstances(prefsState.insts);
|
||||||
|
tps.toggleSummary(prefsState.summary);
|
||||||
|
tps.toggleDetails(prefsState.detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -328,15 +288,15 @@
|
|||||||
.controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout',
|
.controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout',
|
||||||
'$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
|
'$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
|
||||||
'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
|
'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
|
||||||
'WebSocketService',
|
'WebSocketService', 'PrefsService',
|
||||||
'TopoEventService', 'TopoForceService', 'TopoPanelService',
|
'TopoEventService', 'TopoForceService', 'TopoPanelService',
|
||||||
'TopoInstService', 'TopoSelectService', 'TopoLinkService',
|
'TopoInstService', 'TopoSelectService', 'TopoLinkService',
|
||||||
'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
|
'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
|
||||||
'TopoToolbarService',
|
'TopoToolbarService',
|
||||||
|
|
||||||
function ($scope, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
|
function ($scope, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
|
||||||
_zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _tes_, _tfs_, _tps_,
|
_zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_,
|
||||||
_tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_) {
|
_tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_) {
|
||||||
var self = this,
|
var self = this,
|
||||||
projection,
|
projection,
|
||||||
dim,
|
dim,
|
||||||
@ -359,6 +319,7 @@
|
|||||||
sus = _sus_;
|
sus = _sus_;
|
||||||
flash = _flash_;
|
flash = _flash_;
|
||||||
wss = _wss_;
|
wss = _wss_;
|
||||||
|
ps = _ps_;
|
||||||
tes = _tes_;
|
tes = _tes_;
|
||||||
tfs = _tfs_;
|
tfs = _tfs_;
|
||||||
// TODO: consider funnelling actions through TopoForceService...
|
// TODO: consider funnelling actions through TopoForceService...
|
||||||
@ -403,7 +364,7 @@
|
|||||||
function (proj) {
|
function (proj) {
|
||||||
projection = proj;
|
projection = proj;
|
||||||
$log.debug('** We installed the projection: ', proj);
|
$log.debug('** We installed the projection: ', proj);
|
||||||
toggleMap(cookieState.bg);
|
toggleMap(prefsState.bg);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -414,7 +375,7 @@
|
|||||||
tes.start();
|
tes.start();
|
||||||
|
|
||||||
// temporary solution for persisting user settings
|
// temporary solution for persisting user settings
|
||||||
restoreConfigFromCookies();
|
restoreConfigFromPrefs();
|
||||||
|
|
||||||
$log.log('OvTopoCtrl has been created');
|
$log.log('OvTopoCtrl has been created');
|
||||||
}]);
|
}]);
|
||||||
|
|||||||
@ -23,13 +23,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// injected references
|
// injected references
|
||||||
var $log, tbs, api;
|
var $log, tbs, ps, api;
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
var toolbar, keyData;
|
var toolbar, keyData;
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
var name = 'topo-tbar';
|
var name = 'topo-tbar',
|
||||||
|
cooktag = 'topo_prefs';
|
||||||
|
|
||||||
// key to button mapping data
|
// key to button mapping data
|
||||||
var k2b = {
|
var k2b = {
|
||||||
@ -58,8 +59,46 @@
|
|||||||
E: { id: 'eqMaster-btn', gid: 'eqMaster' }
|
E: { id: 'eqMaster-btn', gid: 'eqMaster' }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// initial toggle state: default settings and tag to key mapping
|
||||||
|
var defaultPrefsState = {
|
||||||
|
bg: 1,
|
||||||
|
insts: 1,
|
||||||
|
summary: 1,
|
||||||
|
detail: 1,
|
||||||
|
hosts: 0
|
||||||
|
},
|
||||||
|
prefsMap = {
|
||||||
|
bg: 'B',
|
||||||
|
insts: 'I',
|
||||||
|
summary: 'O',
|
||||||
|
details: 'D',
|
||||||
|
hosts: 'H'
|
||||||
|
};
|
||||||
|
|
||||||
function init(_api_) {
|
function init(_api_) {
|
||||||
api = _api_;
|
api = _api_;
|
||||||
|
|
||||||
|
// retrieve initial toggle button settings from user prefs
|
||||||
|
setInitToggleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
function topoDefPrefs() {
|
||||||
|
return angular.extend({}, defaultPrefsState);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setInitToggleState() {
|
||||||
|
var state = ps.getPrefs(cooktag);
|
||||||
|
$log.debug('TOOLBAR---- read prefs state:', state);
|
||||||
|
|
||||||
|
if (!state) {
|
||||||
|
state = topoDefPrefs();
|
||||||
|
ps.setPrefs(cooktag, state);
|
||||||
|
$log.debug('TOOLBAR---- Set default prefs state:', state);
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.forEach(prefsMap, function (v, k) {
|
||||||
|
k2b[v].isel = !!state[k];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initKeyData() {
|
function initKeyData() {
|
||||||
@ -142,11 +181,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
angular.module('ovTopo')
|
angular.module('ovTopo')
|
||||||
.factory('TopoToolbarService', ['$log', 'ToolbarService',
|
.factory('TopoToolbarService',
|
||||||
|
['$log', 'ToolbarService', 'PrefsService',
|
||||||
|
|
||||||
function (_$log_, _tbs_) {
|
function (_$log_, _tbs_, _ps_) {
|
||||||
$log = _$log_;
|
$log = _$log_;
|
||||||
tbs = _tbs_;
|
tbs = _tbs_;
|
||||||
|
ps = _ps_;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
|
|||||||
@ -45,6 +45,7 @@
|
|||||||
<script src="app/fw/util/random.js"></script>
|
<script src="app/fw/util/random.js"></script>
|
||||||
<script src="app/fw/util/theme.js"></script>
|
<script src="app/fw/util/theme.js"></script>
|
||||||
<script src="app/fw/util/keys.js"></script>
|
<script src="app/fw/util/keys.js"></script>
|
||||||
|
<script src="app/fw/util/prefs.js"></script>
|
||||||
|
|
||||||
<script src="app/fw/mast/mast.js"></script>
|
<script src="app/fw/mast/mast.js"></script>
|
||||||
<script src="app/fw/nav/nav.js"></script>
|
<script src="app/fw/nav/nav.js"></script>
|
||||||
|
|||||||
57
web/gui/src/main/webapp/tests/app/fw/util/prefs-spec.js
Normal file
57
web/gui/src/main/webapp/tests/app/fw/util/prefs-spec.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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 -- Util -- User Preference Service - Unit Tests
|
||||||
|
*/
|
||||||
|
describe('factory: fw/util/prefs.js', function() {
|
||||||
|
var $cookies, ps, fs;
|
||||||
|
|
||||||
|
beforeEach(module('onosUtil'));
|
||||||
|
|
||||||
|
var mockCookies = {
|
||||||
|
foo: 'bar'
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
module(function ($provide) {
|
||||||
|
$provide.value('$cookies', mockCookies);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(inject(function (PrefsService, FnService, _$cookies_) {
|
||||||
|
ps = PrefsService;
|
||||||
|
fs = FnService;
|
||||||
|
$cookies = _$cookies_;
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should define PrefsService', function () {
|
||||||
|
expect(ps).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should define api functions', function () {
|
||||||
|
expect(fs.areFunctions(ps, [
|
||||||
|
'getPrefs', 'setPrefs'
|
||||||
|
])).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// === Tests for getPrefs()
|
||||||
|
// TODO unit tests for getPrefs()
|
||||||
|
|
||||||
|
// === Tests for setPrefs()
|
||||||
|
// TODO unit tests for setPrefs()
|
||||||
|
|
||||||
|
});
|
||||||
@ -19,6 +19,7 @@ module.exports = function(config) {
|
|||||||
'../tp/angular.js',
|
'../tp/angular.js',
|
||||||
'../tp/angular-mocks.js',
|
'../tp/angular-mocks.js',
|
||||||
'../tp/angular-route.js',
|
'../tp/angular-route.js',
|
||||||
|
'../tp/angular-cookies.js',
|
||||||
'../tp/d3.js',
|
'../tp/d3.js',
|
||||||
'../tp/topojson.v1.min.js',
|
'../tp/topojson.v1.min.js',
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user