Skip to content

Commit

Permalink
OR-2453 Core Angular constants are now configurable through esn-config.
Browse files Browse the repository at this point in the history
  • Loading branch information
ddolcimascolo committed Nov 15, 2016
1 parent c2c71c5 commit 6b9aa50
Show file tree
Hide file tree
Showing 30 changed files with 331 additions and 72 deletions.
3 changes: 3 additions & 0 deletions backend/core/esn-config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ module.exports = {
user: {
public: false
},
constants: {
public: false
},
'application-menu.profile': {
public: true
},
Expand Down
28 changes: 28 additions & 0 deletions backend/webserver/controllers/generated-javascript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

const q = require('q'),
ejs = require('ejs'),
esnConfig = require('../../core/esn-config');

function getConstantFrom(constants) {
return (key, defaultValue) => {
if (constants && typeof constants[key] !== 'undefined') {
return constants[key];
}

return defaultValue;
};
}

function constants(req, res) {
esnConfig('constants').inModule('core').forUser(req.user).get()
.then(constants => q.ninvoke(ejs, 'renderFile', 'templates/js/constants.ejs', { getConstant: getConstantFrom(constants) }))
.then(
file => res.status(200).send(file),
err => res.status(500).send('Failed to generate constants file. ' + err)
);
}

module.exports = {
constants
};
3 changes: 3 additions & 0 deletions backend/webserver/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ exports = module.exports = function(application) {
var cssController = require('./controllers/css');
application.get('/generated/css/:app/:foo.css', cssController.getCss);

var generatedJavascript = require('./controllers/generated-javascript');
application.get('/js/constants.js', generatedJavascript.constants);

var apiModule = require('./api');
apiModule.setupAPI(application);
};
42 changes: 42 additions & 0 deletions doc/code_convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,48 @@ Skeleton:
}]);

### Angular constants

We have a way to make angular constants configurable, by defining an override in the database.
However, this only applies to constants actually used to define a setting (e.g.: the number of elements displayed in a "page",
a timeout for HTTP requests, etc.). These constants should be defined in the `esn.constants` angular modules which is
actually generated by the backend.

To define such a new constant, add a line in the `templates/js/constants.ejs` file. Evey line defines an angular constant.
The syntax is as follows

.constant('XXX', <%= getConstant('XXX', defaultValue) %>)

where:

* `XXX` is the name of the constant, the one you'll depend on in your Angular modules
* `defaultValue` is the default value for the constant, if there's no override in the database
* The `getConstant` function is provided automatically and does the heavy work of looking through the DB

Then in your Angular module, depend on the `esn.constants` module and use your shiny new configurable constant!

To override a value, simply define the following configuration (in the `configurations` collection) at any level
of the configuration (system-wide, domain-wide, etc.), in the `core` module:

{
"name" : "constants",
"value" : {
"XXX" : 10,
"YYY" : true,
...
}
}

where `XXX` and `YYY` are constant names.

#### What about tests?

There are midway tests covering the generation of the Javascript file from the EJS template in both cases (with or without overrides).
They work by comparing the results of querying the route against a pre-made Javascript file (in the _fixtures_ folder). The pre-made JS file
is also used by frontend tests so that they have the `esn.constants` module available.

Should you upgrade the EJS template, you should also change these fixtures, but tests will break anyway!

## Documentation

See `REST_skeleton.md`.
7 changes: 3 additions & 4 deletions frontend/js/modules/aggregator.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';

angular.module('esn.aggregator', [])

.constant('AGGREGATOR_DEFAULT_RESULTS_PER_PAGE', 5)
.constant('AGGREGATOR_DEFAULT_FIRST_PAGE_SIZE', 40)
angular.module('esn.aggregator', [
'esn.constants'
])

.factory('PageAggregatorSourceWrapper', function($q) {
function PageAggregatorSourceWrapper(source) {
Expand Down
7 changes: 4 additions & 3 deletions frontend/js/modules/async-action.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

angular.module('esn.async-action', ['esn.notification'])

.constant('ASYNC_ACTION_LONG_TASK_DURATION', 1000)
angular.module('esn.async-action', [
'esn.notification',
'esn.constants'
])

.factory('rejectWithErrorNotification', function($q, notificationFactory) {
return function(message, cancelAction) {
Expand Down
12 changes: 9 additions & 3 deletions frontend/js/modules/avatar.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
'use strict';

angular.module('esn.avatar', ['mgcrea.ngStrap', 'ngAnimate', 'mgcrea.ngStrap.modal', 'angularFileUpload', 'mgcrea.ngStrap.alert', 'ng.deviceDetector'])
.constant('AVATAR_MIN_SIZE_PX', 256)
.constant('AVATAR_MAX_SIZE_MB', 5)
angular.module('esn.avatar', [
'esn.constants',
'mgcrea.ngStrap',
'ngAnimate',
'mgcrea.ngStrap.modal',
'angularFileUpload',
'mgcrea.ngStrap.alert',
'ng.deviceDetector'
])
.constant('AVATAR_OFFSET', 10)
.provider('avatarDefaultUrl', function() {
var url = '/images/community.png';
Expand Down
8 changes: 5 additions & 3 deletions frontend/js/modules/box-overlay.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict';

angular.module('esn.box-overlay', ['esn.back-detector', 'ng.deviceDetector'])

.constant('MAX_BOX_COUNT', 2)
angular.module('esn.box-overlay', [
'esn.constants',
'esn.back-detector',
'ng.deviceDetector'
])

.service('boxOverlayOpener', function($boxOverlay) {

Expand Down
5 changes: 3 additions & 2 deletions frontend/js/modules/cache.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict';

angular.module('esn.cache', [])
angular.module('esn.cache', [
'esn.constants'
])

.constant('CACHE_NO_TTL', -1)
.constant('CACHE_DEFAULT_TTL', 60000)

.factory('CacheEntry', function($q, CACHE_NO_TTL) {

Expand Down
7 changes: 3 additions & 4 deletions frontend/js/modules/dragndrop.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use strict';

angular.module('esn.dragndrop', [
'ng.deviceDetector',
'esn.escape-html'
'esn.constants',
'esn.escape-html',
'ng.deviceDetector'
])

.constant('ESN_DRAG_ANIMATION_CLASS', 'esn-drag-tooltip-animation')
.constant('ESN_DRAG_ANIMATION_DURATION', 500)
.constant('ESN_DRAG_DISTANCE_THRESHOLD', 10)

.factory('esnDragService', function() {
var listeners = {};
Expand Down
8 changes: 5 additions & 3 deletions frontend/js/modules/esn.router.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict';

angular.module('esn.router', ['ui.router', 'esn.session'])

.constant('ESN_ROUTER_DEFAULT_HOME_PAGE', 'unifiedinbox')
angular.module('esn.router', [
'esn.session',
'esn.constants',
'ui.router'
])

.config(function($urlMatcherFactoryProvider) {
// This option allows to have trailing slash at the end of the browser url.
Expand Down
7 changes: 4 additions & 3 deletions frontend/js/modules/feedback.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

angular.module('esn.feedback', ['esn.http'])

.constant('ESN_FEEDBACK_DEFAULT_SUBJECT', '[OpenPaas] New feedback')
angular.module('esn.feedback', [
'esn.http',
'esn.constants'
])

.factory('feedbackAPI', function(esnRestangular) {

Expand Down
19 changes: 10 additions & 9 deletions frontend/js/modules/follow.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
'use strict';

angular.module('esn.follow', [
'esn.resource-link',
'esn.timeline',
'esn.session',
'esn.http',
'esn.aggregator',
'esn.infinite-list',
'openpaas-logo'
])
'esn.resource-link',
'esn.timeline',
'esn.session',
'esn.http',
'esn.aggregator',
'esn.infinite-list',
'esn.constants',
'openpaas-logo'
])

.constant('FOLLOW_LINK_TYPE', 'follow')
.constant('UNFOLLOW_LINK_TYPE', 'unfollow')
.constant('FOLLOW_PAGE_SIZE', 10)

.run(function(esnTimelineEntryProviders, FOLLOW_LINK_TYPE, UNFOLLOW_LINK_TYPE) {
esnTimelineEntryProviders.register({
Expand Down
7 changes: 4 additions & 3 deletions frontend/js/modules/http.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
'use strict';

angular.module('esn.http', ['restangular'])
angular.module('esn.http', [
'esn.constants',
'restangular'
])

.factory('esnRestangular', function(Restangular, httpErrorHandler) {
return Restangular.withConfig(function(RestangularConfigurer) {
Expand All @@ -25,8 +28,6 @@ angular.module('esn.http', ['restangular'])
};
})

.constant('HTTP_LAG_UPPER_BOUND', 500)

.factory('httpErrorHandler', function($window, $location, $log) {

function redirectToLogin() {
Expand Down
25 changes: 11 additions & 14 deletions frontend/js/modules/infinite-list.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
'use strict';

angular.module('esn.infinite-list', ['infinite-scroll'])
angular.module('esn.infinite-list', [
'esn.constants',
'infinite-scroll'
])

.constant('INFINITE_LIST_EVENTS', {
LOAD_MORE_ELEMENTS: 'infiniteList:loadMoreElements',
REMOVE_ELEMENTS: 'infiniteList:removeElements',
ADD_ELEMENTS: 'infiniteList:addElements'
})

.constant('defaultConfiguration', {
scrollDistance: 0.5,
scrollDisabled: false,
scrollImmediateCheck: 'true',
throttle: 10
})

.config(function($provide, defaultConfiguration) {
$provide.value('THROTTLE_MILLISECONDS', defaultConfiguration.throttle);
.config(function($provide, INFINITE_LIST_THROTTLE) {
$provide.value('THROTTLE_MILLISECONDS', INFINITE_LIST_THROTTLE);
})

.factory('infiniteListService', function($rootScope, $q, INFINITE_LIST_EVENTS) {
Expand Down Expand Up @@ -69,7 +65,8 @@ angular.module('esn.infinite-list', ['infinite-scroll'])
};
})

.directive('infiniteList', function(defaultConfiguration, INFINITE_LIST_EVENTS) {
.directive('infiniteList', function(INFINITE_LIST_EVENTS, INFINITE_LIST_IMMEDIATE_CHECK, INFINITE_LIST_DISTANCE,
INFINITE_LIST_DISABLED) {
return {
restrict: 'E',
transclude: true,
Expand All @@ -94,9 +91,9 @@ angular.module('esn.infinite-list', ['infinite-scroll'])
compile: function() {
return {
pre: function(scope, element) {
scope.infiniteScrollDistance = angular.isDefined(scope.infiniteScrollDistance) ? scope.infiniteScrollDistance : defaultConfiguration.scrollDistance;
scope.infiniteScrollDisabled = angular.isDefined(scope.infiniteScrollDisabled) ? scope.infiniteScrollDisabled : defaultConfiguration.scrollDisabled;
scope.infiniteScrollImmediateCheck = angular.isDefined(scope.infiniteScrollImmediateCheck) ? scope.infiniteScrollImmediateCheck : defaultConfiguration.scrollImmediateCheck;
scope.infiniteScrollDistance = angular.isDefined(scope.infiniteScrollDistance) ? scope.infiniteScrollDistance : INFINITE_LIST_DISTANCE;
scope.infiniteScrollDisabled = angular.isDefined(scope.infiniteScrollDisabled) ? scope.infiniteScrollDisabled : INFINITE_LIST_DISABLED;
scope.infiniteScrollImmediateCheck = angular.isDefined(scope.infiniteScrollImmediateCheck) ? scope.infiniteScrollImmediateCheck : INFINITE_LIST_IMMEDIATE_CHECK;
scope.infiniteScrollContainer = scope.scrollInsideContainer ? element.parent() : null;
scope.infiniteScrollListenForEvent = INFINITE_LIST_EVENTS.LOAD_MORE_ELEMENTS;
scope.marker = 'test';
Expand Down
8 changes: 3 additions & 5 deletions frontend/js/modules/provider.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
'use strict';

angular.module('esn.provider', [
'esn.constants',
'esn.aggregator',
'esn.lodash-wrapper',
'esn.infinite-list',
'uuid4'
])

.constant('ELEMENTS_PER_REQUEST', 200)
.constant('ELEMENTS_PER_PAGE', 1)

.factory('Providers', function($q, _, toAggregatorSource, ELEMENTS_PER_PAGE) {

function Providers() {
Expand Down Expand Up @@ -243,7 +241,7 @@ angular.module('esn.provider', [

return ByDateElementGroupingTool;
})
.factory('infiniteScrollHelperBuilder', function($q, $timeout, defaultConfiguration, infiniteListService,
.factory('infiniteScrollHelperBuilder', function($q, $timeout, infiniteListService, INFINITE_LIST_THROTTLE,
ELEMENTS_PER_PAGE) {
return function(scope, loadNextItems, updateScope, elements_per_page) {
elements_per_page = elements_per_page || ELEMENTS_PER_PAGE;
Expand Down Expand Up @@ -279,7 +277,7 @@ angular.module('esn.provider', [
.then(function(result) {
$timeout(function() {
infiniteListService.loadMoreElements();
}, defaultConfiguration.throttle, false);
}, INFINITE_LIST_THROTTLE, false);

return result;
})
Expand Down
8 changes: 6 additions & 2 deletions frontend/js/modules/scroll.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
'use strict';

angular.module('esn.scroll', ['esn.header', 'ng.deviceDetector'])
angular.module('esn.scroll', [
'esn.constants',
'esn.header',
'ng.deviceDetector'
])

.constant('SCROLL_EVENTS', {
RESET_SCROLL: 'scroll:reset'
})
.constant('SCROLL_DIFF_DELTA', 30) // in px
.constant('SCROLL_CACHE_KEY', 'scrollPosition')

.directive('keepScrollPosition', function($cacheFactory, $location, $document, $timeout, SCROLL_EVENTS, SCROLL_CACHE_KEY) {
Expand Down
6 changes: 3 additions & 3 deletions frontend/js/modules/timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ angular.module('esn.timeline', [
'esn.infinite-list',
'esn.provider',
'esn.aggregator',
'openpaas-logo'])
'openpaas-logo',
'esn.constants'
])

.constant('DEFAULT_TIMELINE_ELEMENT', '/views/modules/timeline/default-timeline-element.html')

.constant('TIMELINE_PAGE_SIZE', 10)

.config(function(dynamicDirectiveServiceProvider) {
var timelineControlCenterMenu = new dynamicDirectiveServiceProvider.DynamicDirective(
true, 'controlcenter-menu-timeline', { priority: -10 });
Expand Down
10 changes: 5 additions & 5 deletions frontend/js/modules/ui.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use strict';

angular.module('esn.ui', [
'op.dynamicDirective',
'mgcrea.ngStrap.modal',
'esn.autolinker-wrapper'
])
'esn.autolinker-wrapper',
'esn.constants',
'op.dynamicDirective',
'mgcrea.ngStrap.modal'
])

.constant('DEFAULT_COLOR_CLASS', 'accent')
.constant('FAB_ICONS', {
default: 'mdi mdi-plus',
create: 'mdi mdi-plus',
Expand Down
Loading

0 comments on commit 6b9aa50

Please sign in to comment.