From 00626b0cd80bad4fbc8ca33963fecf4c4c41ec31 Mon Sep 17 00:00:00 2001 From: Jamie Popkin Date: Fri, 18 Oct 2024 11:54:07 -0700 Subject: [PATCH 1/5] This was causing the infinite loop --- api/src/paths/public/search.ts | 7 ++++++- api/src/paths/search.ts | 13 ++++++++++++- app/src/features/search/SearchPage.tsx | 5 ++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/api/src/paths/public/search.ts b/api/src/paths/public/search.ts index df5a23fe..a01c8bbb 100644 --- a/api/src/paths/public/search.ts +++ b/api/src/paths/public/search.ts @@ -59,7 +59,8 @@ export function getSearchResults(): RequestHandler { p.state_code, psc.number_sites, psc.size_ha, - public.ST_asGeoJSON(psc.geography) as geometry + public.ST_asGeoJSON(psc.geography) as geometry, + psc.geojson#>>'{}' as geojson FROM project p LEFT JOIN @@ -83,12 +84,16 @@ export function getSearchResults(): RequestHandler { await connection.commit(); + // defaultLog.debug({ label: 'getSearchResults', message: 'response', response }); + if (!response || !response.rows) { return res.status(200).json(null); } const result: any[] = _extractResults(response.rows); + defaultLog.debug({ label: 'getSearchResults', message: 'result', result }); + return res.status(200).json(result); } catch (error) { defaultLog.error({ label: 'getSearchResults', message: 'error', error }); diff --git a/api/src/paths/search.ts b/api/src/paths/search.ts index da9c8508..c536b05c 100644 --- a/api/src/paths/search.ts +++ b/api/src/paths/search.ts @@ -125,6 +125,10 @@ export interface IGeoJSON { * @returns new feature array with mask applied */ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) => { + + // // TESTING: + // return JSON.parse(originalFeatureArray); + const featureArray: IFeatureArray = originalFeatureArray && JSON.parse(originalFeatureArray); try { const geojson: IGeoJSON[] = originalGeoJSON && JSON.parse(originalGeoJSON); @@ -150,6 +154,10 @@ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) return featureArray; }; +const _findMaskedLocation = (rows: any[]) => { + defaultLog.debug({ label: 'rows', message: rows }); + return true; +} /** * Extract an array of search result data from DB query. * @@ -163,6 +171,8 @@ export function _extractResults(rows: any[]): any[] { } const searchResults: any[] = []; + + const maskedLocations = _findMaskedLocation(rows); rows.forEach((row) => { // Protected shapes must have their geometry masked here @@ -175,7 +185,8 @@ export function _extractResults(rows: any[]): any[] { state_code: row.state_code, number_sites: row.number_sites, size_ha: row.size_ha, - geometry: [features] + geometry: [features], + maskedLocation: maskedLocations }; searchResults.push(result); diff --git a/app/src/features/search/SearchPage.tsx b/app/src/features/search/SearchPage.tsx index d46080ef..cd4cd7f9 100644 --- a/app/src/features/search/SearchPage.tsx +++ b/app/src/features/search/SearchPage.tsx @@ -99,11 +99,10 @@ const SearchPage: React.FC = () => { } }, [restorationApi.search, restorationApi.public.search, authStateContext.auth]); + // This was the source of the infinite loop. useEffect(() => { - if (performSearch) { getSearchResults(); - } - }, [performSearch, getSearchResults]); + }, []); const [sidebarOpen, setSidebarOpen] = useState(true); From 8c154553163c7f601bfe965d5ba751da67f559f2 Mon Sep 17 00:00:00 2001 From: Jamie Popkin Date: Fri, 18 Oct 2024 12:50:12 -0700 Subject: [PATCH 2/5] Think this should do it for now --- api/src/paths/public/search.ts | 4 ---- api/src/paths/search.ts | 25 ++++++++++++++------- app/src/components/map/MapContainer.tsx | 7 +++++- app/src/components/map/components/Popup.tsx | 5 ----- app/src/features/search/SearchPage.tsx | 7 ------ 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/api/src/paths/public/search.ts b/api/src/paths/public/search.ts index a01c8bbb..937be911 100644 --- a/api/src/paths/public/search.ts +++ b/api/src/paths/public/search.ts @@ -84,16 +84,12 @@ export function getSearchResults(): RequestHandler { await connection.commit(); - // defaultLog.debug({ label: 'getSearchResults', message: 'response', response }); - if (!response || !response.rows) { return res.status(200).json(null); } const result: any[] = _extractResults(response.rows); - defaultLog.debug({ label: 'getSearchResults', message: 'result', result }); - return res.status(200).json(result); } catch (error) { defaultLog.error({ label: 'getSearchResults', message: 'error', error }); diff --git a/api/src/paths/search.ts b/api/src/paths/search.ts index c536b05c..b30f7e22 100644 --- a/api/src/paths/search.ts +++ b/api/src/paths/search.ts @@ -126,9 +126,6 @@ export interface IGeoJSON { */ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) => { - // // TESTING: - // return JSON.parse(originalFeatureArray); - const featureArray: IFeatureArray = originalFeatureArray && JSON.parse(originalFeatureArray); try { const geojson: IGeoJSON[] = originalGeoJSON && JSON.parse(originalGeoJSON); @@ -154,9 +151,22 @@ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) return featureArray; }; -const _findMaskedLocation = (rows: any[]) => { - defaultLog.debug({ label: 'rows', message: rows }); - return true; +/** + * Check if there are any masked locations in the geojson. + * @param geojsonString + * @returns {boolean} + */ +const _findMaskedLocations = (geojsonString: string) => { + let maskedLocations = false; + try { + const geojson = JSON.parse(geojsonString); + if (geojson && geojson.some((feature: any) => feature.properties.maskedLocation)) { + maskedLocations = true; + } + } catch (error) { + console.log('error', error); + } + return maskedLocations; } /** * Extract an array of search result data from DB query. @@ -171,12 +181,11 @@ export function _extractResults(rows: any[]): any[] { } const searchResults: any[] = []; - - const maskedLocations = _findMaskedLocation(rows); rows.forEach((row) => { // Protected shapes must have their geometry masked here const features = _maskGateKeeper(row.geometry, row.geojson); + const maskedLocations = _findMaskedLocations(row.geojson || '{[]}'); const result: any = { id: row.id, diff --git a/app/src/components/map/MapContainer.tsx b/app/src/components/map/MapContainer.tsx index 08aba1cf..b349c403 100644 --- a/app/src/components/map/MapContainer.tsx +++ b/app/src/components/map/MapContainer.tsx @@ -415,7 +415,8 @@ const convertToCentroidGeoJSON = (features: any) => { is_project: f.is_project, state_code: f.state_code, number_sites: f.number_sites, - size_ha: f.size_ha + size_ha: f.size_ha, + maskedLocation: f.maskedLocation } }; }) @@ -1056,6 +1057,7 @@ const initializeMap = ( const numberSites = prop.number_sites; const sizeHa = prop.size_ha; const stateCode = prop.state_code; + const maskedLocation = prop.maskedLocation; let thumbnail = ''; try { @@ -1082,6 +1084,7 @@ const initializeMap = ( number_sites={numberSites} size_ha={sizeHa} state_code={stateCode} + maskedLocation={maskedLocation} thumbnail={thumbnail} maskDisclaimer={true} /> @@ -1109,6 +1112,7 @@ const initializeMap = ( const numberSites = prop.number_sites; const sizeHa = prop.size_ha; const stateCode = prop.state_code; + const maskedLocation = prop.maskedLocation; let thumbnail = ''; try { @@ -1132,6 +1136,7 @@ const initializeMap = ( state_code={stateCode} thumbnail={thumbnail} maskDisclaimer={true} + maskedLocation={maskedLocation} /> ); diff --git a/app/src/components/map/components/Popup.tsx b/app/src/components/map/components/Popup.tsx index 438d370d..9a3cb5e7 100644 --- a/app/src/components/map/components/Popup.tsx +++ b/app/src/components/map/components/Popup.tsx @@ -110,11 +110,6 @@ const MapPopup = (props: any) => { {maskedLocation && (
Location sensitive site - see FOIPPA 16, 17, 18 & 18.1.
)} - {maskDisclaimer && ( -
- Point location is approximate and does not represent the exact location of the site. -
- )} {!hideButton && (
diff --git a/app/src/features/search/SearchPage.tsx b/app/src/features/search/SearchPage.tsx index cd4cd7f9..f7ba5463 100644 --- a/app/src/features/search/SearchPage.tsx +++ b/app/src/features/search/SearchPage.tsx @@ -28,7 +28,6 @@ import { SYSTEM_ROLE } from 'constants/roles'; const SearchPage: React.FC = () => { const restorationApi = useNertApi(); - const [performSearch, setPerformSearch] = useState(true); const [geometries, setGeometries] = useState([]); const authStateContext = useAuthStateContext(); @@ -63,11 +62,6 @@ const SearchPage: React.FC = () => { ? await restorationApi.search.getSearchResults() : await restorationApi.public.search.getSearchResults(); - if (!response) { - setPerformSearch(false); - return; - } - const clusteredPointGeometries: any = []; response.forEach((result: IGetSearchResultsResponse) => { @@ -87,7 +81,6 @@ const SearchPage: React.FC = () => { } }); - setPerformSearch(false); setGeometries(clusteredPointGeometries); } catch (error) { const apiError = error as APIError; From 81ac9b05d8b9e9af372f345c677423884fea5611 Mon Sep 17 00:00:00 2001 From: Jamie Popkin Date: Fri, 18 Oct 2024 12:50:57 -0700 Subject: [PATCH 3/5] linting --- api/src/paths/search.ts | 5 ++--- app/src/features/search/SearchPage.tsx | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/api/src/paths/search.ts b/api/src/paths/search.ts index b30f7e22..761de682 100644 --- a/api/src/paths/search.ts +++ b/api/src/paths/search.ts @@ -125,7 +125,6 @@ export interface IGeoJSON { * @returns new feature array with mask applied */ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) => { - const featureArray: IFeatureArray = originalFeatureArray && JSON.parse(originalFeatureArray); try { const geojson: IGeoJSON[] = originalGeoJSON && JSON.parse(originalGeoJSON); @@ -153,7 +152,7 @@ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) /** * Check if there are any masked locations in the geojson. - * @param geojsonString + * @param geojsonString * @returns {boolean} */ const _findMaskedLocations = (geojsonString: string) => { @@ -167,7 +166,7 @@ const _findMaskedLocations = (geojsonString: string) => { console.log('error', error); } return maskedLocations; -} +}; /** * Extract an array of search result data from DB query. * diff --git a/app/src/features/search/SearchPage.tsx b/app/src/features/search/SearchPage.tsx index f7ba5463..d254078e 100644 --- a/app/src/features/search/SearchPage.tsx +++ b/app/src/features/search/SearchPage.tsx @@ -94,7 +94,7 @@ const SearchPage: React.FC = () => { // This was the source of the infinite loop. useEffect(() => { - getSearchResults(); + getSearchResults(); }, []); const [sidebarOpen, setSidebarOpen] = useState(true); From 5d144a4af1cb042a416385b695f7a630108d2252 Mon Sep 17 00:00:00 2001 From: Jamie Popkin Date: Fri, 18 Oct 2024 13:10:46 -0700 Subject: [PATCH 4/5] Fixed tests --- api/src/paths/public/search.test.ts | 2 ++ api/src/paths/search.test.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/api/src/paths/public/search.test.ts b/api/src/paths/public/search.test.ts index 463061e7..7264eaa4 100644 --- a/api/src/paths/public/search.test.ts +++ b/api/src/paths/public/search.test.ts @@ -81,6 +81,7 @@ describe('search', () => { number_sites: 1, size_ha: 100, state_code: 1, + maskedLocation: false, geometry: '{"type":"Point","coordinates":[50.7,60.9]}' } ]; @@ -109,6 +110,7 @@ describe('search', () => { number_sites: searchList[0].number_sites, size_ha: searchList[0].size_ha, state_code: searchList[0].state_code, + maskedLocation: searchList[0].maskedLocation, geometry: [ { type: 'Point', diff --git a/api/src/paths/search.test.ts b/api/src/paths/search.test.ts index 07e3a18c..549bb5d7 100644 --- a/api/src/paths/search.test.ts +++ b/api/src/paths/search.test.ts @@ -107,6 +107,7 @@ describe('search', () => { number_sites: 1, size_ha: 100, state_code: 1, + maskedLocation: false, geometry: '{"type":"Point","coordinates":[50.7,60.9]}' } ]; @@ -133,6 +134,7 @@ describe('search', () => { number_sites: searchList[0].number_sites, size_ha: searchList[0].size_ha, state_code: searchList[0].state_code, + maskedLocation: searchList[0].maskedLocation, geometry: [ { type: 'Point', From 083e5923d3cf240b5f4fc9771a036d255b53120c Mon Sep 17 00:00:00 2001 From: Kjartan Einarsson Date: Fri, 18 Oct 2024 15:35:36 -0700 Subject: [PATCH 5/5] fix cord error --- api/src/paths/search.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/paths/search.ts b/api/src/paths/search.ts index 761de682..c0f86050 100644 --- a/api/src/paths/search.ts +++ b/api/src/paths/search.ts @@ -140,11 +140,12 @@ const _maskGateKeeper = (originalFeatureArray: string, originalGeoJSON: string) units: 'meters', properties: feature.properties }); - featureArray.coordinates[index] = mask.geometry.coordinates; + featureArray.coordinates[index] = mask.geometry.coordinates[0]; } }); } catch (error) { console.log('error', error); + throw error; } return featureArray; @@ -164,6 +165,7 @@ const _findMaskedLocations = (geojsonString: string) => { } } catch (error) { console.log('error', error); + throw error; } return maskedLocations; };