From 6d521934372df4d84ab0f06149dc6afe93460392 Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Fri, 12 Jul 2024 21:55:45 -0400 Subject: [PATCH 1/6] get filters working where data is available --- .vscode/settings.json | 5 +- src/actions/actions.js | 23 +++- .../ChooseResource/ChooseResource.js | 5 + src/components/Filter/Filter.js | 30 +++++- .../ReactGoogleMaps/ReactGoogleMaps.js | 38 +++++-- src/reducers/filterMarkers.js | 76 ++++++++----- src/selectors/resourceSelectors.js | 101 +++++++++++++++++ src/selectors/waterSelectors.js | 102 ------------------ 8 files changed, 235 insertions(+), 145 deletions(-) create mode 100644 src/selectors/resourceSelectors.js delete mode 100644 src/selectors/waterSelectors.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 07b55e81..0d3e7a73 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" + } } diff --git a/src/actions/actions.js b/src/actions/actions.js index 71d1ee09..132cb0cc 100644 --- a/src/actions/actions.js +++ b/src/actions/actions.js @@ -19,8 +19,27 @@ export const setToggleStateFood = (toggle, toggleState) => ({ }); export const SET_FILTER_FUNCTION = 'SET_FILTER_FUNCTION'; -export const setFilterFunction = () => ({ - type: SET_FILTER_FUNCTION +export const setFilterFunction = (tag) => ({ + type: SET_FILTER_FUNCTION, + tag, +}); + +export const SET_ENTRY_FILTER_FUNCTION = 'SET_ENTRY_FILTER_FUNCTION'; +export const setEntryFilterFunction = (tag) => ({ + type: SET_ENTRY_FILTER_FUNCTION, + tag, +}); + +export const REMOVE_FILTER_FUNCTION = 'REMOVE_FILTER_FUNCTION'; +export const removeFilterFunction = (tag) => ({ + type: REMOVE_FILTER_FUNCTION, + tag, +}); + +export const REMOVE_ENTRY_FILTER_FUNCTION = 'REMOVE_ENTRY_FILTER_FUNCTION'; +export const removeEntryFilterFunction = (tag) => ({ + type: REMOVE_ENTRY_FILTER_FUNCTION, + tag, }); export const RESET_FILTER_FUNCTION = 'RESET_FILTER_FUNCTION'; diff --git a/src/components/ChooseResource/ChooseResource.js b/src/components/ChooseResource/ChooseResource.js index 600b42d6..7d992bca 100644 --- a/src/components/ChooseResource/ChooseResource.js +++ b/src/components/ChooseResource/ChooseResource.js @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/src/components/Filter/Filter.js b/src/components/Filter/Filter.js index 758ed994..3968486f 100644 --- a/src/components/Filter/Filter.js +++ b/src/components/Filter/Filter.js @@ -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 }) => ( @@ -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}`} > @@ -52,7 +53,7 @@ const FilterTagsExclusive = ({ : '') } onClick={() => { - handleTag(1, resourceType, index, key); + handleTag(1, resourceType, tag, index, key); }} data-cy={`filter-option-${tag}`} > @@ -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 && ( @@ -183,7 +185,27 @@ export default function Filter({ Clear All

- + +

+ Resources: {filteredResources.length} +

+
+ {/* - +
*/} diff --git a/src/components/ReactGoogleMaps/ReactGoogleMaps.js b/src/components/ReactGoogleMaps/ReactGoogleMaps.js index 7a68f684..e11775a1 100644 --- a/src/components/ReactGoogleMaps/ReactGoogleMaps.js +++ b/src/components/ReactGoogleMaps/ReactGoogleMaps.js @@ -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'; @@ -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'; @@ -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; @@ -154,6 +159,7 @@ export const ReactGoogleMaps = ({ google }) => { const isMobile = useIsMobile(); const allResources = useSelector(state => state.filterMarkers.allResources); const filteredResources = useSelector(state => selectFilteredResource(state)); + // const filterTags = useSelector(state => state.filterMarkers.filterTags); const mapCenter = useSelector(state => state.filterMarkers.mapCenter); const resourceType = useSelector(state => state.filterMarkers.resourceType); @@ -168,10 +174,10 @@ export const ReactGoogleMaps = ({ google }) => { const [searchedTap, setSearchedTap] = useState(null); const [map, setMap] = useState(null); const [activeFilterTags, setActiveFilterTags] = useState( - JSON.parse(JSON.stringify(noActiveFilterTags)) + noActiveFilterTags ); const [appliedFilterTags, setAppliedFilterTags] = useState( - JSON.parse(JSON.stringify(noActiveFilterTags)) + noActiveFilterTags ); useEffect(() => { @@ -250,29 +256,41 @@ 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(filterTag)) + } + else { + dispatch(setFilterFunction(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(filterTag)) } else { - activeFilterTags_[filterType][index] = { ...key }; + activeFilterTags_[filterType][index] = key; + dispatch(setEntryFilterFunction(filterTag)) } setActiveFilterTags(activeFilterTags_); } }; const clearAllTags = () => { - setActiveFilterTags(JSON.parse(JSON.stringify(noActiveFilterTags))); + setActiveFilterTags(noActiveFilterTags); + dispatch(resetFilterFunction()) }; const applyTags = () => { - setAppliedFilterTags(JSON.parse(JSON.stringify(activeFilterTags))); + setAppliedFilterTags(activeFilterTags); }; return ( diff --git a/src/reducers/filterMarkers.js b/src/reducers/filterMarkers.js index b86196f1..566cb852 100644 --- a/src/reducers/filterMarkers.js +++ b/src/reducers/filterMarkers.js @@ -15,6 +15,8 @@ const initialState = { showingInfoWindow: false, infoIsExpanded: false, infoWindowClass: 'info-window-out-desktop', + filterTags: [], + filterEntry: "", tapFilters: { filtered: false, handicap: false, @@ -98,7 +100,29 @@ export default (state = initialState, act) => { }; case actions.SET_FILTER_FUNCTION: - return { filterFunction: !state.filterFunction, ...state }; + return { ...state, filterTags: [...state.filterTags, act.tag] } + + case actions.SET_ENTRY_FILTER_FUNCTION: + return { ...state, filterEntry: act.tag } + + case actions.REMOVE_FILTER_FUNCTION: + return { + ...state, + filterTags: state.filterTags.filter(x => x !== act.tag) + } + + case actions.REMOVE_ENTRY_FILTER_FUNCTION: + return { + ...state, + filterEntry: '' + } + + case actions.RESET_FILTER_FUNCTION: + return { + ...state, + filterTags: [], + filterEntry: '' + }; case actions.SET_SELECTED_PLACE: // if passed Selected Place as an object, set selected place as the object @@ -106,10 +130,10 @@ export default (state = initialState, act) => { return typeof act.selectedPlace === 'object' ? { ...state, selectedPlace: act.selectedPlace } : { - ...state, - selectedPlace: state.allResources[act.selectedPlace], - showingInfoWindow: true - }; + ...state, + selectedPlace: state.allResources[act.selectedPlace], + showingInfoWindow: true + }; case actions.toggleInfoWindow.type: return { @@ -126,27 +150,27 @@ export default (state = initialState, act) => { case actions.TOGGLE_INFO_EXPANDED: return { ...state, infoIsExpanded: act.isExpanded }; - case actions.RESET_FILTER_FUNCTION: - return { - ...state, - tapFilters: { - accessTypesHidden: [], - filtered: false, - handicap: false, - sparkling: false, - openNow: false - }, - foodFilters: { - foodSite: false, - school: false, - charter: false, - pha: false, - idRequired: false, - kidOnly: false, - openNow: false, - accessTypesHidden: [] - } - }; + // case actions.RESET_FILTER_FUNCTION: + // return { + // ...state, + // tapFilters: { + // accessTypesHidden: [], + // filtered: false, + // handicap: false, + // sparkling: false, + // openNow: false + // }, + // foodFilters: { + // foodSite: false, + // school: false, + // charter: false, + // pha: false, + // idRequired: false, + // kidOnly: false, + // openNow: false, + // accessTypesHidden: [] + // } + // }; case actions.SET_FILTERED_TAP_TYPES: { let currentAccessTypesHidden = [...state.tapFilters.accessTypesHidden]; diff --git a/src/selectors/resourceSelectors.js b/src/selectors/resourceSelectors.js new file mode 100644 index 00000000..c9934262 --- /dev/null +++ b/src/selectors/resourceSelectors.js @@ -0,0 +1,101 @@ +import { createSelector } from 'reselect'; + +const getAllResources = state => state.filterMarkers.allResources; +const getResourceType = state => state.filterMarkers.resourceType; +const filterTags = state => state.filterMarkers.filterTags; +const filterEntry = state => state.filterMarkers.filterEntry; + +const tagMapping = { + //ENTRY TYPES + 'Open Access': 'OPEN', + 'Restricted': 'RESTRICTED', + 'Unsure': 'UNSURE', + //WATER + //dispenser types + 'Drinking fountain': 'DRINKING_FOUNTAIN', + 'Bottle filler': 'BOTTLE_FILLER', + 'Sink': 'SINK', + 'Water cooler': 'WATER_COOLER', + 'Soda machine': 'SODA_MACHINE', + 'Vessel': 'VESSEL', + //features + 'ADA accessible': 'WHEELCHAIR_ACCESSIBLE', + 'Filtered water': 'FILTERED', + 'Vessel needed': 'BYOB', + 'ID required': 'ID_REQUIRED', + //FOOD + //food types + 'Perishable': 'PERISHABLE', + 'Non-perishable': 'NON_PERISHABLE', + 'Prepared foods and meals': 'PREPARED', + //distribution types + 'Eat on site': 'EAT_ON_SITE', + 'Delivery': 'DELIVERY', + 'Pick up': 'PICKUP', + //organization types + 'Government': 'GOVERNMENT', 'Business': 'BUSINESS', 'Non-profit': 'NON_PROFIT', + //FORAGING + //forage type + 'Nut': 'NUT', 'Fruit': 'FRUIT', 'Leaves': 'LEAVES', 'Bark': 'BARK', 'Flowers': 'FLOWERS', + //features + 'Medicinal': 'MEDICINAL', 'In season': 'IN_SEASON', 'Community garden': 'COMMUNITY_GARDEN', + //BATHROOM + //features + 'Gender neutral': 'GENDER_NEUTRAL', + 'Changing table': 'CHANGING_TABLE', + 'Single occupancy': 'SINGLE_OCCUPANCY', + 'Family bathroom': 'FAMILY', + 'Has water fountain': 'HAS_FOUNTAIN', +} + +const propertyMapping = { + 'WATER': ['dispenser_type', 'tags'], + 'FOOD': [], + 'FORAGE': [], + 'BATHROOM': ['tags'] +} + +/** + * This creates a selector for all resources filtered by the requested filters. + */ +const selectFilteredResource = createSelector( + [getAllResources, getResourceType, filterTags, filterEntry], + (allResources, resourceType, tags, entryType) => { + // First, filter based on resource type + let filteredResources = [] + allResources.filter(resource => { + let isValid = false + let isEntryValid = true + if (resource.resource_type === resourceType) isValid = true + //run through filters + if (isValid) { + //logic for entry types + if (entryType) { + if (resource.entry_type != tagMapping[entryType]) isEntryValid = false + } + const resourceTypeFormatted = resource.resource_type.toLowerCase() + //logic for other filters + tags.forEach(tag => { + const tagFormatted = tagMapping[tag] + //check to make sure resource has property with filter info + if (resourceTypeFormatted in resource) { + let tagFound = false + //loop through filter info types to find filter value + propertyMapping[resourceType].forEach(prop => { + if (prop in resource[resourceTypeFormatted]) { + if (resource[resourceTypeFormatted][prop].includes(tagFormatted)) tagFound = true + } + }) + if (!tagFound) isValid = false + } + else if (!(resourceTypeFormatted in resource)) isValid = false + }) + } + //return resource if it matches resource type and entry type filters + if (isValid && isEntryValid) filteredResources.push(resource) + }); + return filteredResources + } +); + +export default selectFilteredResource; diff --git a/src/selectors/waterSelectors.js b/src/selectors/waterSelectors.js deleted file mode 100644 index 92cd8ca7..00000000 --- a/src/selectors/waterSelectors.js +++ /dev/null @@ -1,102 +0,0 @@ -import { createSelector } from 'reselect'; - -import { hours } from '../helpers/hours'; - -const getTapFilters = state => state.filterMarkers.tapFilters; -const getAllResources = state => state.filterMarkers.allResources; -const getResourceType = state => state.filterMarkers.resourceType; - -/** - * This creates a selector for all resources filtered by the requested filters. - */ -const selectFilteredResource = createSelector( - [getAllResources, getResourceType], - (allResources, resourceType) => { - // First, filter based on resource - return allResources.filter(resource => { - return resource.resource_type === resourceType; - }); - - // // Default filters - // filteredTaps = Object.keys(filteredTaps) - // .filter(key => { - // return ( - // allTaps[key].permanently_closed !== undefined && - // allTaps[key].permanently_closed !== true - // ); - // }) - // .reduce((obj, key) => { - // obj[key] = allTaps[key]; - // return obj; - // }, []); - // - // // If we want to filter for filtered taps (water filter) - // if (tapFilters.filtered) { - // filteredTaps = Object.keys(filteredTaps) - // .filter(key => allTaps[key].filtration === 'Yes') - // .reduce((obj, key) => { - // obj[key] = allTaps[key]; - // return obj; - // }, []); - // } - // - // // If we want to filter for handicap-accessible taps - // if (tapFilters.handicap) { - // filteredTaps = Object.keys(filteredTaps) - // .filter(key => filteredTaps[key].handicap === 'Yes') - // .reduce((obj, key) => { - // obj[key] = filteredTaps[key]; - // return obj; - // }, []); - // } - // - // // If we want to filter for taps that offer sparkling water - // if (tapFilters.sparkling) { - // filteredTaps = Object.keys(filteredTaps) - // .filter(key => filteredTaps[key].sparkling === 'yes') - // .reduce((obj, key) => { - // obj[key] = filteredTaps[key]; - // return obj; - // }, []); - // } - // - // if (tapFilters.openNow) { - // filteredTaps = Object.keys(filteredTaps) - // .filter(key => { - // const today = new Date(); - // const currentDay = today.getDay(); - // - // let selectedPlace = filteredTaps[key]; - // - // return selectedPlace.hours !== undefined - // ? selectedPlace.hours.length >= currentDay + 1 - // ? selectedPlace.hours[currentDay].close !== undefined && - // selectedPlace.hours[currentDay].open !== undefined - // ? hours.checkOpen( - // selectedPlace.hours[currentDay].open.time, - // selectedPlace.hours[currentDay].close.time - // ) - // : false - // : false - // : false; - // }) - // .reduce((obj, key) => { - // obj[key] = filteredTaps[key]; - // return obj; - // }, []); - // } - // - // filteredTaps = Object.keys(filteredTaps) - // .filter( - // key => !tapFilters.accessTypesHidden.includes(filteredTaps[key].access) - // ) - // .reduce((obj, key) => { - // obj[key] = filteredTaps[key]; - // return obj; - // }, []); - // return filteredTaps; - // }); - } -); - -export default selectFilteredResource; From 81abd50cd419d33e23b74b6d27d6d04fcac0bfb9 Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Fri, 12 Jul 2024 22:14:21 -0400 Subject: [PATCH 2/6] revert back to JSON.parse & JSON.stringify to make deep copy of state --- src/components/ReactGoogleMaps/ReactGoogleMaps.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ReactGoogleMaps/ReactGoogleMaps.js b/src/components/ReactGoogleMaps/ReactGoogleMaps.js index e11775a1..6e3afe6b 100644 --- a/src/components/ReactGoogleMaps/ReactGoogleMaps.js +++ b/src/components/ReactGoogleMaps/ReactGoogleMaps.js @@ -174,10 +174,10 @@ export const ReactGoogleMaps = ({ google }) => { const [searchedTap, setSearchedTap] = useState(null); const [map, setMap] = useState(null); const [activeFilterTags, setActiveFilterTags] = useState( - noActiveFilterTags + JSON.parse(JSON.stringify(noActiveFilterTags)) ); const [appliedFilterTags, setAppliedFilterTags] = useState( - noActiveFilterTags + JSON.parse(JSON.stringify(noActiveFilterTags)) ); useEffect(() => { @@ -285,12 +285,12 @@ export const ReactGoogleMaps = ({ google }) => { }; const clearAllTags = () => { - setActiveFilterTags(noActiveFilterTags); + setActiveFilterTags(JSON.parse(JSON.stringify(noActiveFilterTags))); dispatch(resetFilterFunction()) }; const applyTags = () => { - setAppliedFilterTags(activeFilterTags); + setAppliedFilterTags(JSON.parse(JSON.stringify(activeFilterTags))); }; return ( From d3a38bc9d9e43c491147d04cf6973362a85df0cf Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Tue, 30 Jul 2024 18:52:26 -0400 Subject: [PATCH 3/6] remove test for apply button which no longer exists --- cypress/e2e/desktop/filters.cy.js | 86 +++++++++++++++---------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/cypress/e2e/desktop/filters.cy.js b/cypress/e2e/desktop/filters.cy.js index c7469faf..ff4aa17b 100644 --- a/cypress/e2e/desktop/filters.cy.js +++ b/cypress/e2e/desktop/filters.cy.js @@ -3,47 +3,47 @@ // 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() + + // 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 + }); }); From f85d485fa4e434a8cd77d2eeec72d791d8aa6c6d Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Tue, 30 Jul 2024 19:22:41 -0400 Subject: [PATCH 4/6] remove test looking for html title that doesn't exist --- cypress/e2e/desktop/filters.cy.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cypress/e2e/desktop/filters.cy.js b/cypress/e2e/desktop/filters.cy.js index ff4aa17b..03f1084b 100644 --- a/cypress/e2e/desktop/filters.cy.js +++ b/cypress/e2e/desktop/filters.cy.js @@ -21,18 +21,8 @@ describe("filters", () => { 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", () => { From 82cbe0f21aac2c77b6395121cc7896b70a5cf703 Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Tue, 30 Jul 2024 20:03:22 -0400 Subject: [PATCH 5/6] fix issues for PR --- src/actions/actions.js | 30 ++++--------------- src/components/Filter/Filter.js | 19 ------------ .../ReactGoogleMaps/ReactGoogleMaps.js | 10 +++---- src/reducers/filterMarkers.js | 29 +++++------------- src/selectors/resourceSelectors.js | 5 ++-- 5 files changed, 21 insertions(+), 72 deletions(-) diff --git a/src/actions/actions.js b/src/actions/actions.js index 132cb0cc..b4ec389c 100644 --- a/src/actions/actions.js +++ b/src/actions/actions.js @@ -18,34 +18,16 @@ export const setToggleStateFood = (toggle, toggleState) => ({ toggleState }); -export const SET_FILTER_FUNCTION = 'SET_FILTER_FUNCTION'; -export const setFilterFunction = (tag) => ({ - type: SET_FILTER_FUNCTION, - tag, -}); +export const setFilterFunction = createAction('SET_FILTER_FUNCTION') -export const SET_ENTRY_FILTER_FUNCTION = 'SET_ENTRY_FILTER_FUNCTION'; -export const setEntryFilterFunction = (tag) => ({ - type: SET_ENTRY_FILTER_FUNCTION, - tag, -}); +export const setEntryFilterFunction = createAction('SET_ENTRY_FILTER_FUNCTION') -export const REMOVE_FILTER_FUNCTION = 'REMOVE_FILTER_FUNCTION'; -export const removeFilterFunction = (tag) => ({ - type: REMOVE_FILTER_FUNCTION, - tag, -}); +export const removeFilterFunction = createAction('REMOVE_FILTER_FUNCTION') -export const REMOVE_ENTRY_FILTER_FUNCTION = 'REMOVE_ENTRY_FILTER_FUNCTION'; -export const removeEntryFilterFunction = (tag) => ({ - type: REMOVE_ENTRY_FILTER_FUNCTION, - tag, -}); +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', diff --git a/src/components/Filter/Filter.js b/src/components/Filter/Filter.js index 3968486f..9f15212b 100644 --- a/src/components/Filter/Filter.js +++ b/src/components/Filter/Filter.js @@ -205,25 +205,6 @@ export default function Filter({ Resources: {filteredResources.length}

- {/* - - */} diff --git a/src/components/ReactGoogleMaps/ReactGoogleMaps.js b/src/components/ReactGoogleMaps/ReactGoogleMaps.js index 6e3afe6b..e594b584 100644 --- a/src/components/ReactGoogleMaps/ReactGoogleMaps.js +++ b/src/components/ReactGoogleMaps/ReactGoogleMaps.js @@ -159,8 +159,6 @@ export const ReactGoogleMaps = ({ google }) => { const isMobile = useIsMobile(); const allResources = useSelector(state => state.filterMarkers.allResources); const filteredResources = useSelector(state => selectFilteredResource(state)); - // const filterTags = useSelector(state => state.filterMarkers.filterTags); - const mapCenter = useSelector(state => state.filterMarkers.mapCenter); const resourceType = useSelector(state => state.filterMarkers.resourceType); const showingInfoWindow = useSelector( @@ -261,10 +259,10 @@ export const ReactGoogleMaps = ({ google }) => { if (type == 0) { let activeFilterTags_ = { ...activeFilterTags }; if (activeFilterTags_[filterType][index][key]) { - dispatch(removeFilterFunction(filterTag)) + dispatch(removeFilterFunction({ tag: filterTag })) } else { - dispatch(setFilterFunction(filterTag)) + dispatch(setFilterFunction({ tag: filterTag })) } activeFilterTags_[filterType][index][key] = !activeFilterTags_[filterType][index][key]; @@ -275,10 +273,10 @@ export const ReactGoogleMaps = ({ google }) => { let activeFilterTags_ = { ...activeFilterTags }; if (activeFilterTags_[filterType][index] == key) { activeFilterTags_[filterType][index] = null; - dispatch(removeEntryFilterFunction(filterTag)) + dispatch(removeEntryFilterFunction()) } else { activeFilterTags_[filterType][index] = key; - dispatch(setEntryFilterFunction(filterTag)) + dispatch(setEntryFilterFunction({ tag: filterTag })) } setActiveFilterTags(activeFilterTags_); } diff --git a/src/reducers/filterMarkers.js b/src/reducers/filterMarkers.js index 566cb852..bcbd36ca 100644 --- a/src/reducers/filterMarkers.js +++ b/src/reducers/filterMarkers.js @@ -17,19 +17,6 @@ const initialState = { infoWindowClass: 'info-window-out-desktop', filterTags: [], filterEntry: "", - tapFilters: { - filtered: false, - handicap: false, - sparkling: false, - openNow: false, - accessTypesHidden: [] - }, - foodFilters: { - idRequired: false, - kidOnly: false, - openNow: false, - accessTypesHidden: [] - }, /** @type {ResourceEntry[]} */ allResources: [], selectedPlace: {}, @@ -99,25 +86,25 @@ export default (state = initialState, act) => { allResources: [...state.allResources, act.newResource] }; - case actions.SET_FILTER_FUNCTION: - return { ...state, filterTags: [...state.filterTags, act.tag] } + case actions.setFilterFunction.type: + return { ...state, filterTags: [...state.filterTags, act.payload.tag] } - case actions.SET_ENTRY_FILTER_FUNCTION: - return { ...state, filterEntry: act.tag } + case actions.setEntryFilterFunction.type: + return { ...state, filterEntry: act.payload.tag } - case actions.REMOVE_FILTER_FUNCTION: + case actions.removeFilterFunction.type: return { ...state, - filterTags: state.filterTags.filter(x => x !== act.tag) + filterTags: state.filterTags.filter(x => x !== act.payload.tag) } - case actions.REMOVE_ENTRY_FILTER_FUNCTION: + case actions.removeEntryFilterFunction.type: return { ...state, filterEntry: '' } - case actions.RESET_FILTER_FUNCTION: + case actions.resetFilterFunction.type: return { ...state, filterTags: [], diff --git a/src/selectors/resourceSelectors.js b/src/selectors/resourceSelectors.js index c9934262..9bc629cd 100644 --- a/src/selectors/resourceSelectors.js +++ b/src/selectors/resourceSelectors.js @@ -5,6 +5,7 @@ const getResourceType = state => state.filterMarkers.resourceType; const filterTags = state => state.filterMarkers.filterTags; const filterEntry = state => state.filterMarkers.filterEntry; +//this controls the mapping between values shown in the frontend and values used in the database, keys correspond to frontend and values to the database const tagMapping = { //ENTRY TYPES 'Open Access': 'OPEN', @@ -50,8 +51,8 @@ const tagMapping = { const propertyMapping = { 'WATER': ['dispenser_type', 'tags'], - 'FOOD': [], - 'FORAGE': [], + 'FOOD': ['food_type', 'distribution_type'], + 'FORAGE': ['forage_type', 'tags'], 'BATHROOM': ['tags'] } From df641b0d5542d9068760ea4b4caeb124fc2f1e59 Mon Sep 17 00:00:00 2001 From: tayloraj10 Date: Tue, 30 Jul 2024 20:13:18 -0400 Subject: [PATCH 6/6] remove old dead reset code --- src/reducers/filterMarkers.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/reducers/filterMarkers.js b/src/reducers/filterMarkers.js index dd98b363..e5ba791a 100644 --- a/src/reducers/filterMarkers.js +++ b/src/reducers/filterMarkers.js @@ -146,28 +146,6 @@ export default (state = initialState, act) => { case actions.TOGGLE_INFO_EXPANDED: return { ...state, infoIsExpanded: act.isExpanded }; - // case actions.RESET_FILTER_FUNCTION: - // return { - // ...state, - // tapFilters: { - // accessTypesHidden: [], - // filtered: false, - // handicap: false, - // sparkling: false, - // openNow: false - // }, - // foodFilters: { - // foodSite: false, - // school: false, - // charter: false, - // pha: false, - // idRequired: false, - // kidOnly: false, - // openNow: false, - // accessTypesHidden: [] - // } - // }; - case actions.SET_FILTERED_TAP_TYPES: { let currentAccessTypesHidden = [...state.tapFilters.accessTypesHidden]; if (currentAccessTypesHidden.includes(act.tapType)) {