From e62684342fe8ee5d2279a3af7da23046c1fbfc86 Mon Sep 17 00:00:00 2001 From: Suzanne Aitchison Date: Tue, 24 May 2022 14:51:18 +0100 Subject: [PATCH] Member index view - collapse other filter sections when one is clicked (#17740) * collapse any filter sections when a new one is clicked * add a cypress test --- app/javascript/packs/admin/users/controls.js | 30 +--------- .../packs/admin/users/filtersModal.js | 59 +++++++++++++++++++ .../admin/users/index/_filters_modal.html.erb | 10 ++-- .../adminFlows/users/filterUserIndex.spec.js | 24 ++++++++ 4 files changed, 90 insertions(+), 33 deletions(-) create mode 100644 app/javascript/packs/admin/users/filtersModal.js create mode 100644 cypress/integration/seededFlows/adminFlows/users/filterUserIndex.spec.js diff --git a/app/javascript/packs/admin/users/controls.js b/app/javascript/packs/admin/users/controls.js index e85d21870..51ab5dbc3 100644 --- a/app/javascript/packs/admin/users/controls.js +++ b/app/javascript/packs/admin/users/controls.js @@ -1,9 +1,5 @@ +import { initializeFiltersModal } from './filtersModal'; import { INTERACTIVE_ELEMENTS_QUERY } from '@utilities/dropdownUtils'; -import { - showWindowModal, - closeWindowModal, - WINDOW_MODAL_ID, -} from '@utilities/showModal'; const expandSearchButton = document.getElementById('expand-search-btn'); const expandFilterButton = document.getElementById('expand-filter-btn'); @@ -117,28 +113,6 @@ const toggleIndicator = ({ value, indicator }) => { } }; -/** - * Controls the triggering of the filters popover modal - */ -const initializeFilterPopoverButtons = () => { - document.querySelectorAll('.js-open-filter-modal-btn').forEach((button) => { - button.addEventListener('click', () => { - showWindowModal({ - contentSelector: '.js-filters-modal', - showHeader: false, - sheet: true, - sheetAlign: 'right', - size: 'small', - onOpen: () => { - document - .querySelector(`#${WINDOW_MODAL_ID} .js-filter-modal-cancel-btn`) - .addEventListener('click', closeWindowModal); - }, - }); - }); - }); -}; - initializeExpandingSections(); initializeSectionIndicators(); -initializeFilterPopoverButtons(); +initializeFiltersModal(); diff --git a/app/javascript/packs/admin/users/filtersModal.js b/app/javascript/packs/admin/users/filtersModal.js new file mode 100644 index 000000000..6f1064fd3 --- /dev/null +++ b/app/javascript/packs/admin/users/filtersModal.js @@ -0,0 +1,59 @@ +import { + showWindowModal, + closeWindowModal, + WINDOW_MODAL_ID, +} from '@utilities/showModal'; + +/** + * Details panels will automatically expand on click when required. + * We want to make sure only _one_ panel is expanded at any given time, + * so here we collapse any which don't match the click's target + */ +const initializeFilterDetailsToggles = () => { + const allDetailsPanels = document.querySelectorAll( + `#${WINDOW_MODAL_ID} details`, + ); + allDetailsPanels?.forEach((panel) => { + panel.addEventListener('toggle', ({ target }) => { + // If the panel is closing, do nothing + if (target.getAttribute('open') === null) { + return; + } + + const { + dataset: { section: clickedSection }, + } = target; + + document + .querySelectorAll(`#${WINDOW_MODAL_ID} details[open]`) + .forEach((openPanel) => { + if (openPanel.dataset?.section !== clickedSection) { + openPanel.removeAttribute('open'); + } + }); + }); + }); +}; + +const initializeModalCloseButton = () => + document + .querySelector(`#${WINDOW_MODAL_ID} .js-filter-modal-cancel-btn`) + .addEventListener('click', closeWindowModal); + +export const initializeFiltersModal = () => { + document.querySelectorAll('.js-open-filter-modal-btn').forEach((button) => { + button.addEventListener('click', () => { + showWindowModal({ + contentSelector: '.js-filters-modal', + showHeader: false, + sheet: true, + sheetAlign: 'right', + size: 'small', + onOpen: () => { + initializeModalCloseButton(); + initializeFilterDetailsToggles(); + }, + }); + }); + }); +}; diff --git a/app/views/admin/users/index/_filters_modal.html.erb b/app/views/admin/users/index/_filters_modal.html.erb index 58e875e18..8fea9ffd1 100644 --- a/app/views/admin/users/index/_filters_modal.html.erb +++ b/app/views/admin/users/index/_filters_modal.html.erb @@ -5,7 +5,7 @@
-
+
Member roles<%= crayons_icon_tag("chevron-down", aria_hidden: true, class: "summary-icon") %>
Member roles @@ -15,19 +15,19 @@
-
+
Status<%= crayons_icon_tag("chevron-down", aria_hidden: true, class: "summary-icon") %> Status options
-
+
Joining date<%= crayons_icon_tag("chevron-down", aria_hidden: true, class: "summary-icon") %> Joining date options
-
+
Last activity<%= crayons_icon_tag("chevron-down", aria_hidden: true, class: "summary-icon") %> Last activity options
-
+
Organizations<%= crayons_icon_tag("chevron-down", aria_hidden: true, class: "summary-icon") %> Organizations options
diff --git a/cypress/integration/seededFlows/adminFlows/users/filterUserIndex.spec.js b/cypress/integration/seededFlows/adminFlows/users/filterUserIndex.spec.js new file mode 100644 index 000000000..e7766fb4b --- /dev/null +++ b/cypress/integration/seededFlows/adminFlows/users/filterUserIndex.spec.js @@ -0,0 +1,24 @@ +describe('Filter user index', () => { + beforeEach(() => { + cy.testSetup(); + cy.fixture('users/adminUser.json').as('user'); + + cy.enableFeatureFlag('member_index_view') + .then(() => cy.get('@user')) + .then((user) => cy.loginAndVisit(user, '/admin/member_manager/users')); + }); + + it('Collapses previously opened sections when a new section is expanded', () => { + // TODO: When the V1 Filter input is removed, we can change this to cy.findByRole('button', { name: 'Filter' }) + cy.findAllByRole('button', { name: 'Filter' }).last().click(); + + cy.getModal().within(() => { + cy.findAllByText('Member roles').first().click(); + cy.findByRole('group', { name: 'Member roles' }).should('be.visible'); + + cy.findByText('Status').click(); + cy.findByText('Status options').should('be.visible'); + cy.findByRole('group', { name: 'Member roles' }).should('not.be.visible'); + }); + }); +});