diff --git a/app/layout/project/sidebar/scenario/grid-setup/cost-surface/index.tsx b/app/layout/project/sidebar/scenario/grid-setup/cost-surface/index.tsx
index e5af34d1bb..6f39612dcb 100644
--- a/app/layout/project/sidebar/scenario/grid-setup/cost-surface/index.tsx
+++ b/app/layout/project/sidebar/scenario/grid-setup/cost-surface/index.tsx
@@ -1,4 +1,4 @@
-import { ComponentProps, useCallback, useEffect, useRef, useState } from 'react';
+import { ComponentProps, useCallback, useRef, useState } from 'react';
import { Form as FormRFF, FormProps, Field } from 'react-final-form';
@@ -10,6 +10,7 @@ import { getScenarioEditSlice } from 'store/slices/scenarios/edit';
import { motion } from 'framer-motion';
import { sortBy } from 'lodash';
import { HiOutlineArrowUpOnSquareStack } from 'react-icons/hi2';
+import { useEffectOnceWhen } from 'rooks';
import { useProjectCostSurfaces } from 'hooks/cost-surface';
import { useCanEditScenario } from 'hooks/permissions';
@@ -57,10 +58,11 @@ export const GridSetupCostSurface = (): JSX.Element => {
{},
{
select: (data) =>
- sortBy(
- data.filter(({ isDefault }) => !isDefault),
- 'name'
- )?.map(({ id, name }) => ({ value: id, label: name })),
+ sortBy(data, 'name')?.map(({ id, name, isDefault }) => ({
+ value: id,
+ label: name,
+ isDefault,
+ })),
}
);
const scenarioQuery = useScenario(sid, {
@@ -95,21 +97,23 @@ export const GridSetupCostSurface = (): JSX.Element => {
setSuccessFile(null);
}, []);
+ const defaultCostSurface = costSurfaceQuery.data?.find(({ isDefault }) => isDefault);
+
const onChangeCostSurface = useCallback(
(value: string) => {
formRef.current.change('costSurfaceId', value);
- dispatch(setSelectedCostSurface(value));
+ dispatch(setSelectedCostSurface(value ?? defaultCostSurface?.value));
dispatch(
setLayerSettings({
- id: value,
+ id: value ?? defaultCostSurface?.value,
settings: {
visibility: true,
},
})
);
},
- [dispatch, setSelectedCostSurface, setLayerSettings]
+ [dispatch, setSelectedCostSurface, setLayerSettings, defaultCostSurface]
);
const handleCostSurfaceChange = useCallback(
@@ -119,10 +123,20 @@ export const GridSetupCostSurface = (): JSX.Element => {
{ sid },
{
onSuccess: () => {
+ dispatch(setSelectedCostSurface(defaultCostSurface?.value));
+ dispatch(
+ setLayerSettings({
+ id: defaultCostSurface?.value,
+ settings: {
+ visibility: true,
+ },
+ })
+ );
+
addToast(
'scenario-cost-surface-unlink-success',
<>
-
Cost surface unlinked successfully
+ Cost surface applied successfully
>,
{
level: 'success',
@@ -149,6 +163,16 @@ export const GridSetupCostSurface = (): JSX.Element => {
{ sid, csid: data.costSurfaceId },
{
onSuccess: () => {
+ dispatch(setSelectedCostSurface(data.costSurfaceId));
+ dispatch(
+ setLayerSettings({
+ id: data.costSurfaceId,
+ settings: {
+ visibility: true,
+ },
+ })
+ );
+
addToast(
'scenario-cost-surface-success',
<>
@@ -174,24 +198,31 @@ export const GridSetupCostSurface = (): JSX.Element => {
}
);
},
- [linkScenarioMutation, unlinkScenarioMutation, sid, addToast]
+ [
+ linkScenarioMutation,
+ unlinkScenarioMutation,
+ sid,
+ addToast,
+ dispatch,
+ setSelectedCostSurface,
+ setLayerSettings,
+ defaultCostSurface,
+ ]
);
- useEffect(() => {
- if (scenarioQuery.isSuccess) {
- const costSurfaceId = scenarioQuery.data.costSurface?.id;
- dispatch(setSelectedCostSurface(costSurfaceId));
+ useEffectOnceWhen(() => {
+ const costSurfaceId = scenarioQuery.data.costSurface.id;
- dispatch(
- setLayerSettings({
- id: costSurfaceId,
- settings: {
- visibility: true,
- },
- })
- );
- }
- }, [scenarioQuery, dispatch, setSelectedCostSurface, setLayerSettings]);
+ dispatch(setSelectedCostSurface(costSurfaceId));
+ dispatch(
+ setLayerSettings({
+ id: costSurfaceId,
+ settings: {
+ visibility: true,
+ },
+ })
+ );
+ }, Boolean(scenarioQuery.data?.id));
return (
{
onSubmit={handleCostSurfaceChange}
initialValues={{
- costSurfaceId: scenarioQuery.data.costSurface?.id || null,
+ costSurfaceId: scenarioQuery.data?.costSurface?.id || null,
}}
keepDirtyOnReinitialize
>
@@ -256,9 +287,10 @@ export const GridSetupCostSurface = (): JSX.Element => {
size="base"
theme="dark"
selected={fprops.values.costSurfaceId}
- options={costSurfaceQuery.data}
+ options={costSurfaceQuery.data?.filter(({ isDefault }) => !isDefault)}
clearSelectionActive
onChange={onChangeCostSurface}
+ clearSelectionLabel="Default cost surface"
/>
)}
diff --git a/app/package.json b/app/package.json
index cb8ac85955..4e658f094e 100644
--- a/app/package.json
+++ b/app/package.json
@@ -87,6 +87,7 @@
"react-redux": "8.1.2",
"react-resize-detector": "^6.7.3",
"react-table": "^7.7.0",
+ "rooks": "7.14.1",
"tailwind-merge": "1.13.2",
"tailwindcss": "3.3.1",
"use-debounce": "^6.0.1",
diff --git a/app/yarn.lock b/app/yarn.lock
index 0b8aead2e5..7972eeb966 100644
--- a/app/yarn.lock
+++ b/app/yarn.lock
@@ -4194,6 +4194,7 @@ __metadata:
react-redux: 8.1.2
react-resize-detector: ^6.7.3
react-table: ^7.7.0
+ rooks: 7.14.1
svg-sprite-loader: 6.0.11
svgo: 3.0.2
svgo-loader: 4.0.0
@@ -9724,6 +9725,13 @@ __metadata:
languageName: node
linkType: hard
+"performance-now@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "performance-now@npm:2.1.0"
+ checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550
+ languageName: node
+ linkType: hard
+
"picocolors@npm:^1.0.0":
version: 1.0.0
resolution: "picocolors@npm:1.0.0"
@@ -10255,6 +10263,15 @@ __metadata:
languageName: node
linkType: hard
+"raf@npm:^3.4.1":
+ version: 3.4.1
+ resolution: "raf@npm:3.4.1"
+ dependencies:
+ performance-now: ^2.1.0
+ checksum: 50ba284e481c8185dbcf45fc4618ba3aec580bb50c9121385d5698cb6012fe516d2015b1df6dd407a7b7c58d44be8086108236affbce1861edd6b44637c8cd52
+ languageName: node
+ linkType: hard
+
"raw-loader@npm:^2.0.0":
version: 2.0.0
resolution: "raw-loader@npm:2.0.0"
@@ -10881,6 +10898,21 @@ __metadata:
languageName: node
linkType: hard
+"rooks@npm:7.14.1":
+ version: 7.14.1
+ resolution: "rooks@npm:7.14.1"
+ dependencies:
+ fast-deep-equal: ^3.1.3
+ lodash.debounce: ^4.0.8
+ raf: ^3.4.1
+ use-sync-external-store: ^1.2.0
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ checksum: b88dc3d7451b017503b11be995fba2ccc260ac18a386922e490ef3d328a796cfd677c4425454efd2de4e2c936eb879febe2f9f8a939be4f22aa2a66329567895
+ languageName: node
+ linkType: hard
+
"run-parallel@npm:^1.1.9":
version: 1.1.10
resolution: "run-parallel@npm:1.1.10"
@@ -12083,7 +12115,7 @@ __metadata:
languageName: node
linkType: hard
-"use-sync-external-store@npm:^1.0.0":
+"use-sync-external-store@npm:^1.0.0, use-sync-external-store@npm:^1.2.0":
version: 1.2.0
resolution: "use-sync-external-store@npm:1.2.0"
peerDependencies: