summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--service/pixelated/user_agent.py10
-rw-r--r--web-ui/app/index.html1
-rw-r--r--web-ui/app/js/features/features.js30
-rw-r--r--web-ui/app/js/page/default.js7
-rw-r--r--web-ui/app/js/page/logout.js27
-rw-r--r--web-ui/app/js/views/templates.js3
-rw-r--r--web-ui/app/scss/styles.scss4
-rw-r--r--web-ui/app/templates/page/logout.hbs1
-rw-r--r--web-ui/test/features.js6
-rw-r--r--web-ui/test/spec/page/logout.spec.js33
11 files changed, 109 insertions, 14 deletions
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 @@
<header id="main">
<div id="logo" class="small-4 large-2 columns"><strong>Pixelated</strong> <i class="fa fa-angle-right"></i> Messages</div>
<div id="user-alerts"></div>
+ <div id="logout"></div>
</header>
<div class="inner-wrap">
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 <http://www.gnu.org/licenses/>.
+ */
+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 @@
+<a href="{{logout_url}}">Logout</a>
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('<div id="logout"></div>', {});
+
+ 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('<div id="logout"></div>', {});
+
+ var logout_link = this.component.$node.find('a')[0];
+ expect(logout_link).not.toExist();
+ });
+ });
+});
+