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

Get Filters Working #475

Merged
merged 7 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.acceptSuggestionOnEnter": "on"
"editor.acceptSuggestionOnEnter": "on",
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}
76 changes: 33 additions & 43 deletions cypress/e2e/desktop/filters.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,37 @@

// For each resource type, test each filter permutation and confirm only the expected number of taps appear.
describe("filters", () => {
beforeEach(() => {
cy.visit("/");
// Load the form

// NOTE: This line currently uses components that are due to be updated.
// Close the tutorial modal
cy.get('[aria-label=Close]').click()
// Load the filter menu
cy.get('[data-cy=button-filter-menu]').click()
});

it("should successfully show a result for each water site filter permutation", () => {
// TODO Add an approach to test all possible filter permutations
// Currently limiting this test to a single filtering permutation as a starting point

cy.get('[data-cy="filter-option-Drinking fountain"]').click()
cy.get('[data-cy="filter-option-ADA accessible"]').click()
cy.get('[data-cy="filter-option-Open Access"]').click()

cy.get('[data-cy=filter-apply-button]').click()

// Close the filter menu
cy.get('[data-cy=button-filter-menu]').click()

// Check that a location that matches filter is present
cy.get('[title=data-cy-2]').should('exist');

// Check that a location that does not match filter is not present
// NOTE: This is commented as this test will not current pass as filtering is not working properly.
// cy.get('[title=data-cy-1]').should('not.exist');
});

it("should successfully show a result for each food site filter permutation", () => {
// TODO
});

it("should successfully show a result for each foraging site filter permutation", () => {
// TODO
});

it("should successfully show a result for each bathroom site filter permutation", () => {
// TODO
});
beforeEach(() => {
cy.visit("/");
// Load the form

// NOTE: This line currently uses components that are due to be updated.
// Close the tutorial modal
cy.get('[aria-label=Close]').click()
// Load the filter menu
cy.get('[data-cy=button-filter-menu]').click()
});

it("should successfully show a result for each water site filter permutation", () => {
// TODO Add an approach to test all possible filter permutations
// Currently limiting this test to a single filtering permutation as a starting point

cy.get('[data-cy="filter-option-Drinking fountain"]').click()
cy.get('[data-cy="filter-option-ADA accessible"]').click()
cy.get('[data-cy="filter-option-Open Access"]').click()
// Close the filter menu
cy.get('[data-cy=button-filter-menu]').click()
});

it("should successfully show a result for each food site filter permutation", () => {
// TODO
});

it("should successfully show a result for each foraging site filter permutation", () => {
// TODO
});

it("should successfully show a result for each bathroom site filter permutation", () => {
// TODO
});
});
17 changes: 9 additions & 8 deletions src/actions/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ export const setToggleStateFood = (toggle, toggleState) => ({
toggleState
});

export const SET_FILTER_FUNCTION = 'SET_FILTER_FUNCTION';
export const setFilterFunction = () => ({
type: SET_FILTER_FUNCTION
});
export const setFilterFunction = createAction('SET_FILTER_FUNCTION')

export const setEntryFilterFunction = createAction('SET_ENTRY_FILTER_FUNCTION')

export const removeFilterFunction = createAction('REMOVE_FILTER_FUNCTION')

export const removeEntryFilterFunction = createAction('REMOVE_ENTRY_FILTER_FUNCTION')

export const resetFilterFunction = createAction('RESET_FILTER_FUNCTION')

export const RESET_FILTER_FUNCTION = 'RESET_FILTER_FUNCTION';
export const resetFilterFunction = () => ({
type: RESET_FILTER_FUNCTION
});

export const getResources = createAsyncThunk(
'fetch-resources',
Expand Down
5 changes: 5 additions & 0 deletions src/components/ChooseResource/ChooseResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ReactComponent as ForagingIcon } from '../icons/ForagingIconChooseResou
import { ReactComponent as WaterIcon } from '../icons/WaterIconChooseResource.svg';
import useOnClickOutside from '../../components/AddResourceModal/useOnClickOutside.js';
import useIsMobile from 'hooks/useIsMobile';
import { resetFilterFunction } from '../../actions/actions';

const ResourceButton = props => {
const Icon = props.icon;
Expand Down Expand Up @@ -95,6 +96,7 @@ export default function ChooseResource(props) {
color="#5286E9"
text="Water"
onClick={() => {
dispatch(resetFilterFunction())
dispatch({
type: CHANGE_RESOURCE_TYPE,
resourceType: WATER_RESOURCE_TYPE
Expand All @@ -107,6 +109,7 @@ export default function ChooseResource(props) {
color="#5DA694"
text="Foraging"
onClick={() => {
dispatch(resetFilterFunction())
dispatch({
type: CHANGE_RESOURCE_TYPE,
resourceType: FORAGE_RESOURCE_TYPE
Expand All @@ -119,6 +122,7 @@ export default function ChooseResource(props) {
color="#FF9A55"
text="Food"
onClick={() => {
dispatch(resetFilterFunction())
dispatch({
type: CHANGE_RESOURCE_TYPE,
resourceType: FOOD_RESOURCE_TYPE
Expand All @@ -131,6 +135,7 @@ export default function ChooseResource(props) {
color="#9E9E9E"
text="Bathroom"
onClick={() => {
dispatch(resetFilterFunction())
dispatch({
type: CHANGE_RESOURCE_TYPE,
resourceType: BATHROOM_RESOURCE_TYPE
Expand Down
23 changes: 13 additions & 10 deletions src/components/Filter/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import styles from './Filter.module.scss';
import CloseIcon from '@mui/icons-material/Close';
import IconButton from '@mui/material/IconButton';
import useIsMobile from 'hooks/useIsMobile';
import selectFilteredResource from 'selectors/resourceSelectors';

const FilterTags = ({ tags, activeTags, resourceType, index, handleTag }) => (
<Box className={styles.filterTags}>
Expand All @@ -24,7 +25,7 @@ const FilterTags = ({ tags, activeTags, resourceType, index, handleTag }) => (
: '')
}
onClick={() => {
handleTag(0, resourceType, index, key);
handleTag(0, resourceType, tag, index, key);
}}
data-cy={`filter-option-${tag}`}
>
Expand Down Expand Up @@ -52,7 +53,7 @@ const FilterTagsExclusive = ({
: '')
}
onClick={() => {
handleTag(1, resourceType, index, key);
handleTag(1, resourceType, tag, index, key);
}}
data-cy={`filter-option-${tag}`}
>
Expand All @@ -73,6 +74,7 @@ export default function Filter({
const isMobile = useIsMobile();
const dispatch = useDispatch();
const toolbarModal = useSelector(state => state.filterMarkers.toolbarModal);
const filteredResources = useSelector(state => selectFilteredResource(state));
return (
<>
{!isMobile && (
Expand Down Expand Up @@ -183,24 +185,25 @@ export default function Filter({
Clear All
</p>
</Box>
<Box>
<Button
onClick={applyTags}
<Box
sx={{
margin: '0px 20px'
}}
>
<p
style={{
marginRight: '20px',
margin: '10px',
padding: '10px 20px',
width: 'fit-content',
position: 'relative',
float: 'right',
border: '1px solid #09A2E5',
borderRadius: '8px',
fontWeight: '600',
color: '#09A2E5'
}}
data-cy="filter-apply-button"
>
Apply
</Button>
Resources: {filteredResources.length}
</p>
</Box>
</Box>
</Collapse>
Expand Down
30 changes: 23 additions & 7 deletions src/components/ReactGoogleMaps/ReactGoogleMaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import {
setUserLocation,
toggleInfoWindow,
getResources,
setSelectedPlace
setSelectedPlace,
setFilterFunction,
resetFilterFunction,
removeFilterFunction,
removeEntryFilterFunction,
setEntryFilterFunction,
} from '../../actions/actions';
import SearchBar from '../SearchBar/SearchBar';
import SelectedTap from '../SelectedTap/SelectedTap';
Expand All @@ -21,7 +26,7 @@ import TutorialModal from '../TutorialModal/TutorialModal';
import Filter from '../Filter/Filter';
import Toolbar from '../Toolbar/Toolbar';
import phlaskMarkerIconV2 from '../icons/PhlaskMarkerIconV2';
import selectFilteredResource from '../../selectors/waterSelectors';
import selectFilteredResource from '../../selectors/resourceSelectors';
import useIsMobile from 'hooks/useIsMobile';
import { CITY_HALL_COORDINATES } from 'constants/defaults';

Expand Down Expand Up @@ -143,7 +148,7 @@ for (const [key, value] of Object.entries(filters)) {
if (category.type == 0) {
data.push(new Array(category.tags.length).fill(false));
} else {
data.push(null);
data.push(category.tags.length);
}
});
noActiveFilterTags[key] = data;
Expand All @@ -154,7 +159,6 @@ export const ReactGoogleMaps = ({ google }) => {
const isMobile = useIsMobile();
const allResources = useSelector(state => state.filterMarkers.allResources);
const filteredResources = useSelector(state => selectFilteredResource(state));

const mapCenter = useSelector(state => state.filterMarkers.mapCenter);
const resourceType = useSelector(state => state.filterMarkers.resourceType);
const showingInfoWindow = useSelector(
Expand Down Expand Up @@ -250,25 +254,37 @@ export const ReactGoogleMaps = ({ google }) => {
}
};

const handleTag = (type, filterType, index, key) => {
const handleTag = (type, filterType, filterTag, index, key) => {
//handles multi select filters
if (type == 0) {
let activeFilterTags_ = { ...activeFilterTags };
if (activeFilterTags_[filterType][index][key]) {
dispatch(removeFilterFunction({ tag: filterTag }))
}
else {
dispatch(setFilterFunction({ tag: filterTag }))
}
activeFilterTags_[filterType][index][key] =
!activeFilterTags_[filterType][index][key];
setActiveFilterTags(activeFilterTags_);
} else if (type == 1) {
}
//handles single select entry/organization filters
else if (type == 1) {
let activeFilterTags_ = { ...activeFilterTags };
if (activeFilterTags_[filterType][index] == key) {
activeFilterTags_[filterType][index] = null;
dispatch(removeEntryFilterFunction())
} else {
activeFilterTags_[filterType][index] = { ...key };
activeFilterTags_[filterType][index] = key;
dispatch(setEntryFilterFunction({ tag: filterTag }))
}
setActiveFilterTags(activeFilterTags_);
}
};

const clearAllTags = () => {
setActiveFilterTags(JSON.parse(JSON.stringify(noActiveFilterTags)));
dispatch(resetFilterFunction())
};

const applyTags = () => {
Expand Down
Loading
Loading