From e7d606868dfb88980b281df6216e49020f93ea55 Mon Sep 17 00:00:00 2001 From: Karolis Kazlauskis Date: Fri, 10 Nov 2023 13:48:46 +0200 Subject: [PATCH] #263 Add child sample distance warning --- package-lock.json | 45 ++++++++++++++++++++++++++-- package.json | 1 + src/Survey/List/Home/Main/index.tsx | 26 +++++++++++----- src/Survey/List/Home/index.tsx | 23 ++++++++++++-- src/Survey/Plant/Home/Main/index.tsx | 24 ++++++++++----- src/Survey/Plant/Home/index.tsx | 21 ++++++++++++- 6 files changed, 119 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 812e2b1d..472292e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "@ionic/react-router": "7.3.3", "@sentry/browser": "7.68.0", "@sentry/integrations": "7.68.0", + "@turf/distance": "^6.5.0", "axios": "1.5.0", "clsx": "2.0.0", "cordova-launch-review": "4.0.1", @@ -4264,11 +4265,33 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@turf/distance": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-6.5.0.tgz", + "integrity": "sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg==", + "dependencies": { + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, "node_modules/@turf/helpers": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", - "optional": true, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/invariant": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", + "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", + "dependencies": { + "@turf/helpers": "^6.5.0" + }, "funding": { "url": "https://opencollective.com/turf" } @@ -25040,11 +25063,27 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "@turf/distance": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-6.5.0.tgz", + "integrity": "sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg==", + "requires": { + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + } + }, "@turf/helpers": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", - "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", - "optional": true + "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==" + }, + "@turf/invariant": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", + "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", + "requires": { + "@turf/helpers": "^6.5.0" + } }, "@turf/kinks": { "version": "6.5.0", diff --git a/package.json b/package.json index 8ff6aa23..284cd0c8 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@ionic/react-router": "7.3.3", "@sentry/browser": "7.68.0", "@sentry/integrations": "7.68.0", + "@turf/distance": "^6.5.0", "axios": "1.5.0", "clsx": "2.0.0", "cordova-launch-review": "4.0.1", diff --git a/src/Survey/List/Home/Main/index.tsx b/src/Survey/List/Home/Main/index.tsx index 68874678..29e12c12 100644 --- a/src/Survey/List/Home/Main/index.tsx +++ b/src/Survey/List/Home/Main/index.tsx @@ -1,22 +1,26 @@ -import { FC } from 'react'; import { observer } from 'mobx-react'; +import { Trans as T } from 'react-i18next'; +import { useRouteMatch } from 'react-router'; +import { InfoMessage, Main } from '@flumens'; import { IonButton, IonLabel, IonList } from '@ionic/react'; -import { Main } from '@flumens'; -import MenuDynamicAttrs from 'Survey/common/Components/MenuDynamicAttrs'; -import MenuAttr from 'Survey/common/Components/MenuAttr'; +import Sample from 'models/sample'; import DisabledRecordMessage from 'Survey/common/Components/DisabledRecordMessage'; +import MenuAttr from 'Survey/common/Components/MenuAttr'; +import MenuDynamicAttrs from 'Survey/common/Components/MenuDynamicAttrs'; import SpeciesList from 'Survey/common/Components/SpeciesList'; -import Sample from 'models/sample'; -import { useRouteMatch } from 'react-router'; -import { Trans as T } from 'react-i18next'; import './styles.scss'; type Props = { sample: Sample; onDelete: any; + showChildSampleDistanceWarning: boolean; }; -const HomeMain: FC = ({ sample, onDelete }) => { +const HomeMain = ({ + sample, + onDelete, + showChildSampleDistanceWarning, +}: Props) => { const { url } = useRouteMatch(); // calculate unique taxa @@ -51,6 +55,12 @@ const HomeMain: FC = ({ sample, onDelete }) => { )}
+ {showChildSampleDistanceWarning && ( + + Some species are located far from the survey area. Please check + that this is correct. + + )}
diff --git a/src/Survey/List/Home/index.tsx b/src/Survey/List/Home/index.tsx index b85309a8..530b3ab9 100644 --- a/src/Survey/List/Home/index.tsx +++ b/src/Survey/List/Home/index.tsx @@ -1,9 +1,10 @@ import { FC, useContext } from 'react'; import { observer } from 'mobx-react'; +import { Page, Header, useToast } from '@flumens'; import { NavContext } from '@ionic/react'; +import distance from '@turf/distance'; import Sample, { useValidateCheck } from 'models/sample'; import { useUserStatusCheck } from 'models/user'; -import { Page, Header, useToast } from '@flumens'; import AppHeaderBand from 'Survey/common/Components/AppHeaderBand'; import PrimaryHeaderButton from 'Survey/common/Components/PrimaryHeaderButton'; import Main from './Main'; @@ -57,6 +58,20 @@ const ListHome: FC = ({ sample }) => { const subheader = !!training && ; + const { location } = sample.attrs; + + const isLocationFurtherThan5000m = (smp: Sample) => + distance( + [location.latitude, location.longitude], + [smp.attrs.location.latitude, smp.attrs.location.longitude], + { + units: 'meters', + } + ) > 5000; + const showChildSampleDistanceWarning = sample.samples.some( + isLocationFurtherThan5000m + ); + return (
= ({ sample }) => { defaultHref="/home/surveys" subheader={subheader} /> -
+
); }; diff --git a/src/Survey/Plant/Home/Main/index.tsx b/src/Survey/Plant/Home/Main/index.tsx index 16cffb91..cae1df7b 100644 --- a/src/Survey/Plant/Home/Main/index.tsx +++ b/src/Survey/Plant/Home/Main/index.tsx @@ -1,21 +1,25 @@ -import { FC } from 'react'; import { observer } from 'mobx-react'; +import { Trans as T } from 'react-i18next'; +import { useRouteMatch } from 'react-router'; +import { InfoMessage, Main } from '@flumens'; import { IonButton, IonLabel, IonList } from '@ionic/react'; -import MenuDynamicAttrs from 'Survey/common/Components/MenuDynamicAttrs'; +import Sample from 'models/sample'; import DisabledRecordMessage from 'Survey/common/Components/DisabledRecordMessage'; +import MenuDynamicAttrs from 'Survey/common/Components/MenuDynamicAttrs'; import SpeciesList from 'Survey/common/Components/SpeciesList'; -import { Main } from '@flumens'; -import Sample from 'models/sample'; -import { useRouteMatch } from 'react-router'; -import { Trans as T } from 'react-i18next'; import './styles.scss'; type Props = { sample: Sample; onDelete: any; + showChildSampleDistanceWarning: boolean; }; -const PlantHomeMain: FC = ({ sample, onDelete }) => { +const PlantHomeMain = ({ + sample, + onDelete, + showChildSampleDistanceWarning, +}: Props) => { const { url } = useRouteMatch(); const isDisabled = sample.isDisabled(); @@ -30,6 +34,12 @@ const PlantHomeMain: FC = ({ sample, onDelete }) => { )}
+ {showChildSampleDistanceWarning && ( + + Some species are located far from the survey area. Please check + that this is correct. + + )}
diff --git a/src/Survey/Plant/Home/index.tsx b/src/Survey/Plant/Home/index.tsx index 163a8823..12929e41 100644 --- a/src/Survey/Plant/Home/index.tsx +++ b/src/Survey/Plant/Home/index.tsx @@ -12,6 +12,7 @@ import { InfoButton, } from '@flumens'; import { NavContext, IonToolbar, isPlatform } from '@ionic/react'; +import distance from '@turf/distance'; import appModel from 'models/app'; import Sample, { useValidateCheck } from 'models/sample'; import { useUserStatusCheck } from 'models/user'; @@ -123,6 +124,20 @@ const PlantHome: FC = ({ sample }) => { ); + const { location } = sample.attrs; + + const isLocationFurtherThan5000m = (smp: Sample) => + distance( + [location.latitude, location.longitude], + [smp.attrs.location.latitude, smp.attrs.location.longitude], + { + units: 'meters', + } + ) > 5000; + const showChildSampleDistanceWarning = sample.samples.some( + isLocationFurtherThan5000m + ); + return (
= ({ sample }) => { defaultHref="/home/surveys" subheader={subheader} /> -
+
); };