Skip to content

Commit

Permalink
Add service filter to GeographicalUnitList view
Browse files Browse the repository at this point in the history
Add possibility to filter services in GeographicalUnitList view in same
way as in the StatisticalDistrictUnitList view.
  • Loading branch information
japauliina committed Nov 19, 2024
1 parent 094f0aa commit a0cafd1
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 104 deletions.
1 change: 1 addition & 0 deletions src/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default {
'area.neighborhood.title': 'Choose neighbourhood',
'area.postcode_area.title': 'Choose postal code',
'area.major_district.title': 'Choose major district',
'area.service.filter': 'Filtering of services for areas',
'area.statisticalDistrict.info': 'First, select a population data area, and then you can browse the area\'s services',
'area.statisticalDistrict.title': 'Select a population data area',
'area.statisticalDistrict.section': 'Cropping: {text}',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/fi.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default {
'area.neighborhood.title': 'Valitse kaupunginosa',
'area.postcode_area.title': 'Valitse postinumero',
'area.major_district.title': 'Valitse suurpiiri',
'area.service.filter': 'Palvelujen suodatus',
'area.statisticalDistrict.info': 'Valitse ensin väestötietoalue, jonka jälkeen voit selata alueen palveluita',
'area.statisticalDistrict.label': '{count} henkilöä, {percent}% alueen koko väestöstä',
'area.statisticalDistrict.label.total': '{count} henkilöä',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/sv.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default {
'area.neighborhood.title': 'Välj stadsdel',
'area.postcode_area.title': 'Välj postnummer',
'area.major_district.title': 'Välj stordistrikt',
'area.service.filter': 'Filtrering av geografiska tjänster',
'area.statisticalDistrict.info': 'Välj först befolkningsdataområdet, varefter du kan bläddra bland regionens tjänster',
'area.statisticalDistrict.title': 'Välj befolkningsdataområde',
'area.statisticalDistrict.section': 'Beskärning: {text}',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Checkbox, List, Typography } from '@mui/material';
import PropTypes from 'prop-types';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, {
useCallback, useEffect, useMemo, useRef, useState,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useIntl } from 'react-intl';
import { UnitItem } from '../../../../components';
import {
addSelectedDistrictService,
Expand All @@ -13,7 +16,7 @@ import {
selectSelectedDistrictServices,
} from '../../../../redux/selectors/district';
import { getLocale } from '../../../../redux/selectors/user';
import { uppercaseFirst } from '../../../../utils';
import { keyboardHandler, uppercaseFirst } from '../../../../utils';
import { orderUnits } from '../../../../utils/orderUnits';
import useLocaleText from '../../../../utils/useLocaleText';
import {
Expand All @@ -24,6 +27,7 @@ import {
StyledUnitList,
StyledUnitListArea,
} from '../styled/styled';
import ServiceFilterContainer from '../ServiceFilterContainer/ServiceFilterContainer';

// Custom uncontrolled checkbox that allows default value
const UnitCheckbox = ({
Expand Down Expand Up @@ -56,7 +60,16 @@ const GeographicalUnitList = ({ initialOpenItems }) => {
const locale = useSelector(getLocale);
const [serviceList, setServiceList] = useState([]);
const [initialCheckedItems] = useState(selectedServices);

const inputRef = useRef();
const { formatMessage } = useIntl();
const [filterValue, setFilterValue] = useState('');
const title = formatMessage({ id: 'area.service.filter' });

const handlefilterButtonClick = () => {
if (inputRef) {
setFilterValue(inputRef.current.value);
}
};

const handleUnitCheckboxChange = useCallback((event, id) => {
if (event.target.checked) {
Expand Down Expand Up @@ -112,18 +125,37 @@ const GeographicalUnitList = ({ initialOpenItems }) => {
if (emptyCategories.length) {
dispatch(removeSelectedDistrictService(emptyCategories));
}

// Use filter
if (filterValue) {
const filteredServiceList = serviceList.filter((category) => {
const name = getLocaleText(category.name);
return name.toLowerCase().includes(filterValue.toLowerCase());
});
setServiceList(filteredServiceList);
return;
}

setServiceList(serviceList);
};


useEffect(() => {
createServiceCategories();
}, [filteredSubdistrictUnits]);

}, [filteredSubdistrictUnits, filterValue]);

// Render list of units for neighborhood and postcode-area subdistricts
const renderUnitList = useMemo(() => (
<StyledUnitListArea>
<ServiceFilterContainer
title={title}
inputRef={inputRef}
keyboardHandler={keyboardHandler}
handlefilterButtonClick={handlefilterButtonClick}
filterValue={filterValue}
setFilterValue={setFilterValue}
formatMessage={formatMessage}
/>
<List disablePadding>
{serviceList.map(category => (
<StyledListItem
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from 'react';
import { useTheme } from '@mui/styles';
import {
IconButton, Typography,
} from '@mui/material';
import { Clear } from '@mui/icons-material';
import { FormattedMessage } from 'react-intl';
import {
StyledServiceFilterContainer,
StyledServiceFilterText,
StyledRowContainer,
StyledServiceFilter,
StyledServiceFilterButton,
} from '../styled/styled';
import { createServiceFilterStyles } from '../../serviceFilterStyles';

const ServiceFilterContainer = ({
title,
inputRef,
keyboardHandler,
handlefilterButtonClick,
filterValue,
setFilterValue,
formatMessage,
}) => {
const theme = useTheme();
const {
serviceFilterInputClass,
serviceFilterButtonLabelClass,
serviceFilterButtonFocusClass,
} = createServiceFilterStyles(theme);

return (
<StyledServiceFilterContainer>
{typeof title === 'string' && (
<StyledServiceFilterText id="ServiceListTitle" variant="body2">
{title}
</StyledServiceFilterText>
)}
<StyledRowContainer>
<StyledServiceFilter
inputRef={inputRef}
inputProps={{
className: serviceFilterInputClass,
'aria-labelledby': 'ServiceListTitle',
}}
type="text"
onKeyPress={keyboardHandler(() => handlefilterButtonClick(), ['enter'])}
endAdornment={
filterValue ? (
<IconButton
aria-label={formatMessage({ id: 'search.cancelText' })}
onClick={() => {
inputRef.current.value = '';
setFilterValue('');
}}
>
<Clear />
</IconButton>
) : null
}
/>
<StyledServiceFilterButton
id="ServiceListFilterButton"
aria-label={formatMessage({ id: 'area.statisticalDistrict.service.filter.button.aria' })}
disableRipple
disableFocusRipple
classes={{
label: serviceFilterButtonLabelClass,
focusVisible: serviceFilterButtonFocusClass,
}}
onClick={handlefilterButtonClick}
color="secondary"
variant="contained"
>
<Typography variant="caption" color="inherit">
<FormattedMessage id="area.statisticalDistrict.service.filter.button" />
</Typography>
</StyledServiceFilterButton>
</StyledRowContainer>
</StyledServiceFilterContainer>
);
};

export default ServiceFilterContainer;
3 changes: 3 additions & 0 deletions src/views/AreaView/components/ServiceFilterContainer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ServiceFilterContainer from './ServiceFilterContainer';

export default ServiceFilterContainer;
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { css } from '@emotion/css';
import { Clear } from '@mui/icons-material';
import {
Button, Checkbox, IconButton, InputBase, List, Typography,
Checkbox, List, Typography,
} from '@mui/material';
import { styled } from '@mui/material/styles';
import { useTheme } from '@mui/styles';
import { visuallyHidden } from '@mui/utils';
import PropTypes from 'prop-types';
import React, { useMemo, useRef, useState } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { UnitItem } from '../../../../components';
import {
Expand All @@ -22,6 +18,7 @@ import {
StyledUnitList,
StyledUnitListArea,
} from '../styled/styled';
import ServiceFilterContainer from '../ServiceFilterContainer/ServiceFilterContainer';

// Custom uncontrolled checkbox that allows default value
const UnitCheckbox = ({
Expand Down Expand Up @@ -53,7 +50,6 @@ const StatisticalDistrictUnitListComponent = ({
const inputRef = useRef();
const { formatMessage } = useIntl();
const getLocaleText = useLocaleText();
const theme = useTheme();
const statisticalDistrictUnits = useSelector(getServiceFilteredStatisticalDistrictUnits);
const [initialCheckedItems] = useState(selectedServices || []);
const [filterValue, setFilterValue] = useState('');
Expand All @@ -69,67 +65,19 @@ const StatisticalDistrictUnitListComponent = ({
setFilterValue(inputRef.current.value);
}
};
const serviceFilterInputClass = css({
margin: theme.spacing(1),
});
const serviceFilterButtonLabelClass = css({
flexDirection: 'column',
});
const serviceFilterButtonFocusClass = css({
boxShadow: `0 0 0 4px ${theme.palette.focusBorder.main} !important`,
});

// Render list of units for neighborhood and postcode-area subdistricts
const renderServiceList = useMemo(() => (
<StyledUnitListArea>
<StyledServiceFilterContainer>
{
typeof title === 'string' && (
<StyledServiceFilterText id="ServiceListTitle" variant="body2">{title}</StyledServiceFilterText>
)
}
<StyledRowContainer>
<StyledServiceFilter
inputRef={inputRef}
inputProps={{
className: serviceFilterInputClass,
'aria-labelledby': 'ServiceListTitle',
}}
type="text"
onKeyPress={keyboardHandler(() => handlefilterButtonClick(), ['enter'])}
endAdornment={
filterValue
? (
<IconButton
aria-label={formatMessage({ id: 'search.cancelText' })}
onClick={() => {
inputRef.current.value = '';
setFilterValue('');
}}
>
<Clear />
</IconButton>
)
: null
}
/>
<StyledServiceFilterButton
id="ServiceListFilterButton"
aria-label={formatMessage({ id: 'area.statisticalDistrict.service.filter.button.aria' })}
disableRipple
disableFocusRipple
classes={{
label: serviceFilterButtonLabelClass,
focusVisible: serviceFilterButtonFocusClass,
}}
onClick={handlefilterButtonClick}
color="secondary"
variant="contained"
>
<Typography variant="caption" color="inherit"><FormattedMessage id="area.statisticalDistrict.service.filter.button" /></Typography>
</StyledServiceFilterButton>
</StyledRowContainer>
</StyledServiceFilterContainer>
<ServiceFilterContainer
title={title}
inputRef={inputRef}
keyboardHandler={keyboardHandler}
handlefilterButtonClick={handlefilterButtonClick}
filterValue={filterValue}
setFilterValue={setFilterValue}
formatMessage={formatMessage}
/>
<Typography aria-live="assertive" variant="body2" style={visuallyHidden}>
{
filterValue && filterValue !== ''
Expand Down Expand Up @@ -204,37 +152,3 @@ UnitCheckbox.defaultProps = {
};

export default StatisticalDistrictUnitListComponent;

const StyledRowContainer = styled('div')`
display: flex;
flex-direction: row;
justify-content: space-between;
`;
const StyledServiceFilterContainer = styled('div')(({ theme }) => ({
padding: theme.spacing(2),
paddingLeft: 72,
display: 'flex',
flexDirection: 'column',
}));
const StyledServiceFilterText = styled(Typography)(({ theme }) => ({
paddingBottom: theme.spacing(1),
fontWeight: 'bold',
}));
const StyledServiceFilter = styled(InputBase)(({ theme }) => ({
backgroundColor: theme.palette.white.main,
flex: '1 0 auto',
}));
const StyledServiceFilterButton = styled(Button)(({ theme }) => ({
flex: '0 0 auto',
borderRadius: 0,
borderTopRightRadius: 4,
borderBottomRightRadius: 4,
boxShadow: 'none',
padding: theme.spacing(1, 2),
textTransform: 'none',
'& svg': {
fontSize: 20,
marginBottom: theme.spacing(0.5),
},
flexDirection: 'column',
}));
Loading

0 comments on commit a0cafd1

Please sign in to comment.