Adds a "Server Prefs" tab to the Stored User Preferences user interface.
Adds options for migrating workstation settings to server settings, both
in test mode and delete-local-once-complete mode.
Signed-off-by: Bill Erickson <berickxx@gmail.com>
s.PRINT_TEMPLATES_FAIL_IMPORT = "[% l('Failed to import any print template(s)') %]";
s.HATCH_SETTINGS_MIGRATION_SUCCESS = "[% l('Settings successfully migrated') %]";
s.HATCH_SETTINGS_MIGRATION_FAILURE = "[% l('Settings migration failed') %]";
+ s.HATCH_SERVER_SETTINGS_MIGRATION_CONFIRM =
+ "[% l('This will delete the local version all settings configured to live on the server. Continue?') %]"
}]);
</script>
[% END %]
</div>
</div>
+
</div><!-- left column -->
<div class="col-md-6"><!-- right column -->
</div>
</div>
+ <div class="row new-entry">
+ <div class="col-md-12">
+ <label>
+ [% l('Experimental: Migrate Workstation Settings to Server') %]
+ </label>
+ <p>[% | l %]Settings may be migrated to the server using the first
+option below as many times as needed for testing and verification. Once
+local settings are deleted via the second option, the migration will be
+marked as complete and no more migration attempts may occur.[% END %]
+ </p>
+ <ol>
+ <li class="pad-vert">
+ <button class="btn btn-default" ng-click="migrateServerSettings()">
+ [% l('Migrate and Keep Local Settings (for testing)') %]
+ </button>
+ </li>
+ <li>
+ <button class="btn btn-warning"
+ ng-click="migrateServerSettings(true)">
+ [% l('Migrate and Delete Local Settings') %]
+ </button>
+ </li>
+ </ol>
+ </div>
+ </div>
+
+
</div><!-- col -->
</div><!-- row -->
[% |l %]
Preference values are stored as JSON strings.
Click on a preference to view the stored value.
-Click on the delete (X) button to remove a preference's value.
+Click on the delete (X) button to remove a preference value.
[% END %]
</div>
</div>
</div>
<div class="row">
+ <div class="col-md-12">
+ <div class="panel panel-info">
+ <div class="panel-heading">
+ <h3 class="panel-title">
+ [% l('Experimental: Migrate Workstation Settings to Server') %]
+ </h3>
+ </div>
+ <div class="panel-body">
+ <p>
+[% | l %]Settings may be migrated to the server using the first option below
+as many times as needed for testing and verification. Once local settings
+are deleted via the second option, no settings will remain to migrate, unless
+they are added back through some external mechanism.[% END %]
+ </p>
+ <p>
+[% | l %]Note that just because a setting exists under "Server Prefs" below
+does not mean it has been migrated. Check the value by clicking on the
+setting name to be sure.[% END %]
+ </p>
+ <div class="row pad-left">
+ <button class="btn btn-success pad-right"
+ ng-click="migrateServerSettings()">
+ [% l('#1 Migrate and Keep Local Settings (Testing)') %]
+ </button>
+ <button class="btn btn-warning pad-left"
+ ng-click="migrateServerSettings(true)">
+ [% l('#2 Migrate and Delete Local Settings') %]
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
<div class="col-md-4">
<ul class="nav nav-tabs">
<a href='' ng-click="setContext('local')">[% l('Local Prefs') %]</a>
</li>
<li ng-class="{active : context == 'remote'}">
- <a href='' ng-click="setContext('remote')">[% l('Remote Prefs') %]</a>
+ <a href='' ng-click="setContext('remote')">[% l('Hatch Prefs') %]</a>
+ </li>
+ <li ng-class="{active : context == 'server'}">
+ <a href='' ng-click="setContext('server')">[% l('Server Prefs') %]</a>
</li>
</ul>
<div class="tab-content">
}])
.controller('StoredPrefsCtrl',
- ['$scope','$q','egCore','egConfirmDialog',
-function($scope , $q , egCore , egConfirmDialog) {
+ ['$scope','$q','egCore','egConfirmDialog','egProgressDialog','$timeout',
+function($scope , $q , egCore , egConfirmDialog , egProgressDialog , $timeout) {
console.log('StoredPrefsCtrl');
$scope.setContext = function(ctx) {
// fetch the keys
function refreshKeys() {
- $scope.keys = {local : [], remote : []};
+ $scope.keys = {local : [], remote : [], server: []};
if (egCore.hatch.hatchAvailable) {
egCore.hatch.getRemoteKeys().then(
// local calls are non-async
$scope.keys.local = egCore.hatch.getLocalKeys();
+
+ egCore.hatch.getServerKeys().then(function(keys) {
+ $scope.keys.server = keys;
+ });
}
refreshKeys();
if ($scope.context == 'local') {
$scope.currentKeyContent = egCore.hatch.getLocalItem(key);
+ } else if ($scope.context === 'server') {
+ egCore.hatch.getServerItem(key)
+ .then(function(content) {
+ $scope.currentKeyContent = content
+ });
} else {
egCore.hatch.getRemoteItem(key)
.then(function(content) {
if ($scope.context == 'local') {
egCore.hatch.removeLocalItem(key);
refreshKeys();
+ } else if ($scope.context == 'server') {
+ egCore.hatch.removeServerItem(key)
+ .then(function() { refreshKeys() });
} else {
egCore.hatch.removeItem(key)
.then(function() { refreshKeys() });
}
);
}
+
+ $scope.migrateServerSettings = function(deleteLocal) {
+
+ var promise = !deleteLocal ? $q.when() :
+ egConfirmDialog.open(
+ egCore.strings.HATCH_SERVER_SETTINGS_MIGRATION_CONFIRM, '', {}
+ ).result;
+
+ promise.then(function() {
+ egProgressDialog.open();
+ // timeout added because closing a progress dialog too quickly
+ // (before it's registered that it's opened) can leave the
+ // dialog stranded open. This is only an issue when no local
+ // settings data exists to migrate, causing the migration to
+ // be instantaneous.
+ $timeout(function() {
+ egCore.hatch.migrateServerSettings(deleteLocal).then(
+ function() {},
+ function() {},
+ function() {
+ egProgressDialog.increment();
+ }
+ )['finally'](egProgressDialog.close);
+ }, 100);
+ });
+ }
+
}])
.controller('WSRegCtrl',
service.messages = {};
service.hatchAvailable = false;
service.auth = null; // ref to egAuth loaded on-demand to avoid circular ref.
+ service.disableServerSettings = false;
// key/value cache -- avoid unnecessary Hatch extension requests.
// Only affects *RemoteItem calls.
];
service.keyStoredOnServer = function(key) {
+
+ if (service.disableServerSettings) {
+ return false;
+ }
+
var browserOnly = false;
angular.forEach(service.browserOnlyPrefixes, function(pfx) {
if (key.match(new RegExp('^' + pfx)))
});
}
- service.migrateServerSettings = function() {
+ service.migrateServerSettings = function(deleteLocal) {
if (!service.auth) service.auth = $injector.get('egAuth');
if (!service.auth.token()) return $q.reject('no authtoken');
var deferred = $q.defer();
var settings = service.serverSettings.slice(0); // clone
+ // Allow get/remove calls to fall back to local options
+ // during migration.
+ service.disableServerSettings = true;
+
function migrateNext(key) {
+
if (!key) {
+ service.disableServerSettings = false;
return deferred.resolve();
}
- service.migrateOneServerSetting(key).then(
+ service.migrateOneServerSetting(key, deleteLocal).then(
function() {
deferred.notify('migrated ' + key);
migrateNext(settings.shift());
},
function() {
+ service.disableServerSettings = false;
deferred.reject(
'Something failed during settings migration');
}
);
-
}
+ migrateNext(settings.shift());
return deferred.promise;
}
- service.migrateOneServerSetting = function(key) {
- console.log('migrating server setting ' + key);
+ service.migrateOneServerSetting = function(key, deleteLocal) {
var deferred = $q.defer();
- function remove(key) {
- return service.useSettings() ?
- service.removeRemoteItem(key) :
- $q.when(service.removeLocalItem(key));
- }
-
- var prom = service.useSettings() ?
- service.getRemoteItem(key) :
- $q.when(service.getLocalItem(key));
-
- prom.then(function(value) {
+ service.getItem(key).then(function(value) {
if (value === undefined || value === null) {
- remove(key); // for good measure.
+ console.log(key + ' has no value to migrate');
+ // Nothing to migrate.
+ if (deleteLocal) {
+ // for good measure.
+ service.removeItem(key);
+ }
return deferred.resolve();
}
console.debug(
'setting ' + key + ' successfully stored on server');
- remove(key).then(function() {
+ if (!deleteLocal) {
+ return deferred.resolve();
+ }
+
+ service.removeItem(key).then(function() {
console.debug(
- 'setting ' + key + ' removed from local storage');
+ 'setting ' + key + ' removed from workstation');
deferred.resolve();
});
},
// remove a stored item
service.removeItem = function(key) {
if (service.keyStoredOnServer(key))
- return service.setServerItem(key, null);
+ return service.removeServerItem(key);
if (!service.useSettings())
return $q.when(service.removeLocalItem(key));
return $q.reject();
}
+ service.removeServerItem = function(key) {
+ return service.setServerItem(key, null);
+ }
+
service.removeRemoteItem = function(key) {
delete service.keyCache[key];
return service.attemptHatchDelivery({
});
}
+ service.getServerKeys = function(prefix) {
+ var keys = [];
+ var idx = 0;
+ service.serverSettings.forEach(function(k) {
+ // key prefix match test
+ if (prefix && k.substr(0, prefix.length) != prefix) {
+ return;
+ }
+ keys.push(k);
+ });
+ // these may eventually come from the server, so return a promise.
+ return $q.when(keys);
+ }
+
service.getLocalKeys = function(prefix) {
var keys = [];
var idx = 0;