From 3492d25a794a4ca25441d8792cf0b5bd0281b215 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Fri, 24 Jul 2026 08:25:38 -0400 Subject: [PATCH 01/11] feat!: add filter layout component and enhance filter chips with card layout [#OCD-4930] --- src/app/components/filter/filter-chips.jsx | 222 ++++++++++-------- src/app/components/filter/filter-layout.jsx | 118 ++++++++++ .../components/filter/filter-search-bar.jsx | 12 +- src/app/components/filter/index.js | 2 + 4 files changed, 250 insertions(+), 104 deletions(-) create mode 100644 src/app/components/filter/filter-layout.jsx diff --git a/src/app/components/filter/filter-chips.jsx b/src/app/components/filter/filter-chips.jsx index e820acd2d4..ca16927955 100755 --- a/src/app/components/filter/filter-chips.jsx +++ b/src/app/components/filter/filter-chips.jsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react'; import { Button, + Card, + CardContent, Chip, FormControlLabel, Switch, @@ -13,48 +15,48 @@ import { useFilterContext } from './filter-context'; import { ChplTooltip } from 'components/util'; import { eventTrack } from 'services/analytics.service'; import { getStatusIcon } from 'services/listing.service'; -import theme from 'themes/theme'; import { palette } from 'themes'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles({ filterContainer: { display: 'flex', - padding: '16px 32px', - marginTop: '-4px', - position: 'relative', - zIndex: 1, - backgroundColor: palette.white, - borderBottom: `1px solid ${palette.greyBorder}`, - flexWrap: 'wrap', - flexFlow: 'column', + flexDirection: 'column', alignItems: 'flex-start', - [theme.breakpoints.up('sm')]: { - flexWrap: 'wrap', - }, + gap: '16px', + width: '100%', }, filterSelectedContainer: { display: 'flex', + flexDirection: 'column', gap: '4px', - alignItems: 'center', + alignItems: 'flex-start', justifyContent: 'flex-start', - flexWrap: 'wrap', + width: '100%', }, filterChipsContainer: { display: 'flex', - gap: '8px', + gap: '16px', alignContent: 'flex-start', - flexWrap: 'wrap', - flexDirection: 'row', - alignItems: 'center', + flexDirection: 'column', + alignItems: 'flex-start', + width: '100%', }, chip: { border: `1px solid ${palette.primary}`, backgroundColor: palette.white, + maxWidth: '100%', }, - chipAvatar: { - backgroundColor: 'transparent !important', + chipDeleteIcon: { + order: -2, + marginLeft: '5px', + marginRight: '-4px', }, -})); + chipLabel: { + alignItems: 'center', + display: 'inline-flex', + gap: '4px', + }, +}); const truncate = (str, n, useWordBoundary) => { if (str.length <= n) { return str; } @@ -127,91 +129,105 @@ function ChplFilterChips() { filterContext.dispatch('toggleShowAll', f); }; + if (filters.length === 0) { return null; } + + const getChipLabel = (f, labelText, iconName) => { + if (f.key !== 'certificationStatuses') { return labelText; } + return ( + + { labelText } + { getStatusIcon({ name: iconName }) } + + ); + }; + return ( - Filters Applied: -
- { filters.map((f) => ( - - - - {f.getFilterDisplay(f)} - - - { f.operatorKey - && ( - toggleOperator(f)} - /> - )} - label={f.operator === 'and' ? 'All' : 'Any'} - /> - )} - { f.developersListingsCriteriaOptionKey - && ( - toggleDevelopersListingsCriteriaOption(f)} - /> - )} - label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'} - /> - )} - {f.values - .filter((v, idx) => f.showAll || idx < DISPLAY_MAX) - .map((v) => ( - - { f.getValueDisplay(v).length > maxLengthForChip - ? ( - - removeChip(f, v)} - variant="outlined" - disabled={f.required && f.values.length === 1} - classes={{ avatar: classes.chipAvatar, root: classes.chip }} - /> - - ) : ( - removeChip(f, v)} - variant="outlined" - disabled={f.required && f.values.length === 1} - classes={{ avatar: classes.chipAvatar, root: classes.chip }} + + + Filters Applied: +
+ { filters.map((f) => ( + + + + {f.getFilterDisplay(f)} + + + { f.operatorKey + && ( + toggleOperator(f)} + /> + )} + label={f.operator === 'and' ? 'All' : 'Any'} + /> + )} + { f.developersListingsCriteriaOptionKey + && ( + toggleDevelopersListingsCriteriaOption(f)} /> )} - - ))} - { f.values.length > DISPLAY_MAX - && ( - - )} - - ))} -
+ label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'} + /> + )} + {f.values + .filter((v, idx) => f.showAll || idx < DISPLAY_MAX) + .map((v) => ( + + { f.getValueDisplay(v).length > maxLengthForChip + ? ( + + removeChip(f, v)} + variant="outlined" + disabled={f.required && f.values.length === 1} + classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }} + /> + + ) : ( + removeChip(f, v)} + variant="outlined" + disabled={f.required && f.values.length === 1} + classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }} + /> + )} + + ))} + { f.values.length > DISPLAY_MAX + && ( + + )} +
+ ))} +
+ +
); } diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx new file mode 100644 index 0000000000..f375e32195 --- /dev/null +++ b/src/app/components/filter/filter-layout.jsx @@ -0,0 +1,118 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + Button, + Collapse, + makeStyles, + useMediaQuery, +} from '@material-ui/core'; +import FilterListIcon from '@material-ui/icons/FilterList'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import ExpandLessIcon from '@material-ui/icons/ExpandLess'; +import { node } from 'prop-types'; + +import ChplFilterChips from './filter-chips'; +import { useFilterContext } from './filter-context'; + +import { palette, theme } from 'themes'; + +const useStyles = makeStyles({ + layoutContainer: { + display: 'grid', + gridTemplateColumns: '1fr', + gap: '16px', + alignItems: 'start', + margin: '16px 0px', + [theme.breakpoints.up('md')]: { + gridTemplateColumns: '260px 1fr', + gap: '24px', + }, + }, + sidebar: { + display: 'flex', + flexDirection: 'column', + gap: '8px', + [theme.breakpoints.up('md')]: { + position: 'sticky', + top: '16px', + borderRight: `1px solid ${palette.greyBorder}`, + }, + }, + sidebarToggle: { + justifyContent: 'space-between', + color: palette.black, + [theme.breakpoints.up('md')]: { + display: 'none', + }, + }, + sidebarToggleLabel: { + display: 'flex', + alignItems: 'center', + gap: '8px', + }, + content: { + minWidth: 0, + }, +}); + +function ChplFilterLayout({ children }) { + const classes = useStyles(); + const filterContext = useFilterContext(); + const isDesktop = useMediaQuery(theme.breakpoints.up('md')); + const [expanded, setExpanded] = useState(false); + + const hasAppliedFilters = filterContext.filters + .some((filter) => filter.values?.some((v) => v.selected)); + + useEffect(() => { + if (isDesktop) { setExpanded(false); } + }, [isDesktop]); + + if (!hasAppliedFilters) { + return ( +
+ {children} +
+ ); + } + + return ( +
+ + + {isDesktop + ? + : ( + + + + )} + +
+ {children} +
+
+ ); +} + +export default ChplFilterLayout; + +ChplFilterLayout.propTypes = { + children: node, +}; + +ChplFilterLayout.defaultProps = { + children: undefined, +}; diff --git a/src/app/components/filter/filter-search-bar.jsx b/src/app/components/filter/filter-search-bar.jsx index e0dde54a00..6ee5858edb 100755 --- a/src/app/components/filter/filter-search-bar.jsx +++ b/src/app/components/filter/filter-search-bar.jsx @@ -48,19 +48,28 @@ const useStyles = makeStyles({ }, }, }, + sticky: { + position: 'sticky', + top: 0, + zIndex: 2, + }, }); function ChplFilterSearchBar({ hideAdvancedSearch = false, hideSearchTerm = false, placeholder = 'Search by Developer, Product, or CHPL ID...', + sticky = false, toggleMultipleFilters = undefined, }) { const { filters } = useFilterContext(); const classes = useStyles(); return ( -
+
{ !hideSearchTerm && ( Date: Fri, 24 Jul 2026 08:35:28 -0400 Subject: [PATCH 02/11] feat: replace ChplFilterChips with ChplFilterLayout in various views for improved layout consistency [#OCD-4930] --- .../change-request/change-requests-view.jsx | 9 +- src/app/components/products/products-view.jsx | 39 ++-- .../complaints/complaints-view.jsx | 11 +- .../certification-criteria-view.jsx | 131 +++++++------ .../functionalities-tested-view.jsx | 177 +++++++++--------- .../system-maintenance/g1g2/g1g2-view.jsx | 123 ++++++------ .../optional-standards-view.jsx | 101 +++++----- .../standard/standards-view.jsx | 173 +++++++++-------- .../system-maintenance/svap/svaps-view.jsx | 117 ++++++------ .../test-tool/test-tools-view.jsx | 107 ++++++----- 10 files changed, 490 insertions(+), 498 deletions(-) diff --git a/src/app/components/change-request/change-requests-view.jsx b/src/app/components/change-request/change-requests-view.jsx index e39d882102..c1eaa95993 100755 --- a/src/app/components/change-request/change-requests-view.jsx +++ b/src/app/components/change-request/change-requests-view.jsx @@ -28,7 +28,7 @@ import ChplChangeRequestsDownload from './change-requests-download'; import { useFetchChangeRequests } from 'api/change-requests'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -194,14 +194,14 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed placeholder="Search by Developer..." hideSearchTerm={disallowedFilters.includes('searchTerm')} /> - - { isLoading + + { isLoading && (
)} - { !isLoading + { !isLoading && ( <> { isError @@ -349,6 +349,7 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed )} )} +
); diff --git a/src/app/components/products/products-view.jsx b/src/app/components/products/products-view.jsx index ae8f39489a..0c37759d08 100755 --- a/src/app/components/products/products-view.jsx +++ b/src/app/components/products/products-view.jsx @@ -11,7 +11,7 @@ import { arrayOf, func } from 'prop-types'; import ChplProductView from './product-view'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -125,19 +125,17 @@ function ChplProductsView({ products = [], dispatch }) { -
- -
-
-
- Search Results: - { displayedProducts.length === 0 + +
+
+ Search Results: + { displayedProducts.length === 0 && ( <> No results found )} - { displayedProducts.length > 0 + { displayedProducts.length > 0 && ( { displayedProducts.length } @@ -146,18 +144,19 @@ function ChplProductsView({ products = [], dispatch }) { { displayedProducts.length === 1 ? '' : 's' } )} +
-
- { displayedProducts - .sort((a, b) => sortProducts(a, b)) - .map((product) => ( - - ))} + { displayedProducts + .sort((a, b) => sortProducts(a, b)) + .map((product) => ( + + ))} + ); diff --git a/src/app/components/surveillance/complaints/complaints-view.jsx b/src/app/components/surveillance/complaints/complaints-view.jsx index fbab7970f4..78d695b483 100755 --- a/src/app/components/surveillance/complaints/complaints-view.jsx +++ b/src/app/components/surveillance/complaints/complaints-view.jsx @@ -25,7 +25,7 @@ import ChplComplaint from './complaint'; import { useFetchComplaints, usePostReportRequest } from 'api/complaints'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -281,14 +281,12 @@ function ChplComplaintsView(props) { -
- -
- { isLoading + + { isLoading && ( )} - { !isLoading + { !isLoading && ( <>
@@ -375,6 +373,7 @@ function ChplComplaintsView(props) { )} )} + ); diff --git a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx index d0ed75d682..c4268c8893 100755 --- a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx +++ b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx @@ -7,7 +7,7 @@ import { import { arrayOf } from 'prop-types'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -97,73 +97,72 @@ function ChplCertificationCriteriaView({ certificationCriteria: initialCertifica -
- -
- - - - Search Results - - - {`(${certificationCriteria.length} Result${certificationCriteria.length !== 1 ? 's' : ''})`} - + + + + + Search Results + + + {`(${certificationCriteria.length} Result${certificationCriteria.length !== 1 ? 's' : ''})`} + + + + + - - + + {certificationCriteria + .map((item) => ( + + ) : 'N/A', + }, + { + label: 'Attributes', + value: item.displayAttributes.length > 0 ? item.displayAttributes : 'N/A', + }, + ], + ]} + /> + ))} - - - {certificationCriteria - .map((item) => ( - - ) : 'N/A', - }, - { - label: 'Attributes', - value: item.displayAttributes.length > 0 ? item.displayAttributes : 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx index 1e9e2b5d75..9f778780f7 100755 --- a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx +++ b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchFunctionalitiesTestedActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -80,30 +80,28 @@ function ChplFunctionalitiesTestedView({ dispatch, functionalitiesTested: initia -
- -
- - - - Search Results - - - {`(${functionalitiesTested.length} Result${functionalitiesTested.length !== 1 ? 's' : ''})`} - - - - - - {hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + + Search Results + + + {`(${functionalitiesTested.length} Result${functionalitiesTested.length !== 1 ? 's' : ''})`} + + + + + + {hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - {functionalitiesTested - .map((item) => ( - + + {functionalitiesTested + .map((item) => ( + )} - fieldGroups={[ - [ - { - label: 'Regulatory Text Citation', - value: item.regulatoryTextCitation || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Rule', - value: item.rule?.name || 'N/A', - }, - { - label: 'Practice Type', - value: item.practiceType?.name || 'N/A', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay) || 'N/A', - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay) || 'N/A', - }, - { - label: 'Required Date', - value: getDisplayDateFormat(item.requiredDay) || 'N/A', - }, - { - label: 'Extension End Date', - value: getDisplayDateFormat(item.extensionEndDay) || 'N/A', - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Regulatory Text Citation', + value: item.regulatoryTextCitation || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Rule', + value: item.rule?.name || 'N/A', + }, + { + label: 'Practice Type', + value: item.practiceType?.name || 'N/A', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay) || 'N/A', + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay) || 'N/A', + }, + { + label: 'Required Date', + value: getDisplayDateFormat(item.requiredDay) || 'N/A', + }, + { + label: 'Extension End Date', + value: getDisplayDateFormat(item.extensionEndDay) || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx index f729b86e0f..355994f0a7 100755 --- a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx +++ b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx @@ -11,7 +11,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -67,69 +67,68 @@ function ChplG1g2View({ g1g2: initialG1g2 }) { -
- -
- - - Search Results - - {`(${g1g2.length} Result${g1g2.length !== 1 ? 's' : ''})`} - + + + + Search Results + + {`(${g1g2.length} Result${g1g2.length !== 1 ? 's' : ''})`} + + + + + - - + + { g1g2 + .map((item) => ( + + + + + + ), + }, + { + label: 'Domain', + value: item.domainDisplay || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Required Test', + value: `${item.removed ? 'Removed | ' : ''}${item.requiredTest || 'N/A'}`, + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + /> + ))} - - - { g1g2 - .map((item) => ( - - - - - - ), - }, - { - label: 'Domain', - value: item.domainDisplay || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Required Test', - value: `${item.removed ? 'Removed | ' : ''}${item.requiredTest || 'N/A'}`, - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx b/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx index f43c51eb4d..2147449629 100755 --- a/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx +++ b/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx @@ -11,7 +11,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -63,58 +63,57 @@ function ChplOptionalStandardsView({ optionalStandards: initialOptionalStandards -
- -
- - - Search Results - - {`(${optionalStandards.length} Result${optionalStandards.length !== 1 ? 's' : ''})`} - + + + + Search Results + + {`(${optionalStandards.length} Result${optionalStandards.length !== 1 ? 's' : ''})`} + + + + + - - + + { optionalStandards + .map((item) => ( + + + + + + ), + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + /> + ))} - - - { optionalStandards - .map((item) => ( - - - - - - ), - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/standard/standards-view.jsx b/src/app/components/system-maintenance/standard/standards-view.jsx index af99a95016..008ada9ac3 100755 --- a/src/app/components/system-maintenance/standard/standards-view.jsx +++ b/src/app/components/system-maintenance/standard/standards-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchStandardsActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -87,28 +87,26 @@ function ChplStandardsView({ dispatch, standards: initialStandards }) { -
- -
- - - Search Results - - {`(${standards.length} Result${standards.length !== 1 ? 's' : ''})`} - - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + Search Results + + {`(${standards.length} Result${standards.length !== 1 ? 's' : ''})`} + + + + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - { standards - .map((item) => ( - + + { standards + .map((item) => ( + )} - fieldGroups={[ - [ - { - label: 'Regulatory Text Citation', - value: item.regulatoryTextCitation || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Rule', - value: item.rule?.name ?? 'N/A', - }, - { - label: 'Group', - value: item.groupName ?? 'N/A', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay), - }, - { - label: 'Required Date', - value: getDisplayDateFormat(item.requiredDay), - }, - { - label: 'Extension End Date', - value: getDisplayDateFormat(item.extensionEndDay), - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay), - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Regulatory Text Citation', + value: item.regulatoryTextCitation || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Rule', + value: item.rule?.name ?? 'N/A', + }, + { + label: 'Group', + value: item.groupName ?? 'N/A', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay), + }, + { + label: 'Required Date', + value: getDisplayDateFormat(item.requiredDay), + }, + { + label: 'Extension End Date', + value: getDisplayDateFormat(item.extensionEndDay), + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay), + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/svap/svaps-view.jsx b/src/app/components/system-maintenance/svap/svaps-view.jsx index b6059eb792..df22de09e2 100755 --- a/src/app/components/system-maintenance/svap/svaps-view.jsx +++ b/src/app/components/system-maintenance/svap/svaps-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchSvapsActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -76,28 +76,26 @@ function ChplSvapsView({ dispatch, svaps: initialSvaps }) { -
- -
- - - Search Results - - {`(${svaps.length} Result${svaps.length !== 1 ? 's' : ''})`} - - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + Search Results + + {`(${svaps.length} Result${svaps.length !== 1 ? 's' : ''})`} + + + + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - { svaps - .map((item) => ( - - - - - - ), - }, + + { svaps + .map((item) => ( + + + + + + ), + }, - { - label: 'Replaced', - value: item.replaced ? 'Yes' : 'No', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - actions={ + { + label: 'Replaced', + value: item.replaced ? 'Yes' : 'No', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/test-tool/test-tools-view.jsx b/src/app/components/system-maintenance/test-tool/test-tools-view.jsx index 1e7b361f0c..2e1876cfe7 100755 --- a/src/app/components/system-maintenance/test-tool/test-tools-view.jsx +++ b/src/app/components/system-maintenance/test-tool/test-tools-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -70,24 +70,22 @@ function ChplTestToolsView({ dispatch, testTools: initialTestTools }) { -
- -
- - - Search Results - - {`(${testTools.length} Result${testTools.length !== 1 ? 's' : ''})`} - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + Search Results + + {`(${testTools.length} Result${testTools.length !== 1 ? 's' : ''})`} + + + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - { testTools - .map((item) => ( - - - - - + + { testTools + .map((item) => ( + + + + + )} - fieldGroups={[ - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay), - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay), - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay), + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay), + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } From 7804e820e1c55d230d3521001c82ab142b39d4a0 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Mon, 27 Jul 2026 10:45:50 -0400 Subject: [PATCH 03/11] feat: enhance filter components with improved layout and sticky behavior [#OCD-4930] --- src/app/components/filter/filter-chips.jsx | 7 ++- src/app/components/filter/filter-layout.jsx | 3 +- .../components/filter/filter-search-bar.jsx | 47 +++++++++++++++++-- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/app/components/filter/filter-chips.jsx b/src/app/components/filter/filter-chips.jsx index ca16927955..5a6081d6e1 100755 --- a/src/app/components/filter/filter-chips.jsx +++ b/src/app/components/filter/filter-chips.jsx @@ -56,6 +56,11 @@ const useStyles = makeStyles({ display: 'inline-flex', gap: '4px', }, + card: { + width: '100%', + maxHeight: '50vh', + overflowY: 'auto', + }, }); const truncate = (str, n, useWordBoundary) => { @@ -143,7 +148,7 @@ function ChplFilterChips() { return ( - + Filters Applied:
diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx index f375e32195..af6bfa9d54 100644 --- a/src/app/components/filter/filter-layout.jsx +++ b/src/app/components/filter/filter-layout.jsx @@ -34,8 +34,7 @@ const useStyles = makeStyles({ gap: '8px', [theme.breakpoints.up('md')]: { position: 'sticky', - top: '16px', - borderRight: `1px solid ${palette.greyBorder}`, + top: '190px', }, }, sidebarToggle: { diff --git a/src/app/components/filter/filter-search-bar.jsx b/src/app/components/filter/filter-search-bar.jsx index 6ee5858edb..af8e904f4e 100755 --- a/src/app/components/filter/filter-search-bar.jsx +++ b/src/app/components/filter/filter-search-bar.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Box, makeStyles, @@ -50,8 +50,20 @@ const useStyles = makeStyles({ }, sticky: { position: 'sticky', - top: 0, - zIndex: 2, + top: '100px', + zIndex: 3, + }, + stuck: { + '&::before': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: '100%', + height: '100px', + background: `linear-gradient(to top, ${palette.backgroundPage} 55%, transparent)`, + pointerEvents: 'none', + }, }, }); @@ -64,10 +76,24 @@ function ChplFilterSearchBar({ }) { const { filters } = useFilterContext(); const classes = useStyles(); + const sentinelRef = useRef(null); + const [isStuck, setIsStuck] = useState(false); - return ( + useEffect(() => { + if (!sticky) { return undefined; } + const sentinel = sentinelRef.current; + if (!sentinel) { return undefined; } + const observer = new IntersectionObserver( + ([entry]) => setIsStuck(!entry.isIntersecting), + { rootMargin: '-100px 0px 0px 0px', threshold: 0 }, + ); + observer.observe(sentinel); + return () => observer.disconnect(); + }, [sticky]); + + const searchBar = (
{ !hideSearchTerm @@ -91,6 +117,17 @@ function ChplFilterSearchBar({
); + + if (!sticky) { + return searchBar; + } + + return ( + <> +
+ {searchBar} + + ); } export default ChplFilterSearchBar; From ad8dc92bf5ebb0f46e6f5bb4ca980d4009dfc8d2 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Mon, 27 Jul 2026 10:46:54 -0400 Subject: [PATCH 04/11] refactor: simplify ChplPagination component by removing unused styles and position change [#OCD-4930] --- src/app/components/util/pagination.jsx | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/app/components/util/pagination.jsx b/src/app/components/util/pagination.jsx index f4208c4742..49694a9071 100755 --- a/src/app/components/util/pagination.jsx +++ b/src/app/components/util/pagination.jsx @@ -1,43 +1,23 @@ import React from 'react'; -import { - TablePagination, - makeStyles, -} from '@material-ui/core'; +import { TablePagination } from '@material-ui/core'; import { arrayOf, - bool, func, number, } from 'prop-types'; import { eventTrack } from 'services/analytics.service'; import { useAnalyticsContext } from 'shared/contexts'; -import { palette, theme } from 'themes'; - -const useStyles = makeStyles({ - pagination: { - position: 'relative', - [theme.breakpoints.up('lg')]: { - position: 'sticky', - bottom: '64px', - width: 'fit-content', - marginLeft: 'auto', - marginRight: 'auto', - }, - }, -}); function ChplPagination({ count, page, rowsPerPage, rowsPerPageOptions, - sticky = true, setPage, setRowsPerPage, }) { const { analytics } = useAnalyticsContext(); - const classes = useStyles(); const handlePageChange = (event, newPage) => { if (analytics) { @@ -65,7 +45,6 @@ function ChplPagination({ return ( Date: Mon, 27 Jul 2026 10:49:00 -0400 Subject: [PATCH 05/11] feat: enhance ChplSearchResultControls with sticky positioning and gradient background [#OCD-4930] --- .../components/util/chpl-search-result-controls.jsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/app/components/util/chpl-search-result-controls.jsx b/src/app/components/util/chpl-search-result-controls.jsx index 556ad87d8b..4f06bd8c7b 100644 --- a/src/app/components/util/chpl-search-result-controls.jsx +++ b/src/app/components/util/chpl-search-result-controls.jsx @@ -14,6 +14,9 @@ const useStyles = makeStyles({ flexDirection: 'column', gap: '4px', marginBottom: '16px', + position: 'sticky', + top: '190px', + zIndex: 2, alignItems: 'flex-start', justifyContent: 'space-between', flexWrap: 'wrap', @@ -22,6 +25,16 @@ const useStyles = makeStyles({ borderRadius: '0px 0px 8px 8px', borderTop: `1px solid ${palette.greyBorder}`, boxShadow: `0px 2px 4px -1px ${theme.palette.grey[300]}, 0px 4px 5px 0px ${theme.palette.grey[300]}, 0px 1px 10px 0px ${theme.palette.grey[300]}`, + '&::before': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: '100%', + height: '90px', + background: `linear-gradient(to top, ${palette.backgroundPage} 40%, transparent)`, + pointerEvents: 'none', + }, [theme.breakpoints.down('sm')]: { gap: '12px', padding: '16px', From 2cf08c629c15d49bde935a6d83048837965b3179 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Mon, 27 Jul 2026 13:39:45 -0400 Subject: [PATCH 06/11] feat: replace ChplFilterChips with ChplFilterLayout for improved layout consistency across search views [#OCD-4930] --- .../api-documentation-view.jsx | 16 +++++++++++----- .../banned-developers-view.jsx | 13 ++++++++----- .../corrective-action-view.jsx | 17 ++++++++++++----- .../decertified-products-view.jsx | 13 ++++++++----- .../decision-support-interventions-view.jsx | 13 ++++++++----- .../inactive-certificates-view.jsx | 13 ++++++++----- src/app/pages/search/listings/listings-view.jsx | 13 ++++++++----- .../real-world-testing-view.jsx | 15 ++++++++++----- src/app/pages/search/sed/sed-view.jsx | 13 ++++++++----- src/app/pages/search/svap/svap-view.jsx | 15 ++++++++++----- 10 files changed, 91 insertions(+), 50 deletions(-) diff --git a/src/app/pages/search/api-documentation/api-documentation-view.jsx b/src/app/pages/search/api-documentation/api-documentation-view.jsx index 4f8d76829a..b53a76a340 100755 --- a/src/app/pages/search/api-documentation/api-documentation-view.jsx +++ b/src/app/pages/search/api-documentation/api-documentation-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -170,10 +170,10 @@ function ChplApiDocumentationSearchView({ displayCriteria }) { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> @@ -282,6 +286,7 @@ function ChplApiDocumentationSearchView({ displayCriteria }) { }, { label: 'Mandatory Disclosures URL', + style: { fontSize: '0.85em' }, value: item.mandatoryDisclosures ? ( )} + ); diff --git a/src/app/pages/search/banned-developers/banned-developers-view.jsx b/src/app/pages/search/banned-developers/banned-developers-view.jsx index a1401db6e7..32f5dc6ad4 100755 --- a/src/app/pages/search/banned-developers/banned-developers-view.jsx +++ b/src/app/pages/search/banned-developers/banned-developers-view.jsx @@ -18,7 +18,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -122,17 +122,18 @@ function ChplBannedDevelopersSearchView() { inline /> . - + )} /> - - {isLoading && ()} - {!isLoading + + {isLoading && ()} + {!isLoading && ( <> )} + ); diff --git a/src/app/pages/search/corrective-action/corrective-action-view.jsx b/src/app/pages/search/corrective-action/corrective-action-view.jsx index 34e350bf10..bdbb93792e 100755 --- a/src/app/pages/search/corrective-action/corrective-action-view.jsx +++ b/src/app/pages/search/corrective-action/corrective-action-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -139,10 +139,10 @@ function ChplCorrectiveActionSearchView() { { directReviewsAvailable && ( <> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + )} diff --git a/src/app/pages/search/decertified-products/decertified-products-view.jsx b/src/app/pages/search/decertified-products/decertified-products-view.jsx index 1774622761..ff209550d3 100755 --- a/src/app/pages/search/decertified-products/decertified-products-view.jsx +++ b/src/app/pages/search/decertified-products/decertified-products-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -124,10 +124,10 @@ function ChplDecertifiedProductsSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx b/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx index 531b2bae64..6fd1bf91b2 100644 --- a/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx +++ b/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -110,10 +110,10 @@ function ChplDecisionSupportInterventionsSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx b/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx index 4084783299..b94d0774b5 100755 --- a/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx +++ b/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -127,10 +127,10 @@ function ChplInactiveCertificatesSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/listings/listings-view.jsx b/src/app/pages/search/listings/listings-view.jsx index 91bf06107f..9a308ee5d3 100755 --- a/src/app/pages/search/listings/listings-view.jsx +++ b/src/app/pages/search/listings/listings-view.jsx @@ -24,7 +24,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -138,10 +138,10 @@ function ChplListingsView() { subtitle="Please note that only active and suspended listings are shown by default. Use the Certification Status filter to display retired, withdrawn, or terminated listings." /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/real-world-testing/real-world-testing-view.jsx b/src/app/pages/search/real-world-testing/real-world-testing-view.jsx index 4cd01b33c6..265d79c329 100755 --- a/src/app/pages/search/real-world-testing/real-world-testing-view.jsx +++ b/src/app/pages/search/real-world-testing/real-world-testing-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -155,10 +155,10 @@ function ChplRealWorldTestingSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/sed/sed-view.jsx b/src/app/pages/search/sed/sed-view.jsx index b5b35de25b..2c7dea9d81 100755 --- a/src/app/pages/search/sed/sed-view.jsx +++ b/src/app/pages/search/sed/sed-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -124,10 +124,10 @@ function ChplSedSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/svap/svap-view.jsx b/src/app/pages/search/svap/svap-view.jsx index b045185163..d67817d656 100755 --- a/src/app/pages/search/svap/svap-view.jsx +++ b/src/app/pages/search/svap/svap-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -232,10 +232,10 @@ function ChplSvapSearchView() { )} /> - - - {isLoading && ()} - {!isLoading + + + {isLoading && ()} + {!isLoading && ( <> )} + ); From e8f098e12adf91ba7edc584532e2ecccedccf45c Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Mon, 27 Jul 2026 15:39:07 -0400 Subject: [PATCH 07/11] feat: enhance search result controls and filter components with customizable background and improved layout [#OCD-4930] --- .../components/filter/filter-search-bar.jsx | 6 +- .../certification-criteria-view.jsx | 51 +++++++-------- .../certification-criteria.jsx | 4 +- .../functionalities-tested-view.jsx | 62 +++++++++---------- .../functionalities-tested.jsx | 4 +- .../system-maintenance/g1g2/g1g2-view.jsx | 49 +++++++-------- .../system-maintenance/g1g2/g1g2.jsx | 4 +- .../standard/standards-view.jsx | 59 +++++++----------- .../system-maintenance/standard/standards.jsx | 4 +- .../util/chpl-search-result-controls.jsx | 8 ++- 10 files changed, 115 insertions(+), 136 deletions(-) diff --git a/src/app/components/filter/filter-search-bar.jsx b/src/app/components/filter/filter-search-bar.jsx index af8e904f4e..2ed25e5431 100755 --- a/src/app/components/filter/filter-search-bar.jsx +++ b/src/app/components/filter/filter-search-bar.jsx @@ -61,13 +61,14 @@ const useStyles = makeStyles({ right: 0, bottom: '100%', height: '100px', - background: `linear-gradient(to top, ${palette.backgroundPage} 55%, transparent)`, + background: ({ fadeBackground }) => `linear-gradient(to top, ${fadeBackground} 55%, transparent)`, pointerEvents: 'none', }, }, }); function ChplFilterSearchBar({ + fadeBackground = palette.backgroundPage, hideAdvancedSearch = false, hideSearchTerm = false, placeholder = 'Search by Developer, Product, or CHPL ID...', @@ -75,7 +76,7 @@ function ChplFilterSearchBar({ toggleMultipleFilters = undefined, }) { const { filters } = useFilterContext(); - const classes = useStyles(); + const classes = useStyles({ fadeBackground }); const sentinelRef = useRef(null); const [isStuck, setIsStuck] = useState(false); @@ -133,6 +134,7 @@ function ChplFilterSearchBar({ export default ChplFilterSearchBar; ChplFilterSearchBar.propTypes = { + fadeBackground: string, hideAdvancedSearch: bool, hideSearchTerm: bool, placeholder: string, diff --git a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx index c4268c8893..d629acbaaa 100755 --- a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx +++ b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx @@ -1,8 +1,6 @@ import React, { useEffect, useState } from 'react'; import { Box, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf } from 'prop-types'; @@ -11,11 +9,16 @@ import { ChplFilterSearchBar, useFilterContext, } from 'components/filter'; -import { ChplLink, ChplSearchResultCard, ChplSortControls } from 'components/util'; +import { + ChplLink, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, +} from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { getDisplayDateFormat } from 'services/date-util'; import { criterion as criterionPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'number', text: 'Number' }, @@ -24,10 +27,6 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - const getDisplay = (key) => { switch (key) { case 'additionalSoftware': return 'Additional Software'; @@ -63,7 +62,6 @@ function ChplCertificationCriteriaView({ certificationCriteria: initialCertifica const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('number'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setCertificationCriteria(initialCertificationCriteria @@ -96,27 +94,24 @@ function ChplCertificationCriteriaView({ certificationCriteria: initialCertifica <> - - - - Search Results - - - {`(${certificationCriteria.length} Result${certificationCriteria.length !== 1 ? 's' : ''})`} - - - - - - - + 0 ? 1 : 0} + pageEnd={certificationCriteria.length} + fadeBackground={palette.white} + > + + + {certificationCriteria .map((item) => ( - + )} /> - + diff --git a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx index 9f778780f7..d41596fbe8 100755 --- a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx +++ b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx @@ -3,8 +3,6 @@ import { Box, Button, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, func } from 'prop-types'; import AddIcon from '@material-ui/icons/Add'; @@ -19,14 +17,18 @@ import { useFilterContext, } from 'components/filter'; import { - ChplSearchResultCard, ChplSortControls, ChplTooltip, ChplUpdateIndicator, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, + ChplTooltip, + ChplUpdateIndicator, } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { sortCriteria } from 'services/criteria.service'; import { getDisplayDateFormat } from 'services/date-util'; import { UserContext } from 'shared/contexts'; import { functionalityTested as functionalityTestedPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'value', text: 'Value' }, @@ -37,17 +39,12 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - function ChplFunctionalitiesTestedView({ dispatch, functionalitiesTested: initialFunctionalitiesTested }) { const { hasAnyRole } = useContext(UserContext); const [functionalitiesTested, setFunctionalitiesTested] = useState([]); const [order, setOrder] = useState('desc'); const [orderBy, setOrderBy] = useState('value'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setFunctionalitiesTested(initialFunctionalitiesTested @@ -79,29 +76,27 @@ function ChplFunctionalitiesTestedView({ dispatch, functionalitiesTested: initia <> - - - - Search Results - - - {`(${functionalitiesTested.length} Result${functionalitiesTested.length !== 1 ? 's' : ''})`} - - - - - - {hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + 0 ? 1 : 0} + pageEnd={functionalitiesTested.length} + fadeBackground={palette.white} + > + + + {hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} - - - + )} + + {functionalitiesTested .map((item) => ( - + )} /> - + { (deleteFunctionalityTested.isLoading || postFunctionalityTested.isLoading || putFunctionalityTested.isLoading) && ( diff --git a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx index 355994f0a7..b3ff833032 100755 --- a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx +++ b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx @@ -2,13 +2,16 @@ import React, { useEffect, useState } from 'react'; import { Box, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, shape, string } from 'prop-types'; import InfoIcon from '@material-ui/icons/Info'; -import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; +import { + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, + ChplTooltip, +} from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { ChplFilterLayout, @@ -16,7 +19,7 @@ import { useFilterContext, } from 'components/filter'; import { sortCriteria } from 'services/criteria.service'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'abbreviation', text: 'Abbreviation' }, @@ -24,16 +27,11 @@ const sortOptions = [ { property: 'name', text: 'Name' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - function ChplG1g2View({ g1g2: initialG1g2 }) { const [g1g2, setG1g2] = useState([]); const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('abbreviation'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setG1g2(initialG1g2 @@ -66,25 +64,24 @@ function ChplG1g2View({ g1g2: initialG1g2 }) { <> - - - Search Results - - {`(${g1g2.length} Result${g1g2.length !== 1 ? 's' : ''})`} - - - - - - - + 0 ? 1 : 0} + pageEnd={g1g2.length} + fadeBackground={palette.white} + > + + + { g1g2 .map((item) => ( - + )} /> - + diff --git a/src/app/components/system-maintenance/standard/standards-view.jsx b/src/app/components/system-maintenance/standard/standards-view.jsx index 008ada9ac3..18d88f82ed 100755 --- a/src/app/components/system-maintenance/standard/standards-view.jsx +++ b/src/app/components/system-maintenance/standard/standards-view.jsx @@ -3,8 +3,6 @@ import { Box, Button, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, func } from 'prop-types'; import AddIcon from '@material-ui/icons/Add'; @@ -20,6 +18,7 @@ import { } from 'components/filter'; import { ChplSearchResultCard, + ChplSearchResultControls, ChplSortControls, ChplUpdateIndicator, ChplTooltip, @@ -29,7 +28,7 @@ import { sortCriteria } from 'services/criteria.service'; import { getDisplayDateFormat } from 'services/date-util'; import { UserContext } from 'shared/contexts'; import { standard as standardPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'value', text: 'Value' }, @@ -40,21 +39,12 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, - tableResultsHeaderContainer: { - display: 'flex', - justifyContent: 'flex-end', - }, -}); - function ChplStandardsView({ dispatch, standards: initialStandards }) { const [standards, setStandards] = useState([]); const { hasAnyRole } = useContext(UserContext); const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('value'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setStandards(initialStandards @@ -86,27 +76,27 @@ function ChplStandardsView({ dispatch, standards: initialStandards }) { <> - - - Search Results - - {`(${standards.length} Result${standards.length !== 1 ? 's' : ''})`} - - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + 0 ? 1 : 0} + pageEnd={standards.length} + fadeBackground={palette.white} + > + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} - - - + )} + + { standards .map((item) => ( - + )} /> - + { (deleteStandard.isLoading || postStandard.isLoading || putStandard.isLoading) && ( diff --git a/src/app/components/util/chpl-search-result-controls.jsx b/src/app/components/util/chpl-search-result-controls.jsx index 4f06bd8c7b..c4e0745148 100644 --- a/src/app/components/util/chpl-search-result-controls.jsx +++ b/src/app/components/util/chpl-search-result-controls.jsx @@ -4,7 +4,7 @@ import { Typography, makeStyles, } from '@material-ui/core'; -import { node, number } from 'prop-types'; +import { node, number, string } from 'prop-types'; import { palette, theme } from 'themes'; @@ -32,7 +32,7 @@ const useStyles = makeStyles({ right: 0, bottom: '100%', height: '90px', - background: `linear-gradient(to top, ${palette.backgroundPage} 40%, transparent)`, + background: ({ fadeBackground }) => `linear-gradient(to top, ${fadeBackground} 40%, transparent)`, pointerEvents: 'none', }, [theme.breakpoints.down('sm')]: { @@ -76,8 +76,9 @@ function ChplSearchResultControls({ pageStart, pageEnd, children = undefined, + fadeBackground = palette.backgroundPage, }) { - const classes = useStyles(); + const classes = useStyles({ fadeBackground }); return (
@@ -113,4 +114,5 @@ ChplSearchResultControls.propTypes = { pageStart: number.isRequired, pageEnd: number.isRequired, children: node, + fadeBackground: string, }; From e25df56c18d28ae23b789a714b0ab13ded7fff30 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Tue, 28 Jul 2026 14:13:56 -0400 Subject: [PATCH 08/11] feat: refactor change request and activity views to use new search result components and improve layout [#OCD-4930] --- .../change-request/change-requests-view.jsx | 286 ++++++++---------- src/app/components/filter/filter-layout.jsx | 31 +- src/app/components/products/products-view.jsx | 2 +- .../pages/reports/activity/activity-view.jsx | 186 ++++-------- .../questionable-activity-view.jsx | 229 +++++--------- 5 files changed, 280 insertions(+), 454 deletions(-) diff --git a/src/app/components/change-request/change-requests-view.jsx b/src/app/components/change-request/change-requests-view.jsx index c1eaa95993..e7a48bd02f 100755 --- a/src/app/components/change-request/change-requests-view.jsx +++ b/src/app/components/change-request/change-requests-view.jsx @@ -1,20 +1,12 @@ import React, { useContext, useEffect, useState } from 'react'; import { + Box, Button, - ButtonGroup, Card, CardContent, CardHeader, - CircularProgress, MenuItem, MenuList, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, - Typography, makeStyles, } from '@material-ui/core'; import VisibilityIcon from '@material-ui/icons/Visibility'; @@ -35,61 +27,36 @@ import { import { ChplAvatar, ChplLink, + ChplLoadingCards, ChplPagination, - ChplSortableHeaders, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, } from 'components/util'; import { eventTrack } from 'services/analytics.service'; import { getDisplayDateFormat } from 'services/date-util'; import { useSessionStorage as useStorage } from 'services/storage.service'; import { UserContext, useAnalyticsContext } from 'shared/contexts'; -import { palette, theme, utilStyles } from 'themes'; +import { palette, utilStyles } from 'themes'; const useStyles = makeStyles({ ...utilStyles, - container: { - maxHeight: '64vh', + card: { + overflow: 'visible', }, - tableResultsHeaderContainer: { - display: 'grid', - gap: '8px', - margin: '16px 32px', - gridTemplateColumns: '1fr', - alignItems: 'center', - justifyContent: 'space-between', - [theme.breakpoints.up('sm')]: { - gridTemplateColumns: 'auto auto', - }, - }, - resultsContainer: { - display: 'grid', - gap: '8px', - justifyContent: 'start', - gridTemplateColumns: 'auto auto', - alignItems: 'center', - }, - wrap: { - flexFlow: 'wrap', - }, - tableFirstColumn: { - position: 'sticky', - left: 0, - boxShadow: 'rgba(149, 157, 165, 0.1) 0px 4px 8px', - backgroundColor: palette.white, - }, - tableDeveloperCell: { + developerTitle: { display: 'flex', alignItems: 'center', gap: '8px', }, - developerName: { - fontWeight: '600', - }, noResultsContainer: { padding: '16px 32px', }, }); -function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embedded = false }) { +function ChplChangeRequestsView({ + disallowedFilters, bonusQuery, dispatch, embedded = false, +}) { const storageKey = 'storageKey-changeRequestsView'; const { analytics } = useAnalyticsContext(); const { hasAnyRole } = useContext(UserContext); @@ -128,20 +95,17 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed } }, [data, isLoading, isSuccess]); - /* eslint object-curly-newline: ["error", { "minProperties": 5, "consistent": true }] */ - const headers = hasAnyRole(['chpl-developer']) ? [ - { property: 'change_request_type', text: 'Request Type', sortable: true }, - { property: 'change_request_status', text: 'Request Status', sortable: true }, - { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', sortable: true, reverseDefault: true }, - { text: 'Actions', invisible: true }, + const isDeveloper = hasAnyRole(['chpl-developer']); + const sortOptions = isDeveloper ? [ + { property: 'change_request_type', text: 'Request Type' }, + { property: 'change_request_status', text: 'Request Status' }, + { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', reverseDefault: true }, ] : [ - { property: 'developer', text: 'Developer', sortable: true }, - { property: 'change_request_type', text: 'Request Type', sortable: true }, - { property: 'submitted_date_time', text: 'Creation Date', sortable: true, reverseDefault: true }, - { property: 'change_request_status', text: 'Request Status', sortable: true }, - { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', sortable: true, reverseDefault: true }, - { text: 'Associated ONC-ACBs' }, - { text: 'Actions', invisible: true }, + { property: 'developer', text: 'Developer' }, + { property: 'change_request_type', text: 'Request Type' }, + { property: 'submitted_date_time', text: 'Creation Date', reverseDefault: true }, + { property: 'change_request_status', text: 'Request Status' }, + { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', reverseDefault: true }, ]; const handleDispatch = (action, payload) => { @@ -156,7 +120,7 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed } }; - const handleTableSort = (event, property, orderDirection) => { + const handleSort = (property, orderDirection) => { eventTrack({ ...analytics, event: 'Sort Column', @@ -187,20 +151,18 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed const pageStart = (pageNumber * pageSize) + 1; const pageEnd = Math.min((pageNumber + 1) * pageSize, data?.recordCount); + const recordCount = data?.recordCount ?? 0; const content = ( <> - { isLoading - && ( -
- -
- )} + { isLoading && ()} { !isLoading && ( <> @@ -217,84 +179,60 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed )} - { isSuccess + { !isError && ( <> -
-
- Search Results: - { changeRequests.length === 0 - && ( - <> - No results found - - )} - { changeRequests.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${data?.recordCount} Results)`} - - )} -
+ + { changeRequests.length > 0 && ( - - - + )} -
+ { changeRequests.length > 0 && ( <> - - - - - {changeRequests - .map((item) => ( - - { !hasAnyRole(['chpl-developer']) - && ( - -
-
- -
-
- -
-
-
- )} - {item.changeRequestType.name} - { !hasAnyRole(['chpl-developer']) - && {getDisplayDateFormat(item.submittedDateTime)}} - {item.currentStatus.name} - + + { changeRequests.map((item) => ( + + + + + )} + fieldGroups={isDeveloper ? [ + [ + { label: 'Request Type', value: item.changeRequestType.name }, + { label: 'Request Status', value: item.currentStatus.name }, + { + label: 'Time Since Last Status Change', + value: ( {item.currentStatus.statusChangeDateTime} - - { !hasAnyRole(['chpl-developer']) - && ( - - { item.certificationBodies.length === 0 - ? ( - <> - None - - ) : ( - <> - { item.certificationBodies.map((acb) => acb.name).join('; ') } - - )} - - )} - - - -
- ))} -
-
-
+ {item.currentStatus.statusChangeDateTime} + + ), + }, + { + label: 'Associated ONC-ACBs', + value: item.certificationBodies.length === 0 + ? 'None' + : item.certificationBodies.map((acb) => acb.name).join('; '), + }, + ], + ]} + actions={( + + )} + /> + ))} + + { bonusQuery && ( diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx index af6bfa9d54..89feb3b51d 100644 --- a/src/app/components/filter/filter-layout.jsx +++ b/src/app/components/filter/filter-layout.jsx @@ -9,7 +9,7 @@ import { import FilterListIcon from '@material-ui/icons/FilterList'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ExpandLessIcon from '@material-ui/icons/ExpandLess'; -import { node } from 'prop-types'; +import { bool, node } from 'prop-types'; import ChplFilterChips from './filter-chips'; import { useFilterContext } from './filter-context'; @@ -28,6 +28,13 @@ const useStyles = makeStyles({ gap: '24px', }, }, + layoutContainerMobileOnly: { + display: 'grid', + gridTemplateColumns: '1fr', + gap: '16px', + alignItems: 'start', + margin: '16px 0px', + }, sidebar: { display: 'flex', flexDirection: 'column', @@ -37,6 +44,11 @@ const useStyles = makeStyles({ top: '190px', }, }, + sidebarMobileOnly: { + display: 'flex', + flexDirection: 'column', + gap: '8px', + }, sidebarToggle: { justifyContent: 'space-between', color: palette.black, @@ -44,6 +56,10 @@ const useStyles = makeStyles({ display: 'none', }, }, + sidebarToggleMobileOnly: { + justifyContent: 'space-between', + color: palette.black, + }, sidebarToggleLabel: { display: 'flex', alignItems: 'center', @@ -54,10 +70,11 @@ const useStyles = makeStyles({ }, }); -function ChplFilterLayout({ children }) { +function ChplFilterLayout({ children, mobileOnly }) { const classes = useStyles(); const filterContext = useFilterContext(); - const isDesktop = useMediaQuery(theme.breakpoints.up('md')); + const isDesktopWidth = useMediaQuery(theme.breakpoints.up('md')); + const isDesktop = isDesktopWidth && !mobileOnly; const [expanded, setExpanded] = useState(false); const hasAppliedFilters = filterContext.filters @@ -76,10 +93,10 @@ function ChplFilterLayout({ children }) { } return ( -
- +
+
- -
- -
- { isLoading - && ( - - )} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> -
-
- Search Results: - { activities.length === 0 - && ( - - No results found - - )} - { activities.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${recordCount} Results)`} - - )} -
+ + { activities.length > 0 && (
+ { activities.length > 0 && ( <> - - - - - { activities - .map((item) => ( - - - { item.developerId - && ( - - )} - - {item.productName} - {item.versionName} - - { item.listingId - && ( + + { activities.map((item) => ( + + ) + : item.developerName || 'N/A'} + fieldGroups={[ + [ + { label: 'Product', value: item.productName }, + { label: 'Version', value: item.versionName }, + { + label: 'CHPL ID', + style: { flex: '2 1 320px' }, + value: item.listingId + ? ( - )} - - {item.triggerName} - { getDisplayDateFormat(item.activityDate) } - - { item.reason - && ( - - {item.reason} - - )} - { item.certificationStatusChangeReason - && ( - - {item.certificationStatusChangeReason} - - )} - - - - - - ))} - -
-
+ ) + : item.chplProductNumber, + }, + ], + [ + { label: 'Activity', value: item.triggerName }, + { label: 'Activity Date', value: getDisplayDateFormat(item.activityDate) }, + { + label: 'Reason', + style: { flex: '2 1 320px' }, + value: item.reason || item.certificationStatusChangeReason || 'N/A', + }, + ], + ]} + actions={} + /> + ))} + )} +
); } From e66e5af83c549c4c8d202ada18bc3e30237e1283 Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Tue, 28 Jul 2026 16:12:15 -0400 Subject: [PATCH 09/11] feat: enhance filter and sort components with improved layout and user feedback [#OCD-4930] --- src/app/components/filter/filter-layout.jsx | 33 +++++++++- .../util/chpl-search-result-controls.jsx | 6 +- .../components/util/chpl-sort-controls.jsx | 10 ++- .../manage-subscriptions-view.jsx | 64 +++++++------------ 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx index 89feb3b51d..3927de6d07 100644 --- a/src/app/components/filter/filter-layout.jsx +++ b/src/app/components/filter/filter-layout.jsx @@ -2,11 +2,15 @@ import React, { useEffect, useState } from 'react'; import { Box, Button, + Card, + CardContent, Collapse, + Typography, makeStyles, useMediaQuery, } from '@material-ui/core'; import FilterListIcon from '@material-ui/icons/FilterList'; +import LabelOffIcon from '@material-ui/icons/LabelOff'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ExpandLessIcon from '@material-ui/icons/ExpandLess'; import { bool, node } from 'prop-types'; @@ -65,6 +69,19 @@ const useStyles = makeStyles({ alignItems: 'center', gap: '8px', }, + emptyCard: { + width: '100%', + }, + emptyContent: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + textAlign: 'center', + gap: '8px', + }, + emptyIcon: { + fontSize: '2rem', + }, content: { minWidth: 0, }, @@ -86,8 +103,20 @@ function ChplFilterLayout({ children, mobileOnly }) { if (!hasAppliedFilters) { return ( -
- {children} +
+ + + + + + No filters applied. Please use the advanced search to apply filters and view results. + + + + +
+ {children} +
); } diff --git a/src/app/components/util/chpl-search-result-controls.jsx b/src/app/components/util/chpl-search-result-controls.jsx index c4e0745148..6135459254 100644 --- a/src/app/components/util/chpl-search-result-controls.jsx +++ b/src/app/components/util/chpl-search-result-controls.jsx @@ -23,8 +23,10 @@ const useStyles = makeStyles({ padding: '16px 32px', backgroundColor: palette.white, borderRadius: '0px 0px 8px 8px', - borderTop: `1px solid ${palette.greyBorder}`, - boxShadow: `0px 2px 4px -1px ${theme.palette.grey[300]}, 0px 4px 5px 0px ${theme.palette.grey[300]}, 0px 1px 10px 0px ${theme.palette.grey[300]}`, + borderRight: `1px solid ${palette.divider}`, + borderBottom: `1px solid ${palette.divider}`, + borderLeft: `1px solid ${palette.divider}`, + boxShadow: `0px 6px 8px -4px ${theme.palette.grey[300]}`, '&::before': { content: '""', position: 'absolute', diff --git a/src/app/components/util/chpl-sort-controls.jsx b/src/app/components/util/chpl-sort-controls.jsx index c18bd2a4d3..1ae25db867 100644 --- a/src/app/components/util/chpl-sort-controls.jsx +++ b/src/app/components/util/chpl-sort-controls.jsx @@ -3,6 +3,7 @@ import { Box, Button, ButtonGroup, + Card, Menu, MenuItem, makeStyles, @@ -19,11 +20,14 @@ import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward'; import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; import SortIcon from '@material-ui/icons/Sort'; -import { theme } from 'themes'; +import { theme, palette } from 'themes'; const useStyles = makeStyles({ container: { marginRight: '16px', + display: 'flex', + border: `1px solid ${theme.palette.divider}`, + alignItems: 'center', [theme.breakpoints.down('sm')]: { width: '100%', marginRight: 0, @@ -83,7 +87,7 @@ function ChplSortControls({ }; return ( - +
+
+ +
); diff --git a/src/app/components/filter/filters/certification-statuses.jsx b/src/app/components/filter/filters/certification-statuses.jsx index f3ce4c83c9..42d4af26e0 100755 --- a/src/app/components/filter/filters/certification-statuses.jsx +++ b/src/app/components/filter/filters/certification-statuses.jsx @@ -32,13 +32,14 @@ const getCertificationStatusValueEntry = ({ filter, handleFilterToggle }) => fil style={{ display: 'flex', alignItems: 'center', + gap: '4px', }} > - {getStatusIcon({ name: filter.getLongValueDisplay(value) })} - {filter.getLongValueDisplay(value)} + {getStatusIcon({ name: filter.getLongValueDisplay(value) })} + ); }); From a1339ccdc0b0d3ae0973576d471ffb088618f4ce Mon Sep 17 00:00:00 2001 From: Matthew Stankiewicz Date: Wed, 29 Jul 2026 11:22:02 -0400 Subject: [PATCH 11/11] fix: standardize padding values in results containers across multiple views [#OCD-4930] --- src/app/components/filter/filter-layout.jsx | 4 ++-- src/app/pages/reports/activity/activity-view.jsx | 2 +- .../questionable-activity/questionable-activity-view.jsx | 2 +- src/app/pages/subscriptions/manage-subscriptions-view.jsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx index 3927de6d07..b259794ffd 100644 --- a/src/app/components/filter/filter-layout.jsx +++ b/src/app/components/filter/filter-layout.jsx @@ -26,7 +26,7 @@ const useStyles = makeStyles({ gridTemplateColumns: '1fr', gap: '16px', alignItems: 'start', - margin: '16px 0px', + margin: '16px 0', [theme.breakpoints.up('md')]: { gridTemplateColumns: '260px 1fr', gap: '24px', @@ -37,7 +37,7 @@ const useStyles = makeStyles({ gridTemplateColumns: '1fr', gap: '16px', alignItems: 'start', - margin: '16px 0px', + margin: '16px 0', }, sidebar: { display: 'flex', diff --git a/src/app/pages/reports/activity/activity-view.jsx b/src/app/pages/reports/activity/activity-view.jsx index 687e60fdcf..b56e5acab0 100755 --- a/src/app/pages/reports/activity/activity-view.jsx +++ b/src/app/pages/reports/activity/activity-view.jsx @@ -42,7 +42,7 @@ const useStyles = makeStyles({ backgroundColor: '#f9f9f9', }, resultsContainer: { - padding: '0px 32px', + padding: '0 32px', }, }); diff --git a/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx b/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx index 11613618f9..f5d391c39b 100755 --- a/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx +++ b/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx @@ -44,7 +44,7 @@ const useStyles = makeStyles({ backgroundColor: '#f9f9f9', }, resultsContainer: { - padding: '0px 32px', + padding: '0 32px', }, }); diff --git a/src/app/pages/subscriptions/manage-subscriptions-view.jsx b/src/app/pages/subscriptions/manage-subscriptions-view.jsx index 632854b819..a690943265 100755 --- a/src/app/pages/subscriptions/manage-subscriptions-view.jsx +++ b/src/app/pages/subscriptions/manage-subscriptions-view.jsx @@ -87,7 +87,7 @@ const useStyles = makeStyles({ }, }, resultsContainer: { - padding: '0px 32px', + padding: '0 32px', }, listContainer: { fontSize: 'smaller',