Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor projects page #294

Merged
merged 24 commits into from
Dec 6, 2024
Merged

Refactor projects page #294

merged 24 commits into from
Dec 6, 2024

Conversation

DinneK
Copy link
Contributor

@DinneK DinneK commented Dec 3, 2024

module-name: Refactor functionality projects.js

Problem:

Metrics project page needs pagination. Fixes on search functionality, filter functionality and sort.

Solution:

Refactor projects page to include pagination. Refactor search to work with pagination. Fix filter boxes. Sort is functional. All icons display. Contrast fixed in footer.

Result:

All functionality works as intended.

Test Plan:

Test in prod

Next steps:

  • Address page styling
  • Address header navigation
  • Ensure mobile view matched designs
  • Ensure all links work properly
  • Style pagination
  • Style graphs

Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
Signed-off-by: Dinne Kopelevich <[email protected]>
@DinneK DinneK added bug Something isn't working enhancement New feature or request front-end labels Dec 3, 2024
@DinneK DinneK self-assigned this Dec 3, 2024
Copy link
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 🐶

import { reportHeadingTemplate, projectCardTemplate } from "./templates";
import DOMPurify from 'dompurify';
const projectsData = document.getElementById('metrics').textContent;
const orgsData = document.getElementById('org-data').textContent;
const parsedOrgsData = JSON.parse(orgsData);
const siteData = JSON.parse(document.getElementById('site-data').textContent);
const parsedProjectsData = JSON.parse(projectsData);
const filtersContainer = document.querySelector('.filters-container');
const templateDiv = document.getElementById('content-container');


[prettier] reported by reviewdog 🐶

const sortDirection = document.getElementById('sort-direction');
const sortSelection = document.getElementById('sort-selection');
let currentPage = 1;
const itemsPerPage = 10;
let filteredProjects = [...parsedProjectsData];


[prettier] reported by reviewdog 🐶

sortSelection.addEventListener('change', () => {


[prettier] reported by reviewdog 🐶

document.getElementById("sort-direction-form").hidden = false;
sortCards();


[prettier] reported by reviewdog 🐶

sortDirection.addEventListener('change', () => {
const isDescending = sortDirection.value === 'descending' ? true : false;
sortCards(isDescending);


[prettier] reported by reviewdog 🐶

if(["maturity_model_tier", "stargazers_count", "forks_count"].includes(selection)) {
sortByNumberAttribute(targetProjects, selection, isDescending);
} else {
sortByStringAttribute(targetProjects, selection, isDescending);


[prettier] reported by reviewdog 🐶

const allProjects = (filteredProjects || parsedProjectsData).map((project) => ({
...project,
org: project.owner
}));
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const paginatedProjects = allProjects.slice(startIndex, endIndex);


[prettier] reported by reviewdog 🐶

if(!acc[curr.org]) {


[prettier] reported by reviewdog 🐶

acc[curr.org].push(curr);


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

const paginationDiv = document.getElementById('pagination-controls') || document.createElement('div');
paginationDiv.id = 'pagination-controls';
paginationDiv.innerHTML = '';


[prettier] reported by reviewdog 🐶

// const totalProjects = Object.values(projects).flat().length;
const totalPages = Math.ceil(totalProjectsCount / itemsPerPage);


[prettier] reported by reviewdog 🐶

const prevButton = document.createElement('button');
prevButton.textContent = 'Previous';
prevButton.disabled = currentPage === 1;
prevButton.addEventListener('click', () => {


[prettier] reported by reviewdog 🐶

currentPage--;
createProjectCards();


[prettier] reported by reviewdog 🐶

});
paginationDiv.appendChild(prevButton);


[prettier] reported by reviewdog 🐶

const pageButton = document.createElement('button');
pageButton.textContent = i;
pageButton.disabled = i === currentPage;
pageButton.addEventListener('click', () => {
currentPage = i;
createProjectCards();
});
paginationDiv.appendChild(pageButton);


[prettier] reported by reviewdog 🐶

const nextButton = document.createElement('button');
nextButton.textContent = 'Next';
nextButton.disabled = currentPage === totalPages;
nextButton.addEventListener('click', () => {


[prettier] reported by reviewdog 🐶

currentPage++;
createProjectCards(); // Re-render cards


[prettier] reported by reviewdog 🐶

});
paginationDiv.appendChild(nextButton);


[prettier] reported by reviewdog 🐶

templateDiv.parentElement.appendChild(paginationDiv);


[prettier] reported by reviewdog 🐶

addGlobalEventListener('change', '.usa-checkbox__input', e => {
// Can use this e.target.name to update selected filters object
updateFilters();
updateFilteredProjects()
}, filtersContainer)


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

projectType: []


[prettier] reported by reviewdog 🐶

document.querySelectorAll('input[name="org-filter"]:checked').forEach(checkbox => {
selectedFiltersObject.organization.push(checkbox.value);
});
document.querySelectorAll('input[name="tier-filter"]:checked').forEach(checkbox => {
selectedFiltersObject.maturityModelTier.push(checkbox.value);
});
document.querySelectorAll('input[name="fisma-level-filter"]:checked').forEach(checkbox => {
selectedFiltersObject.fismaLevel.push(checkbox.value);
});
document.querySelectorAll('input[name="project-type-filter"]:checked').forEach(checkbox => {
selectedFiltersObject.projectType.push(checkbox.value);
});
const allProjects = Object.keys(projects).flatMap((org) => projects[org].map((project) => ({...project, org})))


[prettier] reported by reviewdog 🐶

const matchesOrg = selectedFiltersObject.organization.length === 0 || selectedFiltersObject.organization.includes(project.org);
const matchesTier = selectedFiltersObject.maturityModelTier.length === 0 || selectedFiltersObject.maturityModelTier.includes("Tier" + project.maturityModelTier);
const matchesFisma = selectedFiltersObject.fismaLevel.length === 0 || selectedFiltersObject.fismaLevel.includes(project.fismaLevel);
const matchesType = selectedFiltersObject.projectType.length === 0 || selectedFiltersObject.projectType.includes(project.projectType);
return matchesOrg && matchesTier && matchesFisma && matchesType;
});
updatePagination(filteredProjects);


[prettier] reported by reviewdog 🐶

sortCards();


[prettier] reported by reviewdog 🐶

const totalProjects = (filteredProjects || parsedProjectsData).length;
const totalPages = Math.ceil(totalProjects / itemsPerPage);


[prettier] reported by reviewdog 🐶

currentPage = Math.min(currentPage, totalPages || 1);
renderPaginationControls(totalPages);


[prettier] reported by reviewdog 🐶

const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const paginatedProjects = projects.slice(startIndex, endIndex);


[prettier] reported by reviewdog 🐶

templateDiv.innerHTML = '';


[prettier] reported by reviewdog 🐶

if(!acc[curr.owner]) {


[prettier] reported by reviewdog 🐶

acc[curr.owner].push(curr);


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

const orgProject = findObject(parsedOrgsData, org);
const orgHeading = reportHeadingTemplate(orgProject);
const projectSectionsTemplate = document.createElement('div');
projectSectionsTemplate.className = 'project_section';
const reportHeading = document.createElement('div');
reportHeading.className = "report_heading";
reportHeading.innerHTML = DOMPurify.sanitize(orgHeading);
projectSectionsTemplate.appendChild(reportHeading);
const projectCards = document.createElement('ul');
projectCards.className = "usa-card-group flex-align-stretch";
groupedByOrg[org].forEach(repoData => {
const projectCard = document.createElement('li');
projectCard.className = 'usa-card project-card tablet:grid-col-12';
projectCard.id = repoData.name;
projectCard.setAttribute('org-name', repoData.owner);
projectCard.innerHTML = DOMPurify.sanitize(projectCardTemplate(repoData));
projectCards.appendChild(projectCard);
});
projectSectionsTemplate.appendChild(projectCards);
templateDiv.append(projectSectionsTemplate);


[prettier] reported by reviewdog 🐶

updateHeadingVisibility();


[prettier] reported by reviewdog 🐶

const searchForm = document.getElementById('search-form');
const searchBox = document.getElementById("search-input");


[prettier] reported by reviewdog 🐶

e.preventDefault();


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

const query = searchBox.value.toLowerCase();
filteredProjects = parsedProjectsData.filter((project) => project.name.toLowerCase().includes(query));


[prettier] reported by reviewdog 🐶

export const reportHeadingTemplate = function(data) {
return `


[prettier] reported by reviewdog 🐶

export function projectCardTemplate(data) {
const description = data.description !== null ? data.description : ""
return `


[prettier] reported by reviewdog 🐶

<a href="${ data.url }/${ data.owner }/${ data.name }/" class="href-home">


[prettier] reported by reviewdog 🐶

<h2 class="usa-card__heading">${ data.name }</h2>


[prettier] reported by reviewdog 🐶

<div>${ description }</div>


[prettier] reported by reviewdog 🐶

<span> ${ data.stargazers_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.forks_count } </span>


[prettier] reported by reviewdog 🐶

<svg class="usa-icon" aria-labelledby="issue-count-${ data.name }-title" role="img">


[prettier] reported by reviewdog 🐶

<span> ${ data.issues_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.pull_requests_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.watchers_count } </span>


[prettier] reported by reviewdog 🐶

app/src/css/style.css Show resolved Hide resolved
app/src/css/style.css Show resolved Hide resolved
app/src/css/style.css Show resolved Hide resolved
app/src/css/style.css Show resolved Hide resolved
app/src/css/style.css Show resolved Hide resolved
app/src/js/nav.js Show resolved Hide resolved
app/src/js/nav.js Show resolved Hide resolved
app/src/js/nav.js Show resolved Hide resolved
app/src/js/nav.js Show resolved Hide resolved
app/src/js/nav.js Show resolved Hide resolved
DinneK and others added 2 commits December 4, 2024 16:44
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
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 🐶

templateDiv.innerHTML = '';


[prettier] reported by reviewdog 🐶

if(!acc[curr.owner]) {


[prettier] reported by reviewdog 🐶

acc[curr.owner].push(curr);


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

const orgProject = findObject(parsedOrgsData, org);
const orgHeading = reportHeadingTemplate(orgProject);
const projectSectionsTemplate = document.createElement('div');
projectSectionsTemplate.className = 'project_section';
const reportHeading = document.createElement('div');
reportHeading.className = "report_heading";
reportHeading.innerHTML = DOMPurify.sanitize(orgHeading);
projectSectionsTemplate.appendChild(reportHeading);
const projectCards = document.createElement('ul');
projectCards.className = "usa-card-group flex-align-stretch";
groupedByOrg[org].forEach(repoData => {
const projectCard = document.createElement('li');
projectCard.className = 'usa-card project-card tablet:grid-col-12';
projectCard.id = repoData.name;
projectCard.setAttribute('org-name', repoData.owner);
projectCard.innerHTML = DOMPurify.sanitize(projectCardTemplate(repoData));
projectCards.appendChild(projectCard);
});
projectSectionsTemplate.appendChild(projectCards);
templateDiv.append(projectSectionsTemplate);


[prettier] reported by reviewdog 🐶

updateHeadingVisibility();


[prettier] reported by reviewdog 🐶

const searchForm = document.getElementById('search-form');
const searchBox = document.getElementById("search-input");


[prettier] reported by reviewdog 🐶

e.preventDefault();


[prettier] reported by reviewdog 🐶


[prettier] reported by reviewdog 🐶

const query = searchBox.value.toLowerCase();
filteredProjects = parsedProjectsData.filter((project) => project.name.toLowerCase().includes(query));


[prettier] reported by reviewdog 🐶

export const reportHeadingTemplate = function(data) {
return `


[prettier] reported by reviewdog 🐶

export function projectCardTemplate(data) {
const description = data.description !== null ? data.description : ""
return `


[prettier] reported by reviewdog 🐶

<a href="${ data.url }/${ data.owner }/${ data.name }/" class="href-home">


[prettier] reported by reviewdog 🐶

<h2 class="usa-card__heading">${ data.name }</h2>


[prettier] reported by reviewdog 🐶

<div>${ description }</div>


[prettier] reported by reviewdog 🐶

<span> ${ data.stargazers_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.forks_count } </span>


[prettier] reported by reviewdog 🐶

<svg class="usa-icon" aria-labelledby="issue-count-${ data.name }-title" role="img">


[prettier] reported by reviewdog 🐶

<span> ${ data.issues_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.pull_requests_count } </span>


[prettier] reported by reviewdog 🐶

<span> ${ data.watchers_count } </span>


[prettier] reported by reviewdog 🐶

app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
app/site/index.liquid Show resolved Hide resolved
app/site/index.liquid Show resolved Hide resolved
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
DinneK and others added 3 commits December 5, 2024 07:42
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
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.

Ran npm start and npm run prod and ran into two things:

  • In the footer, the color of the link when hovered is too light as noted here: Refactor home page #292 (comment)
  • When I click on the project card, it doesn't take me to the project report. Instead, it takes me to the repo on github.com

Otherwise, all the issues pointed out in the previous PRs regarding icons and the footer have been resolved! Pagination works great on my end, the logic of it plus incorporating filtering + sort with it makes sense to me!

app/site/_includes/project-card.liquid Show resolved Hide resolved
app/src/js/templates.js Outdated Show resolved Hide resolved
decause-gov
decause-gov previously approved these changes Dec 5, 2024
Copy link
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.

I will defer to Nat/Murt on this one, but LGTM +1 🚢

We'll sort out any issues on dev branch :)

Signed-off-by: Dinne Kopelevich <[email protected]>
Copy link
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.

To fix the project report bug, I think this should work, check out this comment here: #294 (comment)

app/src/js/templates.js Fixed Show fixed Hide fixed
Signed-off-by: Natalia Luzuriaga <[email protected]>
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/projects.js Show resolved Hide resolved
app/src/js/templates.js Show resolved Hide resolved
app/src/js/templates.js Show resolved Hide resolved
app/src/js/templates.js Show resolved Hide resolved
app/src/js/templates.js Show resolved Hide resolved
app/src/js/templates.js Show resolved Hide resolved
Copy link
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.

Fixed the project card url bug and all LGTM! 🙌

@DinneK DinneK merged commit 5d85a59 into dev Dec 6, 2024
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request front-end
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants