-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(template-filter-macro): adds a macro to enable filtering of the template list * feat(styleguide): adds an example of how the template filter macro could be used. The templates list will need to be marked up with some new data attributes in order to make use of this functionality. * chore: add more fullsome docs * feat(template-filter): allow passing of codesets * style(template-filter): add suggestions from pr review * Apply suggestions from code review Co-authored-by: Philippe Caron <[email protected]> * move template filter to templates.html and split css out of the macro * feat: include `template_caetgory` on the class used by the Templates apge * feat: expose template types and categories so the filters can be populated * refactor: simplify template-filter macro * feat: implement template-filter macro on the templates screen * chore: regen resources * chore: formatting * chore: formatting * fix: re-hide hidden items when filters reset back to all * a11y: various fixes - fix aria-describedbys - fix duplicate ids - fix invalid heading structure - remove unneccessary and broken labelledby * fix: get list of template types for template filter * test: add testids * test: add ui tests * fix: update incorrect template category name in test * chore: remove unused import * feat: add action for filtering and use it in the test * a11y: remove aria_labelledby on fieldset * fix: run all template filter tests in both english and french * Update app/templates/components/template-filter.html Co-authored-by: Philippe Caron <[email protected]> * Update app/templates/components/template-filter.html Co-authored-by: Philippe Caron <[email protected]> * Update app/templates/components/template-filter.html Co-authored-by: Philippe Caron <[email protected]> * Apply suggestions from code review Co-authored-by: Philippe Caron <[email protected]> * fix: reset the sticky footer buttons when filtering * fix: remove pill navigation * fix: make tests more reliable and not depend on language strings * a11y: use a nav element for filtering * chore: fix failing tests * chore: update translations * fix: only show dev message to admins; edit doc strings * chore: move js into its own file * feat: Put FF around functionality * chore: fix tests * chore: formatting * chore: fix tests --------- Co-authored-by: Philippe Caron <[email protected]> Co-authored-by: William B <[email protected]>
- Loading branch information
1 parent
01ad65d
commit b6b9043
Showing
24 changed files
with
758 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** | ||
* Template filters | ||
* | ||
* This JS enhances the templates page by adding a filter to enable the user to filter the templates by type and category. | ||
**/ | ||
(function () { | ||
const templateFilter = document.querySelector(".template-filter"); | ||
const rowSelector = templateFilter.dataset.rowSelector; | ||
|
||
// Function to initialize event listeners on filter links | ||
function initializeFilterLinks() { | ||
document.querySelectorAll(".filter-list a").forEach((link) => { | ||
link.addEventListener("click", handleFilterClick); | ||
}); | ||
} | ||
|
||
// Handle click events on filter links | ||
function handleFilterClick(event) { | ||
event.preventDefault(); | ||
const clickedLink = event.target; | ||
const filterGroup = clickedLink.closest(".filter-list"); | ||
|
||
// Remove 'active' class and aria-current=true from all links in the current filter group | ||
filterGroup | ||
.querySelectorAll("a") | ||
.forEach((link) => link.classList.remove("active")); | ||
filterGroup | ||
.querySelectorAll("a") | ||
.forEach((link) => link.removeAttribute("aria-current")); | ||
|
||
// Add 'active' class to the clicked link | ||
clickedLink.classList.add("active"); | ||
clickedLink.setAttribute("aria-current", "true"); | ||
|
||
// Apply filters based on the active selections | ||
applyFilters(); | ||
} | ||
|
||
// Collect active filters and apply them to the rows | ||
function applyFilters() { | ||
const activeFilters = collectActiveFilters(); | ||
filterRows(activeFilters); | ||
} | ||
|
||
// Collect active filters from the UI | ||
function collectActiveFilters() { | ||
const activeFilters = []; | ||
templateFilter.querySelectorAll(".filter-list").forEach((filterGroup) => { | ||
const activeLink = filterGroup.querySelector(".active"); | ||
activeFilters.push({ | ||
target: filterGroup.dataset.target, | ||
value: activeLink.dataset.target, | ||
}); | ||
}); | ||
return activeFilters; | ||
} | ||
|
||
// Apply active filters to rows, showing or hiding them as necessary | ||
function filterRows(activeFilters) { | ||
document.querySelectorAll(rowSelector).forEach((row) => { | ||
const resetFilter = activeFilters.every( | ||
(filter) => filter.value === "all", | ||
); | ||
const shouldShow = activeFilters.every((filter) => { | ||
return ( | ||
filter.value === "all" || | ||
row.getAttribute(filter.target) === filter.value | ||
); | ||
}); | ||
|
||
if (resetFilter) { | ||
row.style.display = ""; | ||
} else { | ||
if (shouldShow) { | ||
row.style.display = "grid"; | ||
} else { | ||
row.style.display = "none"; | ||
} | ||
} | ||
}); | ||
// reset the sticky footer buttons as the height of the list may have changed | ||
if ("stickAtBottomWhenScrolling" in GOVUK) { | ||
GOVUK.stickAtBottomWhenScrolling.recalculate(); | ||
} | ||
} | ||
|
||
// Initialize the script | ||
initializeFilterLinks(); | ||
})(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
@layer components { | ||
/*! purgecss start ignore */ | ||
|
||
.template-filter .filter-list:nth-child(n + 2) { | ||
@apply pl-gutter border-l-4 border-gray-border; | ||
} | ||
|
||
.template-filter .filter-heading { | ||
@apply font-medium text-small text-gray-700 mb-2; | ||
} | ||
|
||
.template-filter .filter-item { | ||
@apply block p-2; | ||
} | ||
|
||
.template-filter .filter-item.active:not(:focus) { | ||
@apply bg-blue-700 text-white; | ||
} | ||
|
||
/*! purgecss end ignore */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{# | ||
This macro creates a filterable template list based on specified criteria. | ||
The macro requires three parameters: | ||
- row_selector: A CSS selector for the rows to filter, i.e '.template-row' | ||
- notification_types: list of notification types, i.e ['Email', 'SMS'] | ||
- template_categories: list of template categories and text to display, i.e ['Status Update', 'Password Reset'] | ||
- notification_type_data_attribue: The data attribute to filter by notification type, i.e 'data-notification-type' | ||
- template_category_data_attribute: The data attribute to filter by template category, i.e 'data-template-category' | ||
|
||
NOTE: the data attributes need to be present on the rows indicated by `row-selector` for the filtering to work. Example | ||
of a complete row: | ||
``` | ||
<div class="template-row" data-notification-type="Email" data-template-category="Status Update"> | ||
``` | ||
#} | ||
{% macro template_filter(row_selector, notification_types, template_categories, notification_type_data_attribue, template_category_data_attribute) %} | ||
{# Ensure all required parameters are provided #} | ||
{% if not row_selector or not notification_type_data_attribue or not template_category_data_attribute %} | ||
{% if current_user.platform_admin %} | ||
<div class="text-red font-bold my-4"> | ||
Missing required parameters: <code>row_selector</code>, <code>notification_type_attribute</code>, and <code>template_category_attribute</code>. Please verify your code and try again. | ||
</div> | ||
{% endif %} | ||
{% else %} | ||
{# Main filter container with data attributes for dynamic filtering #} | ||
<div class="template-filter" data-row-selector="{{ row_selector }}"> | ||
<details data-testid="filter"> | ||
<summary data-testid="filter-toggle">{{ _("Apply filters") }}</summary> | ||
<nav class="flex p-0 gap-gutter pl-gutter mt-2" aria-label="{{ _('Filter by template type and category') }}" data-testid="filter-content"> | ||
{# Filter group for notification types #} | ||
<div class="filter-list" data-target="{{ notification_type_data_attribue }}"> | ||
<h2 class="filter-heading">{{ _("Type") }}</h2> | ||
<div class="space-y-1" data-testid="filter-types"> | ||
<a href="#" class="filter-item active" data-target="all" data-testid="filter-type-all">{{ _("All") }}</a> | ||
{% for notification_type in notification_types %} | ||
<a href="#" class="filter-item" data-target="{{ notification_type }}">{{ notification_type }}</a> | ||
{% endfor %} | ||
</div> | ||
</div> | ||
{# Filter group for template categories #} | ||
<div class="filter-list" data-target="{{ template_category_data_attribute }}"> | ||
<h2 class="filter-heading">{{ _("Category") }}</h2> | ||
<div class="space-y-1" data-testid="filter-categories"> | ||
<a href="#" class="filter-item active" data-target="all" data-testid="filter-category-all">{{ _("All") }}</a> | ||
{# Loop through template categories and create a filter link for each #} | ||
{% for template_category in template_categories %} | ||
<a href="#" class="filter-item" data-target="{{ template_category }}">{{ template_category }}</a> | ||
{% endfor %} | ||
</div> | ||
</div> | ||
</nav> | ||
</details> | ||
</div> | ||
|
||
<script nonce="{{ request_nonce }}" src="{{ asset_url('javascripts/templateFilters.min.js') }}"></script> | ||
{% endif %} | ||
{% endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.