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)) {