Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3492d25
feat!: add filter layout component and enhance filter chips with card…
mattystank Jul 24, 2026
17f6bf3
feat: replace ChplFilterChips with ChplFilterLayout in various views …
mattystank Jul 24, 2026
7804e82
feat: enhance filter components with improved layout and sticky behavior
mattystank Jul 27, 2026
ad8dc92
refactor: simplify ChplPagination component by removing unused styles…
mattystank Jul 27, 2026
a643398
feat: enhance ChplSearchResultControls with sticky positioning and gr…
mattystank Jul 27, 2026
2cf08c6
feat: replace ChplFilterChips with ChplFilterLayout for improved layo…
mattystank Jul 27, 2026
e8f098e
feat: enhance search result controls and filter components with custo…
mattystank Jul 27, 2026
e25df56
feat: refactor change request and activity views to use new search re…
mattystank Jul 28, 2026
e66e5af
feat: enhance filter and sort components with improved layout and use…
mattystank Jul 28, 2026
8a8813a
refactor: Update ChplComplaintsWrapper to use ChplPageHeader and Chpl…
mattystank Jul 29, 2026
a1339cc
fix: standardize padding values in results containers across multiple…
mattystank Jul 29, 2026
7923981
feat: Standardize complaints view and fix nav download icons
mattystank Jul 29, 2026
ea2f802
Merge branch 'staging' into OCD-4930
mattystank Jul 30, 2026
df6bb3d
feat: Enhance filter and layout components with horizontal support an…
mattystank Aug 3, 2026
3c7b407
fix: Adjust resultsContainer padding in activity and questionable act…
mattystank Aug 3, 2026
50de53c
feat: Update ChplSortControls styles for improved layout and button f…
mattystank Aug 3, 2026
d26028b
feat: Update styles and layout in complaints view and filter layout f…
mattystank Aug 3, 2026
b6826b1
Merge branch 'staging' into OCD-4930
mattystank Aug 4, 2026
dcb768d
refactor: Address PR review feedback on filter and complaints components
mattystank Aug 6, 2026
a16e9e5
Merge remote-tracking branch 'upstream/staging' into OCD-4930
mattystank Aug 7, 2026
3a8cae1
feat: update filter planel, activity views to use same format as other
mattystank Aug 10, 2026
733af8f
fix: refactor analytics and download icon functions in mobile nav drawer
mattystank Aug 13, 2026
7eaf9e7
Merge branch 'staging' into OCD-4930
mattystank Aug 18, 2026
ffbaff9
fix: adjust flex properties for Email and API Key columns in api-keys…
mattystank Aug 19, 2026
b39a276
fix: integrate FlagContext and enhance search result card rendering
mattystank Aug 20, 2026
fa7a22b
Merge remote-tracking branch 'upstream/staging' into OCD-4930
mattystank Aug 20, 2026
df9a83e
fix: enhance CHPL Developer page with new search components
mattystank Aug 21, 2026
00859ac
fix: add ConditionalWrapper to enhance tooltip rendering for filter c…
mattystank Aug 21, 2026
8148963
fix: update filter button width condition for specific filter keys
mattystank Aug 24, 2026
8f2a3f8
fix: update filter panel layout and enable text wrapping for develope…
mattystank Aug 24, 2026
491daa6
Merge branch 'OCD-4930' of https://github.com/mattystank/chpl-website…
mattystank Aug 24, 2026
f7e1cf9
fix: set Button component to fullWidth for all filters in filter panel
mattystank Aug 24, 2026
4b6c844
fix: enhance chip styling for better text wrapping and responsiveness
mattystank Aug 24, 2026
77da1e3
fix: make filterGridMinColWidth prop required and reset active catego…
mattystank Aug 24, 2026
9d119f6
Merge branch 'staging' into OCD-4930
mattystank Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
297 changes: 127 additions & 170 deletions src/app/components/change-request/change-requests-view.jsx

Large diffs are not rendered by default.

240 changes: 136 additions & 104 deletions src/app/components/filter/filter-chips.jsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,76 @@
import React, { useEffect, useState } from 'react';
import {
Button,
Card,
CardContent,
Chip,
FormControlLabel,
Switch,
Typography,
makeStyles,
} from '@material-ui/core';
import { bool } from 'prop-types';

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',
width: '100%',
},
filterSelectedContainerHorizontal: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
},
filterChipsContainer: {
display: 'flex',
gap: '8px',
gap: '16px',
alignContent: 'flex-start',
flexWrap: 'wrap',
flexDirection: 'row',
alignItems: 'center',
flexDirection: 'column',
alignItems: 'flex-start',
width: '100%',
},
filterGroupTitleHorizontal: {
width: '100%',
},
chip: {
border: `1px solid ${palette.primary}`,
backgroundColor: palette.white,
maxWidth: '100%',
},
chipDeleteIcon: {
order: -2,
marginLeft: '5px',
marginRight: '-4px',
},
chipLabel: {
alignItems: 'center',
display: 'inline-flex',
gap: '4px',
},
chipAvatar: {
backgroundColor: 'transparent !important',
card: {
width: '100%',
maxHeight: '50vh',
overflowY: 'auto',
},
}));
});

const truncate = (str, n, useWordBoundary) => {
if (str.length <= n) { return str; }
Expand All @@ -64,7 +80,7 @@ const truncate = (str, n, useWordBoundary) => {

const maxLengthForChip = 40;

function ChplFilterChips() {
function ChplFilterChips({ horizontal = false }) {
const [filters, setFilters] = useState([]);
const filterContext = useFilterContext();
const classes = useStyles();
Expand Down Expand Up @@ -127,95 +143,111 @@ function ChplFilterChips() {
filterContext.dispatch('toggleShowAll', f);
};

if (filters.length === 0) { return null; }

const getChipLabel = (f, labelText, iconName) => {
if (f.key !== 'certificationStatuses') { return labelText; }
return (
<span className={classes.chipLabel}>
{ labelText }
{ getStatusIcon({ name: iconName }) }
</span>
);
};

return (
<span className={classes.filterContainer} id="filter-chips">
<Typography variant="subtitle2">Filters Applied:</Typography>
<div className={classes.filterChipsContainer}>
{ filters.map((f) => (
<span
className={classes.filterSelectedContainer}
key={f.key}
>
<Typography variant="body1">
<strong>
{f.getFilterDisplay(f)}
</strong>
</Typography>
{ f.operatorKey
&& (
<FormControlLabel
control={(
<Switch
id={`${f.key}-operator-chips-toggle`}
color="primary"
checked={f.operator === 'and'}
onChange={() => toggleOperator(f)}
/>
)}
label={f.operator === 'and' ? 'All' : 'Any'}
/>
)}
{ f.developersListingsCriteriaOptionKey
&& (
<FormControlLabel
control={(
<Switch
id={`${f.key}-developers-listings-criteria-option-chips-toggle`}
color="primary"
checked={f.developersListingsCriteriaOption === 'all'}
onChange={() => toggleDevelopersListingsCriteriaOption(f)}
/>
)}
label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'}
/>
)}
{f.values
.filter((v, idx) => f.showAll || idx < DISPLAY_MAX)
.map((v) => (
<React.Fragment key={v.value}>
{ f.getValueDisplay(v).length > maxLengthForChip
? (
<ChplTooltip
title={f.getLongValueDisplay(v)}
>
<Chip
avatar={f.key === 'certificationStatuses' ? getStatusIcon({ name: f.getValueDisplay(v) }) : undefined}
label={truncate(f.getValueDisplay(v), maxLengthForChip, true)}
onDelete={() => removeChip(f, v)}
variant="outlined"
disabled={f.required && f.values.length === 1}
classes={{ avatar: classes.chipAvatar, root: classes.chip }}
/>
</ChplTooltip>
) : (
<Chip
avatar={f.key === 'certificationStatuses' ? getStatusIcon({ name: f.getValueDisplay(v) }) : undefined}
label={f.getValueDisplay(v)}
onDelete={() => removeChip(f, v)}
variant="outlined"
disabled={f.required && f.values.length === 1}
classes={{ avatar: classes.chipAvatar, root: classes.chip }}
<Card className={classes.card}>
<CardContent>
<Typography variant="subtitle2">Filters Applied:</Typography>
<div className={classes.filterChipsContainer}>
{ filters.map((f) => (
<span
className={horizontal ? `${classes.filterSelectedContainer} ${classes.filterSelectedContainerHorizontal}` : classes.filterSelectedContainer}
key={f.key}
>
<Typography variant="body1" className={horizontal ? classes.filterGroupTitleHorizontal : undefined}>
<strong>
{f.getFilterDisplay(f)}
</strong>
</Typography>
{ f.operatorKey
&& (
<FormControlLabel
control={(
<Switch
id={`${f.key}-operator-chips-toggle`}
color="primary"
checked={f.operator === 'and'}
onChange={() => toggleOperator(f)}
/>
)}
</React.Fragment>
))}
{ f.values.length > DISPLAY_MAX
&& (
<Button
onClick={() => toggleShowAll(f)}
color="primary"
variant="text"
>
{ f.showAll ? 'Show Fewer' : `Show ${f.values.length - DISPLAY_MAX} More` }
</Button>
)}
</span>
))}
</div>
label={f.operator === 'and' ? 'All' : 'Any'}
/>
)}
{ f.developersListingsCriteriaOptionKey
&& (
<FormControlLabel
control={(
<Switch
id={`${f.key}-developers-listings-criteria-option-chips-toggle`}
color="primary"
checked={f.developersListingsCriteriaOption === 'all'}
onChange={() => toggleDevelopersListingsCriteriaOption(f)}
/>
)}
label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'}
/>
)}
{f.values
.filter((v, idx) => f.showAll || idx < DISPLAY_MAX)
.map((v) => (
<React.Fragment key={v.value}>
{ f.getValueDisplay(v).length > maxLengthForChip
? (
<ChplTooltip
title={f.getLongValueDisplay(v)}
>
<Chip
label={getChipLabel(f, truncate(f.getValueDisplay(v), maxLengthForChip, true), f.getValueDisplay(v))}
onDelete={() => removeChip(f, v)}
variant="outlined"
disabled={f.required && f.values.length === 1}
classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }}
/>
</ChplTooltip>
) : (
<Chip
label={getChipLabel(f, f.getValueDisplay(v), f.getValueDisplay(v))}
onDelete={() => removeChip(f, v)}
variant="outlined"
disabled={f.required && f.values.length === 1}
classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }}
/>
)}
</React.Fragment>
))}
{ f.values.length > DISPLAY_MAX
&& (
<Button
onClick={() => toggleShowAll(f)}
color="primary"
variant="text"
>
{ f.showAll ? 'Show Fewer' : `Show ${f.values.length - DISPLAY_MAX} More` }
</Button>
)}
</span>
))}
</div>
</CardContent>
</Card>
</span>
);
}

export default ChplFilterChips;

ChplFilterChips.propTypes = {};
ChplFilterChips.propTypes = {
horizontal: bool,
};
Loading
Loading