From 7358061ec53a28d9863eb8124c38a95f3d8fba8c Mon Sep 17 00:00:00 2001
From: Thomas Lund Fagermyr <35408743+thomaslf97@users.noreply.github.com>
Date: Tue, 12 Nov 2024 09:46:14 +0100
Subject: [PATCH] Feat/fix global state bugs (#370)

* chore: Pulling main

* chore: WIP

* fix: Fixed missing empty check. Moved analogue model to its own useEffect
---
 .../AreaCoordinates/AreaCoordinates.tsx       | 32 +++----
 .../hooks/AreaCoordinates.hooks.ts            |  8 +-
 .../GrossDepositionEnviromentGroup.tsx        | 11 ++-
 .../ImageView/AnalogueModelImageView.tsx      | 24 ++---
 .../OutcropAnalogueGroup.tsx                  | 15 ++-
 .../OutcropSelect/OutcropSelect.tsx           | 15 ++-
 .../StratigrapicGroups/StratigrapicGroups.tsx | 14 ++-
 .../CaseGroup/CaseRow/hooks/useModelArea.tsx  |  1 -
 .../ModelMetadataView/ModelMetadataView.tsx   | 19 +---
 src/hooks/GlobalState.tsx                     | 92 +++++++++++++++++++
 src/hooks/useFetchCases.ts                    |  5 +-
 src/hooks/useFetchImage.tsx                   | 26 ++++++
 src/hooks/useFetchImageMetadata.tsx           | 10 +-
 src/hooks/useFetchModelAreas.ts               |  6 ++
 src/pages/ModelPages/Model/Model.tsx          | 18 +++-
 .../Results/ObjectResult/ObjectResult.tsx     |  9 +-
 .../VariogramResults/VariogramResults.tsx     |  9 +-
 17 files changed, 232 insertions(+), 82 deletions(-)
 create mode 100644 src/hooks/useFetchImage.tsx

diff --git a/src/components/AreaCoordinates/AreaCoordinates.tsx b/src/components/AreaCoordinates/AreaCoordinates.tsx
index d3d04263..bc61401f 100644
--- a/src/components/AreaCoordinates/AreaCoordinates.tsx
+++ b/src/components/AreaCoordinates/AreaCoordinates.tsx
@@ -10,7 +10,6 @@ import {
 } from '@equinor/eds-core-react';
 import { cloneDeep } from 'lodash';
 import { useState } from 'react';
-import { useParams } from 'react-router-dom';
 import {
   AddAnalogueModelAreaCommandForm,
   CoordinateDto,
@@ -84,8 +83,13 @@ export const AreaCoordinates = ({
   });
   const [fallbackAreaCoordinate, setfallbackAreaCoordinate] =
     useState<AreaCoordinateType>();
-  const { modelId } = useParams();
-  const { analogueModel, modelAreaTypes, computeCases } = usePepmContextStore();
+  const {
+    analogueModel,
+    modelAreaTypes,
+    computeCases,
+    addAnalogueModelArea,
+    updateAnalogueModelArea,
+  } = usePepmContextStore();
   const { activeAreaResultList } = useModelResults(
     activeArea.name,
     computeCases,
@@ -107,13 +111,9 @@ export const AreaCoordinates = ({
       return;
     }
 
-    const selectableAreas =
-      analogueModel.modelAreas && analogueModel.modelAreas;
-
-    const selectedArea = selectableAreas?.filter(
+    const selectedArea = analogueModel.modelAreas?.filter(
       (area) => area.modelAreaType === changes.selectedItems[0].name,
     );
-
     // Area has no previous coordinates set
     //    Initialize
     if (selectedArea?.length === 0) {
@@ -200,7 +200,7 @@ export const AreaCoordinates = ({
   };
 
   const postModelArea = async () => {
-    if (modelId) {
+    if (analogueModel.analogueModelId) {
       if (activeArea && areaCoordinate) {
         const postRequestBody: AddAnalogueModelAreaCommandForm = {
           modelAreaTypeId: activeArea.modelAreaTypeId,
@@ -209,11 +209,12 @@ export const AreaCoordinates = ({
 
         const coordinateRes =
           await mutateAreaCoordinates.postAreaCoordinates.mutateAsync({
-            id: modelId,
+            id: analogueModel.analogueModelId,
             requestBody: postRequestBody,
           });
 
         if (coordinateRes.success) {
+          addAnalogueModelArea(coordinateRes.data);
           const res = await clearAndUpdate();
           if (res === 'success') setSaveAlert(true);
         }
@@ -222,14 +223,15 @@ export const AreaCoordinates = ({
   };
 
   const putModelArea = async () => {
-    if (modelId) {
+    if (analogueModel.analogueModelId) {
       const coordinateRes =
         await mutateAreaCoordinates.putAreaCoordinates.mutateAsync({
-          id: modelId,
+          id: analogueModel.analogueModelId,
           modelAreaId: areaCoordinate.modelAreaId,
           requestBody: { coordinates: areaCoordinate.coordinates },
         });
       if (coordinateRes.success) {
+        updateAnalogueModelArea(coordinateRes.data);
         const res = await clearAndUpdate();
         if (res === 'success') setSaveAlert(true);
       }
@@ -375,11 +377,7 @@ export const AreaCoordinates = ({
           )}
         {analogueModel.analogueModelId &&
           analogueModel.analogueModelImage?.analogueModelImageId && (
-            <AnalogueModelImageView
-              modelId={analogueModel.analogueModelId}
-              imageId={analogueModel.analogueModelImage?.analogueModelImageId}
-              coordinateBox={areaCoordinate}
-            />
+            <AnalogueModelImageView coordinateBox={areaCoordinate} />
           )}
       </Styled.ContentSplitter>
     </>
diff --git a/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts b/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts
index 7fcece8c..747ad035 100644
--- a/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts
+++ b/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts
@@ -22,16 +22,16 @@ export const validateCoordinates = async (
     errors.area = 'You must select a model area';
   }
 
-  if (area && area.coordinates[0].x > area.coordinates[1].x) {
+  if (area && area.coordinates[0].x > +area.coordinates[1].x) {
     errors.x0 = 'X start cannot be greater than X end.';
   }
-  if (area && area.coordinates[0].y > area.coordinates[1].y) {
+  if (area && area.coordinates[0].y > +area.coordinates[1].y) {
     errors.y0 = 'Y start cannot be greater than Y end.';
   }
-  if (area && area.coordinates[0].x === area.coordinates[1].x) {
+  if (area && area.coordinates[0].x === +area.coordinates[1].x) {
     errors.x0 = "X start/end coordinates can't be equal.";
   }
-  if (area && area.coordinates[0].y === area.coordinates[1].y) {
+  if (area && area.coordinates[0].y === +area.coordinates[1].y) {
     errors.y0 = "Y start/end coordinates can't be equal.";
   }
   if (area && NotANumber(area.coordinates[0].x)) {
diff --git a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx
index 22a69787..89f63776 100644
--- a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx
+++ b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx
@@ -53,7 +53,8 @@ export const GrossDepositionEnviromentGroup = ({
   ) => Promise<DeleteGeologicalGroupCommandResponse | undefined>;
 }) => {
   const isOwnerOrAdmin = useIsOwnerOrAdmin();
-  const { analogueModel } = usePepmContextStore();
+  const { analogueModel, addAnalogueModelGde, deleteAnalogueModelGde } =
+    usePepmContextStore();
   const [showGdeDialog, setShowGdeDialog] = useState<boolean>(false);
   const [gdeObject, setGdeObject] = useState<GdeType>(defaultGdeData);
   const [errors, setErrors] = useState<GDEErrorType>({});
@@ -62,6 +63,11 @@ export const GrossDepositionEnviromentGroup = ({
     setShowGdeDialog(!showGdeDialog);
   };
 
+  const handleGdeDelete = async (id: string) => {
+    const res = await deleteGdeRow(id);
+    if (res?.success) deleteAnalogueModelGde(id);
+  };
+
   const postGdeRow = useMutation({
     mutationFn: ({
       id,
@@ -112,6 +118,7 @@ export const GrossDepositionEnviromentGroup = ({
         requestBody: postRequestBody,
       });
       if (rowUpload.success) {
+        addAnalogueModelGde(rowUpload.data);
         setGdeObject(defaultGdeData);
         handleGdeDialog();
       }
@@ -143,7 +150,7 @@ export const GrossDepositionEnviromentGroup = ({
                     {isOwnerOrAdmin && (
                       <Button
                         variant="ghost_icon"
-                        onClick={() => deleteGdeRow(row.geologicalGroupId)}
+                        onClick={() => handleGdeDelete(row.geologicalGroupId)}
                       >
                         <Icon
                           data={deleteIcon}
diff --git a/src/components/ImageView/AnalogueModelImageView.tsx b/src/components/ImageView/AnalogueModelImageView.tsx
index f2f7235e..dff6cd11 100644
--- a/src/components/ImageView/AnalogueModelImageView.tsx
+++ b/src/components/ImageView/AnalogueModelImageView.tsx
@@ -1,35 +1,25 @@
 import { Typography } from '@equinor/eds-core-react';
-import { getAnalogueModelImage } from '../../api/custom/getAnalogueModelImageById';
-import { useQuery } from '@tanstack/react-query';
-import { useFetchImageMetadata } from '../../hooks/useFetchImageMetadata';
 import { AreaCoordinateType } from '../AreaCoordinates/AreaCoordinates';
 import { ModelImageCanvas } from './ModelImageCanvas/ModelImageCanvas';
 import { CanvasWrapper } from './AnalogueModelImageView.styled';
+import { usePepmContextStore } from '../../hooks/GlobalState';
 
 export const AnalogueModelImageView = ({
-  modelId,
-  imageId,
   coordinateBox,
 }: {
-  modelId: string;
-  imageId: string;
   coordinateBox: AreaCoordinateType;
 }) => {
-  const { data, isLoading } = useQuery({
-    queryKey: ['analogue-model-image', modelId, imageId],
-    queryFn: () => getAnalogueModelImage(modelId, imageId),
-  });
-
-  const imageMetadata = useFetchImageMetadata(imageId);
+  const { analogueModelImageURL, analogueModelImageMetadata } =
+    usePepmContextStore();
 
   return (
     <>
-      {isLoading && <Typography>Loading ...</Typography>}
-      {data && imageMetadata.data?.data && (
+      {!analogueModelImageURL && <Typography>Loading ...</Typography>}
+      {analogueModelImageURL && analogueModelImageMetadata && (
         <CanvasWrapper>
           <ModelImageCanvas
-            imageData={data}
-            imageMetadata={imageMetadata.data?.data}
+            imageData={analogueModelImageURL}
+            imageMetadata={analogueModelImageMetadata}
             coordinateBox={coordinateBox}
             showLegend={true}
             showCoordinates={true}
diff --git a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx
index 322177a0..0309b759 100644
--- a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx
+++ b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx
@@ -42,7 +42,8 @@ export const OutcropAnalogueGroup = ({
   modelIdParent?: string;
 }) => {
   const isOwnerOrAdmin = useIsOwnerOrAdmin();
-  const { analogueModel } = usePepmContextStore();
+  const { analogueModel, addAnalogueModelOutcrop, deleteAnalogueModelOutcrop } =
+    usePepmContextStore();
   const [showOutcropDialog, setShowOutcropDialog] = useState<boolean>(false);
   const [errors, setErrors] = useState<OutcropErrorType>({});
   const [outcropObject, setOutcropObject] =
@@ -78,7 +79,10 @@ export const OutcropAnalogueGroup = ({
         id: id,
         requestBody: postRequestBody,
       });
-      if (rowUpload.success) handleOutcropDialog();
+      if (rowUpload.success) {
+        handleOutcropDialog();
+        addAnalogueModelOutcrop(rowUpload.data);
+      }
     }
   };
 
@@ -88,6 +92,7 @@ export const OutcropAnalogueGroup = ({
       id: id,
       outcropId: stratigraphicGroupId,
     });
+    if (res.success) deleteAnalogueModelOutcrop(stratigraphicGroupId);
     return res;
   };
 
@@ -132,7 +137,8 @@ export const OutcropAnalogueGroup = ({
                 <Table.Cell>
                   <Styled.StratColCell>{row.name}</Styled.StratColCell>
                 </Table.Cell>
-                {row.region.locations.length !== 0 ? (
+                {row.region?.locations &&
+                row.region?.locations?.length !== 0 ? (
                   <>
                     <Table.Cell>{row.region.locations[0].country}</Table.Cell>
                     <Table.Cell>
@@ -145,7 +151,7 @@ export const OutcropAnalogueGroup = ({
                     <Table.Cell></Table.Cell>
                   </>
                 )}
-                <Table.Cell>{row.region.name}</Table.Cell>
+                <Table.Cell>{row.region?.name}</Table.Cell>
                 <Table.Cell>
                   <Styled.StratColCell>
                     {row.basins?.map((item) => item)}
@@ -173,7 +179,6 @@ export const OutcropAnalogueGroup = ({
         <Dialog.CustomContent>
           <OutcropSelect
             outcropObject={outcropObject}
-            outcropGroup={analogueModel.outcrops}
             setOutcropObject={setOutcropObject}
             error={errors}
           />
diff --git a/src/components/OutcropAnalogue/OutcropSelect/OutcropSelect.tsx b/src/components/OutcropAnalogue/OutcropSelect/OutcropSelect.tsx
index 8f8eb128..36d3c5f3 100644
--- a/src/components/OutcropAnalogue/OutcropSelect/OutcropSelect.tsx
+++ b/src/components/OutcropAnalogue/OutcropSelect/OutcropSelect.tsx
@@ -11,27 +11,24 @@ import { usePepmContextStore } from '../../../hooks/GlobalState';
 
 export const OutcropSelect = ({
   outcropObject,
-  outcropGroup,
   error,
   setOutcropObject,
 }: {
   outcropObject: OutcropType;
-  outcropGroup: OutcropDto[];
   error: OutcropErrorType;
   setOutcropObject: React.Dispatch<React.SetStateAction<OutcropType>>;
 }) => {
-  const { outcrops } = usePepmContextStore();
+  const { outcrops, analogueModel } = usePepmContextStore();
   const oc: OutcropDto[] = [...outcrops];
 
   if (outcrops.length === 0) return <p>Loading .....</p>;
 
   const filterDisabled = (option: OutcropDto) => {
-    const caseExists = outcropGroup.filter(
+    const caseExists = analogueModel.outcrops.filter(
       (outcrop) => outcrop.outcropId === option.outcropId,
     );
     return caseExists.length > 0;
   };
-
   return (
     <StyledDialog.AutocompleteList>
       <Autocomplete
@@ -64,8 +61,8 @@ export const OutcropSelect = ({
         variant={error.Analogue ? 'error' : undefined}
         helperText={error.Analogue ? error.Analogue : undefined}
       />
-
-      {outcropObject.region?.locations.length !== 0 ? (
+      {outcropObject.region?.locations &&
+      outcropObject.region?.locations?.length !== 0 ? (
         <>
           <Autocomplete
             label="Country"
@@ -89,12 +86,12 @@ export const OutcropSelect = ({
             selectedOptions={[outcropObject.region?.locations[0].locationName]}
             initialSelectedOptions={
               outcropObject.region
-                ? [outcropObject.region.locations[0].locationName]
+                ? [outcropObject.region?.locations[0].locationName]
                 : ['']
             }
             options={
               outcropObject.region !== undefined
-                ? [outcropObject.region.locations[0].locationName]
+                ? [outcropObject.region?.locations[0].locationName]
                 : ['']
             }
             noOptionsText="No options"
diff --git a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx
index f7855f2f..acdc38e0 100644
--- a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx
+++ b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx
@@ -64,7 +64,11 @@ export const StratigrapicGroups = ({
   ) => Promise<DeleteStratigraphicGroupCommandResponse | undefined>;
 }) => {
   const isOwnerOrAdmin = useIsOwnerOrAdmin();
-  const { analogueModel } = usePepmContextStore();
+  const {
+    analogueModel,
+    addAnalogueModelStratGroup,
+    deleteAnalogueModelStratGroup,
+  } = usePepmContextStore();
   const [stratColumnObject, setStratColumnObject] = useState<StratColumnType>(
     defaultStratColumnData,
   );
@@ -76,7 +80,8 @@ export const StratigrapicGroups = ({
   };
 
   const deleteRow = async (id: string) => {
-    await deleteStratColRow(id);
+    const res = await deleteStratColRow(id);
+    if (res?.success) deleteAnalogueModelStratGroup(id);
   };
 
   const postSmdaMetadataRow = useMutation({
@@ -135,7 +140,10 @@ export const StratigrapicGroups = ({
         id: id,
         requestBody: postRequestBody,
       });
-      if (rowUpload.success) handleStratColDialog();
+      if (rowUpload.success) {
+        handleStratColDialog();
+        addAnalogueModelStratGroup(rowUpload.data);
+      }
     }
   };
 
diff --git a/src/features/Compute/CaseGroup/CaseRow/hooks/useModelArea.tsx b/src/features/Compute/CaseGroup/CaseRow/hooks/useModelArea.tsx
index 370f32fb..1ab33a7d 100644
--- a/src/features/Compute/CaseGroup/CaseRow/hooks/useModelArea.tsx
+++ b/src/features/Compute/CaseGroup/CaseRow/hooks/useModelArea.tsx
@@ -21,7 +21,6 @@ export const useModelArea = (allCasesList: ComputeCaseDto[]) => {
     analogueModel !== analogueModelDefault && analogueModel.modelAreas
       ? analogueModel.modelAreas.concat(wholeModelObject)
       : wholeModelObject;
-
   const selectedRowArea = useCallback(
     (rowId: string) => {
       const rowCase = allCasesList.filter((c) => c.computeCaseId === rowId);
diff --git a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx
index d76ac473..e787c875 100644
--- a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx
+++ b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx
@@ -1,7 +1,7 @@
 /* eslint-disable max-lines */
 /* eslint-disable max-lines-per-function */
 import { Button, Typography } from '@equinor/eds-core-react';
-import { useMutation, useQuery } from '@tanstack/react-query';
+import { useMutation } from '@tanstack/react-query';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import { useParams } from 'react-router-dom';
 import {
@@ -21,7 +21,6 @@ import { OutcropAnalogueGroup } from '../../../components/OutcropAnalogue/Outcro
 import { StratigrapicGroups } from '../../../components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups';
 import { EditNameDescription } from '../EditNameDescription/EditNameDescription';
 import * as Styled from './ModelMetadataView.styled';
-import { getAnalogueModelImage } from '../../../api/custom/getAnalogueModelImageById';
 import { useIsOwnerOrAdmin } from '../../../hooks/useIsOwnerOrAdmin';
 import {
   analogueModelDefault,
@@ -36,7 +35,7 @@ export const ModelMetadataView = ({
   uploadingProgress?: number;
 }) => {
   const isOwnerOrAdmin = useIsOwnerOrAdmin();
-  const { analogueModel } = usePepmContextStore();
+  const { analogueModel, analogueModelImageURL } = usePepmContextStore();
 
   const [isAddModelDialog, setAddModelDialog] = useState<boolean>(false);
 
@@ -48,14 +47,6 @@ export const ModelMetadataView = ({
     ? analogueModel
     : analogueModelDefault;
 
-  const imageId = analogueModel.analogueModelImage?.analogueModelImageId ?? '';
-
-  const imageRequest = useQuery({
-    queryKey: ['analogue-model-image', modelId, imageId],
-    queryFn: () => getAnalogueModelImage(modelId!, imageId),
-    enabled: imageId !== '',
-  });
-
   const generateThumbnail = useMutation({
     mutationFn: (requestBody: GenerateThumbnailCommand) => {
       return JobsService.postApiJobsComputeThumbnailGen(requestBody);
@@ -263,15 +254,15 @@ export const ModelMetadataView = ({
               closeDialog={toggleEditMetadata}
             />
           </Styled.DescriptionMeta>
-          {imageRequest.data && analogueModel !== analogueModelDefault && (
+          {analogueModelImageURL && analogueModel !== analogueModelDefault && (
             <Styled.ModelImageView>
-              <img src={imageRequest.data} alt=""></img>
+              <img src={analogueModelImageURL} alt=""></img>
               <Typography>{analogueModel.name}</Typography>
             </Styled.ModelImageView>
           )}
           <Styled.ImageMessage>
             {analogueModel.isProcessed &&
-              !imageRequest.data &&
+              !analogueModelImageURL &&
               generateImageRequested.current && (
                 <div>
                   <Typography as="p">
diff --git a/src/hooks/GlobalState.tsx b/src/hooks/GlobalState.tsx
index b8d3da0f..49bc4e43 100644
--- a/src/hooks/GlobalState.tsx
+++ b/src/hooks/GlobalState.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable max-lines-per-function */
 import { create } from 'zustand';
 import { immer } from 'zustand/middleware/immer';
 import {
@@ -6,12 +7,18 @@ import {
   ComputeCaseDto,
   CountryDto,
   FieldDto,
+  GeologicalGroupDto,
   GeologicalStandardDto,
+  GetObjectResultsDto,
+  GetVariogramResultsDto,
+  ImageMetadataDto,
   JobStatus,
   ListComputeSettingsMethodDto,
+  ModelAreaDto,
   ModelAreaTypeDto,
   OutcropDto,
   StratColumnDto,
+  StratigraphicGroupDto,
   StratUnitDto,
 } from '../api/generated';
 
@@ -37,6 +44,8 @@ export const analogueModelDefault: AnalogueModelDetail = {
 
 type IPepmContext = {
   analogueModel: AnalogueModelDetail;
+  analogueModelImageURL: string;
+  analogueModelImageMetadata?: ImageMetadataDto;
   computeCases: ComputeCaseDto[];
   modelAreaTypes: ModelAreaTypeDto[];
   outcrops: OutcropDto[];
@@ -46,11 +55,24 @@ type IPepmContext = {
   stratigraphicUnits: StratUnitDto[];
   geologyStandards: GeologicalStandardDto[];
   computeSettings: ListComputeSettingsMethodDto[];
+  objectResults: GetObjectResultsDto[];
+  variogramResults: GetVariogramResultsDto[];
 };
 
 type IPepmContextActions = {
   setAnalogueModel: (analogueModel: AnalogueModelDetail) => void;
   setAnalogueModelDefault: () => void;
+  setAnalogueModelImage: (image: string) => void;
+  setAnalogueModelImageMetadata: (imageMetadata: ImageMetadataDto) => void;
+  addAnalogueModelStratGroup: (stratGroup: StratigraphicGroupDto) => void;
+  deleteAnalogueModelStratGroup: (id: string) => void;
+  addAnalogueModelArea: (modelArea: ModelAreaDto) => void;
+  updateAnalogueModelArea: (modelArea: ModelAreaDto) => void;
+  deleteAnalogueModelArea: (id: string) => void;
+  addAnalogueModelGde: (gde: GeologicalGroupDto) => void;
+  deleteAnalogueModelGde: (id: string) => void;
+  addAnalogueModelOutcrop: (outcrop: OutcropDto) => void;
+  deleteAnalogueModelOutcrop: (id: string) => void;
   setComputeCases: (computeCases: ComputeCaseDto[]) => void;
   setComputeCasesDefault: () => void;
   setModelAreaTypes: (modelAreaTypes: ModelAreaTypeDto[]) => void;
@@ -61,11 +83,14 @@ type IPepmContextActions = {
   setStratigraphicUnits: (fields: StratUnitDto[]) => void;
   setGeologicalStandards: (geologyStandards: GeologicalStandardDto[]) => void;
   setComputeSettings: (computeSettings: ListComputeSettingsMethodDto[]) => void;
+  setObjectEstimationResults: (objectResults: GetObjectResultsDto[]) => void;
+  setVariogramResults: (variogramResults: GetVariogramResultsDto[]) => void;
 };
 
 export const usePepmContextStore = create<IPepmContext & IPepmContextActions>()(
   immer((set, get) => ({
     analogueModel: analogueModelDefault,
+    analogueModelImageURL: '',
     computeCases: [],
     modelAreaTypes: [],
     outcrops: [],
@@ -75,6 +100,8 @@ export const usePepmContextStore = create<IPepmContext & IPepmContextActions>()(
     stratigraphicUnits: [],
     geologyStandards: [],
     computeSettings: [],
+    objectResults: [],
+    variogramResults: [],
     setAnalogueModel: (analogueModel: AnalogueModelDetail) =>
       set((state) => {
         state.analogueModel = analogueModel;
@@ -82,6 +109,63 @@ export const usePepmContextStore = create<IPepmContext & IPepmContextActions>()(
     setAnalogueModelDefault: () =>
       set((state) => {
         state.analogueModel = analogueModelDefault;
+        state.analogueModelImageURL = '';
+      }),
+    setAnalogueModelImage: (image: string) =>
+      set((state) => {
+        state.analogueModelImageURL = image;
+      }),
+    setAnalogueModelImageMetadata: (imageMetadata: ImageMetadataDto) =>
+      set((state) => {
+        state.analogueModelImageMetadata = imageMetadata;
+      }),
+    addAnalogueModelStratGroup: (stratGroup: StratigraphicGroupDto) =>
+      set((state) => {
+        state.analogueModel.stratigraphicGroups.push(stratGroup);
+      }),
+    deleteAnalogueModelStratGroup: (id: string) =>
+      set((state) => {
+        state.analogueModel.stratigraphicGroups =
+          state.analogueModel.stratigraphicGroups.filter(
+            (stratGroup) => stratGroup.stratigraphicGroupId !== id,
+          );
+      }),
+    addAnalogueModelGde: (gde: GeologicalGroupDto) =>
+      set((state) => {
+        state.analogueModel.geologicalGroups.push(gde);
+      }),
+    deleteAnalogueModelGde: (id: string) =>
+      set((state) => {
+        state.analogueModel.geologicalGroups =
+          state.analogueModel.geologicalGroups.filter(
+            (gde) => gde.geologicalGroupId !== id,
+          );
+      }),
+    addAnalogueModelOutcrop: (outcrop: OutcropDto) =>
+      set((state) => {
+        state.analogueModel.outcrops.push(outcrop);
+      }),
+    deleteAnalogueModelOutcrop: (id: string) =>
+      set((state) => {
+        state.analogueModel.outcrops = state.analogueModel.outcrops.filter(
+          (outcrop) => outcrop.outcropId !== id,
+        );
+      }),
+    addAnalogueModelArea: (modelArea: ModelAreaDto) =>
+      set((state) => {
+        state.analogueModel.modelAreas.push(modelArea);
+      }),
+    updateAnalogueModelArea: (modelArea: ModelAreaDto) =>
+      set((state) => {
+        state.analogueModel.modelAreas = state.analogueModel.modelAreas.map(
+          (ma) => (ma.modelAreaId !== modelArea.modelAreaId ? ma : modelArea),
+        );
+      }),
+    deleteAnalogueModelArea: (id: string) =>
+      set((state) => {
+        state.analogueModel.modelAreas = state.analogueModel.modelAreas.filter(
+          (ma) => ma.modelAreaId !== id,
+        );
       }),
     setComputeCases: (computeCases: ComputeCaseDto[]) =>
       set((state) => {
@@ -123,5 +207,13 @@ export const usePepmContextStore = create<IPepmContext & IPepmContextActions>()(
       set((state) => {
         state.computeSettings = computeSettings;
       }),
+    setObjectEstimationResults: (objectResults: GetObjectResultsDto[]) =>
+      set((state) => {
+        state.objectResults = objectResults;
+      }),
+    setVariogramResults: (variogramResults: GetVariogramResultsDto[]) =>
+      set((state) => {
+        state.variogramResults = variogramResults;
+      }),
   })),
 );
diff --git a/src/hooks/useFetchCases.ts b/src/hooks/useFetchCases.ts
index e58290d4..814e0472 100644
--- a/src/hooks/useFetchCases.ts
+++ b/src/hooks/useFetchCases.ts
@@ -10,7 +10,7 @@ export const useFetchCases = () => {
   const { modelId } = useParams();
   const { instance, accounts } = useMsal();
   const token = useAccessToken(instance, accounts[0]);
-  const { setComputeCases } = usePepmContextStore();
+  const { setComputeCases, computeCases } = usePepmContextStore();
 
   const query = useQuery({
     queryKey: ['model-cases', modelId],
@@ -22,7 +22,8 @@ export const useFetchCases = () => {
     refetchInterval: 30000,
   });
 
-  if (query.data?.data) setComputeCases(query.data.data);
+  if (query.data?.data && computeCases.length !== 0)
+    setComputeCases(query.data.data);
 
   return query;
 };
diff --git a/src/hooks/useFetchImage.tsx b/src/hooks/useFetchImage.tsx
new file mode 100644
index 00000000..c2db8ce7
--- /dev/null
+++ b/src/hooks/useFetchImage.tsx
@@ -0,0 +1,26 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+import { useQuery } from '@tanstack/react-query';
+import { useMsal } from '@azure/msal-react';
+import { useAccessToken } from './useAccessToken';
+import { analogueModelDefault, usePepmContextStore } from './GlobalState';
+import { getAnalogueModelImage } from '../api/custom/getAnalogueModelImageById';
+
+export const useFetchImage = () => {
+  const { analogueModel } = usePepmContextStore();
+  const { instance, accounts } = useMsal();
+  const token = useAccessToken(instance, accounts[0]);
+
+  const imageId = analogueModel.analogueModelImage?.analogueModelImageId
+    ? analogueModel.analogueModelImage.analogueModelImageId
+    : '';
+
+  const query = useQuery({
+    queryKey: ['analogue-model-image', analogueModel.analogueModelId, imageId],
+    queryFn: () =>
+      getAnalogueModelImage(analogueModel.analogueModelId, imageId),
+    enabled:
+      !!token && analogueModel !== analogueModelDefault && imageId !== '',
+  });
+
+  return query;
+};
diff --git a/src/hooks/useFetchImageMetadata.tsx b/src/hooks/useFetchImageMetadata.tsx
index 5f52f5b5..1bc5184c 100644
--- a/src/hooks/useFetchImageMetadata.tsx
+++ b/src/hooks/useFetchImageMetadata.tsx
@@ -3,12 +3,18 @@ import { useMsal } from '@azure/msal-react';
 import { useParams } from 'react-router-dom';
 import { useAccessToken } from './useAccessToken';
 import { AnalogueModelImagesService } from '../api/generated';
+import { usePepmContextStore } from './GlobalState';
 
-export const useFetchImageMetadata = (imageId: string) => {
+export const useFetchImageMetadata = () => {
+  const { analogueModel } = usePepmContextStore();
   const { modelId = '' } = useParams();
   const { instance, accounts } = useMsal();
   const token = useAccessToken(instance, accounts[0]);
 
+  const imageId = analogueModel.analogueModelImage?.analogueModelImageId
+    ? analogueModel.analogueModelImage.analogueModelImageId
+    : '';
+
   const query = useQuery({
     queryKey: ['analogue-model-image-metadata', modelId, imageId],
     queryFn: () =>
@@ -16,7 +22,7 @@ export const useFetchImageMetadata = (imageId: string) => {
         modelId,
         imageId,
       ),
-    enabled: !!token && modelId !== '',
+    enabled: !!token && modelId !== '' && imageId !== '',
   });
 
   return query;
diff --git a/src/hooks/useFetchModelAreas.ts b/src/hooks/useFetchModelAreas.ts
index 3a06f51c..df9915ab 100644
--- a/src/hooks/useFetchModelAreas.ts
+++ b/src/hooks/useFetchModelAreas.ts
@@ -1,10 +1,16 @@
 import { useQuery } from '@tanstack/react-query';
 import { ModelAreaTypeService } from '../api/generated';
+import { useMsal } from '@azure/msal-react';
+import { useAccessToken } from './useAccessToken';
 
 export const useFetchModelAreas = () => {
+  const { instance, accounts } = useMsal();
+  const token = useAccessToken(instance, accounts[0]);
+
   const query = useQuery({
     queryKey: ['model-area'],
     queryFn: () => ModelAreaTypeService.getApiModelareatype(),
+    enabled: !!token,
   });
 
   return query;
diff --git a/src/pages/ModelPages/Model/Model.tsx b/src/pages/ModelPages/Model/Model.tsx
index c8960885..ab7355b0 100644
--- a/src/pages/ModelPages/Model/Model.tsx
+++ b/src/pages/ModelPages/Model/Model.tsx
@@ -24,6 +24,8 @@ import {
 import { useFetchGrossDepData } from '../../../hooks/useFetchGrossDepData';
 import { useFetchCases } from '../../../hooks/useFetchCases';
 import { useFetchComputeSettings } from '../../../hooks/useFetchComputeSettings';
+import { useFetchImage } from '../../../hooks/useFetchImage';
+import { useFetchImageMetadata } from '../../../hooks/useFetchImageMetadata';
 
 // eslint-disable-next-line camelcase
 Icon.add({ mood_sad });
@@ -39,9 +41,12 @@ export const Model = () => {
   const geologyStandards = useFetchGrossDepData();
   const cases = useFetchCases();
   const computeSettings = useFetchComputeSettings();
+  const image = useFetchImage();
+  const imageMetadata = useFetchImageMetadata();
 
   const {
     setAnalogueModel,
+    setAnalogueModelImage,
     setComputeCases,
     setModelAreaTypes,
     setOutcrops,
@@ -51,10 +56,17 @@ export const Model = () => {
     setStratigraphicUnits,
     setGeologicalStandards,
     setComputeSettings,
+    setAnalogueModelImageMetadata,
   } = usePepmContextStore();
 
   useEffect(() => {
     if (data) setAnalogueModel(data.data);
+  }, [data, setAnalogueModel]);
+
+  useEffect(() => {
+    if (image.data) setAnalogueModelImage(image.data);
+    if (imageMetadata.data?.data)
+      setAnalogueModelImageMetadata(imageMetadata.data.data);
     if (cases.data?.data) setComputeCases(cases.data.data);
     if (modelArea.data?.data) setModelAreaTypes(modelArea.data.data);
     if (outcropData.data?.data) setOutcrops(outcropData.data.data);
@@ -64,12 +76,14 @@ export const Model = () => {
       setComputeSettings(computeSettings.data.data);
   }, [
     cases.data?.data,
-    data,
+    image,
     geologyStandards.data?.data,
     modelArea.data?.data,
     outcropData.data?.data,
     computeSettings.data?.data,
-    setAnalogueModel,
+    imageMetadata.data?.data,
+    setAnalogueModelImage,
+    setAnalogueModelImageMetadata,
     setComputeCases,
     setGeologicalStandards,
     setModelAreaTypes,
diff --git a/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx b/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx
index 535d9adc..2aa4fe59 100644
--- a/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx
+++ b/src/pages/ModelPages/Results/ObjectResult/ObjectResult.tsx
@@ -2,11 +2,16 @@ import { CaseResultView } from '../../../../features/Results/CaseResult/CaseResu
 import { NoResults } from '../../../../features/Results/NoResults/NoResults';
 import { useFetchObjectResults } from '../../../../hooks/useFetchChannelResults';
 import { usePepmContextStore } from '../../../../hooks/GlobalState';
+import { useEffect } from 'react';
 
 export const ObjectResult = () => {
-  const { computeCases } = usePepmContextStore();
+  const { computeCases, objectResults, setObjectEstimationResults } =
+    usePepmContextStore();
   const { data, isLoading } = useFetchObjectResults();
-  const objectResults = data?.data;
+
+  useEffect(() => {
+    if (data) setObjectEstimationResults(data.data);
+  }, [data, setObjectEstimationResults]);
 
   if (isLoading) return <>Loading ...</>;
 
diff --git a/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx b/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx
index bff5b86f..2e447b89 100644
--- a/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx
+++ b/src/pages/ModelPages/Results/VariogramResults/VariogramResults.tsx
@@ -1,3 +1,4 @@
+import { useEffect } from 'react';
 import { CaseResultView } from '../../../../features/Results/CaseResult/CaseResultView/CaseResultView';
 import { NoResults } from '../../../../features/Results/NoResults/NoResults';
 import { usePepmContextStore } from '../../../../hooks/GlobalState';
@@ -5,8 +6,12 @@ import { useFetchVariogramResults } from '../../../../hooks/useFetchVariogramRes
 
 export const VariogramResults = () => {
   const { data, isLoading } = useFetchVariogramResults();
-  const { computeCases } = usePepmContextStore();
-  const variogramResults = data?.data;
+  const { computeCases, variogramResults, setVariogramResults } =
+    usePepmContextStore();
+
+  useEffect(() => {
+    if (data) setVariogramResults(data.data);
+  }, [data, setVariogramResults]);
 
   if (isLoading) return <>Loading ...</>;