diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts index 60a4d5a2..2d9eb334 100644 --- a/frontend/.storybook/main.ts +++ b/frontend/.storybook/main.ts @@ -14,5 +14,6 @@ const config: StorybookConfig = { name: '@storybook/react-vite', options: {}, }, + staticDirs: ['../public'], }; export default config; diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx index a5ffb12e..18cb2bb7 100644 --- a/frontend/.storybook/preview.tsx +++ b/frontend/.storybook/preview.tsx @@ -1,10 +1,18 @@ import * as React from 'react'; import type { Preview } from '@storybook/react'; +import { initialize, mswLoader } from 'msw-storybook-addon'; import { atom, RecoilRoot } from 'recoil'; import { useSyncRecoilState } from '../src/lib/recoil/sync-state'; import { viewStateEffect } from '../src/app/state/view'; import { useStateEffect } from '../src/lib/recoil/state-effects/use-state-effect'; +/* + * Initializes MSW + * See https://github.com/mswjs/msw-storybook-addon#configuring-msw + * to learn how to customize it + */ +initialize(); + const mockViewState = atom({ key: 'mockViewState', default: 'exposure', @@ -34,6 +42,7 @@ const preview: Preview = { ), ], + loaders: [mswLoader], }; export default preview; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bd5a3bf1..b5d253cb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -79,6 +79,8 @@ "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-storybook": "^0.8.0", + "msw": "^2.3.5", + "msw-storybook-addon": "^2.0.3", "openapi-typescript-codegen": "^0.21.0", "prettier": "^3.2.5", "storybook": "^8.2.8", @@ -2156,6 +2158,43 @@ "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/cookie/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dev": true, + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@chromatic-com/storybook": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-1.6.1.tgz", @@ -3007,6 +3046,138 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@inquirer/confirm": { + "version": "3.1.22", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", + "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.10", + "@inquirer/type": "^1.5.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.10.tgz", + "integrity": "sha512-TdESOKSVwf6+YWDz8GhS6nKscwzkIyakEzCLJ5Vh6O3Co2ClhCJ0A4MG909MUWfaWdpJm7DE45ii51/2Kat9tA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.2", + "@types/mute-stream": "^0.0.4", + "@types/node": "^22.1.0", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/@types/node": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@inquirer/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@inquirer/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@inquirer/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/core/node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "dev": true + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.5.tgz", + "integrity": "sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.2.tgz", + "integrity": "sha512-w9qFkumYDCNyDZmNQjf/n6qQuvQ4dMC3BJesY4oF+yr0CxR5vxujflAVeIcS6U336uzi9GM0kAfZlLrZ9UTkpA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -3968,6 +4139,23 @@ "react": ">=16" } }, + "node_modules/@mswjs/interceptors": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.29.1.tgz", + "integrity": "sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==", + "dev": true, + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@mui/base": { "version": "5.0.0-beta.40", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", @@ -4382,6 +4570,28 @@ "node": ">=10" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -6234,6 +6444,12 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, "node_modules/@types/cross-spawn": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", @@ -6462,6 +6678,15 @@ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==" }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "20.14.15", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", @@ -6588,6 +6813,12 @@ "@types/send": "*" } }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "dev": true + }, "node_modules/@types/supercluster": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", @@ -6596,6 +6827,12 @@ "@types/geojson": "*" } }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true + }, "node_modules/@types/unist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", @@ -6613,6 +6850,12 @@ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.18.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", @@ -7105,6 +7348,33 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -8035,6 +8305,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -11133,6 +11412,15 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/graphql": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/h3-js": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-3.7.2.tgz", @@ -11313,6 +11601,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -11866,6 +12160,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -13136,11 +13436,163 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/msw": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.3.5.tgz", + "integrity": "sha512-+GUI4gX5YC5Bv33epBrD+BGdmDvBg2XGruiWnI3GbIbRmMMBeZ5gs3mJ51OWSGHgJKztZ8AtZeYMMNMVrje2/Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^3.0.0", + "@mswjs/interceptors": "^0.29.0", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.7.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw-storybook-addon": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-2.0.3.tgz", + "integrity": "sha512-CzHmGO32JeOPnyUnRWnB0PFTXCY1HKfHiEB/6fYoUYiFm2NYosLjzs9aBd3XJUryYEN0avJqMNh7nCRDxE5JjQ==", + "dev": true, + "dependencies": { + "is-node-process": "^1.0.1" + }, + "peerDependencies": { + "msw": "^2.0.0" + } + }, + "node_modules/msw/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/msw/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/msw/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/msw/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/msw/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true + }, + "node_modules/msw/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.24.0.tgz", + "integrity": "sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/murmurhash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -13831,6 +14283,12 @@ "node": ">=8" } }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -14331,6 +14789,12 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -14374,6 +14838,12 @@ "node": ">=14" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -15106,6 +15576,12 @@ "node": ">=0.10.5" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -16013,6 +16489,12 @@ "node": ">=8" } }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -16568,6 +17050,30 @@ "topoquantize": "bin/topoquantize" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -17130,6 +17636,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/urs": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/urs/-/urs-0.0.8.tgz", @@ -18200,6 +18716,18 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/frontend/package.json b/frontend/package.json index 32cbe1c6..d35e994f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -75,6 +75,8 @@ "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-storybook": "^0.8.0", + "msw": "^2.3.5", + "msw-storybook-addon": "^2.0.3", "openapi-typescript-codegen": "^0.21.0", "prettier": "^3.2.5", "storybook": "^8.2.8", @@ -108,5 +110,10 @@ "extends": [ "plugin:storybook/recommended" ] + }, + "msw": { + "workerDirectory": [ + "public" + ] } -} +} \ No newline at end of file diff --git a/frontend/public/mockServiceWorker.js b/frontend/public/mockServiceWorker.js new file mode 100644 index 00000000..15751fa1 --- /dev/null +++ b/frontend/public/mockServiceWorker.js @@ -0,0 +1,284 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + * - Please do NOT serve this file on production. + */ + +const PACKAGE_VERSION = '2.3.5' +const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423' +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') +const activeClientIds = new Set() + +self.addEventListener('install', function () { + self.skipWaiting() +}) + +self.addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) + +self.addEventListener('message', async function (event) { + const clientId = event.source.id + + if (!clientId || !self.clients) { + return + } + + const client = await self.clients.get(clientId) + + if (!client) { + return + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }) + break + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }) + break + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: true, + }) + break + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +self.addEventListener('fetch', function (event) { + const { request } = event + + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + // Generate unique request ID. + const requestId = crypto.randomUUID() + event.respondWith(handleRequest(event, requestId)) +}) + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + ;(async function () { + const responseClone = response.clone() + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + requestId, + isMockedResponse: IS_MOCKED_RESPONSE in response, + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + body: responseClone.body, + headers: Object.fromEntries(responseClone.headers.entries()), + }, + }, + [responseClone.body], + ) + })() + } + + return response +} + +// Resolve the main client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (client?.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +async function getResponse(event, client, requestId) { + const { request } = event + + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = request.clone() + + function passthrough() { + const headers = Object.fromEntries(requestClone.headers.entries()) + + // Remove internal MSW request header so the passthrough request + // complies with any potential CORS preflight checks on the server. + // Some servers forbid unknown request headers. + delete headers['x-msw-intention'] + + return fetch(requestClone, { headers }) + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough() + } + + // Notify the client that a request has been intercepted. + const requestBuffer = await request.arrayBuffer() + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: requestBuffer, + keepalive: request.keepalive, + }, + }, + [requestBuffer], + ) + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) + } + + case 'PASSTHROUGH': { + return passthrough() + } + } + + return passthrough() +} + +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage( + message, + [channel.port2].concat(transferrables.filter(Boolean)), + ) + }) +} + +async function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error() + } + + const mockedResponse = new Response(response.body, response) + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }) + + return mockedResponse +} diff --git a/frontend/src/details/adaptations/AdaptationsSidebar.stories.tsx b/frontend/src/details/adaptations/AdaptationsSidebar.stories.tsx new file mode 100644 index 00000000..8c4f0104 --- /dev/null +++ b/frontend/src/details/adaptations/AdaptationsSidebar.stories.tsx @@ -0,0 +1,40 @@ +import { StoryObj, Meta } from '@storybook/react'; + +import { AdaptationsSidebar } from './AdaptationsSidebar'; +import { http, HttpResponse } from 'msw'; +import mockItemSearch from 'mocks/details/adaptations/mockItemSearch.json'; +import mockItem from 'mocks/details/adaptations/mockItem.json'; + +const meta = { + title: 'Details/AdaptationsSidebar', + component: AdaptationsSidebar, +} as Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + parameters: { + msw: { + handlers: [ + http.get('/api/features/sorted-by/adaptation', ({ request }) => { + const url = new URL(request.url); + if ( + url.searchParams.get('asset_type') === 'pole' && + url.searchParams.get('sector') === 'power' && + url.searchParams.get('field') === 'avoided_ead_mean' && + url.searchParams.get('dimensions') === + '{"hazard":"TC","rcp":"4.5","adaptation_name":"Upgrade wooden poles to steel","adaptation_protection_level":0.76}' + ) { + return HttpResponse.json(mockItemSearch); + } + return new HttpResponse(null, { status: 404 }); + }), + http.get(/\/api\/features\/\d+/, () => { + return HttpResponse.json(mockItem); + }), + ], + }, + }, +}; diff --git a/frontend/src/details/features/FeatureSidebar.stories.tsx b/frontend/src/details/features/FeatureSidebar.stories.tsx new file mode 100644 index 00000000..eb425b0f --- /dev/null +++ b/frontend/src/details/features/FeatureSidebar.stories.tsx @@ -0,0 +1,32 @@ +import { StoryObj, Meta } from '@storybook/react'; +import { http, HttpResponse, delay } from 'msw'; + +import { FeatureSidebarContent } from './FeatureSidebarContent'; +import mockFeature from 'mocks/details/features/mockFeature.json'; +import mockFeatureDetails from 'mocks/details/features/mockFeatureDetails.json'; + +const meta = { + title: 'Details/FeatureSidebarContent', + component: FeatureSidebarContent, +} as Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + feature: mockFeature, + assetType: 'road_edges_class_b', + showRiskSection: true, + }, + parameters: { + msw: { + handlers: [ + http.get('/api/features/1000036526', () => { + return HttpResponse.json(mockFeatureDetails); + }), + ], + }, + }, +}; diff --git a/frontend/src/details/regions/RegionDetailsContent.stories.tsx b/frontend/src/details/regions/RegionDetailsContent.stories.tsx new file mode 100644 index 00000000..35dd9198 --- /dev/null +++ b/frontend/src/details/regions/RegionDetailsContent.stories.tsx @@ -0,0 +1,19 @@ +import { StoryObj, Meta } from '@storybook/react'; + +import mockRegion from 'mocks/details/regions/mockRegion.json'; +import { RegionDetailsContent } from './RegionDetailsContent'; + +const meta = { + title: 'Details/RegionDetailsContent', + component: RegionDetailsContent, +} as Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + selectedRegion: mockRegion, + }, +}; diff --git a/frontend/src/details/solutions/SolutionsSidebar.stories.tsx b/frontend/src/details/solutions/SolutionsSidebar.stories.tsx new file mode 100644 index 00000000..ce3a30d9 --- /dev/null +++ b/frontend/src/details/solutions/SolutionsSidebar.stories.tsx @@ -0,0 +1,29 @@ +import { StoryObj, Meta } from '@storybook/react'; + +import mockTerrestrialFeature from 'mocks/details/solutions/mockTerrestrialFeature.json'; +import mockMarineFeature from 'mocks/details/solutions/mockMarineFeature.json'; +import { SolutionsSidebarContent } from './SolutionsSidebarContent'; + +const meta = { + title: 'Details/SolutionsSidebarContent', + component: SolutionsSidebarContent, +} as Meta; + +export default meta; +type Story = StoryObj; + +export const Terrestrial: Story = { + args: { + feature: mockTerrestrialFeature, + solutionType: 'terrestrial', + showRiskSection: true, + }, +}; + +export const Marine: Story = { + args: { + feature: mockMarineFeature, + solutionType: 'marine', + showRiskSection: true, + }, +}; diff --git a/frontend/src/mocks/details/adaptations/mockItem.json b/frontend/src/mocks/details/adaptations/mockItem.json new file mode 100644 index 00000000..fefabafd --- /dev/null +++ b/frontend/src/mocks/details/adaptations/mockItem.json @@ -0,0 +1,27 @@ +{ + "id": 123456789, + "properties": { + "asset_id": "node_123456", + "_asset_type": "junction", + "asset_type": "pole", + "capacity": 8.4, + "uc_min": 1000, + "uc_max": 5000, + "uc_avg": 3000, + "uc_uom": "USD", + "cost_min": 155000, + "cost_max": 775000, + "cost_mean": 465000, + "cost_unit": "J$", + "degree": 4, + "population": 0, + "ei": 0.000126738458173, + "ei_uom": "KW/person", + "parish": "Example Parish", + "title": null, + "source": null, + "uid": 1100018779, + "sector": "power", + "subsector": "transmission" + } +} diff --git a/frontend/src/mocks/details/adaptations/mockItemSearch.json b/frontend/src/mocks/details/adaptations/mockItemSearch.json new file mode 100644 index 00000000..b5819fd9 --- /dev/null +++ b/frontend/src/mocks/details/adaptations/mockItemSearch.json @@ -0,0 +1,148 @@ +{ + "items": [ + { + "id": 1100021723, + "string_id": "node_21847", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10387418236505 18.274396684183213)", + "value": 1466.5405443779705 + }, + { + "id": 1100020360, + "string_id": "node_20477", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11063693200619 18.275868650885847)", + "value": 1466.5405443779705 + }, + { + "id": 1100020559, + "string_id": "node_20677", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10992233186853 18.278361477767437)", + "value": 1466.5405443779705 + }, + { + "id": 1100020566, + "string_id": "node_20684", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11061904865835 18.27719232760382)", + "value": 1466.5405443779705 + }, + { + "id": 1100020353, + "string_id": "node_20470", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11153779473679 18.27156252204142)", + "value": 1466.5405443779705 + }, + { + "id": 1100020357, + "string_id": "node_20474", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10603701539358 18.277140485558967)", + "value": 1466.5405443779705 + }, + { + "id": 1100020554, + "string_id": "node_20672", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10741041380685 18.278193155443148)", + "value": 1466.5405443779705 + }, + { + "id": 1100020557, + "string_id": "node_20675", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10958017350045 18.278462158339096)", + "value": 1466.5405443779705 + }, + { + "id": 1100020563, + "string_id": "node_20681", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10648558101032 18.27818056480247)", + "value": 1466.5405443779705 + }, + { + "id": 1100020564, + "string_id": "node_20682", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.1105797328665 18.276467734016933)", + "value": 1466.5405443779705 + }, + { + "id": 1100020350, + "string_id": "node_20467", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11156334829772 18.274543134652784)", + "value": 1466.5405443779705 + }, + { + "id": 1100020352, + "string_id": "node_20469", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11320869898016 18.271958836122522)", + "value": 1466.5405443779705 + }, + { + "id": 1100020354, + "string_id": "node_20471", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.1088091442301 18.27260794939098)", + "value": 1466.5405443779705 + }, + { + "id": 1100020355, + "string_id": "node_20472", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.1082030820493 18.27213781868278)", + "value": 1466.5405443779705 + }, + { + "id": 1100020348, + "string_id": "node_20465", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11058328202644 18.275726801109816)", + "value": 1466.5405443779705 + }, + { + "id": 1100020553, + "string_id": "node_20671", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.1075711530118 18.27809327861013)", + "value": 1466.5405443779705 + }, + { + "id": 1100020555, + "string_id": "node_20673", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10598892522904 18.277677358574607)", + "value": 1466.5405443779705 + }, + { + "id": 1100020556, + "string_id": "node_20674", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.10597373247143 18.277846967311064)", + "value": 1466.5405443779705 + }, + { + "id": 1100020561, + "string_id": "node_20679", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.1068663527804 18.277904527368324)", + "value": 1466.5405443779705 + }, + { + "id": 1100021751, + "string_id": "node_21875", + "layer": "elec_nodes_pole", + "bbox_wkt": "POINT(-77.11342623933814 18.267993273596883)", + "value": 1466.5405443779705 + } + ], + "total": 29934, + "page": 1, + "size": 20, + "pages": 1497 +} diff --git a/frontend/src/mocks/details/features/mockFeature.json b/frontend/src/mocks/details/features/mockFeature.json new file mode 100644 index 00000000..f516513b --- /dev/null +++ b/frontend/src/mocks/details/features/mockFeature.json @@ -0,0 +1,38 @@ +{ + "type": "Feature", + "geometry": { + "type": "LineString" + }, + "properties": { + "asset_id": "example_road_12345", + "asset_type": "CLASS B", + "ead__fluvial__rcp_2.6__epoch_2050__conf_None": 654.9977648163444, + "eael__fluvial__rcp_2.6__epoch_2050__conf_None": 2.8651382222680457, + "ead__fluvial__rcp_2.6__epoch_2080__conf_None": 733.5935769378004, + "eael__fluvial__rcp_2.6__epoch_2080__conf_None": 2.8651382222680457, + "ead__fluvial__rcp_4.5__epoch_2050__conf_None": 766.4011283676974, + "eael__fluvial__rcp_4.5__epoch_2050__conf_None": 2.8651382222680457, + "ead__fluvial__rcp_4.5__epoch_2080__conf_None": 552.0132196633816, + "eael__fluvial__rcp_4.5__epoch_2080__conf_None": 2.8651382222680457, + "ead__fluvial__rcp_8.5__epoch_2050__conf_None": 253.75512546195085, + "eael__fluvial__rcp_8.5__epoch_2050__conf_None": 2.8651382222680457, + "ead__fluvial__rcp_baseline__epoch_2010__conf_None": 3346.289085559888, + "eael__fluvial__rcp_baseline__epoch_2010__conf_None": 2.8651382222680457, + "ead__surface__rcp_2.6__epoch_2050__conf_None": 3514.535728810853, + "eael__surface__rcp_2.6__epoch_2050__conf_None": 29.36766677824747, + "ead__surface__rcp_2.6__epoch_2080__conf_None": 3514.535728810853, + "eael__surface__rcp_2.6__epoch_2080__conf_None": 29.36766677824747, + "ead__surface__rcp_4.5__epoch_2050__conf_None": 3805.873483715005, + "eael__surface__rcp_4.5__epoch_2050__conf_None": 29.36766677824747, + "ead__surface__rcp_4.5__epoch_2080__conf_None": 3805.873483715005, + "eael__surface__rcp_4.5__epoch_2080__conf_None": 29.36766677824747, + "ead__surface__rcp_8.5__epoch_2050__conf_None": 3514.535728810853, + "eael__surface__rcp_8.5__epoch_2050__conf_None": 29.36766677824747, + "ead__surface__rcp_8.5__epoch_2080__conf_None": 4133.002221143524, + "eael__surface__rcp_8.5__epoch_2080__conf_None": 29.36766677824747, + "ead__surface__rcp_baseline__epoch_2010__conf_None": 4664.595752553787, + "eael__surface__rcp_baseline__epoch_2010__conf_None": 61.60047177876298, + "layerName": "road_edges_class_b" + }, + "id": 1000036526 +} diff --git a/frontend/src/mocks/details/features/mockFeatureDetails.json b/frontend/src/mocks/details/features/mockFeatureDetails.json new file mode 100644 index 00000000..d5ba0a44 --- /dev/null +++ b/frontend/src/mocks/details/features/mockFeatureDetails.json @@ -0,0 +1,816 @@ +{ + "id": 1000036526, + "string_id": "example_road_12345", + "layer": "road_edges_class_b", + "sublayer": null, + "properties": { + "from_node": "example_road_12354", + "to_node": "example_road_12543", + "asset_id": "example_road_12345", + "component": 0.0, + "asset_type": "CLASS B", + "section_name": "0999/xx", + "street_name": "", + "street_type": "", + "vertalignm": "Flat", + "road_construction": "Asphaltic Concrete", + "road_width": 8.51, + "traffic_count": 1100.0, + "length_m": 945.7315640765089, + "cost_unit": "$J/m", + "cost_min": 179104.4776119403, + "cost_mean": 223880.59701492536, + "cost_max": 268656.7164179104, + "_asset_type": "asphalt", + "speed": 110.0, + "lanes": 2.0, + "cost_reopen": 152000.0, + "cost_reopen_unit": "J$/day", + "uid": 1000036526, + "sector": "transport", + "subsector": "transport" + }, + "damages_expected": [ + { + "ead_amin": 96.32320070828594, + "ead_mean": 654.9977648163444, + "ead_amax": 1348.5248099160033, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "2.6", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 107.88140837320594, + "ead_mean": 733.5935769378004, + "ead_amax": 1510.339717224883, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "2.6", + "epoch": "2080", + "protection_standard": 0 + }, + { + "ead_amin": 112.70604828936726, + "ead_mean": 766.4011283676974, + "ead_amax": 1577.8846760511417, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "4.5", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 81.17841465637964, + "ead_mean": 552.0132196633816, + "ead_amax": 1136.497805189315, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "4.5", + "epoch": "2080", + "protection_standard": 0 + }, + { + "ead_amin": 37.31693021499277, + "ead_mean": 253.75512546195085, + "ead_amax": 522.4370230098988, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "8.5", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 497.1218826340963, + "ead_mean": 3346.289085559888, + "ead_amax": 6882.891995085422, + "eael_amin": 2.8651382222680457, + "eael_mean": 2.8651382222680457, + "eael_amax": 2.8651382222680457, + "hazard": "fluvial", + "rcp": "baseline", + "epoch": "2010", + "protection_standard": 0 + }, + { + "ead_amin": 516.8434895310079, + "ead_mean": 3514.535728810853, + "ead_amax": 7235.8088534341105, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 516.8434895310079, + "ead_mean": 3514.535728810853, + "ead_amax": 7235.8088534341105, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2080", + "protection_standard": 0 + }, + { + "ead_amin": 559.6872770169124, + "ead_mean": 3805.873483715005, + "ead_amax": 7835.621878236773, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 559.6872770169124, + "ead_mean": 3805.873483715005, + "ead_amax": 7835.621878236773, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2080", + "protection_standard": 0 + }, + { + "ead_amin": 516.8434895310079, + "ead_mean": 3514.535728810853, + "ead_amax": 7235.8088534341105, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2050", + "protection_standard": 0 + }, + { + "ead_amin": 607.7944442858123, + "ead_mean": 4133.002221143524, + "ead_amax": 8509.122220001374, + "eael_amin": 29.367666778247468, + "eael_mean": 29.36766677824747, + "eael_amax": 29.367666778247468, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2080", + "protection_standard": 0 + }, + { + "ead_amin": 685.969963610851, + "ead_mean": 4664.595752553787, + "ead_amax": 9603.579490551916, + "eael_amin": 61.60047177876298, + "eael_mean": 61.60047177876298, + "eael_amax": 61.60047177876298, + "hazard": "surface", + "rcp": "baseline", + "epoch": "2010", + "protection_standard": 0 + } + ], + "damages_return_period": [ + { + "exposure": 273.8147650573674, + "damage_amin": 144484.8010624289, + "damage_mean": 982496.6472245165, + "damage_amax": 2022787.2148740047, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "2.6", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 273.8147650573674, + "damage_amin": 161822.11255980888, + "damage_mean": 1100390.3654067004, + "damage_amax": 2265509.575837325, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "2.6", + "epoch": "2080", + "rp": 1500 + }, + { + "exposure": 273.8147650573674, + "damage_amin": 169059.07243405088, + "damage_mean": 1149601.6925515458, + "damage_amax": 2366827.014076712, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "4.5", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 273.8147650573674, + "damage_amin": 121767.62198456944, + "damage_mean": 828019.8294950722, + "damage_amax": 1704746.7077839721, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "4.5", + "epoch": "2080", + "rp": 1500 + }, + { + "exposure": 211.893050959556, + "damage_amin": 55975.39532248915, + "damage_mean": 380632.68819292623, + "damage_amax": 783655.5345148481, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "8.5", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 397.67850255065485, + "damage_amin": 745682.8239511444, + "damage_mean": 5019433.628339832, + "damage_amax": 10324337.992628133, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "fluvial", + "rcp": "baseline", + "epoch": "2010", + "rp": 1500 + }, + { + "exposure": 30.863365627714717, + "damage_amin": 563.8368339508532, + "damage_mean": 3834.0904708658013, + "damage_amax": 7893.715675311944, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "baseline", + "epoch": "2010", + "rp": 100 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2080", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2080", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2050", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2080", + "rp": 1500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "baseline", + "epoch": "2010", + "rp": 1500 + }, + { + "exposure": 92.9835235432204, + "damage_amin": 6340.328666558573, + "damage_mean": 43114.234932598294, + "damage_amax": 88764.60133182001, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2050", + "rp": 200 + }, + { + "exposure": 92.9835235432204, + "damage_amin": 6340.328666558573, + "damage_mean": 43114.234932598294, + "damage_amax": 88764.60133182001, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2080", + "rp": 200 + }, + { + "exposure": 124.0418575122016, + "damage_amin": 10374.829617289768, + "damage_mean": 70548.8413975704, + "damage_amax": 145247.61464205672, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2050", + "rp": 200 + }, + { + "exposure": 124.0418575122016, + "damage_amin": 10374.829617289768, + "damage_mean": 70548.8413975704, + "damage_amax": 145247.61464205672, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2080", + "rp": 200 + }, + { + "exposure": 92.9835235432204, + "damage_amin": 6340.328666558573, + "damage_mean": 43114.234932598294, + "damage_amax": 88764.60133182001, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2050", + "rp": 200 + }, + { + "exposure": 124.0418575122016, + "damage_amin": 15310.044809223868, + "damage_mean": 104108.3047027223, + "damage_amax": 214340.62732913415, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2080", + "rp": 200 + }, + { + "exposure": 124.0418575122016, + "damage_amin": 28632.586578744114, + "damage_mean": 194701.58873545998, + "damage_amax": 400856.2121024176, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "baseline", + "epoch": "2010", + "rp": 200 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 165240.36946252067, + "damage_mean": 1123634.5123451403, + "damage_amax": 2313365.172475289, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2050", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 165240.36946252067, + "damage_mean": 1123634.5123451403, + "damage_amax": 2313365.172475289, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "2.6", + "epoch": "2080", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 177566.1157777421, + "damage_mean": 1207449.5872886463, + "damage_amax": 2485925.620888389, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2050", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 177566.1157777421, + "damage_mean": 1207449.5872886463, + "damage_amax": 2485925.620888389, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "4.5", + "epoch": "2080", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 165240.36946252067, + "damage_mean": 1123634.5123451403, + "damage_amax": 2313365.172475289, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2050", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 190658.25723981755, + "damage_mean": 1296476.1492307594, + "damage_amax": 2669215.601357446, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "8.5", + "epoch": "2080", + "rp": 500 + }, + { + "exposure": 255.90247019633765, + "damage_amin": 200192.06154396816, + "damage_mean": 1361306.0184989835, + "damage_amax": 2802688.8616155544, + "loss_amin": 4297.707333402068, + "loss_mean": 4297.707333402068, + "loss_amax": 4297.707333402068, + "hazard": "surface", + "rcp": "baseline", + "epoch": "2010", + "rp": 500 + } + ], + "damages_npv": [ + { + "ead_amin": 4121.922165354665, + "ead_mean": 27768.363490452757, + "ead_amax": 57120.31903855759, + "eael_amin": 31.92956686440493, + "eael_mean": 33.58691221830215, + "eael_amax": 35.63193614367749, + "hazard": "fluvial", + "rcp": "2.6" + }, + { + "ead_amin": 4169.111690249439, + "ead_mean": 28089.25225973719, + "ead_amax": 57780.97238708441, + "eael_amin": 31.92956686440493, + "eael_mean": 33.58691221830215, + "eael_amax": 35.63193614367749, + "hazard": "fluvial", + "rcp": "4.5" + }, + { + "ead_amin": 3915.057121502469, + "ead_mean": 26361.6811922578, + "ead_amax": 54224.20842462684, + "eael_amin": 31.434151277309567, + "eael_mean": 32.837846186375, + "eael_amax": 34.490115921264895, + "hazard": "fluvial", + "rcp": "8.5" + }, + { + "ead_amin": 6974.515408137568, + "ead_mean": 47426.70477533546, + "ead_amax": 97643.21571392604, + "eael_amin": 574.8893029869656, + "eael_mean": 595.9090831421685, + "eael_amax": 621.2472777541249, + "hazard": "surface", + "rcp": "2.6" + }, + { + "ead_amin": 7118.431235309964, + "ead_mean": 48405.33240010781, + "ead_amax": 99658.03729433952, + "eael_amin": 574.8893029869656, + "eael_mean": 595.9090831421685, + "eael_amax": 621.2472777541249, + "hazard": "surface", + "rcp": "4.5" + }, + { + "ead_amin": 6991.068888411265, + "ead_mean": 47539.2684411966, + "ead_amax": 97874.96443775774, + "eael_amin": 574.8893029869656, + "eael_mean": 595.9090831421685, + "eael_amax": 621.2472777541249, + "hazard": "surface", + "rcp": "8.5" + } + ], + "adaptation": [ + { + "adaptation_cost": 715456828.5280758, + "avoided_ead_amin": 11033.588508162831, + "avoided_ead_mean": 74762.60684006926, + "avoided_ead_amax": 153883.64783787203, + "avoided_eael_amin": 9080.273159537064, + "avoided_eael_mean": 9420.071643037763, + "avoided_eael_amax": 9830.430881153132, + "hazard": "flooding", + "rcp": "2.6", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.0 + }, + { + "adaptation_cost": 1073185242.7921138, + "avoided_ead_amin": 11096.437573492232, + "avoided_ead_mean": 75195.06826578823, + "avoided_ead_amax": 154763.53475248365, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "2.6", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.5 + }, + { + "adaptation_cost": 1430913657.0561516, + "avoided_ead_amin": 11096.437573492232, + "avoided_ead_mean": 75195.06826578823, + "avoided_ead_amax": 154763.53475248365, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "2.6", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.0 + }, + { + "adaptation_cost": 1788642071.3201897, + "avoided_ead_amin": 11096.437573492232, + "avoided_ead_mean": 75195.06826578823, + "avoided_ead_amax": 154763.53475248365, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "2.6", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.5 + }, + { + "adaptation_cost": 306624355.0834607, + "avoided_ead_amin": 11096.437573492232, + "avoided_ead_mean": 75195.06826578823, + "avoided_ead_amax": 154763.53475248365, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "2.6", + "adaptation_name": "Upgrade concrete mix, upgrade mortar mix, upgrade rubble masonry wall, increase number of drainage structure", + "adaptation_protection_level": 999.0 + }, + { + "adaptation_cost": 715456828.5280758, + "avoided_ead_amin": 11224.693860230003, + "avoided_ead_mean": 76062.12323412603, + "avoided_ead_amax": 156559.12276681233, + "avoided_eael_amin": 9080.273159537064, + "avoided_eael_mean": 9420.071643037763, + "avoided_eael_amax": 9830.430881153132, + "hazard": "flooding", + "rcp": "4.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.0 + }, + { + "adaptation_cost": 1073185242.7921138, + "avoided_ead_amin": 11287.542925559404, + "avoided_ead_mean": 76494.584659845, + "avoided_ead_amax": 157439.00968142392, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "4.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.5 + }, + { + "adaptation_cost": 1430913657.0561516, + "avoided_ead_amin": 11287.542925559404, + "avoided_ead_mean": 76494.584659845, + "avoided_ead_amax": 157439.00968142392, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "4.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.0 + }, + { + "adaptation_cost": 1788642071.3201897, + "avoided_ead_amin": 11287.542925559404, + "avoided_ead_mean": 76494.584659845, + "avoided_ead_amax": 157439.00968142392, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "4.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.5 + }, + { + "adaptation_cost": 306624355.0834607, + "avoided_ead_amin": 11287.542925559404, + "avoided_ead_mean": 76494.584659845, + "avoided_ead_amax": 157439.00968142392, + "avoided_eael_amin": 9102.28304777056, + "avoided_eael_mean": 9442.43993040706, + "avoided_eael_amax": 9853.188208467036, + "hazard": "flooding", + "rcp": "4.5", + "adaptation_name": "Upgrade concrete mix, upgrade mortar mix, upgrade rubble masonry wall, increase number of drainage structure", + "adaptation_protection_level": 999.0 + }, + { + "adaptation_cost": 715456828.5280758, + "avoided_ead_amin": 10843.276944584337, + "avoided_ead_mean": 73468.48820773543, + "avoided_ead_amax": 151219.285947773, + "avoided_eael_amin": 9072.841925730634, + "avoided_eael_mean": 9408.835652558855, + "avoided_eael_amax": 9813.303577816943, + "hazard": "flooding", + "rcp": "8.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.0 + }, + { + "adaptation_cost": 1073185242.7921138, + "avoided_ead_amin": 10906.126009913734, + "avoided_ead_mean": 73900.9496334544, + "avoided_ead_amax": 152099.17286238458, + "avoided_eael_amin": 9094.85181396413, + "avoided_eael_mean": 9431.203939928151, + "avoided_eael_amax": 9836.060905130847, + "hazard": "flooding", + "rcp": "8.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 1.5 + }, + { + "adaptation_cost": 1430913657.0561516, + "avoided_ead_amin": 10906.126009913734, + "avoided_ead_mean": 73900.9496334544, + "avoided_ead_amax": 152099.17286238458, + "avoided_eael_amin": 9094.85181396413, + "avoided_eael_mean": 9431.203939928151, + "avoided_eael_amax": 9836.060905130847, + "hazard": "flooding", + "rcp": "8.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.0 + }, + { + "adaptation_cost": 1788642071.3201897, + "avoided_ead_amin": 10906.126009913734, + "avoided_ead_mean": 73900.9496334544, + "avoided_ead_amax": 152099.17286238458, + "avoided_eael_amin": 9094.85181396413, + "avoided_eael_mean": 9431.203939928151, + "avoided_eael_amax": 9836.060905130847, + "hazard": "flooding", + "rcp": "8.5", + "adaptation_name": "Elevate the roads", + "adaptation_protection_level": 2.5 + }, + { + "adaptation_cost": 306624355.0834607, + "avoided_ead_amin": 10906.126009913734, + "avoided_ead_mean": 73900.9496334544, + "avoided_ead_amax": 152099.17286238458, + "avoided_eael_amin": 9094.85181396413, + "avoided_eael_mean": 9431.203939928151, + "avoided_eael_amax": 9836.060905130847, + "hazard": "flooding", + "rcp": "8.5", + "adaptation_name": "Upgrade concrete mix, upgrade mortar mix, upgrade rubble masonry wall, increase number of drainage structure", + "adaptation_protection_level": 999.0 + } + ] +} diff --git a/frontend/src/mocks/details/regions/mockRegion.json b/frontend/src/mocks/details/regions/mockRegion.json new file mode 100644 index 00000000..634be890 --- /dev/null +++ b/frontend/src/mocks/details/regions/mockRegion.json @@ -0,0 +1,34 @@ +{ + "interactionGroup": "regions", + "interactionStyle": "vector", + "viewLayer": { + "id": "population_enumeration", + "interactionGroup": "regions", + "spatialType": "vector", + "group": "regions", + "params": { + "regionLevel": "enumeration" + } + }, + "target": { + "feature": { + "type": "Feature", + "geometry": { + "type": "Polygon" + }, + "properties": { + "ED_CLASS": "URBAN", + "ED_ID": 1234567, + "AREA": 401610.89, + "PERIMETER": 2758, + "PARISH": "EXAMPLE PARISH", + "CONST_NAME": "SOUTH EAST", + "ED": "SE 999", + "population": 975, + "population_density_per_km2": 2427.737849485618, + "layerName": "population" + }, + "id": 12345678 + } + } +} diff --git a/frontend/src/mocks/details/solutions/mockMarineFeature.json b/frontend/src/mocks/details/solutions/mockMarineFeature.json new file mode 100644 index 00000000..7471efc7 --- /dev/null +++ b/frontend/src/mocks/details/solutions/mockMarineFeature.json @@ -0,0 +1,14 @@ +{ + "type": "Feature", + "geometry": { + "type": "MultiPolygon" + }, + "properties": { + "mangrove_type": "Fringing", + "is_mangrove": "1", + "within_mangrove_500m": "1", + "habitat": "mangrove", + "layerName": "natural_marine_combined" + }, + "id": 1234567 +} diff --git a/frontend/src/mocks/details/solutions/mockTerrestrialFeature.json b/frontend/src/mocks/details/solutions/mockTerrestrialFeature.json new file mode 100644 index 00000000..9e81f6ea --- /dev/null +++ b/frontend/src/mocks/details/solutions/mockTerrestrialFeature.json @@ -0,0 +1,24 @@ +{ + "type": "Feature", + "geometry": { "type": "Point" }, + "properties": { + "landuse_desc": "Buildings and other infrastructures", + "landuse_code": "BA", + "cell_index": 60204525, + "slope_degrees": 3.7629384994506836, + "elevation_m": 41, + "soil_type": "Clay", + "hydrologic_soil_group_code": "D", + "within_bauxite_area": "0", + "within_forest_100m": "0", + "within_forest_reserve": "0", + "protected_area_PROTECTED_AREA_name": "Example Protected Area", + "is_protected": "1", + "is_proposed_protected": "0", + "within_major_river_50m": "0", + "within_large_stream_50m": "false", + "within_headwater_stream_50m": false, + "layerName": "natural_terrestrial_combined_points" + }, + "id": 1234567 +}