Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save default view parameters #179

Merged
merged 12 commits into from
Apr 13, 2018
1 change: 1 addition & 0 deletions app/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ nconf.defaults({
url: dataMineHost
},
osExplorerUrl: process.env.OS_EXPLORER_URL || DEFAULT_HOST + '/',
osConductorUrl: conductorUrl + '/',
authLibraryUrl: authHost + '/user/lib',
basePath: process.env.OS_VIEWER_BASE_PATH || DEFAULT_BASE_PATH,
snippets: {
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ module.exports = function(req, res) {
api: config.get('api'),
search: config.get('search'),
dataMine: config.get('dataMine'),
osExplorerUrl: config.get('osExplorerUrl')
osExplorerUrl: config.get('osExplorerUrl'),
osConductorUrl: config.get('osConductorUrl')
});
};

50 changes: 35 additions & 15 deletions app/front/scripts/controllers/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ngModule.controller('MainController', [

// Extend state with some UI-related data
$scope.state.params.isEmbedded = isEmbedded;
$scope.state.params.availableSoring = osViewerService
$scope.state.params.availableSorting = osViewerService
.getAvailableSorting($scope.state);
$scope.state.params.breadcrumbs = osViewerService
.buildBreadcrumbs($scope.state);
Expand Down Expand Up @@ -95,6 +95,7 @@ ngModule.controller('MainController', [
$location.url()))
.then(function(state) {
osViewerService.translateHierarchies(state, i18n);
osViewerService.addIsOwner(state, userId);
$scope.state = state;
return $q(osViewerService.fullyPopulateModel(state));
})
Expand Down Expand Up @@ -188,20 +189,27 @@ ngModule.controller('MainController', [
var urlParams = osViewerService.parseUrl(url);
if (!$scope.state || (packageId != $scope.state.package.id)) {
$scope.isLoading.package = true;
$q(osViewerService.loadDataPackage(packageId, urlParams))
.then(function(state) {
state.params.lang = $scope.state.params.lang;
state.params.theme = $scope.state.params.theme;
$scope.state = state;
osViewerService.translateHierarchies(state, i18n);
return $q(osViewerService.fullyPopulateModel(state));
})
.then(function(state) {
$scope.isLoading.package = false;
$scope.state = state;
// Do not update url and history when populating data from url
updateStateParams(state.params, !isUrlAvailable,
!isUrlAvailable);

return $q(LoginService.tryGetToken())
.then(function(token) {
var userId = token ? LoginService.getUserId() : null;

$q(osViewerService.loadDataPackage(packageId, urlParams))
.then(function(state) {
state.params.lang = $scope.state.params.lang;
state.params.theme = $scope.state.params.theme;
$scope.state = state;
osViewerService.translateHierarchies(state, i18n);
osViewerService.addIsOwner(state, userId);
return $q(osViewerService.fullyPopulateModel(state));
})
.then(function(state) {
$scope.isLoading.package = false;
$scope.state = state;
// Do not update url and history when populating data from url
updateStateParams(state.params, !isUrlAvailable,
!isUrlAvailable);
});
});
} else {
if (isUrlAvailable) {
Expand Down Expand Up @@ -233,6 +241,18 @@ ngModule.controller('MainController', [
$scope.state.package));
});

$scope.$on(Configuration.events.visualizations.clearAllParams,
function() {
updateStateParams(osViewerService.params
.clearAllParams($scope.state.params,
$scope.state.package));
});

$scope.$on(Configuration.events.visualizations.resetToDefault,
function($event, defaultParams) {
updateStateParams(defaultParams, true, true);
});

$scope.$on(Configuration.events.visualizations.drillDown,
function($event, drillDownValue) {
updateStateParams(osViewerService.params
Expand Down
35 changes: 35 additions & 0 deletions app/front/scripts/directives/confirmation-popover/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

var ngModule = require('../../module');

ngModule.directive('confirmationPopover', [
function() {
return {
restrict: 'A',
replace: false,
template: '',
scope: {
onClick: '&',
container: '@'
},
link: function($scope, element, attrs) {
var container = $scope.container;
var onClickHandler = $scope.onClick;
element.popover({
content: $scope.content,
html: true,
container: container,
trigger: 'focus',
placement: 'bottom'
});
element.on('inserted.bs.popover', function(e) {
$(container + ' button').on('click', function() {
onClickHandler();
element.popover('hide');
$scope.$applyAsync();
});
});
}
};
}
]);
2 changes: 2 additions & 0 deletions app/front/scripts/directives/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ babbageApiExporter.setExportFunc(function(key, value) {

// Application directives
require('./autoselect');
require('./confirmation-popover');
require('./filter-list');
require('./history-navigation');
require('./package-selector');
require('./package-info');
require('./popover');
require('./sidebar');
require('./visualizations');
require('./param-controls');
52 changes: 52 additions & 0 deletions app/front/scripts/directives/param-controls/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

var $q = require('../../services/ng-utils').$q;
var dataPackageApi = require('../../services/data-package-api');

var ngModule = require('../../module');


ngModule.directive('paramControls', [
'LoginService', 'Configuration',
function(LoginService, Configuration) {
return {
template: require('./template.html'),
replace: false,
restrict: 'E',
scope: {
datapackage: '=',
params: '=',
defaultParams: '=',
isOwner: '=?'
},
controllerAs: 'vm',
controller: function($scope) {
var vm = this;

var setDefaultParams = function(params) {
var token = LoginService.permissionToken;
$q(dataPackageApi.setDefaultParams(token,
vm.datapackage.id,
params))
.then(function(success) {
vm.defaultParams = params;
});
};

vm.setCurrentViewAsDefault = function() {
setDefaultParams(vm.params);
};

vm.clearParamsAndVisualisations = function() {
$scope.$emit(Configuration.events.visualizations.clearAllParams);
};

vm.resetToDefaults = function() {
$scope.$emit(Configuration.events.visualizations.resetToDefault,
_.extend({}, vm.params, vm.defaultParams));
};
},
bindToController: true
};
}
]);
3 changes: 3 additions & 0 deletions app/front/scripts/directives/param-controls/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<button ng-show="vm.isOwner" type="button" data-container="#confirm-default-popover" data-toggle="popover" confirmation-popover data-on-click="vm.setCurrentViewAsDefault()" data-content="This will save the current view as the<br>default for all users of this dataset.<br/>Are you sure?<br/><button class='btn btn-danger btn-sm btn-block'>Yes</button>" class="btn btn-danger">Save View As Default</button> <button type="button" class="btn btn-default" ng-click="vm.clearParamsAndVisualisations()">Reset View</button> <button ng-if="vm.defaultParams" type="button" class="btn btn-default" ng-click="vm.resetToDefaults()">Reset to Defaults</button>

<span id="confirm-default-popover"></span>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div ng-if="!params.isEmbedded" class="clearfix">
<sorting-control
selected="params.orderBy"
items="params.availableSoring">
items="params.availableSorting">
</sorting-control>
</div>
<div class="x-visualization-chart clearfix">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div ng-if="!params.isEmbedded" class="clearfix">
<sorting-control
selected="params.orderBy"
items="params.availableSoring">
items="params.availableSorting">
</sorting-control>
</div>
<div class="x-visualization-chart clearfix">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div ng-if="!params.isEmbedded" class="clearfix">
<sorting-control
selected="params.orderBy"
items="params.availableSoring">
items="params.availableSorting">
</sorting-control>
</div>
<div class="x-visualization-chart clearfix">
Expand Down
4 changes: 3 additions & 1 deletion app/front/scripts/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ var config = {
drillDown: 'visualizations.drillDown',
changeOrderBy: 'visualizations.changeOrderBy',
showShareModal: 'visualizations.showShareModal',
breadcrumbClick: 'visualizations.breadcrumbClick'
breadcrumbClick: 'visualizations.breadcrumbClick',
clearAllParams: 'visualizations.clearAllParams',
resetToDefault: 'visualizations.resetToDefault'
},
sidebar: {
listItemChange: 'sidebar.listItemChange',
Expand Down
35 changes: 35 additions & 0 deletions app/front/scripts/services/data-package-api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var downloader = require('../downloader');
module.exports.apiConfig = {};
module.exports.searchConfig = {};
module.exports.osExplorerUrl = null;
module.exports.osConductorUrl = null;
module.exports.defaultSettingsUrl = 'settings.json';

function loadConfig(settingsUrl) {
Expand All @@ -17,6 +18,7 @@ function loadConfig(settingsUrl) {
module.exports.searchConfig = config.search;
module.exports.dataMineConfig = config.dataMine;
module.exports.osExplorerUrl = config.osExplorerUrl;
module.exports.osConductorUrl = config.osConductorUrl;
return config;
});
}
Expand Down Expand Up @@ -76,6 +78,7 @@ function getDataPackageMetadata(dataPackage, model) {
// jscs:enable

return {
defaultParams: dataPackage.defaultParams,
name: dataPackage.name,
title: dataPackage.title,
description: dataPackage.description,
Expand Down Expand Up @@ -424,10 +427,42 @@ function serializeCut(filters, drilldown) {
.value();
}

function setDefaultParams(token, packageId, params) {
return loadConfig().then(function() {
var url = module.exports.osConductorUrl + '/package/update_params';

var data = _.chain({
jwt: token,
id: packageId
})
.map(function(value, key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
})
.join('&')
.value();

var options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
};
return downloader.getJson(url + '?' + data, options, true)
.then(function(result) {
if (!result.success) {
throw new Error(result.error);
}
return result.json;
});
});
}

module.exports.serializeCut = serializeCut;
module.exports.loadConfig = loadConfig;
module.exports.getDataPackages = getDataPackages;
module.exports.getDataPackage = getDataPackage;
module.exports.loadDimensionValues = loadDimensionValues;
module.exports.loadDimensionsValues = loadDimensionsValues;
module.exports.createPackageModel = createPackageModel;
module.exports.setDefaultParams = setDefaultParams;
15 changes: 10 additions & 5 deletions app/front/scripts/services/downloader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,28 @@ function getNormalizedUrl(originalUrl) {
}

module.exports = {
get: function(url) {
get: function(url, options, bypassCache) {
// Make cache more efficient - use normalized url
url = getNormalizedUrl(url);
if (!cache[url]) {
cache[url] = fetch(url).then(function(response) {
if (bypassCache || !cache[url]) {
var requestPromise = fetch(url, options).then(function(response) {
if (response.status != 200) {
throw new Error('Failed loading data from ' + response.url);
}
return response.text();
});

if (bypassCache) {
return requestPromise;
}
cache[url] = requestPromise;
}
return new Promise(function(resolve, reject) {
cache[url].then(resolve).catch(reject);
});
},
getJson: function(url) {
return this.get(url)
getJson: function(url, options, bypassCache) {
return this.get(url, options, bypassCache)
.then(JSON.parse)
.catch(function(error) {
console.trace(error);
Expand Down
14 changes: 12 additions & 2 deletions app/front/scripts/services/os-viewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ function loadDataPackage(packageId, initialParams) {
stateParams.init(packageModel, initialParams), {
babbageApiUrl: dataPackageApi.apiConfig.url,
cosmopolitanApiUrl: dataPackageApi.apiConfig.cosmoUrl
}
);
});
if (!_.has(initialParams, 'visualizations')) {
var params = _.extend(params, packageModel.meta.defaultParams);
}

return {
package: packageModel,
Expand All @@ -76,6 +78,13 @@ function loadDataPackage(packageId, initialParams) {
});
}

function addIsOwner(state, userId) {
/*
Add owner status to package in state if owned by userId.
*/
state.package.meta.isOwner = (state.package.meta.owner == userId);
}

function fullyPopulateModel(state) {
return dataPackageApi.loadDimensionsValues(state.package, null,
state.params.filters)
Expand Down Expand Up @@ -422,6 +431,7 @@ module.exports.params = stateParams;
module.exports.history = history;
module.exports.loadDataPackages = loadDataPackages;
module.exports.loadDataPackage = loadDataPackage;
module.exports.addIsOwner = addIsOwner;
module.exports.parseUrl = parseUrl;
module.exports.getInitialState = getInitialState;
module.exports.fullyPopulateModel = fullyPopulateModel;
Expand Down
7 changes: 7 additions & 0 deletions app/front/scripts/services/os-viewer/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,12 @@ function updateFromParams(state, urlParams, packageModel) {
return result;
}

function clearAllParams(state, packageModel) {
var result = cloneState(state);
clearParams(result, packageModel);
return result;
}

module.exports.init = init;
module.exports.changeMeasure = changeMeasure;
module.exports.changeFilter = changeFilter;
Expand All @@ -665,3 +671,4 @@ module.exports.removeAllVisualizations = removeAllVisualizations;
module.exports.changeOrderBy = changeOrderBy;
module.exports.updateFromParams = updateFromParams;
module.exports._getDefaultState = getDefaultState;
module.exports.clearAllParams = clearAllParams;
Loading