Skip to content

Filter refactor#377

Merged
DinneK merged 4 commits into
devfrom
Filter-refactor
May 5, 2025
Merged

Filter refactor#377
DinneK merged 4 commits into
devfrom
Filter-refactor

Conversation

@DinneK
Copy link
Copy Markdown
Contributor

@DinneK DinneK commented Apr 23, 2025

module-name: Refactor filter functionality

Problem

  • Initialization Issues:
    • Project cards load randomly on first render, instead of being organized by orgs.
    • Filter state does not properly initialize on page load
  • Code duplication:
    • Filter logic repeats across multiple functions
    • UI state management is mixed with core filtering logic
  • Maintainability:
    • Adding new filter types requires changes in multiple places
    • Filter configuration is hardcoded in several places

Solution

  • Code Architecture Changes:
    • Create centralized filter checks
    • Implement shared utility functions (getSelectedFilters etc.)
    • Separate UI logic from core filtering logic
  • Initialization Fixes:
    • Add proper async initialization
    • Ensure consistent org grouping on first render and with filters and search
  • Code organization:
    • Extract menu logic into new ui.js module
    • Simplify main project initialization flow

Result

  • Behavioral Improvements:
    • Projects now consistently group by organization
    • Filter state applies immediately without requiring pagination interaction
  • Code:
    • Reduced duplication
    • Clear separation of concerns between modules
    • Single source of truth for filter configuration

Some important notes regarding the summary line:

  • Backwards Compatibility: All existing functionality remains unchanged
  • Foundation set for CSS refactor

Test Plan

  • Verified projects group by org
  • Check for correct initialization
  • Test each filters
  • Verify clear filter functionality
  • Verify page reset on changes
  • Test in prod

Next Steps

  • CSS refactor
  • Begin backlog metrics tickets
  • Implement testing (unit and UI)

DinneK added 4 commits April 17, 2025 19:59
Signed-off-by: Dinne Kopelevich <dinne.kopelevich@gsa.gov>
Signed-off-by: Dinne Kopelevich <dinne.kopelevich@gsa.gov>
Signed-off-by: Dinne Kopelevich <dinne.kopelevich@gsa.gov>
Signed-off-by: Dinne Kopelevich <dinne.kopelevich@gsa.gov>
@DinneK DinneK added enhancement New feature or request front-end javascript Pull requests that update Javascript code metrics labels Apr 23, 2025
@DinneK DinneK self-assigned this Apr 23, 2025
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

prettier

[prettier] reported by reviewdog 🐶

iconPosition = 'before',
onclick


[prettier] reported by reviewdog 🐶

const item = document.createElement('li');
item.className = 'usa-pagination__item usa-pagination__arrow';


[prettier] reported by reviewdog 🐶

const button = document.createElement('a');
button.href = 'javascript:void(0);';
button.className = `usa-pagination__link ${className}`;
button.setAttribute('aria-label', label);
if(disabled) button.classList.add('usa-pagination__disabled');


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

button.innerHTML = iconPosition === 'before'
? `${iconHtml}<span class="usa-pagination__link-text">${text}</span>`
: `<span class="usa-pagination__link-text">${text}</span>${iconHtml}`;


[prettier] reported by reviewdog 🐶

if(!disabled) {
button.addEventListener('click', onclick);


[prettier] reported by reviewdog 🐶

item.appendChild(button);
return item;


[prettier] reported by reviewdog 🐶

import { sortSelection, filtersContainer } from "./data";
import { addGlobalEventListener } from "./utilities";
import { updateFilters, updateFilteredProjects, getFilteredProjects, setFilteredProjects } from "./filters";
import { renderPaginatedProjects } from "./rendering";


[prettier] reported by reviewdog 🐶

const targetProjects = getFilteredProjects();


[prettier] reported by reviewdog 🐶

setFilteredProjects(targetProjects);
renderPaginatedProjects();


[prettier] reported by reviewdog 🐶

import { baseurl } from "./data";


[prettier] reported by reviewdog 🐶

const filterButtons = document.querySelectorAll(".usa-accordion__button");
const isMobile = window.innerWidth < 768;


[prettier] reported by reviewdog 🐶

filterButtons.forEach((button) => {
const contentId = button.getAttribute("aria-controls");
const content = document.getElementById(contentId);
const icon = button.querySelector("svg use");


[prettier] reported by reviewdog 🐶

if(isMobile) {
button.setAttribute("aria-expanded", "false");
content.setAttribute("hidden", "true");
icon.setAttribute("href", `${baseurl}/assets/img/sprite.svg#expand_more`);
} else {
button.setAttribute("aria-expanded", "true");
content.removeAttribute("hidden");
icon.setAttribute("href", `${baseurl}/assets/img/sprite.svg#expand_less`);
}
});
}


[prettier] reported by reviewdog 🐶

updateFilterMenuState()
window.addEventListener("resize", updateFilterMenuState)


[prettier] reported by reviewdog 🐶

document.querySelectorAll(".usa-accordion__button").forEach((button) => {
button.addEventListener("click", () => {
const expanded = button.getAttribute("aria-expanded");
const content = document.getElementById(button.getAttribute("id"));
const icon = button.querySelector("svg use");
if(expanded === 'false') {
content.removeAttribute("hidden");
icon.setAttribute("href", `${baseurl}/assets/img/sprite.svg#expand_less`);
} else {
content.setAttribute("hidden", "true");
icon.setAttribute("href", `${baseurl}/assets/img/sprite.svg#expand_more`);
}
});
});
}


[prettier] reported by reviewdog 🐶

export function addGlobalEventListener(type, selector, callback, parent = document) {
parent.addEventListener(type, e => {


[prettier] reported by reviewdog 🐶

import { createProjectCards } from "./modules/rendering";
import { updateFilteredProjects } from "./modules/filters";
import { setupEventListeners } from './modules/events';
import { setupFilterMenuListeners } from "./modules/ui";


[prettier] reported by reviewdog 🐶

await createProjectCards();
updateFilteredProjects();
setupEventListeners();
}, 50);


[prettier] reported by reviewdog 🐶

setupFilterMenuListeners();
});

Comment thread app/src/js/modules/events.js
Comment thread app/src/js/modules/events.js
Comment thread app/src/js/modules/filters.js
Comment thread app/src/js/modules/filters.js
Comment thread app/src/js/modules/filters.js
Comment thread app/src/js/modules/rendering.js
Comment thread app/src/js/modules/rendering.js
Comment thread app/src/js/modules/rendering.js
Comment thread app/src/js/modules/rendering.js
Comment thread app/src/js/modules/rendering.js
Comment thread app/src/js/modules/data.js
Comment thread app/src/js/modules/filters.js
Comment thread app/src/js/modules/filters.js
Copy link
Copy Markdown
Contributor

@decause-gov decause-gov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should def get a proper review from @natalialuzuriaga on this when she's back at her desk, but FWIW, LGTM +1 🚢

Comment thread app/src/js/modules/utilities.js
Copy link
Copy Markdown
Collaborator

@natalialuzuriaga natalialuzuriaga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did testing using the filters, search, and sort! Question: One case I was experimenting with was doing a search and apply a filter on top of those results. Does the site support this at the moment?

But for the rest of the cases, all is working great on my end. Pagination works beautifully with updating based on project results. Amazing job with the refactor rewrite, this is so much easier to read and build on top of 🙌

Comment thread app/src/js/modules/filters.js
@DinneK DinneK merged commit 344dca4 into dev May 5, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request front-end javascript Pull requests that update Javascript code metrics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants