+
{onGoBack && (
);
diff --git a/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/constants.ts b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/constants.ts
new file mode 100644
index 0000000000..cca30b60da
--- /dev/null
+++ b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/constants.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2025 LiteFarm.org
+ * This file is part of LiteFarm.
+ *
+ * LiteFarm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LiteFarm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details, see
.
+ */
+
+import EsciLogo from '../../../../../assets/images/partners/esci_logo.png';
+
+export const PARTNERS = {
+ ESCI: { id: 1, name: 'Ensemble Scientific', url: 'www.esci.io', logoPath: EsciLogo },
+};
diff --git a/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/styles.module.scss b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/styles.module.scss
index aa95ee5cc4..2064765215 100644
--- a/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/styles.module.scss
+++ b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/styles.module.scss
@@ -15,6 +15,8 @@
.formWrapper {
height: 100%;
- background-color: var(--White);
- padding: 24px;
+}
+
+.pageTitle {
+ padding: 24px 24px 0 24px;
}
diff --git a/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/types.ts b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/types.ts
new file mode 100644
index 0000000000..e9c48d8766
--- /dev/null
+++ b/packages/webapp/src/containers/LocationDetails/PointDetails/SensorDetail/v2/types.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2025 LiteFarm.org
+ * This file is part of LiteFarm.
+ *
+ * LiteFarm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LiteFarm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details, see
.
+ */
+
+import { FarmAddon } from '../../../../../store/api/types';
+
+export const PARTNER = 'partner';
+
+export const FarmAddonField = {
+ ORG_UUID: 'org_uuid',
+ PARTNER_ID: 'addon_partner_id',
+} as const;
+
+export type AddSensorsFormFields = {
+ [PARTNER]: FarmAddon;
+};
diff --git a/packages/webapp/src/containers/Map/index.jsx b/packages/webapp/src/containers/Map/index.jsx
index 9b1cd76a00..a6c51ecaf2 100644
--- a/packages/webapp/src/containers/Map/index.jsx
+++ b/packages/webapp/src/containers/Map/index.jsx
@@ -4,25 +4,15 @@ import { useTranslation } from 'react-i18next';
import styles from './styles.module.scss';
import GoogleMap from 'google-map-react';
import { saveAs } from 'file-saver';
-import {
- DEFAULT_ZOOM,
- GMAPS_API_KEY,
- isArea,
- isLine,
- locationEnum,
- SENSOR_BULK_UPLOAD_SUCCESS,
-} from './constants';
+import { DEFAULT_ZOOM, GMAPS_API_KEY, isArea, isLine, locationEnum } from './constants';
import { useDispatch, useSelector } from 'react-redux';
import { measurementSelector, userFarmSelector } from '../userFarmSlice';
import html2canvas from 'html2canvas';
import {
sendMapToEmail,
setSpotlightToShown,
- bulkUploadSensorsInfoFile,
getSensorReadings,
getAllSensorReadingTypes,
- resetBulkUploadSensorsInfoFile,
- resetShowTransitionModalState,
} from './saga';
import {
canShowSuccessHeader,
@@ -39,8 +29,6 @@ import DrawAreaModal from '../../components/Map/Modals/DrawArea';
import DrawLineModal from '../../components/Map/Modals/DrawLine';
import AdjustAreaModal from '../../components/Map/Modals/AdjustArea';
import AdjustLineModal from '../../components/Map/Modals/AdjustLine';
-import BulkSensorUploadModal from '../../components/Map/Modals/BulkSensorUploadModal';
-import BulkUploadTransitionModal from '../../components/Modals/BulkUploadTransitionModal';
import CustomZoom from '../../components/Map/CustomZoom';
import CustomCompass from '../../components/Map/CustomCompass';
import DrawingManager from '../../components/Map/DrawingManager';
@@ -65,10 +53,6 @@ import {
setIsRedrawing,
hookFormPersistIsRedrawingSelector,
} from '../hooks/useHookFormPersist/hookFormPersistSlice';
-import {
- bulkSensorsUploadSliceSelector,
- bulkSensorsUploadReInit,
-} from '../../containers/bulkSensorUploadSlice';
import LocationSelectionModal from './LocationSelectionModal';
import { useMaxZoom } from './useMaxZoom';
import {
@@ -77,6 +61,7 @@ import {
setMapAddDrawerShow,
} from './mapAddDrawerSlice';
import clsx from 'clsx';
+import { POST_SENSOR_URL } from '../../util/siteMapConstants';
export default function Map({ history, isCompactSideMenu }) {
const { farm_name, grid_points, is_admin, farm_id } = useSelector(userFarmSelector);
@@ -88,7 +73,6 @@ export default function Map({ history, isCompactSideMenu }) {
const dispatch = useDispatch();
const system = useSelector(measurementSelector);
const overlayData = useSelector(hookFormPersistSelector);
- const bulkSensorsUploadResponse = useSelector(bulkSensorsUploadSliceSelector);
const [gMap, setGMap] = useState(null);
const [gMaps, setGMaps] = useState(null);
const [gMapBounds, setGMapBounds] = useState(null);
@@ -130,23 +114,6 @@ export default function Map({ history, isCompactSideMenu }) {
};
}, []);
- useEffect(() => {
- if (bulkSensorsUploadResponse?.isBulkUploadSuccessful && gMaps && gMap) {
- getMaxZoom(gMaps, gMap);
- setShowBulkSensorUploadModal(false);
- }
- }, [bulkSensorsUploadResponse?.isBulkUploadSuccessful, gMaps, gMap]);
-
- useEffect(() => {
- setShowBulkSensorUploadModal(false);
- }, [bulkSensorsUploadResponse?.showTransitionModal]);
-
- useEffect(() => {
- if (history.location.state?.notification_type === SENSOR_BULK_UPLOAD_SUCCESS) {
- dispatch(setMapFilterShowAll(farm_id));
- }
- }, []);
-
const [
drawingState,
{
@@ -183,7 +150,6 @@ export default function Map({ history, isCompactSideMenu }) {
const [showExportModal, setShowExportModal] = useState(false);
const [showDrawAreaSpotlightModal, setShowDrawAreaSpotlightModal] = useState(false);
const [showDrawLineSpotlightModal, setShowDrawLineSpotlightModal] = useState(false);
- const [showBulkSensorUploadModal, setShowBulkSensorUploadModal] = useState(false);
const getMapOptions = (maps) => {
return {
@@ -389,8 +355,7 @@ export default function Map({ history, isCompactSideMenu }) {
setShowDrawLineSpotlightModal(true);
} else if (locationType === locationEnum.sensor) {
dispatch(showAddDrawer ? setMapAddDrawerHide(farm_id) : setMapAddDrawerShow(farm_id));
- setShowBulkSensorUploadModal(true);
- dispatch(resetBulkUploadSensorsInfoFile());
+ history.push(POST_SENSOR_URL);
return;
}
isLineWithWidth(locationType) && dispatch(upsertFormData(initialLineData[locationType]));
@@ -408,9 +373,6 @@ export default function Map({ history, isCompactSideMenu }) {
const handleCloseSuccessHeader = () => {
dispatch(canShowSuccessHeader(false));
setShowSuccessHeader(false);
- if (bulkSensorsUploadResponse?.isBulkUploadSuccessful) {
- dispatch(bulkSensorsUploadReInit());
- }
};
useEffect(() => {
@@ -462,11 +424,6 @@ export default function Map({ history, isCompactSideMenu }) {
return lineTypesWithWidth.includes(type);
};
- const dismissBulkSensorsUploadModal = () => {
- setShowBulkSensorUploadModal(false);
- dispatch(setMapAddDrawerShow(farm_id));
- };
-
const {
showAdjustAreaSpotlightModal,
showAdjustLineSpotlightModal,
@@ -615,22 +572,6 @@ export default function Map({ history, isCompactSideMenu }) {
}}
/>
)}
- {showBulkSensorUploadModal && (
-
{
- const payload = { file };
- dispatch(bulkUploadSensorsInfoFile(payload));
- }}
- />
- )}
- {(bulkSensorsUploadResponse?.showTransitionModal ?? false) && (
- {
- dispatch(resetShowTransitionModalState());
- }}
- />
- )}
>
);
diff --git a/packages/webapp/src/routes/index.jsx b/packages/webapp/src/routes/index.jsx
index 7df29c0c11..93ac5e9741 100644
--- a/packages/webapp/src/routes/index.jsx
+++ b/packages/webapp/src/routes/index.jsx
@@ -29,6 +29,8 @@ import { chooseFarmFlowSelector } from '../containers/ChooseFarm/chooseFarmFlowS
import useScrollToTop from '../containers/hooks/useScrollToTop';
import { useReduxSnackbar } from '../containers/Snackbar/useReduxSnackbar';
+import { POST_SENSOR_URL } from '../util/siteMapConstants';
+
//dynamic imports
const Home = React.lazy(() => import('../containers/Home'));
const Account = React.lazy(() => import('../containers/Profile/Account'));
@@ -54,85 +56,87 @@ const Prices = React.lazy(() => import('../containers/Insights/Prices'));
const ExpiredTokenScreen = React.lazy(() => import('../containers/ExpiredTokenScreen'));
const Map = React.lazy(() => import('../containers/Map'));
const MapVideo = React.lazy(() => import('../components/Map/Videos'));
-const PostFarmSiteBoundaryForm = React.lazy(() =>
- import(
- '../containers/LocationDetails/AreaDetails/FarmSiteBoundaryDetailForm/PostFarmSiteBoundary'
- ),
+const PostFarmSiteBoundaryForm = React.lazy(
+ () =>
+ import(
+ '../containers/LocationDetails/AreaDetails/FarmSiteBoundaryDetailForm/PostFarmSiteBoundary'
+ ),
);
const FarmSiteBoundaryDetails = React.lazy(() => import('./FarmSiteBoundaryDetailsRoutes'));
-const PostFieldForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/FieldDetailForm/PostField'),
+const PostFieldForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/FieldDetailForm/PostField'),
);
const FieldDetails = React.lazy(() => import('./FieldDetailsRoutes'));
-const PostGardenForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/GardenDetailForm/PostGarden'),
+const PostGardenForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/GardenDetailForm/PostGarden'),
);
const GardenDetails = React.lazy(() => import('./GardenDetailsRoutes'));
-const PostGateForm = React.lazy(() =>
- import('../containers/LocationDetails/PointDetails/GateDetailForm/PostGate'),
+const PostGateForm = React.lazy(
+ () => import('../containers/LocationDetails/PointDetails/GateDetailForm/PostGate'),
);
const GateDetails = React.lazy(() => import('./GateDetailsRoutes'));
-const PostWaterValveForm = React.lazy(() =>
- import('../containers/LocationDetails/PointDetails/WaterValveDetailForm/PostWaterValve'),
+const PostWaterValveForm = React.lazy(
+ () => import('../containers/LocationDetails/PointDetails/WaterValveDetailForm/PostWaterValve'),
);
const WaterValveDetails = React.lazy(() => import('./WaterValveDetailsRoutes'));
-const EditSensor = React.lazy(() =>
- import('../containers/LocationDetails/PointDetails/SensorDetail/EditSensor'),
+const EditSensor = React.lazy(
+ () => import('../containers/LocationDetails/PointDetails/SensorDetail/EditSensor'),
);
-const PostBarnForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/BarnDetailForm/PostBarn'),
+const PostBarnForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/BarnDetailForm/PostBarn'),
);
const BarnDetails = React.lazy(() => import('./BarnDetailsRoutes'));
-const PostNaturalAreaForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/NaturalAreaDetailForm/PostNaturalArea'),
+const PostNaturalAreaForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/NaturalAreaDetailForm/PostNaturalArea'),
);
const NaturalAreaDetails = React.lazy(() => import('./NaturalAreaDetailsRoutes'));
-const PostSurfaceWaterForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/SurfaceWaterDetailForm/PostSurfaceWater'),
+const PostSurfaceWaterForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/SurfaceWaterDetailForm/PostSurfaceWater'),
);
const SurfaceWaterDetails = React.lazy(() => import('./SurfaceWaterDetailsRoutes'));
-const PostResidenceForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/ResidenceDetailForm/PostResidence'),
+const PostResidenceForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/ResidenceDetailForm/PostResidence'),
);
const ResidenceDetails = React.lazy(() => import('./ResidenceDetailsRoutes'));
-const PostCeremonialForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/CeremonialAreaDetailForm/PostCeremonialArea'),
+const PostCeremonialForm = React.lazy(
+ () =>
+ import('../containers/LocationDetails/AreaDetails/CeremonialAreaDetailForm/PostCeremonialArea'),
);
const CeremonialAreaDetails = React.lazy(() => import('./CeremonialAreaDetailsRoutes'));
-const PostGreenhouseForm = React.lazy(() =>
- import('../containers/LocationDetails/AreaDetails/GreenhouseDetailForm/PostGreenhouse'),
+const PostGreenhouseForm = React.lazy(
+ () => import('../containers/LocationDetails/AreaDetails/GreenhouseDetailForm/PostGreenhouse'),
);
const GreenhouseDetails = React.lazy(() => import('./GreenhouseDetailsRoutes'));
const CropManagement = React.lazy(() => import('../containers/Crop/CropManagement'));
const CropDetail = React.lazy(() => import('../containers/Crop/CropDetail/index'));
-const PostFenceForm = React.lazy(() =>
- import('../containers/LocationDetails/LineDetails/FenceDetailForm/PostFence'),
+const PostFenceForm = React.lazy(
+ () => import('../containers/LocationDetails/LineDetails/FenceDetailForm/PostFence'),
);
const FenceDetails = React.lazy(() => import('./FenceDetailsRoutes'));
-const PostBufferZoneForm = React.lazy(() =>
- import('../containers/LocationDetails/LineDetails/BufferZoneDetailForm/PostBufferZone'),
+const PostBufferZoneForm = React.lazy(
+ () => import('../containers/LocationDetails/LineDetails/BufferZoneDetailForm/PostBufferZone'),
);
const BufferZoneDetails = React.lazy(() => import('./BufferZoneDetailsRoutes'));
-const PostWatercourseForm = React.lazy(() =>
- import('../containers/LocationDetails/LineDetails/WatercourseDetailForm/PostWatercourse'),
+const PostWatercourseForm = React.lazy(
+ () => import('../containers/LocationDetails/LineDetails/WatercourseDetailForm/PostWatercourse'),
);
const WatercourseDetails = React.lazy(() => import('./WatercourseDetailsRoutes'));
-const PostSensorForm = React.lazy(() =>
- import('../containers/LocationDetails/PointDetails/SensorDetail/v2/PostSensor'),
+const PostSensorForm = React.lazy(
+ () => import('../containers/LocationDetails/PointDetails/SensorDetail/v2/PostSensor'),
);
const SensorDetails = React.lazy(() => import('./SensorDetailsRoutes'));
@@ -142,34 +146,34 @@ const AddCrop = React.lazy(() => import('../containers/AddCropVariety/AddCropVar
const EditCrop = React.lazy(() => import('../containers/EditCropVariety'));
const ComplianceInfo = React.lazy(() => import('../containers/AddCropVariety/ComplianceInfo'));
const AddNewCrop = React.lazy(() => import('../containers/AddNewCrop'));
-const PlantingLocation = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/PlantingLocation'),
+const PlantingLocation = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/PlantingLocation'),
);
const Transplant = React.lazy(() => import('../containers/Crop/AddManagementPlan/Transplant'));
const PlantingDate = React.lazy(() => import('../containers/Crop/AddManagementPlan/PlantingDate'));
-const PlantingMethod = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/PlantingMethod'),
+const PlantingMethod = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/PlantingMethod'),
);
-const PlantInContainer = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/PlantInContainer'),
+const PlantInContainer = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/PlantInContainer'),
);
-const PlantBroadcast = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/BroadcastPlan'),
+const PlantBroadcast = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/BroadcastPlan'),
);
const BedPlan = React.lazy(() => import('../containers/Crop/AddManagementPlan/BedPlan/BedPlan'));
-const BedPlanGuidance = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/BedPlan/BedPlanGuidance'),
+const BedPlanGuidance = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/BedPlan/BedPlanGuidance'),
);
-const ManagementPlanName = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/ManagementPlanName'),
+const ManagementPlanName = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/ManagementPlanName'),
);
const RowMethod = React.lazy(() => import('../containers/Crop/AddManagementPlan/RowMethod'));
-const RowMethodGuidance = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/RowMethod/RowGuidance'),
+const RowMethodGuidance = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/RowMethod/RowGuidance'),
);
-const PlantedAlready = React.lazy(() =>
- import('../containers/Crop/AddManagementPlan/PlantedAlready'),
+const PlantedAlready = React.lazy(
+ () => import('../containers/Crop/AddManagementPlan/PlantedAlready'),
);
const Documents = React.lazy(() => import('../containers/Documents'));
@@ -178,60 +182,63 @@ const EditDocument = React.lazy(() => import('../containers/Documents/Edit'));
const AddDocument = React.lazy(() => import('../containers/Documents/Add'));
const MainDocument = React.lazy(() => import('../containers/Documents/Main'));
-const CertificationReportingPeriod = React.lazy(() =>
- import('../containers/Certifications/ReportingPeriod'),
+const CertificationReportingPeriod = React.lazy(
+ () => import('../containers/Certifications/ReportingPeriod'),
);
const CertificationSurvey = React.lazy(() => import('../containers/Certifications/Survey'));
-const InterestedOrganic = React.lazy(() =>
- import('../containers/OrganicCertifierSurvey/InterestedOrganic/UpdateInterestedOrganic'),
+const InterestedOrganic = React.lazy(
+ () => import('../containers/OrganicCertifierSurvey/InterestedOrganic/UpdateInterestedOrganic'),
);
-const CertificationSelection = React.lazy(() =>
- import(
- '../containers/OrganicCertifierSurvey/CertificationSelection/UpdateCertificationSelection'
- ),
+const CertificationSelection = React.lazy(
+ () =>
+ import(
+ '../containers/OrganicCertifierSurvey/CertificationSelection/UpdateCertificationSelection'
+ ),
);
-const CertifierSelectionMenu = React.lazy(() =>
- import(
- '../containers/OrganicCertifierSurvey/CertifierSelectionMenu/UpdateCertifierSelectionMenu'
- ),
+const CertifierSelectionMenu = React.lazy(
+ () =>
+ import(
+ '../containers/OrganicCertifierSurvey/CertifierSelectionMenu/UpdateCertifierSelectionMenu'
+ ),
);
-const SetCertificationSummary = React.lazy(() =>
- import(
- '../containers/OrganicCertifierSurvey/SetCertificationSummary/UpdateSetCertificationSummary'
- ),
+const SetCertificationSummary = React.lazy(
+ () =>
+ import(
+ '../containers/OrganicCertifierSurvey/SetCertificationSummary/UpdateSetCertificationSummary'
+ ),
);
-const RequestCertifier = React.lazy(() =>
- import('../containers/OrganicCertifierSurvey/RequestCertifier/UpdateRequestCertifier'),
+const RequestCertifier = React.lazy(
+ () => import('../containers/OrganicCertifierSurvey/RequestCertifier/UpdateRequestCertifier'),
);
-const ViewCertification = React.lazy(() =>
- import('../containers/OrganicCertifierSurvey/ViewCertification/ViewCertification'),
+const ViewCertification = React.lazy(
+ () => import('../containers/OrganicCertifierSurvey/ViewCertification/ViewCertification'),
);
const RenderSurvey = React.lazy(() => import('../containers/RenderSurvey/RenderSurvey'));
const ExportDownload = React.lazy(() => import('../containers/ExportDownload'));
-const ManagementTasks = React.lazy(() =>
- import('../containers/Crop/ManagementDetail/ManagementTasks'),
+const ManagementTasks = React.lazy(
+ () => import('../containers/Crop/ManagementDetail/ManagementTasks'),
);
-const ManagementDetails = React.lazy(() =>
- import('../containers/Crop/ManagementDetail/ManagementDetails'),
+const ManagementDetails = React.lazy(
+ () => import('../containers/Crop/ManagementDetail/ManagementDetails'),
);
-const EditManagementDetails = React.lazy(() =>
- import('../containers/Crop/ManagementDetail/EditManagementDetails'),
+const EditManagementDetails = React.lazy(
+ () => import('../containers/Crop/ManagementDetail/EditManagementDetails'),
);
-const CompleteManagementPlan = React.lazy(() =>
- import('../containers/Crop/CompleteManagementPlan/CompleteManagementPlan'),
+const CompleteManagementPlan = React.lazy(
+ () => import('../containers/Crop/CompleteManagementPlan/CompleteManagementPlan'),
);
-const AbandonManagementPlan = React.lazy(() =>
- import('../containers/Crop/CompleteManagementPlan/AbandonManagementPlan'),
+const AbandonManagementPlan = React.lazy(
+ () => import('../containers/Crop/CompleteManagementPlan/AbandonManagementPlan'),
);
const RepeatCropPlan = React.lazy(() => import('../containers/Crop/RepeatCropPlan'));
-const RepeatCropPlanConfirmation = React.lazy(() =>
- import('../containers/Crop/RepeatCropPlan/Confirmation'),
+const RepeatCropPlanConfirmation = React.lazy(
+ () => import('../containers/Crop/RepeatCropPlan/Confirmation'),
);
const TaskAssignment = React.lazy(() => import('../containers/Task/TaskAssignment'));
@@ -245,41 +252,41 @@ const Tasks = React.lazy(() => import('../containers/Task'));
const ManageCustomTasks = React.lazy(() => import('../containers/Task/ManageCustomTasks'));
const AddCustomTask = React.lazy(() => import('../containers/Task/AddCustomTask'));
const TaskComplete = React.lazy(() => import('../containers/Task/TaskComplete'));
-const HarvestCompleteQuantity = React.lazy(() =>
- import('../containers/Task/TaskComplete/HarvestComplete/Quantity'),
+const HarvestCompleteQuantity = React.lazy(
+ () => import('../containers/Task/TaskComplete/HarvestComplete/Quantity'),
);
-const HarvestUses = React.lazy(() =>
- import('../containers/Task/TaskComplete/HarvestComplete/HarvestUses'),
+const HarvestUses = React.lazy(
+ () => import('../containers/Task/TaskComplete/HarvestComplete/HarvestUses'),
);
const TaskCompleteStepOne = React.lazy(() => import('../containers/Task/TaskComplete/StepOne'));
const TaskReadOnly = React.lazy(() => import('../containers/Task/TaskReadOnly'));
const EditCustomTask = React.lazy(() => import('../containers/Task/EditCustomTask'));
const TaskAbandon = React.lazy(() => import('../containers/Task/TaskAbandon'));
const EditCustomTaskUpdate = React.lazy(() => import('../containers/Task/EditCustomTaskUpdate'));
-const TaskTransplantMethod = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskTransplantMethod'),
+const TaskTransplantMethod = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskTransplantMethod'),
);
-const TaskBedMethod = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskBedMethod'),
+const TaskBedMethod = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskBedMethod'),
);
-const TaskBedGuidance = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskBedGuidance'),
+const TaskBedGuidance = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskBedGuidance'),
);
-const TaskRowMethod = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskRowMethod'),
+const TaskRowMethod = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskRowMethod'),
);
-const TaskRowGuidance = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskRowGuidance'),
+const TaskRowGuidance = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskRowGuidance'),
);
-const TaskContainerMethod = React.lazy(() =>
- import('../containers/Task/TaskTransplantMethod/TaskContainerMethod'),
+const TaskContainerMethod = React.lazy(
+ () => import('../containers/Task/TaskTransplantMethod/TaskContainerMethod'),
);
const Notification = React.lazy(() => import('../containers/Notification'));
-const NotificationReadOnly = React.lazy(() =>
- import('../containers/Notification/NotificationReadOnly'),
+const NotificationReadOnly = React.lazy(
+ () => import('../containers/Notification/NotificationReadOnly'),
);
-const UnknownRecord = React.lazy(() =>
- import('../containers/ErrorHandler/UnknownRecord/UnknownRecord'),
+const UnknownRecord = React.lazy(
+ () => import('../containers/ErrorHandler/UnknownRecord/UnknownRecord'),
);
const Routes = ({ isCompactSideMenu, isFeedbackSurveyOpen, setFeedbackSurveyOpen }) => {
@@ -536,7 +543,13 @@ const Routes = ({ isCompactSideMenu, isFeedbackSurveyOpen, setFeedbackSurveyOpen
-
+
(
+
+ )}
+ />
@@ -821,7 +834,13 @@ const Routes = ({ isCompactSideMenu, isFeedbackSurveyOpen, setFeedbackSurveyOpen
-
+ (
+
+ )}
+ />
diff --git a/packages/webapp/src/store/api/apiSlice.ts b/packages/webapp/src/store/api/apiSlice.ts
index 6dcf2ffda0..70429b8c54 100644
--- a/packages/webapp/src/store/api/apiSlice.ts
+++ b/packages/webapp/src/store/api/apiSlice.ts
@@ -35,6 +35,7 @@ import {
url,
animalMovementPurposesUrl,
sensorUrl,
+ farmAddonUrl,
} from '../../apiConfig';
import type {
Animal,
@@ -55,6 +56,7 @@ import type {
AnimalUse,
AnimalMovementPurpose,
SensorData,
+ FarmAddon,
} from './types';
export const api = createApi({
@@ -91,6 +93,7 @@ export const api = createApi({
'SoilAmendmentFertiliserTypes',
'SoilAmendmentProduct',
'Sensors',
+ 'FarmAddon',
],
endpoints: (build) => ({
// redux-toolkit.js.org/rtk-query/usage-with-typescript#typing-query-and-mutation-endpoints
@@ -246,6 +249,14 @@ export const api = createApi({
keepUnusedDataFor: 60 * 60 * 24 * 365, // 1 year
providesTags: ['Sensors'],
}),
+ addFarmAddon: build.mutation({
+ query: (body) => ({
+ url: `${farmAddonUrl}`,
+ method: 'POST',
+ body,
+ }),
+ invalidatesTags: ['FarmAddon'],
+ }),
}),
});
@@ -277,4 +288,6 @@ export const {
useAddSoilAmendmentProductMutation,
useUpdateSoilAmendmentProductMutation,
useGetSensorsQuery,
+ useLazyGetSensorsQuery,
+ useAddFarmAddonMutation,
} = api;
diff --git a/packages/webapp/src/store/api/types/index.ts b/packages/webapp/src/store/api/types/index.ts
index 577994987b..fb40807e53 100644
--- a/packages/webapp/src/store/api/types/index.ts
+++ b/packages/webapp/src/store/api/types/index.ts
@@ -270,3 +270,8 @@ export interface SensorData {
sensors: Sensor[];
sensor_arrays: SensorArray[];
}
+
+export interface FarmAddon {
+ addon_partner_id: number;
+ org_uuid: string;
+}
diff --git a/packages/webapp/src/stories/ContextForm/ContextForm.stories.tsx b/packages/webapp/src/stories/ContextForm/ContextForm.stories.tsx
index 34739f03c0..787d0aa148 100644
--- a/packages/webapp/src/stories/ContextForm/ContextForm.stories.tsx
+++ b/packages/webapp/src/stories/ContextForm/ContextForm.stories.tsx
@@ -114,21 +114,48 @@ const asyncFunc = async (status: 'success' | 'fail') => {
});
};
-export const StepperFormWithCustomActionOnContinue: Story = {
+export const StepperSuccessFormWithLoading: Story = {
args: {
...stepperFormCommonProps,
hasSummaryWithinForm: true,
+ showLoading: true,
+ onSave: async (data: any, onSuccess: () => void) => {
+ await asyncFunc('success');
+ onSuccess();
+ },
+ getSteps: () => [
+ {
+ title: 'Page 1',
+ FormContent: () => Page 1
,
+ dataName: 'sensor',
+ },
+ {
+ title: 'Page 2',
+ FormContent: () => Page 2
,
+ },
+ {
+ title: 'Done',
+ FormContent: () => Summary
,
+ },
+ ],
+ },
+};
+
+export const StepperFailedFormWithLoading: Story = {
+ args: {
+ ...stepperFormCommonProps,
+ hasSummaryWithinForm: true,
+ showLoading: true,
+ onSave: () => asyncFunc('fail'),
getSteps: () => [
{
title: 'Page 1',
FormContent: () => Page 1
,
- onContinueAction: () => asyncFunc('success'),
dataName: 'sensor',
},
{
title: 'Page 2',
FormContent: () => Page 2
,
- onContinueAction: () => asyncFunc('fail'),
},
{
title: 'Done',
diff --git a/packages/webapp/src/types/index.ts b/packages/webapp/src/types/index.ts
index 318ee7f60b..eaa1bebc1e 100644
--- a/packages/webapp/src/types/index.ts
+++ b/packages/webapp/src/types/index.ts
@@ -37,3 +37,5 @@ export interface Location {
[key: string]: any;
}
+
+export type CSSLength = `${number}px` | `${number}%` | `${number}vw` | `${number}vh` | 'auto';
diff --git a/packages/webapp/src/util/siteMapConstants.ts b/packages/webapp/src/util/siteMapConstants.ts
index 20dd5d424e..eb6b1ca765 100644
--- a/packages/webapp/src/util/siteMapConstants.ts
+++ b/packages/webapp/src/util/siteMapConstants.ts
@@ -92,3 +92,6 @@ export const createCompleteTaskUrl = (id: string | number, hasAnimals: boolean):
// Maps
export const MAP_URL = '/map';
export const POST_SENSOR_URL = '/create_location/sensor';
+
+// Sensors
+export const SENSORS = '/sensors';