diff options
Diffstat (limited to 'apps/user_ldap/js/wizard/view.js')
-rw-r--r-- | apps/user_ldap/js/wizard/view.js | 437 |
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; +})(); |