summaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/js/wizard/view.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_ldap/js/wizard/view.js')
-rw-r--r--apps/user_ldap/js/wizard/view.js437
1 files changed, 437 insertions, 0 deletions
diff --git a/apps/user_ldap/js/wizard/view.js b/apps/user_ldap/js/wizard/view.js
new file mode 100644
index 00000000000..7743c277d61
--- /dev/null
+++ b/apps/user_ldap/js/wizard/view.js
@@ -0,0 +1,437 @@
+/**
+ * Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+
+OCA = OCA || {};
+
+(function() {
+
+ /**
+ * @classdesc main view class. It takes care of tab-unrelated control
+ * elements (status bar, control buttons) and does or requests configuration
+ * checks. It also manages the separate tab views.
+ *
+ * @constructor
+ */
+ var WizardView = function() {};
+
+ WizardView.prototype = {
+ /** @constant {number} */
+ STATUS_ERROR: 0,
+ /** @constant {number} */
+ STATUS_INCOMPLETE: 1,
+ /** @constant {number} */
+ STATUS_SUCCESS: 2,
+
+ /**
+ * initializes the instance. Always call it after creating the instance.
+ */
+ init: function () {
+ this.tabs = {};
+ this.tabs.server = new OCA.LDAP.Wizard.WizardTabElementary();
+ this.$settings = $('#ldapSettings');
+ this.$saveSpinners = $('.ldap_saving');
+ this.saveProcesses = 0;
+ _.bindAll(this, 'onTabChange', 'onTestButtonClick');
+ },
+
+ /**
+ * applies click events to the forward and backword buttons
+ */
+ initControls: function() {
+ var view = this;
+ $('.ldap_action_continue').click(function(event) {
+ event.preventDefault();
+ view._controlContinue(view);
+ });
+
+ $('.ldap_action_back').click(function(event) {
+ event.preventDefault();
+ view._controlBack(view);
+ });
+
+ $('.ldap_action_test_connection').click(this.onTestButtonClick);
+ },
+
+ /**
+ * registers a tab
+ *
+ * @param {OCA.LDAP.Wizard.WizardTabGeneric} tabView
+ * @param {string} index
+ * @returns {boolean}
+ */
+ registerTab: function(tabView, index) {
+ if( _.isUndefined(this.tabs[index])
+ && tabView instanceof OCA.LDAP.Wizard.WizardTabGeneric
+ ) {
+ this.tabs[index] = tabView;
+ this.tabs[index].setModel(this.configModel);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * checks certain config values for completeness and depending on them
+ * enables or disables non-elementary tabs.
+ */
+ basicStatusCheck: function(view) {
+ var host = view.configModel.configuration.ldap_host;
+ var port = view.configModel.configuration.ldap_port;
+ var base = view.configModel.configuration.ldap_base;
+ var agent = view.configModel.configuration.ldap_dn;
+ var pwd = view.configModel.configuration.ldap_agent_password;
+
+ if((host && port && base) && ((!agent && !pwd) || (agent && pwd))) {
+ view.enableTabs();
+ } else {
+ view.disableTabs();
+ }
+ },
+
+ /**
+ * if the configuration is sufficient the model is being request to
+ * perform a configuration test. Otherwise, the status indicator is
+ * being updated with the status "incomplete"
+ */
+ functionalityCheck: function() {
+ // this method should be called only if necessary, because it may
+ // cause an LDAP request!
+ var host = this.configModel.configuration.ldap_host;
+ var port = this.configModel.configuration.ldap_port;
+ var base = this.configModel.configuration.ldap_base;
+ var userFilter = this.configModel.configuration.ldap_userlist_filter;
+ var loginFilter = this.configModel.configuration.ldap_login_filter;
+
+ if(host && port && base && userFilter && loginFilter) {
+ this.configModel.requestConfigurationTest();
+ } else {
+ this._updateStatusIndicator(this.STATUS_INCOMPLETE);
+ }
+ },
+
+ /**
+ * will request a functionality check if one of the related configuration
+ * settings was changed.
+ *
+ * @param {ConfigSetPayload|Object} [changeSet]
+ */
+ considerFunctionalityCheck: function(changeSet) {
+ var testTriggers = [
+ 'ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password',
+ 'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter'
+ ];
+ for(var key in changeSet) {
+ if($.inArray(key, testTriggers) >= 0) {
+ this.functionalityCheck();
+ return;
+ }
+ }
+ },
+
+ /**
+ * keeps number of running save processes and shows a spinner if
+ * necessary
+ *
+ * @param {WizardView} [view]
+ * @listens ConfigModel#setRequested
+ */
+ onSetRequested: function(view) {
+ view.saveProcesses += 1;
+ if(view.saveProcesses === 1) {
+ view.showSaveSpinner();
+ }
+ },
+
+ /**
+ * keeps number of running save processes and hides the spinner if
+ * necessary. Also triggers checks, to adjust tabs state and status bar.
+ *
+ * @param {WizardView} [view]
+ * @param {ConfigSetPayload} [result]
+ * @listens ConfigModel#setCompleted
+ */
+ onSetRequestDone: function(view, result) {
+ if(view.saveProcesses > 0) {
+ view.saveProcesses -= 1;
+ if(view.saveProcesses === 0) {
+ view.hideSaveSpinner();
+ }
+ }
+
+ view.basicStatusCheck(view);
+ var param = {};
+ param[result.key] = 1;
+ view.considerFunctionalityCheck(param);
+ },
+
+ /**
+ * updates the status indicator based on the configuration test result
+ *
+ * @param {WizardView} [view]
+ * @param {ConfigTestPayload} [result]
+ * @listens ConfigModel#configurationTested
+ */
+ onTestCompleted: function(view, result) {
+ if(result.isSuccess) {
+ view._updateStatusIndicator(view.STATUS_SUCCESS);
+ } else {
+ view._updateStatusIndicator(view.STATUS_ERROR);
+ }
+ },
+
+ /**
+ * triggers initial checks upon configuration loading to update status
+ * controls
+ *
+ * @param {WizardView} [view]
+ * @listens ConfigModel#configLoaded
+ */
+ onConfigLoaded: function(view) {
+ view.basicStatusCheck(view);
+ view.functionalityCheck();
+ },
+
+ /**
+ * reacts on attempts to switch to a different tab
+ *
+ * @param {object} event
+ * @param {object} ui
+ * @returns {boolean}
+ */
+ onTabChange: function(event, ui) {
+ if(this.saveProcesses > 0) {
+ return false;
+ }
+
+ var newTabID = ui.newTab[0].id;
+ if(newTabID === '#ldapWizard1') {
+ newTabID = 'server';
+ }
+ var oldTabID = ui.oldTab[0].id;
+ if(oldTabID === '#ldapWizard1') {
+ oldTabID = 'server';
+ }
+ if(!_.isUndefined(this.tabs[newTabID])) {
+ this.tabs[newTabID].isActive = true;
+ this.tabs[newTabID].onActivate();
+ } else {
+ console.warn('Unreferenced activated tab ' + newTabID);
+ }
+ if(!_.isUndefined(this.tabs[oldTabID])) {
+ this.tabs[oldTabID].isActive = false;
+ } else {
+ console.warn('Unreferenced left tab ' + oldTabID);
+ }
+
+ if(!_.isUndefined(this.tabs[newTabID])) {
+ this._controlUpdate(this.tabs[newTabID].tabIndex);
+ }
+ },
+
+ /**
+ * triggers checks upon configuration updates to keep status controls
+ * up to date
+ *
+ * @param {WizardView} [view]
+ * @param {object} [changeSet]
+ * @listens ConfigModel#configUpdated
+ */
+ onConfigUpdated: function(view, changeSet) {
+ view.basicStatusCheck(view);
+ view.considerFunctionalityCheck(changeSet);
+ },
+
+ /**
+ * requests a configuration test
+ */
+ onTestButtonClick: function() {
+ this.configModel.requestWizard('ldap_action_test_connection', this.configModel.configuration);
+ },
+
+ /**
+ * sets the model instance and registers event listeners
+ *
+ * @param {OCA.LDAP.Wizard.ConfigModel} [configModel]
+ */
+ setModel: function(configModel) {
+ /** @type {OCA.LDAP.Wizard.ConfigModel} */
+ this.configModel = configModel;
+ for(var i in this.tabs) {
+ this.tabs[i].setModel(configModel);
+ }
+
+ // make sure this is definitely run after tabs did their work, order is important here
+ // for now this works, because tabs are supposed to register their listeners in their
+ // setModel() method.
+ // alternative: make Elementary Tab a Publisher as well.
+ this.configModel.on('configLoaded', this.onConfigLoaded, this);
+ this.configModel.on('configUpdated', this.onConfigUpdated, this);
+ this.configModel.on('setRequested', this.onSetRequested, this);
+ this.configModel.on('setCompleted', this.onSetRequestDone, this);
+ this.configModel.on('configurationTested', this.onTestCompleted, this);
+ },
+
+ /**
+ * enables tab and navigation buttons
+ */
+ enableTabs: function() {
+ //do not use this function directly, use basicStatusCheck instead.
+ if(this.saveProcesses === 0) {
+ $('.ldap_action_continue').removeAttr('disabled');
+ $('.ldap_action_back').removeAttr('disabled');
+ this.$settings.tabs('option', 'disabled', []);
+ }
+ },
+
+ /**
+ * disables tab and navigation buttons
+ */
+ disableTabs: function() {
+ $('.ldap_action_continue').attr('disabled', 'disabled');
+ $('.ldap_action_back').attr('disabled', 'disabled');
+ this.$settings.tabs('option', 'disabled', [1, 2, 3, 4, 5]);
+ },
+
+ /**
+ * shows a save spinner
+ */
+ showSaveSpinner: function() {
+ this.$saveSpinners.removeClass('hidden');
+ $('#ldap *').addClass('save-cursor');
+ },
+
+ /**
+ * hides the save spinner
+ */
+ hideSaveSpinner: function() {
+ this.$saveSpinners.addClass('hidden');
+ $('#ldap *').removeClass('save-cursor');
+ },
+
+ /**
+ * performs a config load request to the model
+ *
+ * @param {string} [configID]
+ * @private
+ */
+ _requestConfig: function(configID) {
+ this.configModel.load(configID);
+ },
+
+ /**
+ * bootstraps the visual appearance and event listeners, as well as the
+ * first config
+ */
+ render: function () {
+ $('#ldapAdvancedAccordion').accordion({ heightStyle: 'content', animate: 'easeInOutCirc'});
+ this.$settings.tabs({});
+ $('.ldap_submit').button();
+ $('.ldap_action_test_connection').button();
+ $('#ldapSettings').tabs({ beforeActivate: this.onTabChange });
+
+ this.initControls();
+ this.disableTabs();
+
+ this._requestConfig(this.tabs.server.getConfigID());
+ },
+
+ /**
+ * updates the status indicator / bar
+ *
+ * @param {number} [state]
+ * @private
+ */
+ _updateStatusIndicator: function(state) {
+ var $indicator = $('.ldap_config_state_indicator');
+ var $indicatorLight = $('.ldap_config_state_indicator_sign');
+
+ switch(state) {
+ case this.STATUS_ERROR:
+ $indicator.text(t('user_ldap',
+ 'Configuration incorrect'
+ ));
+ $indicator.removeClass('ldap_grey');
+ $indicatorLight.addClass('error');
+ $indicatorLight.removeClass('success');
+ break;
+ case this.STATUS_INCOMPLETE:
+ $indicator.text(t('user_ldap',
+ 'Configuration incomplete'
+ ));
+ $indicator.removeClass('ldap_grey');
+ $indicatorLight.removeClass('error');
+ $indicatorLight.removeClass('success');
+ break;
+ case this.STATUS_SUCCESS:
+ $indicator.text(t('user_ldap', 'Configuration OK'));
+ $indicator.addClass('ldap_grey');
+ $indicatorLight.removeClass('error');
+ $indicatorLight.addClass('success');
+ if(!this.tabs.server.isActive) {
+ this.configModel.set('ldap_configuration_active', 1);
+ }
+ break;
+ }
+ },
+
+ /**
+ * handles a click on the Back button
+ *
+ * @param {WizardView} [view]
+ * @private
+ */
+ _controlBack: function(view) {
+ var curTabIndex = view.$settings.tabs('option', 'active');
+ if(curTabIndex == 0) {
+ return;
+ }
+ view.$settings.tabs('option', 'active', curTabIndex - 1);
+ view._controlUpdate(curTabIndex - 1);
+ },
+
+ /**
+ * handles a click on the Continue button
+ *
+ * @param {WizardView} [view]
+ * @private
+ */
+ _controlContinue: function(view) {
+ var curTabIndex = view.$settings.tabs('option', 'active');
+ if(curTabIndex == 3) {
+ return;
+ }
+ view.$settings.tabs('option', 'active', 1 + curTabIndex);
+ view._controlUpdate(curTabIndex + 1);
+ },
+
+ /**
+ * updates the controls (navigation buttons)
+ *
+ * @param {number} [nextTabIndex] - index of the tab being switched to
+ * @private
+ */
+ _controlUpdate: function(nextTabIndex) {
+ if(nextTabIndex == 0) {
+ $('.ldap_action_back').addClass('invisible');
+ $('.ldap_action_continue').removeClass('invisible');
+ } else
+ if(nextTabIndex == 1) {
+ $('.ldap_action_back').removeClass('invisible');
+ $('.ldap_action_continue').removeClass('invisible');
+ } else
+ if(nextTabIndex == 2) {
+ $('.ldap_action_continue').removeClass('invisible');
+ $('.ldap_action_back').removeClass('invisible');
+ } else
+ if(nextTabIndex == 3) {
+ $('.ldap_action_back').removeClass('invisible');
+ $('.ldap_action_continue').addClass('invisible');
+ }
+ }
+ };
+
+ OCA.LDAP.Wizard.WizardView = WizardView;
+})();