From a4fb6e11a48ab4b1620b0cc1c3c1311a775324bb Mon Sep 17 00:00:00 2001 From: victorarbuesmallada Date: Mon, 2 Sep 2024 13:46:38 +0100 Subject: [PATCH] wip with data attributes --- .../javascripts/paginationController.js | 78 --------------- .../paginationWithFilterController.js | 97 +++++++++++++++++++ app/views/components/Paginator.scala.html | 4 +- .../team/ViewTeamApplicationsView.scala.html | 14 ++- 4 files changed, 108 insertions(+), 85 deletions(-) create mode 100644 app/assets/javascripts/paginationWithFilterController.js diff --git a/app/assets/javascripts/paginationController.js b/app/assets/javascripts/paginationController.js index 6538baaf..885b6361 100644 --- a/app/assets/javascripts/paginationController.js +++ b/app/assets/javascripts/paginationController.js @@ -57,81 +57,3 @@ export function buildPaginator(itemsPerPage, itemVisibilityHandler = defaultItem } }; } - -export function onPageShow(panelSelector, countId, filterFields, paginationSize) { - const view = (() => { - const apiDetailPanelEls = Array.from(document.querySelectorAll(panelSelector)), - elNoResultsPanel = document.getElementById('noResultsPanel'), - elApiCount = document.getElementById(countId), - elNameFilter = document.getElementById('nameFilter'); - - let onFiltersChangedHandler = noop; - - elNameFilter ? elNameFilter.addEventListener('input', () => { - onFiltersChangedHandler(); - }) : noop; - - return { - get apiDetailPanels() { - return [...apiDetailPanelEls]; - }, - onFiltersChanged(handler) { - onFiltersChangedHandler = handler; - }, - setApiPanelVisibility(apis) { - apis.forEach(apiDetail => { - setVisible(apiDetail.el, !apiDetail.hiddenByFilter); - }); - }, - get nameFilterValue() { - return elNameFilter.value; - }, - toggleNoResultsPanel(visible) { - setVisible(elNoResultsPanel, visible); - }, - set resultCount(value) { - elApiCount.textContent = value; - } - }; - })(); - - if (view.apiDetailPanels?.length > 0) { - const apiPanels = view.apiDetailPanels.map(el => (Object.assign({ - el, - hiddenByFilter: false - }, Object.fromEntries(filterFields.map(f => [f, el.dataset[f]])) - ))); - const paginator = buildPaginator(paginationSize); - - function applyFilter() { - const normalisedNameFilterValue = normaliseText(view.nameFilterValue); - apiPanels.forEach(apiDetail => { - apiDetail.hiddenByFilter = !filterFields.some(filter => - normaliseText(apiDetail[filter]).includes(normalisedNameFilterValue) - ); - }); - - const filteredPanels = apiPanels.filter(apiDetail => ! apiDetail.hiddenByFilter); - view.setApiPanelVisibility(apiPanels); - paginator.render(filteredPanels.map(panel => panel.el)); - - const resultCount = filteredPanels.length; - view.toggleNoResultsPanel(resultCount === 0); - view.resultCount = resultCount; - } - - view.onFiltersChanged(() => { - applyFilter(); - }); - - paginator.render(apiPanels.map(o => o.el)); - applyFilter(); - } -} - -if (typeof window !== 'undefined') { - window.addEventListener( - "pageshow", - () => onPageShow('#appDetailPanels .hip-application', 'appCount', ['applicationName', 'applicationId'], 2) - ); -} \ No newline at end of file diff --git a/app/assets/javascripts/paginationWithFilterController.js b/app/assets/javascripts/paginationWithFilterController.js new file mode 100644 index 00000000..4dc0aaa5 --- /dev/null +++ b/app/assets/javascripts/paginationWithFilterController.js @@ -0,0 +1,97 @@ +import {buildPaginator} from './paginationController.js'; +import {noop, normaliseText, setVisible} from "./utils.js"; + +export function onPageShow(panelAttribute, countAttribute, filterAttribute, paginationAttribute) { + const view = (() => { + const detailsPanelEls = Array.from(document.querySelectorAll(`[${panelAttribute}]`)), + elNoResultsPanel = document.getElementById('noResultsPanel'), + elCount = document.querySelector(`[${countAttribute}]`), + elNameFilter = document.getElementById('nameFilter'); + + let onFiltersChangedHandler = noop; + + elNameFilter ? elNameFilter.addEventListener('input', () => { + onFiltersChangedHandler(); + }) : noop; + + return { + get detailPanels() { + return [...detailsPanelEls]; + }, + onFiltersChanged(handler) { + onFiltersChangedHandler = handler; + }, + setPanelVisibility(panels) { + panels.forEach(panel => { + setVisible(panel.el, !panel.hiddenByFilter); + }); + }, + get nameFilterValue() { + return elNameFilter.value; + }, + toggleNoResultsPanel(visible) { + setVisible(elNoResultsPanel, visible); + }, + panelFilters(panel) { + return Array.from(panel.dataset[filterAttribute].replaceAll(" ", "").split(",")); + }, + get paginationSize() { + return parseInt( + document.querySelector(`[${paginationAttribute}]`).getAttribute(paginationAttribute) + ); + }, + set resultCount(value) { + elCount.textContent = value; + } + }; + })(); + + if (view.detailPanels?.length > 0) { + const details = view.detailPanels.map(el => { + const panelFilters = view.panelFilters(el); + const filterValues = Object.fromEntries(panelFilters.map(f => [f, el.dataset[f]])); + return (Object.assign({ + el, + hiddenByFilter: false, + filters: panelFilters, + }, filterValues)); + }); + const paginator = buildPaginator(view.paginationSize); + + function applyFilter() { + const normalisedNameFilterValue = normaliseText(view.nameFilterValue); + details.forEach(detail => { + detail.hiddenByFilter = !detail.filters.some(filter => + normaliseText(detail[filter]).includes(normalisedNameFilterValue) + ); + }); + + const filteredPanels = details.filter(detail => ! detail.hiddenByFilter); + view.setPanelVisibility(details); + paginator.render(filteredPanels.map(panel => panel.el)); + + const resultCount = filteredPanels.length; + view.toggleNoResultsPanel(resultCount === 0); + view.resultCount = resultCount; + } + + view.onFiltersChanged(() => { + applyFilter(); + }); + + paginator.render(details.map(o => o.el)); + applyFilter(); + } +} + +if (typeof window !== 'undefined') { + window.addEventListener( + "pageshow", + () => onPageShow( + 'data-has-pagination', + 'data-paginator-count', + 'filterBy', + 'data-pagination-size' + ) + ); +} \ No newline at end of file diff --git a/app/views/components/Paginator.scala.html b/app/views/components/Paginator.scala.html index 80c69f52..1d611dfe 100644 --- a/app/views/components/Paginator.scala.html +++ b/app/views/components/Paginator.scala.html @@ -16,9 +16,9 @@ @this() -@()(implicit messages: Messages) +@(paginationSize: Int = 10)(implicit messages: Messages) -
+

@Html(messages("site.displayCount", , ))

diff --git a/app/views/team/ViewTeamApplicationsView.scala.html b/app/views/team/ViewTeamApplicationsView.scala.html index 42ca685f..626c391c 100644 --- a/app/views/team/ViewTeamApplicationsView.scala.html +++ b/app/views/team/ViewTeamApplicationsView.scala.html @@ -37,25 +37,29 @@ @(team: Team, applications: Seq[Application], user: UserModel)(implicit request: Request[?], messages: Messages) @scripts() = { - + } @layout( pageTitle = messages("viewTeamApplications.title"), user = Some(user), fullWidth = true, - customScriptsBlock = Some(scripts()) + customScriptsBlock = Some(scripts()), ) { @views.html.templates.SideNav(messages("manageApis.admin"), ManageTeamNavItems(team, ManageTeamSideNavPages.ViewTeamApplicationsPage)) {

- @messages("viewTeamApplications.heading")(@{applications.size}) + @messages("viewTeamApplications.heading") (@{applications.size})

@searchBox(messages("viewTeamApplications.search.label"), Some(messages("viewTeamApplications.search.hint")), "nameFilter", "govuk-!-margin-bottom-5")
@for(application <- applications){ -
+
@if(application.deleted.isEmpty){ @@ -93,6 +97,6 @@
- @paginator() + @paginator(paginationSize=2) } } \ No newline at end of file