From 8235f8301571a9b55a14b94b2ed687e53cbc2f4e Mon Sep 17 00:00:00 2001 From: Jacopo Date: Sun, 6 Nov 2016 19:41:23 +0100 Subject: [PATCH] Fixed Wrong Tab Selected When Loggin Fails And Multiple Login Tabs Exists When ldap is enabled and use "Standard" authentication method, if authentication fails the correct tab remain selected. This is done by saving into localStorage when the active tab changes and by always selecting that tab when the page is loaded. --- .eslintrc | 3 +- app/assets/javascripts/dispatcher.js.es6 | 1 + .../javascripts/signin_tabs_memoizer.js.es6 | 49 +++++++++++++++++ app/views/devise/sessions/new.html.haml | 1 + .../15081-wrong-login-tab-ldap-frontend.yml | 4 ++ .../fixtures/signin_tabs.html.haml | 5 ++ .../signin_tabs_memoizer_spec.js.es6 | 53 +++++++++++++++++++ 7 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/signin_tabs_memoizer.js.es6 create mode 100644 changelogs/unreleased/15081-wrong-login-tab-ldap-frontend.yml create mode 100644 spec/javascripts/fixtures/signin_tabs.html.haml create mode 100644 spec/javascripts/signin_tabs_memoizer_spec.js.es6 diff --git a/.eslintrc b/.eslintrc index b80dcec9d1d..e13f76b213c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,8 @@ "globals": { "_": false, "gl": false, - "gon": false + "gon": false, + "localStorage": false }, "plugins": [ "filenames" diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index 16df4b0b005..fb366e2eb88 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -24,6 +24,7 @@ switch (page) { case 'sessions:new': new UsernameValidator(); + new ActiveTabMemoizer(); break; case 'projects:boards:show': case 'projects:boards:index': diff --git a/app/assets/javascripts/signin_tabs_memoizer.js.es6 b/app/assets/javascripts/signin_tabs_memoizer.js.es6 new file mode 100644 index 00000000000..d811d1cd53a --- /dev/null +++ b/app/assets/javascripts/signin_tabs_memoizer.js.es6 @@ -0,0 +1,49 @@ +/* eslint no-param-reassign: ["error", { "props": false }]*/ +/* eslint no-new: "off" */ +((global) => { + /** + * Memorize the last selected tab after reloading a page. + * Does that setting the current selected tab in the localStorage + */ + class ActiveTabMemoizer { + constructor({ currentTabKey = 'current_signin_tab', tabSelector = 'ul.nav-tabs' } = {}) { + this.currentTabKey = currentTabKey; + this.tabSelector = tabSelector; + this.bootstrap(); + } + + bootstrap() { + const tabs = document.querySelectorAll(this.tabSelector); + if (tabs.length > 0) { + tabs[0].addEventListener('click', (e) => { + if (e.target && e.target.nodeName === 'A') { + const anchorName = e.target.getAttribute('href'); + this.saveData(anchorName); + } + }); + } + + this.showTab(); + } + + showTab() { + const anchorName = this.readData(); + if (anchorName) { + const tab = document.querySelector(`${this.tabSelector} a[href="${anchorName}"]`); + if (tab) { + tab.click(); + } + } + } + + saveData(val) { + localStorage.setItem(this.currentTabKey, val); + } + + readData() { + return localStorage.getItem(this.currentTabKey); + } + } + + global.ActiveTabMemoizer = ActiveTabMemoizer; +})(window); diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index fa8e7979461..af87129e49e 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -1,4 +1,5 @@ - page_title "Sign in" + %div - if form_based_providers.any? = render 'devise/shared/tabs_ldap' diff --git a/changelogs/unreleased/15081-wrong-login-tab-ldap-frontend.yml b/changelogs/unreleased/15081-wrong-login-tab-ldap-frontend.yml new file mode 100644 index 00000000000..19c76b5b437 --- /dev/null +++ b/changelogs/unreleased/15081-wrong-login-tab-ldap-frontend.yml @@ -0,0 +1,4 @@ +--- +title: Fix wrong tab selected when loggin fails and multiple login tabs exists +merge_request: 7314 +author: Jacopo Beschi @jacopo-beschi diff --git a/spec/javascripts/fixtures/signin_tabs.html.haml b/spec/javascripts/fixtures/signin_tabs.html.haml new file mode 100644 index 00000000000..12b8d423cbe --- /dev/null +++ b/spec/javascripts/fixtures/signin_tabs.html.haml @@ -0,0 +1,5 @@ +%ul.nav-tabs + %li + %a.active{ id: 'standard', href: '#standard'} Standard + %li + %a{ id: 'ldap', href: '#ldap'} Ldap diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js.es6 b/spec/javascripts/signin_tabs_memoizer_spec.js.es6 new file mode 100644 index 00000000000..9a9fb22255b --- /dev/null +++ b/spec/javascripts/signin_tabs_memoizer_spec.js.es6 @@ -0,0 +1,53 @@ +/*= require signin_tabs_memoizer */ + +((global) => { + describe('SigninTabsMemoizer', () => { + const fixtureTemplate = 'signin_tabs.html'; + const tabSelector = 'ul.nav-tabs'; + const currentTabKey = 'current_signin_tab'; + let memo; + + function createMemoizer() { + memo = new global.ActiveTabMemoizer({ + currentTabKey, + tabSelector, + }); + return memo; + } + + fixture.preload(fixtureTemplate); + + beforeEach(() => { + fixture.load(fixtureTemplate); + }); + + it('does nothing if no tab was previously selected', () => { + createMemoizer(); + + expect(document.querySelector('li a.active').getAttribute('id')).toEqual('standard'); + }); + + it('shows last selected tab on boot', () => { + createMemoizer().saveData('#ldap'); + const fakeTab = { + click: () => {}, + }; + spyOn(document, 'querySelector').and.returnValue(fakeTab); + spyOn(fakeTab, 'click'); + + memo.bootstrap(); + + // verify that triggers click on the last selected tab + expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`); + expect(fakeTab.click).toHaveBeenCalled(); + }); + + it('saves last selected tab on change', () => { + createMemoizer(); + + document.getElementById('standard').click(); + + expect(memo.readData()).toEqual('#standard'); + }); + }); +})(window);