-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Map and Label breaking on back action #3825
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,11 +99,14 @@ export const MapAndLabelProvider: React.FC<MapAndLabelProviderProps> = ( | |
}); | ||
|
||
const [activeIndex, setActiveIndex] = useState<number>( | ||
previousFormData?.length - 1 || -1, | ||
previousFormData ? previousFormData?.length - 1 : 0, | ||
); | ||
|
||
const [minError, setMinError] = useState<boolean>(false); | ||
const [maxError, setMaxError] = useState<boolean>(false); | ||
const [loadPreviousValues, setLoadPreviousValues] = useState<boolean>( | ||
Boolean(previouslySubmittedData), | ||
); | ||
|
||
const handleGeoJSONChange = (event: GeoJSONChangeEvent) => { | ||
// If the user clicks 'reset' on the map, geojson will be empty object | ||
|
@@ -147,7 +150,9 @@ export const MapAndLabelProvider: React.FC<MapAndLabelProviderProps> = ( | |
formik.setErrors({}); | ||
}; | ||
|
||
const removeAllFeaturesFromMap = () => setFeatures(undefined); | ||
const removeAllFeaturesFromMap = () => { | ||
setFeatures(undefined); | ||
}; | ||
|
||
const removeAllFeaturesFromForm = () => { | ||
formik.setFieldValue("schemaData", []); | ||
|
@@ -179,8 +184,11 @@ export const MapAndLabelProvider: React.FC<MapAndLabelProviderProps> = ( | |
setActiveIndex(newFeatures.length - 1); | ||
}; | ||
|
||
const addInitialFeaturesToMap = (features: Feature[]) => { | ||
setFeatures(features); | ||
const addInitialFeaturesToMap = (initialFeatures: Feature[]) => { | ||
if (loadPreviousValues) { | ||
setFeatures(initialFeatures); | ||
setLoadPreviousValues(false); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, see above comment - not following this change in particular ! |
||
}; | ||
|
||
const addFeatureToForm = () => { | ||
|
@@ -198,7 +206,10 @@ export const MapAndLabelProvider: React.FC<MapAndLabelProviderProps> = ( | |
|
||
const copyFeature = (sourceIndex: number, destinationIndex: number) => { | ||
const sourceFeature = formik.values.schemaData[sourceIndex]; | ||
formik.setFieldValue(`schemaData[${destinationIndex}]`, sourceFeature); | ||
formik.setFieldValue(`schemaData[${destinationIndex}]`, { | ||
...sourceFeature, | ||
label: `${destinationIndex + 1}`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The label was being assigned based on the object you were copying from rather than the object we were copying to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch but I don't think this is quite working in all scenarios correctly yet! For example:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks so much for catching this, I'll add some adjustments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Testing added for this and hope I have solved it. I couldn't find another bug through manual testing... |
||
}); | ||
}; | ||
|
||
const removeFeatureFromForm = (index: number) => { | ||
|
@@ -236,7 +247,6 @@ export const MapAndLabelProvider: React.FC<MapAndLabelProviderProps> = ( | |
// Set active index as highest tab after removal, so that when you "add" a new feature the tabs increment correctly | ||
setActiveIndex((features && features.length - 2) || 0); | ||
}; | ||
|
||
return ( | ||
<MapAndLabelContext.Provider | ||
value={{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
import { FeatureCollection } from "geojson"; | ||
|
||
import { mockTreeData } from "./GenericValues"; | ||
export type MockPayload = { data: { MockFn: FeatureCollection } }; | ||
export interface MockPayload { | ||
data: { MockFn: FeatureCollection }; | ||
} | ||
|
||
interface PreviousData extends MockPayload { | ||
auto: boolean; | ||
} | ||
|
||
export const mockSingleFeaturePayload: MockPayload = { | ||
data: { | ||
|
@@ -11,11 +18,47 @@ export const mockSingleFeaturePayload: MockPayload = { | |
coordinates: [-3.685929607119201, 57.15301433687542], | ||
type: "Point", | ||
}, | ||
properties: { mockTreeData }, | ||
properties: { mockTreeData, label: "1" }, | ||
type: "Feature", | ||
}, | ||
], | ||
type: "FeatureCollection", | ||
}, | ||
}, | ||
}; | ||
|
||
export const previousMockDoubleFeatureData: MockPayload = { | ||
data: { | ||
MockFn: { | ||
features: [ | ||
{ | ||
geometry: { | ||
coordinates: [-3.685929607119201, 57.15301433687542], | ||
type: "Point", | ||
}, | ||
properties: { mockTreeData, label: "1" }, | ||
type: "Feature", | ||
}, | ||
{ | ||
type: "Feature", | ||
properties: { ...mockTreeData, label: "2" }, | ||
geometry: { | ||
type: "Point", | ||
coordinates: [-3.686529607119201, 57.15310433687542], | ||
}, | ||
}, | ||
], | ||
type: "FeatureCollection", | ||
}, | ||
}, | ||
}; | ||
|
||
export const previouslySubmittedSingleData: PreviousData = { | ||
auto: false, | ||
...mockSingleFeaturePayload, | ||
}; | ||
|
||
export const previouslySubmittedDoubleData: PreviousData = { | ||
auto: false, | ||
...previousMockDoubleFeatureData, | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per your question in the PR description, mocking |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { MyMap } from "@opensystemslab/map"; | ||
import React from "react"; | ||
import { setup } from "testUtils"; | ||
import { it, vi } from "vitest"; | ||
|
||
import { Presentational as MapAndLabel } from "../Public"; | ||
import { point1, point2, point3 } from "./mocks/geojson"; | ||
import { | ||
previousDoubleDataProps, | ||
previousSingleDataProps, | ||
} from "./mocks/Trees"; | ||
import { addMultipleFeatures } from "./utils"; | ||
|
||
beforeAll(() => { | ||
if (!window.customElements.get("my-map")) { | ||
window.customElements.define("my-map", MyMap); | ||
} | ||
|
||
const ResizeObserverMock = vi.fn(() => ({ | ||
observe: vi.fn(), | ||
unobserve: vi.fn(), | ||
disconnect: vi.fn(), | ||
})); | ||
|
||
vi.stubGlobal("ResizeObserver", ResizeObserverMock); | ||
jessicamcinchak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
|
||
describe("navigating back after adding single feature", () => { | ||
it("shows previously submitted features", async () => { | ||
const { getByTestId, queryByRole } = setup( | ||
<MapAndLabel {...previousSingleDataProps} />, | ||
); | ||
const map = getByTestId("map-and-label-map"); | ||
|
||
expect(map).toBeInTheDocument(); | ||
|
||
const firstTab = queryByRole("tab", { name: /Tree 1/ }); | ||
expect(firstTab).toBeVisible(); | ||
|
||
const firstTabPanel = getByTestId("vertical-tabpanel-0"); | ||
expect(firstTabPanel).toBeVisible(); | ||
|
||
// point1 here needs to be reflected in the props you pass in at the start so labels match | ||
addMultipleFeatures([point1, point2]); | ||
|
||
const secondTab = queryByRole("tab", { name: /Tree 2/ }); | ||
expect(secondTab).toBeVisible(); | ||
}); | ||
}); | ||
|
||
describe("navigating back after adding two features", () => { | ||
it("shows previously submitted features", async () => { | ||
const { getByTestId, queryByRole } = setup( | ||
<MapAndLabel {...previousDoubleDataProps} />, | ||
); | ||
const map = getByTestId("map-and-label-map"); | ||
|
||
expect(map).toBeInTheDocument(); | ||
|
||
const firstTab = queryByRole("tab", { name: /Tree 1/ }); | ||
const secondTab = queryByRole("tab", { name: /Tree 2/ }); | ||
expect(firstTab).toBeInTheDocument(); | ||
expect(secondTab).toBeInTheDocument(); | ||
|
||
const secondTabPanel = getByTestId("vertical-tabpanel-1"); | ||
expect(secondTabPanel).toBeVisible(); | ||
|
||
addMultipleFeatures([point1, point2, point3]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: aren't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is correct, it should just be adding one feature at a time. I'll adjust and switch the functions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found that this was correct and just adding a single point deletes the others from the map, so I need them added like this. I've added a comment above each line explaining this need |
||
|
||
const thirdTab = queryByRole("tab", { name: /Tree 3/ }); | ||
expect(thirdTab).toBeVisible(); | ||
}); | ||
}); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file was becoming quite long, so it felt right to move the back navigation tests to separate file, and relocate these files to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went round the blocks with this trying to find an elegant solution, this felt like the best option to ensure previous values only loaded once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand the addition of these local state variables - why can't we simply ensure
addInitialFeaturesToMap
is only called if whenpreviouslySubmittedData
is present? What's a scenario where we're trying to load initial values more than once?If we do indeed need this, can we rename it to something like
loadPreviousValuesOnMap
because it's not actually handling the form tab data (formik.initialValues
is, right?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I could understand,
previouslySubmittedData
is always present once you navigate backwards, so when you add a new point the code will run again and it will add the new point tofeatures
then hit theif()
statement then reassignfeatures
to bepreviouslySubmittedData.data...
I initially tried to place it in a
useEffect()
to only run theif
statement on initial mount then wheneverpreviouslySubmittedData
changed, but I couldn't get it to work so easily, and it felt like a larger change than the state variable.Have I missed a simpler solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explanation - happy to keep this approach then, it seems to be achieving what we want !