From 9fd74021afb0a6d4551b21615f7094b1b0705f63 Mon Sep 17 00:00:00 2001 From: Folker Bernitt Date: Wed, 8 Oct 2014 11:05:01 +0200 Subject: Added logout link to dispatcher (issue #55). - Set DISPATCHER_LOGOUT_URL environment to logout url to show logout. - Logout button currently lacks some design --- .gitignore | 1 + service/pixelated/user_agent.py | 10 +++++++--- web-ui/app/index.html | 1 + web-ui/app/js/features/features.js | 30 +++++++++++++++++++++--------- web-ui/app/js/page/default.js | 7 +++++-- web-ui/app/js/page/logout.js | 27 +++++++++++++++++++++++++++ web-ui/app/js/views/templates.js | 3 +++ web-ui/app/scss/styles.scss | 4 ++++ web-ui/app/templates/page/logout.hbs | 1 + web-ui/test/features.js | 6 ++++++ web-ui/test/spec/page/logout.spec.js | 33 +++++++++++++++++++++++++++++++++ 11 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 web-ui/app/js/page/logout.js create mode 100644 web-ui/app/templates/page/logout.hbs create mode 100644 web-ui/test/spec/page/logout.spec.js diff --git a/.gitignore b/.gitignore index 5330abe3..853bf7d6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.egg-info web-ui/node_modules web-ui/app/bower_components +web-ui/target .tmp .sass-cache/ dist/ diff --git a/service/pixelated/user_agent.py b/service/pixelated/user_agent.py index bee0035b..c61618b9 100644 --- a/service/pixelated/user_agent.py +++ b/service/pixelated/user_agent.py @@ -54,9 +54,13 @@ def respond_json(entity, status_code=200): return response -@app.route('/disabled_features') -def disabled_features(): - return respond_json(DISABLED_FEATURES) +@app.route('/features') +def features(): + try: + disabled_features = {'logout': os.environ['DISPATCHER_LOGOUT_URL']} + except KeyError: + disabled_features = {} + return respond_json({'disabled_features': DISABLED_FEATURES, 'dispatcher_features': disabled_features}) @app.route('/mails', methods=['POST']) diff --git a/web-ui/app/index.html b/web-ui/app/index.html index 568cff8a..284ac4e9 100644 --- a/web-ui/app/index.html +++ b/web-ui/app/index.html @@ -18,6 +18,7 @@
+
diff --git a/web-ui/app/js/features/features.js b/web-ui/app/js/features/features.js index 9ca1d932..e008b5fc 100644 --- a/web-ui/app/js/features/features.js +++ b/web-ui/app/js/features/features.js @@ -18,29 +18,41 @@ 'use strict'; define([], function() { var cachedDisabledFeatures; + var cachedDispatcherFeatures; - function getFeatures() { - cachedDisabledFeatures = cachedDisabledFeatures || fetchDisabledFeatures(); + function getDisabledFeatures() { + cachedDisabledFeatures = cachedDisabledFeatures || fetchFeatures().disabled_features; return cachedDisabledFeatures; } - function fetchDisabledFeatures() { - var disabledFeatures; - $.ajax('/disabled_features', { + function getDispatcherFeatures() { + cachedDispatcherFeatures = cachedDispatcherFeatures || fetchFeatures().dispatcher_features; + return cachedDispatcherFeatures; + } + + function fetchFeatures() { + var features; + $.ajax('/features', { async: false, success: function (results){ - disabledFeatures = results; + features = results; }, error: function () { console.error('Could not load feature toggles'); } }); - return disabledFeatures; + return features; } return { - isEnabled: function(featureName) { - return ! _.contains(getFeatures(), featureName); + isEnabled: function (featureName) { + return ! _.contains(getDisabledFeatures(), featureName); + }, + isLogoutEnabled: function () { + return _.has(getDispatcherFeatures(), 'logout'); + }, + getLogoutUrl: function () { + return getDispatcherFeatures().logout; } }; }); diff --git a/web-ui/app/js/page/default.js b/web-ui/app/js/page/default.js index 7fe19b88..a86acfa3 100644 --- a/web-ui/app/js/page/default.js +++ b/web-ui/app/js/page/default.js @@ -39,7 +39,8 @@ define( 'page/pane_contract_expand', 'views/i18n', 'views/recipientListFormatter', - 'flight/lib/logger' + 'flight/lib/logger', + 'page/logout' ], function ( @@ -66,7 +67,8 @@ define( paneContractExpand, viewI18n, recipientListFormatter, - withLogging) { + withLogging, + logout) { 'use strict'; function initialize(path) { @@ -96,6 +98,7 @@ define( leftPaneDispatcher.attachTo(document); offCanvas.attachTo(document); + logout.attachTo('#logout'); } return initialize; diff --git a/web-ui/app/js/page/logout.js b/web-ui/app/js/page/logout.js new file mode 100644 index 00000000..f598fa34 --- /dev/null +++ b/web-ui/app/js/page/logout.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014 ThoughtWorks, Inc. + * + * Pixelated is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Pixelated is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Pixelated. If not, see . + */ +define(['flight/lib/component', 'features', 'views/templates'], function (defineComponent, features, templates) { + 'use strict'; + + return defineComponent(function () { + this.after('initialize', function () { + if (features.isLogoutEnabled()) { + this.$node.html(templates.page.logout({ logout_url: features.getLogoutUrl() })); + } + }); + }); +}); diff --git a/web-ui/app/js/views/templates.js b/web-ui/app/js/views/templates.js index 7a735534..4847eb4d 100644 --- a/web-ui/app/js/views/templates.js +++ b/web-ui/app/js/views/templates.js @@ -52,6 +52,9 @@ define(['hbs/templates'], function (templates) { noMessageSelected: window.Pixelated['app/templates/no_message_selected.hbs'], search: { trigger: window.Pixelated['app/templates/search/search_trigger.hbs'] + }, + page: { + logout: window.Pixelated['app/templates/page/logout.hbs'] } }; diff --git a/web-ui/app/scss/styles.scss b/web-ui/app/scss/styles.scss index 45db96f4..ae9ace1e 100644 --- a/web-ui/app/scss/styles.scss +++ b/web-ui/app/scss/styles.scss @@ -12,6 +12,10 @@ color: #FFF; } +#logout { + color: #FFF; +} + .search-highlight { background-color: $search-highlight; } diff --git a/web-ui/app/templates/page/logout.hbs b/web-ui/app/templates/page/logout.hbs new file mode 100644 index 00000000..dda07eae --- /dev/null +++ b/web-ui/app/templates/page/logout.hbs @@ -0,0 +1 @@ +Logout diff --git a/web-ui/test/features.js b/web-ui/test/features.js index 27c47176..29c6d87d 100644 --- a/web-ui/test/features.js +++ b/web-ui/test/features.js @@ -3,6 +3,12 @@ define([], function() { return { isEnabled: function(featureName) { return true; + }, + isLogoutEnabled: function() { + return true; + }, + getLogoutUrl: function() { + return '/test/logout/url'; } }; }); diff --git a/web-ui/test/spec/page/logout.spec.js b/web-ui/test/spec/page/logout.spec.js new file mode 100644 index 00000000..c614af6d --- /dev/null +++ b/web-ui/test/spec/page/logout.spec.js @@ -0,0 +1,33 @@ +/*global Pixelated */ + +describeComponent('page/logout', function () { + 'use strict'; + + describe('logout link', function () { + var features; + + beforeEach(function() { + features = require('features'); + }); + + it('should provide logout link if logout is enabled', function () { + spyOn(features, 'isLogoutEnabled').andReturn(true); + + setupComponent('
', {}); + + var logout_link = this.component.$node.find('a')[0]; + expect(logout_link).toExist(); + expect(logout_link.href).toMatch('test/logout/url'); + }); + + it('should not provide logout link if disabled', function() { + spyOn(features, 'isLogoutEnabled').andReturn(false); + + setupComponent('
', {}); + + var logout_link = this.component.$node.find('a')[0]; + expect(logout_link).not.toExist(); + }); + }); +}); + -- cgit v1.2.3