diff --git a/app/webpacker/controllers/tabs_and_panels_controller.js b/app/webpacker/controllers/tabs_and_panels_controller.js index 0a1762cedb..b6a119c3e8 100644 --- a/app/webpacker/controllers/tabs_and_panels_controller.js +++ b/app/webpacker/controllers/tabs_and_panels_controller.js @@ -12,13 +12,34 @@ export default class extends Controller { // only display the default panel this.defaultTarget.style.display = "block"; + + // Display panel specified in url anchor + const anchors = window.location.toString().split("#"); + const anchor = anchors.length > 1 ? anchors.pop() : ""; + + if (anchor != "") { + this.updateActivePanel(anchor); + + // tab + const tab_id = anchor.split("_panel").shift(); + this.updateActiveTab(tab_id); + } } changeActivePanel(event) { + this.updateActivePanel(`${event.currentTarget.id}_panel`); + } + + updateActivePanel(panel_id) { const newActivePanel = this.panelTargets.find( - (panel) => panel.id == `${event.currentTarget.id}_panel` + (panel) => panel.id == panel_id ); + if (newActivePanel === undefined) { + // No panel found + return; + } + this.currentActivePanel.style.display = "none"; newActivePanel.style.display = "block"; } @@ -28,6 +49,18 @@ export default class extends Controller { event.currentTarget.classList.add(`${this.classNameValue}`); } + updateActiveTab(tab_id) { + const newActiveTab = this.tabTargets.find((tab) => tab.id == tab_id); + + if (newActiveTab === undefined) { + // No tab found + return; + } + + this.currentActiveTab.classList.remove(`${this.classNameValue}`); + newActiveTab.classList.add(`${this.classNameValue}`); + } + get currentActiveTab() { return this.tabTargets.find((tab) => tab.classList.contains("selected")); } diff --git a/spec/javascripts/stimulus/tabs_and_panels_controller_test.js b/spec/javascripts/stimulus/tabs_and_panels_controller_test.js index 8fdfedd117..c87c08f6d0 100644 --- a/spec/javascripts/stimulus/tabs_and_panels_controller_test.js +++ b/spec/javascripts/stimulus/tabs_and_panels_controller_test.js @@ -2,16 +2,26 @@ * @jest-environment jsdom */ -import { Application } from "stimulus"; -import tabs_and_panels_controller from "../../../app/webpacker/controllers/tabs_and_panels_controller"; +import { Application } from 'stimulus'; +import tabs_and_panels_controller from '../../../app/webpacker/controllers/tabs_and_panels_controller'; -describe("EnterprisePanelController", () => { +describe('EnterprisePanelController', () => { beforeAll(() => { const application = Application.start(); - application.register("tabs-and-panels", tabs_and_panels_controller); + application.register('tabs-and-panels', tabs_and_panels_controller); }); - describe("#tabs-and-panels", () => { + describe('#tabs-and-panels', () => { + const checkDefaultPanel = () => { + const peekPanel = document.getElementById('peek_panel'); + const kaPanel = document.getElementById('ka_panel'); + const booPanel = document.getElementById('boo_panel'); + + expect(peekPanel.style.display).toBe('block'); + expect(kaPanel.style.display).toBe('none'); + expect(booPanel.style.display).toBe('none'); + } + beforeEach(() => { document.body.innerHTML = `
@@ -26,23 +36,75 @@ describe("EnterprisePanelController", () => {
`; }); - it("displays only the default panel", () => { - const peekPanel = document.getElementById("peek_panel"); - const kaPanel = document.getElementById("ka_panel"); - const booPanel = document.getElementById("boo_panel"); - - expect(peekPanel.style.display).toBe("block"); - expect(kaPanel.style.display).toBe("none"); - expect(booPanel.style.display).toBe("none"); + it('displays only the default panel', () => { + checkDefaultPanel() }); - it("displays appropriate panel when associated tab is clicked", () => { - const kaPanel = document.getElementById("ka_panel"); - const ka = document.getElementById("ka"); + describe('when tab is clicked', () => { + let ka; - expect(kaPanel.style.display).toBe("none"); - ka.click(); - expect(kaPanel.style.display).toBe("block"); - }); + beforeEach(() => { + ka = document.getElementById('ka'); + }) + + it('displays appropriate panel', () => { + const kaPanel = document.getElementById('ka_panel'); + + expect(kaPanel.style.display).toBe('none'); + ka.click(); + expect(kaPanel.style.display).toBe('block'); + }); + + it('selects the clicked tab', () => { + ka.click(); + expect(ka.classList.contains('selected')).toBe(true); + }); + }) + + describe('when anchor is specified in the url', () => { + const { location } = window; + const mockLocationToString = (panel) => { + // Mocking window.location.toString() + const url = `http://localhost:3000/admin/enterprises/great-shop/edit#!#${panel}` + const mockedToString = jest.fn() + mockedToString.mockImplementation(() => (url)) + + delete window.location + window.location = { + toString: mockedToString + } + } + + beforeAll(() => { + mockLocationToString('ka_panel') + }) + + afterAll(() => { + // cleaning up + window.location = location + }) + + it('displays the panel associated with the anchor', () => { + const kaPanel = document.getElementById('ka_panel'); + + expect(kaPanel.style.display).toBe('block'); + }) + + it('selects the tab entry associated with the anchor', () => { + const ka = document.getElementById('ka'); + + expect(ka.classList.contains('selected')).toBe(true); + }) + + describe("when anchor doesn't macht any panel", () => { + beforeAll(() => { + mockLocationToString('random_panel') + }) + + it('displays the default panel', () => { + checkDefaultPanel() + }) + }) + }) }); });