{}
+}
diff --git a/packages/ui-components/src/types/types.d.ts b/packages/ui-components/src/types/types.d.ts
new file mode 100644
index 0000000000..6c781fa3ef
--- /dev/null
+++ b/packages/ui-components/src/types/types.d.ts
@@ -0,0 +1,5 @@
+import { ElementType } from 'react';
+
+export type OverrideableComponentProps = P & {
+ component?: keyof JSX.IntrinsicElements | ElementType;
+};
diff --git a/packages/ui-components/stories/button.stories.js b/packages/ui-components/stories/button.stories.js
index 30aaf5cedc..61f070995b 100644
--- a/packages/ui-components/stories/button.stories.js
+++ b/packages/ui-components/stories/button.stories.js
@@ -118,7 +118,9 @@ export const text = () => (
export const loading = () => (
-
+
);
diff --git a/packages/ui-components/tsconfig-build.json b/packages/ui-components/tsconfig-build.json
index 87d4d4f13a..2b8b93fde2 100644
--- a/packages/ui-components/tsconfig-build.json
+++ b/packages/ui-components/tsconfig-build.json
@@ -3,5 +3,12 @@
"compilerOptions": {
"declaration": true,
"noEmit": false,
- }
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "src/__tests__",
+ "src/stories/**/*"
+ ]
}
\ No newline at end of file
diff --git a/packages/ui-components/tsconfig.json b/packages/ui-components/tsconfig.json
index ac2972d6da..c1a5ac85da 100644
--- a/packages/ui-components/tsconfig.json
+++ b/packages/ui-components/tsconfig.json
@@ -3,15 +3,19 @@
"compileOnSave": true,
"compilerOptions": {
"jsx": "react",
- "target": "es5",
"allowJs": true,
"outDir": "dist",
+ "lib": [
+ "es6",
+ "dom"
+ ],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true
},
"include": [
- "src/**/*"
- ],
- "exclude": [
- "src/__tests__",
- "src/stories/**/*"
+ "src/**/*",
+ "jest.config.ts",
+ "helpers/**/*"
]
-}
\ No newline at end of file
+}
diff --git a/packages/web-frontend/src/components/DateRangePicker/DateRangePicker.js b/packages/web-frontend/src/components/DateRangePicker/DateRangePicker.js
index bb18fb9a77..90d6bd0d05 100644
--- a/packages/web-frontend/src/components/DateRangePicker/DateRangePicker.js
+++ b/packages/web-frontend/src/components/DateRangePicker/DateRangePicker.js
@@ -11,7 +11,7 @@ import Typography from '@material-ui/core/Typography';
import CalendarTodayIcon from '@material-ui/icons/CalendarToday';
import KeyboardArrowLeftIcon from '@material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight';
-import { FlexEnd } from '@tupaia/ui-components/src/components/Layout/Flexbox';
+import { FlexEnd } from '@tupaia/ui-components';
import MuiIconButton from '@material-ui/core/IconButton';
import styled from 'styled-components';
import { Error } from '../Error';
diff --git a/yarn.lock b/yarn.lock
index 9a41cca44a..36baf15723 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2855,6 +2855,15 @@ __metadata:
languageName: node
linkType: hard
+"@jest/expect-utils@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "@jest/expect-utils@npm:29.5.0"
+ dependencies:
+ jest-get-type: ^29.4.3
+ checksum: c46fb677c88535cf83cf29f0a5b1f376c6a1109ddda266ad7da1a9cbc53cb441fa402dd61fc7b111ffc99603c11a9b3357ee41a1c0e035a58830bcb360871476
+ languageName: node
+ linkType: hard
+
"@jest/fake-timers@npm:^24.9.0":
version: 24.9.0
resolution: "@jest/fake-timers@npm:24.9.0"
@@ -2989,6 +2998,15 @@ __metadata:
languageName: node
linkType: hard
+"@jest/schemas@npm:^29.4.3":
+ version: 29.4.3
+ resolution: "@jest/schemas@npm:29.4.3"
+ dependencies:
+ "@sinclair/typebox": ^0.25.16
+ checksum: ac754e245c19dc39e10ebd41dce09040214c96a4cd8efa143b82148e383e45128f24599195ab4f01433adae4ccfbe2db6574c90db2862ccd8551a86704b5bebd
+ languageName: node
+ linkType: hard
+
"@jest/source-map@npm:^24.9.0":
version: 24.9.0
resolution: "@jest/source-map@npm:24.9.0"
@@ -3203,6 +3221,20 @@ __metadata:
languageName: node
linkType: hard
+"@jest/types@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "@jest/types@npm:29.5.0"
+ dependencies:
+ "@jest/schemas": ^29.4.3
+ "@types/istanbul-lib-coverage": ^2.0.0
+ "@types/istanbul-reports": ^3.0.0
+ "@types/node": "*"
+ "@types/yargs": ^17.0.8
+ chalk: ^4.0.0
+ checksum: 1811f94b19cf8a9460a289c4f056796cfc373480e0492692a6125a553cd1a63824bd846d7bb78820b7b6f758f6dd3c2d4558293bb676d541b2fa59c70fdf9d39
+ languageName: node
+ linkType: hard
+
"@jridgewell/gen-mapping@npm:^0.3.2":
version: 0.3.2
resolution: "@jridgewell/gen-mapping@npm:0.3.2"
@@ -3504,6 +3536,18 @@ __metadata:
languageName: node
linkType: hard
+"@mui/types@npm:^7.2.4":
+ version: 7.2.4
+ resolution: "@mui/types@npm:7.2.4"
+ peerDependencies:
+ "@types/react": "*"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 16bea0547492193a22fd1794382f314698a114f6c673825314c66b56766c3a9d305992cc495684722b7be16a1ecf7e6e48a79caa64f90c439b530e8c02611a61
+ languageName: node
+ linkType: hard
+
"@nodelib/fs.scandir@npm:2.1.3":
version: 2.1.3
resolution: "@nodelib/fs.scandir@npm:2.1.3"
@@ -4030,6 +4074,13 @@ __metadata:
languageName: node
linkType: hard
+"@sinclair/typebox@npm:^0.25.16":
+ version: 0.25.24
+ resolution: "@sinclair/typebox@npm:0.25.24"
+ checksum: 10219c58f40b8414c50b483b0550445e9710d4fe7b2c4dccb9b66533dd90ba8e024acc776026cebe81e87f06fa24b07fdd7bc30dd277eb9cc386ec50151a3026
+ languageName: node
+ linkType: hard
+
"@sindresorhus/is@npm:^0.14.0":
version: 0.14.0
resolution: "@sindresorhus/is@npm:0.14.0"
@@ -5786,10 +5837,14 @@ __metadata:
"@material-ui/lab": ^4.0.0-alpha.47
"@material-ui/pickers": ^3.2.10
"@material-ui/styles": ^4.9.10
+ "@mui/types": ^7.2.4
"@storybook/react": ^6.3.9
"@tupaia/utils": 1.0.0
- "@types/react": ^18.2.6
+ "@types/jest": ^29.5.1
+ "@types/lodash.throttle": ^4.1.7
"@types/react-dom": ^18.2.4
+ "@types/react-router-dom": ^5.3.3
+ "@types/react-table": ^7.7.14
"@types/styled-components": ^5.1.26
ace-builds: ^1.4.13
date-fns: ^2.12.0
@@ -5805,6 +5860,7 @@ __metadata:
react: ^16.13.1
react-ace: ^10.1.0
react-beautiful-dnd: ^13.1.0
+ react-docgen-typescript-plugin: ^1.0.5
react-dom: ^16.13.1
react-hook-form: ^6.0.6
react-leaflet: ^3.2.1
@@ -6284,6 +6340,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/history@npm:^4.7.11":
+ version: 4.7.11
+ resolution: "@types/history@npm:4.7.11"
+ checksum: c92e2ba407dcab0581a9afdf98f533aa41b61a71133420a6d92b1ca9839f741ab1f9395b17454ba5b88cb86020b70b22d74a1950ccfbdfd9beeaa5459fdc3464
+ languageName: node
+ linkType: hard
+
"@types/hoist-non-react-statics@npm:*, @types/hoist-non-react-statics@npm:^3.3.0":
version: 3.3.1
resolution: "@types/hoist-non-react-statics@npm:3.3.1"
@@ -6369,6 +6432,16 @@ __metadata:
languageName: node
linkType: hard
+"@types/jest@npm:^29.5.1":
+ version: 29.5.1
+ resolution: "@types/jest@npm:29.5.1"
+ dependencies:
+ expect: ^29.0.0
+ pretty-format: ^29.0.0
+ checksum: 0a22491dec86333c0e92b897be2c809c922a7b2b0aa5604ac369810d6b2360908b4a3f2c6892e8a237a54fa1f10ecefe0e823ec5fcb7915195af4dfe88d2197e
+ languageName: node
+ linkType: hard
+
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8":
version: 7.0.9
resolution: "@types/json-schema@npm:7.0.9"
@@ -6501,6 +6574,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/lodash.throttle@npm:^4.1.7":
+ version: 4.1.7
+ resolution: "@types/lodash.throttle@npm:4.1.7"
+ dependencies:
+ "@types/lodash": "*"
+ checksum: 6e1b3836488fecbdc537b6ad9b3fe4855c7336b0fa388773cd57d486619f565a48cabc04b28677fd3819be3f2d13d2bb8f9d4428aa5632885c86cb99729bfd69
+ languageName: node
+ linkType: hard
+
"@types/lodash@npm:*":
version: 4.14.159
resolution: "@types/lodash@npm:4.14.159"
@@ -6766,6 +6848,27 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-router-dom@npm:^5.3.3":
+ version: 5.3.3
+ resolution: "@types/react-router-dom@npm:5.3.3"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ "@types/react-router": "*"
+ checksum: 28c4ea48909803c414bf5a08502acbb8ba414669b4b43bb51297c05fe5addc4df0b8fd00e0a9d1e3535ec4073ef38aaafac2c4a2b95b787167d113bc059beff3
+ languageName: node
+ linkType: hard
+
+"@types/react-router@npm:*":
+ version: 5.1.20
+ resolution: "@types/react-router@npm:5.1.20"
+ dependencies:
+ "@types/history": ^4.7.11
+ "@types/react": "*"
+ checksum: 128764143473a5e9457ddc715436b5d49814b1c214dde48939b9bef23f0e77f52ffcdfa97eb8d3cc27e2c229869c0cdd90f637d887b62f2c9f065a87d6425419
+ languageName: node
+ linkType: hard
+
"@types/react-syntax-highlighter@npm:11.0.5":
version: 11.0.5
resolution: "@types/react-syntax-highlighter@npm:11.0.5"
@@ -6784,6 +6887,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-table@npm:^7.7.14":
+ version: 7.7.14
+ resolution: "@types/react-table@npm:7.7.14"
+ dependencies:
+ "@types/react": "*"
+ checksum: 238047beca9abecc4b3e1e377b823b492b1a00d011b8456012bbcbd2682d5a7e0c0b1cca6384ccc41e724156e991d35e5725a5a3c4b01ff7bbaf095643569da9
+ languageName: node
+ linkType: hard
+
"@types/react-transition-group@npm:^4.2.0":
version: 4.2.3
resolution: "@types/react-transition-group@npm:4.2.3"
@@ -6803,17 +6915,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/react@npm:^18.2.6":
- version: 18.2.6
- resolution: "@types/react@npm:18.2.6"
- dependencies:
- "@types/prop-types": "*"
- "@types/scheduler": "*"
- csstype: ^3.0.2
- checksum: dea9d232d8df7ac357367a69dcb557711ab3d5501807ffa77cebeee73d49ee94d095f298e36853c63ed47cce097eee4c7eae2aaa8c02fac3f0171ec1b523a819
- languageName: node
- linkType: hard
-
"@types/resolve@npm:0.0.8":
version: 0.0.8
resolution: "@types/resolve@npm:0.0.8"
@@ -6832,13 +6933,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/scheduler@npm:*":
- version: 0.16.3
- resolution: "@types/scheduler@npm:0.16.3"
- checksum: 2b0aec39c24268e3ce938c5db2f2e77f5c3dd280e05c262d9c2fe7d890929e4632a6b8e94334017b66b45e4f92a5aa42ba3356640c2a1175fa37bef2f5200767
- languageName: node
- linkType: hard
-
"@types/semver-compare@npm:^1.0.1":
version: 1.0.1
resolution: "@types/semver-compare@npm:1.0.1"
@@ -7049,6 +7143,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/yargs@npm:^17.0.8":
+ version: 17.0.24
+ resolution: "@types/yargs@npm:17.0.24"
+ dependencies:
+ "@types/yargs-parser": "*"
+ checksum: 5f3ac4dc4f6e211c1627340160fbe2fd247ceba002190da6cf9155af1798450501d628c9165a183f30a224fc68fa5e700490d740ff4c73e2cdef95bc4e8ba7bf
+ languageName: node
+ linkType: hard
+
"@types/yauzl@npm:^2.9.1":
version: 2.10.0
resolution: "@types/yauzl@npm:2.10.0"
@@ -13671,6 +13774,13 @@ __metadata:
languageName: node
linkType: hard
+"diff-sequences@npm:^29.4.3":
+ version: 29.4.3
+ resolution: "diff-sequences@npm:29.4.3"
+ checksum: 28b265e04fdddcf7f9f814effe102cc95a9dec0564a579b5aed140edb24fc345c611ca52d76d725a3cab55d3888b915b5e8a4702e0f6058968a90fa5f41fcde7
+ languageName: node
+ linkType: hard
+
"diff@npm:4.0.2, diff@npm:^4.0.1, diff@npm:^4.0.2":
version: 4.0.2
resolution: "diff@npm:4.0.2"
@@ -15704,6 +15814,19 @@ __metadata:
languageName: node
linkType: hard
+"expect@npm:^29.0.0":
+ version: 29.5.0
+ resolution: "expect@npm:29.5.0"
+ dependencies:
+ "@jest/expect-utils": ^29.5.0
+ jest-get-type: ^29.4.3
+ jest-matcher-utils: ^29.5.0
+ jest-message-util: ^29.5.0
+ jest-util: ^29.5.0
+ checksum: 58f70b38693df6e5c6892db1bcd050f0e518d6f785175dc53917d4fa6a7359a048e5690e19ddcb96b65c4493881dd89a3dabdab1a84dfa55c10cdbdabf37b2d7
+ languageName: node
+ linkType: hard
+
"exports-loader@npm:^0.6.3":
version: 0.6.4
resolution: "exports-loader@npm:0.6.4"
@@ -20228,6 +20351,18 @@ __metadata:
languageName: node
linkType: hard
+"jest-diff@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "jest-diff@npm:29.5.0"
+ dependencies:
+ chalk: ^4.0.0
+ diff-sequences: ^29.4.3
+ jest-get-type: ^29.4.3
+ pretty-format: ^29.5.0
+ checksum: dfd0f4a299b5d127779c76b40106c37854c89c3e0785098c717d52822d6620d227f6234c3a9291df204d619e799e3654159213bf93220f79c8e92a55475a3d39
+ languageName: node
+ linkType: hard
+
"jest-docblock@npm:^26.0.0":
version: 26.0.0
resolution: "jest-docblock@npm:26.0.0"
@@ -20376,6 +20511,13 @@ __metadata:
languageName: node
linkType: hard
+"jest-get-type@npm:^29.4.3":
+ version: 29.4.3
+ resolution: "jest-get-type@npm:29.4.3"
+ checksum: 6ac7f2dde1c65e292e4355b6c63b3a4897d7e92cb4c8afcf6d397f2682f8080e094c8b0b68205a74d269882ec06bf696a9de6cd3e1b7333531e5ed7b112605ce
+ languageName: node
+ linkType: hard
+
"jest-haste-map@npm:^24.7.1, jest-haste-map@npm:^24.9.0":
version: 24.9.0
resolution: "jest-haste-map@npm:24.9.0"
@@ -20567,6 +20709,18 @@ __metadata:
languageName: node
linkType: hard
+"jest-matcher-utils@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "jest-matcher-utils@npm:29.5.0"
+ dependencies:
+ chalk: ^4.0.0
+ jest-diff: ^29.5.0
+ jest-get-type: ^29.4.3
+ pretty-format: ^29.5.0
+ checksum: 1d3e8c746e484a58ce194e3aad152eff21fd0896e8b8bf3d4ab1a4e2cbfed95fb143646f4ad9fdf6e42212b9e8fc033268b58e011b044a9929df45485deb5ac9
+ languageName: node
+ linkType: hard
+
"jest-message-util@npm:^24.9.0":
version: 24.9.0
resolution: "jest-message-util@npm:24.9.0"
@@ -20617,6 +20771,23 @@ __metadata:
languageName: node
linkType: hard
+"jest-message-util@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "jest-message-util@npm:29.5.0"
+ dependencies:
+ "@babel/code-frame": ^7.12.13
+ "@jest/types": ^29.5.0
+ "@types/stack-utils": ^2.0.0
+ chalk: ^4.0.0
+ graceful-fs: ^4.2.9
+ micromatch: ^4.0.4
+ pretty-format: ^29.5.0
+ slash: ^3.0.0
+ stack-utils: ^2.0.3
+ checksum: daddece6bbf846eb6a2ab9be9f2446e54085bef4e5cecd13d2a538fa9c01cb89d38e564c6b74fd8e12d37ed9eface8a362240ae9f21d68b214590631e7a0d8bf
+ languageName: node
+ linkType: hard
+
"jest-mock@npm:^24.9.0":
version: 24.9.0
resolution: "jest-mock@npm:24.9.0"
@@ -21026,6 +21197,20 @@ __metadata:
languageName: node
linkType: hard
+"jest-util@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "jest-util@npm:29.5.0"
+ dependencies:
+ "@jest/types": ^29.5.0
+ "@types/node": "*"
+ chalk: ^4.0.0
+ ci-info: ^3.2.0
+ graceful-fs: ^4.2.9
+ picomatch: ^2.2.3
+ checksum: fd9212950d34d2ecad8c990dda0d8ea59a8a554b0c188b53ea5d6c4a0829a64f2e1d49e6e85e812014933d17426d7136da4785f9cf76fff1799de51b88bc85d3
+ languageName: node
+ linkType: hard
+
"jest-validate@npm:^24.7.0, jest-validate@npm:^24.9.0":
version: 24.9.0
resolution: "jest-validate@npm:24.9.0"
@@ -28362,6 +28547,17 @@ __metadata:
languageName: node
linkType: hard
+"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0":
+ version: 29.5.0
+ resolution: "pretty-format@npm:29.5.0"
+ dependencies:
+ "@jest/schemas": ^29.4.3
+ ansi-styles: ^5.0.0
+ react-is: ^18.0.0
+ checksum: 4065356b558e6db25b4d41a01efb386935a6c06a0c9c104ef5ce59f2f476b8210edb8b3949b386e60ada0a6dc5ebcb2e6ccddc8c64dfd1a9943c3c3a9e7eaf89
+ languageName: node
+ linkType: hard
+
"pretty-hrtime@npm:^1.0.3":
version: 1.0.3
resolution: "pretty-hrtime@npm:1.0.3"
@@ -29172,6 +29368,24 @@ __metadata:
languageName: node
linkType: hard
+"react-docgen-typescript-plugin@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "react-docgen-typescript-plugin@npm:1.0.5"
+ dependencies:
+ debug: ^4.1.1
+ endent: ^2.0.1
+ find-cache-dir: ^3.3.1
+ flat-cache: ^3.0.4
+ micromatch: ^4.0.2
+ react-docgen-typescript: ^2.2.2
+ tslib: ^2.0.0
+ peerDependencies:
+ typescript: ">= 4.x"
+ webpack: ">= 4"
+ checksum: 0f83d33c7b6dc82fef34ee820c94485c374d853774c5c26b04754ba3674fe4db2c7fc210b30fa0ca77c5033633553c12742aab6305a7f16cd263c70fedf27589
+ languageName: node
+ linkType: hard
+
"react-docgen-typescript@npm:^2.0.0":
version: 2.1.0
resolution: "react-docgen-typescript@npm:2.1.0"
@@ -29181,6 +29395,15 @@ __metadata:
languageName: node
linkType: hard
+"react-docgen-typescript@npm:^2.2.2":
+ version: 2.2.2
+ resolution: "react-docgen-typescript@npm:2.2.2"
+ peerDependencies:
+ typescript: ">= 4.3.x"
+ checksum: a9826459ea44e818f21402728dd47f5cae60bd936574cefd4f90ad101ff3eebacd67b6e017b793309734ce62c037aa3072dbc855d2b0e29bad1a38cbf5bac115
+ languageName: node
+ linkType: hard
+
"react-docgen@npm:^5.0.0":
version: 5.3.0
resolution: "react-docgen@npm:5.3.0"
@@ -29373,6 +29596,13 @@ __metadata:
languageName: node
linkType: hard
+"react-is@npm:^18.0.0":
+ version: 18.2.0
+ resolution: "react-is@npm:18.2.0"
+ checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e
+ languageName: node
+ linkType: hard
+
"react-leaflet@npm:^3.2.1":
version: 3.2.1
resolution: "react-leaflet@npm:3.2.1"
From c12409607afc1d037eba86f9d9151fef353405a7 Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Mon, 22 May 2023 13:38:10 +1200
Subject: [PATCH 014/251] reference lines
---
.../models-extra/dashboard-item/index.ts | 2 +
.../types/src/types/models-extra/index.ts | 1 +
packages/types/src/types/models.ts | 1 +
.../src/components/Axes/YAxes.tsx | 63 ++++++++++---------
.../src/components/Charts/PieChart.tsx | 1 +
.../src/components/Reference/ChartTooltip.tsx | 10 +--
.../components/Reference/ReferenceLines.tsx | 34 +++++++---
packages/ui-chart-components/src/types.ts | 37 +++--------
.../src/utils/getChartTableData.tsx | 3 +-
9 files changed, 77 insertions(+), 75 deletions(-)
diff --git a/packages/types/src/types/models-extra/dashboard-item/index.ts b/packages/types/src/types/models-extra/dashboard-item/index.ts
index 59896ba43a..4a574781b5 100644
--- a/packages/types/src/types/models-extra/dashboard-item/index.ts
+++ b/packages/types/src/types/models-extra/dashboard-item/index.ts
@@ -55,3 +55,5 @@ export type DashboardItemConfig =
| DataDownloadViewConfig
| SingleDateViewConfig
| MultiValueViewConfig;
+
+export type { ValueType } from './common';
diff --git a/packages/types/src/types/models-extra/index.ts b/packages/types/src/types/models-extra/index.ts
index 1e65e1f4a1..79f9defc01 100644
--- a/packages/types/src/types/models-extra/index.ts
+++ b/packages/types/src/types/models-extra/index.ts
@@ -12,4 +12,5 @@ export type {
LineChartConfig,
PieChartConfig,
BaseChartConfig,
+ ValueType,
} from './dashboard-item';
diff --git a/packages/types/src/types/models.ts b/packages/types/src/types/models.ts
index 62bacba2f4..aca1b4bc9a 100644
--- a/packages/types/src/types/models.ts
+++ b/packages/types/src/types/models.ts
@@ -19,6 +19,7 @@ export {
LineChartConfig,
PieChartConfig,
BaseChartConfig,
+ ValueType,
} from './models-extra';
export interface AccessRequest {
diff --git a/packages/ui-chart-components/src/components/Axes/YAxes.tsx b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
index 56fe36e7d3..6f74f8e1c3 100644
--- a/packages/ui-chart-components/src/components/Axes/YAxes.tsx
+++ b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
@@ -5,11 +5,19 @@
import React from 'react';
import { formatDataValueByType } from '@tupaia/utils';
+import { ValueType } from '@tupaia/types';
import { YAxis as YAxisComponent } from 'recharts';
import { DARK_BLUE } from '../../constants';
-import { ViewContent } from '../../types';
+import { LooseObject, ViewContent } from '../../types';
import { getContrastTextColor } from '../../utils';
+interface AxisDomainProps {
+ min: number;
+ max: number;
+ value: any;
+ type: any;
+}
+
const Y_AXIS_IDS = {
left: 0,
right: 1,
@@ -29,12 +37,12 @@ const DEFAULT_Y_AXIS = {
},
};
-const parseDomainConfig = config => {
+const parseDomainConfig = (config: AxisDomainProps) => {
switch (config.type) {
case 'scale':
- return dataExtreme => dataExtreme * config.value;
+ return (dataExtreme: any) => dataExtreme * config.value;
case 'clamp':
- return dataExtreme => {
+ return (dataExtreme: any) => {
const maxClampedVal = config.max ? Math.min(dataExtreme, config.max) : dataExtreme;
return config.min ? Math.max(maxClampedVal, config.min) : maxClampedVal;
};
@@ -48,13 +56,19 @@ const parseDomainConfig = config => {
const getDefaultYAxisDomain = (viewContent: ViewContent) =>
viewContent.valueType === 'percentage' ? PERCENTAGE_Y_DOMAIN : DEFAULT_Y_AXIS.yAxisDomain;
-const calculateYAxisDomain = ({ min, max }) => {
+const calculateYAxisDomain = ({ min, max }: { min: AxisDomainProps; max: AxisDomainProps }) => {
return [parseDomainConfig(min), parseDomainConfig(max)];
};
-const containsClamp = ({ min, max }) => min.type === 'clamp' || max.type === 'clamp';
+const containsClamp = ({ min, max }: { min: AxisDomainProps; max: AxisDomainProps }) =>
+ min.type === 'clamp' || max.type === 'clamp';
-const renderYAxisLabel = (label, orientation, fillColor, isEnlarged) => {
+const renderYAxisLabel = (
+ label: string,
+ orientation: string,
+ fillColor: string,
+ isEnlarged: boolean,
+) => {
if (label)
return {
value: label,
@@ -69,9 +83,10 @@ const renderYAxisLabel = (label, orientation, fillColor, isEnlarged) => {
/**
* Calculate a dynamic width for the YAxis
*/
-const getAxisWidth = (data, dataKeys, valueType) => {
+const getAxisWidth = (data: any[], dataKeys: string[], valueType: ValueType) => {
// Only use a dynamic width for number types. Otherwise fallback to the recharts default
if (valueType === 'number' || valueType === undefined) {
+ // @ts-ignore
const values = data.map(item => dataKeys.map(key => item[key])).flat();
const maxValue = Math.max(...values);
@@ -89,26 +104,24 @@ const getAxisWidth = (data, dataKeys, valueType) => {
return undefined;
};
-interface YAxisProps {
- viewContent: ViewContent;
- config?: object;
- chartDataConfig: object;
- isEnlarged?: boolean;
- isExporting?: boolean;
-}
const YAxis = ({
- config = {},
+ config = {
+ yAxisId: DEFAULT_Y_AXIS.id,
+ orientation: DEFAULT_Y_AXIS.orientation,
+ yAxisDomain: '',
+ yName: '',
+ },
viewContent,
chartDataConfig,
isExporting = false,
isEnlarged = false,
-}: YAxisProps) => {
+}: any) => {
const fillColor = isExporting ? DARK_BLUE : getContrastTextColor();
const {
- yAxisId = DEFAULT_Y_AXIS.id,
- orientation = DEFAULT_Y_AXIS.orientation,
+ yAxisId,
+ orientation,
yAxisDomain = getDefaultYAxisDomain(viewContent),
yName: yAxisLabel,
} = config;
@@ -119,6 +132,7 @@ const YAxis = ({
const width = getAxisWidth(viewContent.data, dataKeys, valueType);
return (
+ // @ts-ignore
{
+}: any) => {
const { chartConfig = {} } = viewContent;
- const axisPropsById = {
+ const axisPropsById: { [p: number]: LooseObject } = {
[Y_AXIS_IDS.left]: { yAxisId: Y_AXIS_IDS.left, dataKeys: [], orientation: 'left' },
[Y_AXIS_IDS.right]: { yAxisId: Y_AXIS_IDS.right, dataKeys: [], orientation: 'right' },
};
diff --git a/packages/ui-chart-components/src/components/Charts/PieChart.tsx b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
index ef11a3ffbe..abad44e641 100644
--- a/packages/ui-chart-components/src/components/Charts/PieChart.tsx
+++ b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
@@ -171,6 +171,7 @@ export const PieChart = ({
return (
+ {/* @ts-ignore */}
{
if (referenceLineLabel === undefined) return null;
return (
@@ -41,14 +42,20 @@ const DEFAULT_Y_AXIS = {
const orientationToYAxisId = (orientation: 'left' | 'right'): number =>
Y_AXIS_IDS[orientation] || DEFAULT_Y_AXIS.id;
-interface ReferenceLineProps {
- viewContent: ViewContent;
- isExporting: boolean;
- isEnlarged?: boolean;
+interface ChartConfig extends BaseChartConfig {
+ referenceValue: string | number;
+ yAxisOrientation: string | number;
+ referenceLabel: string | number;
}
-const ValueReferenceLine = ({ viewContent, isExporting }: ReferenceLineProps) => {
- const { chartConfig = {} } = viewContent;
+const ValueReferenceLine = ({
+ viewContent,
+ isExporting,
+}: {
+ viewContent: { chartConfig: ChartConfig };
+ isExporting?: boolean;
+}) => {
+ const { chartConfig } = viewContent;
const referenceLines = Object.entries(chartConfig)
.filter(([, { referenceValue }]) => referenceValue)
@@ -73,12 +80,19 @@ const ValueReferenceLine = ({ viewContent, isExporting }: ReferenceLineProps) =>
));
};
+interface ReferenceLineProps {
+ viewContent: ViewContent;
+ isExporting?: boolean;
+ isEnlarged?: boolean;
+}
+
const AverageReferenceLine = ({ viewContent, isExporting, isEnlarged }: ReferenceLineProps) => {
const { valueType, data, presentationOptions } = viewContent;
// show reference line by default
const shouldHideReferenceLine = presentationOptions && presentationOptions.hideAverage;
// average is null for stacked charts that don't have a "value" key in data
- const average = data.reduce((acc, row) => acc + row.value, 0) / data.length;
+ // @ts-ignore
+ const average = data.reduce((acc: number, row: DataProps) => acc + row.value, 0) / data.length;
if (!average || shouldHideReferenceLine) {
return null;
@@ -111,5 +125,5 @@ export const ReferenceLines = ({ viewContent, isExporting, isEnlarged }: Referen
if (viewContent.chartType === ChartType.Bar) {
return BarReferenceLine({ viewContent, isExporting, isEnlarged });
}
- return ValueReferenceLine({ viewContent, isExporting, isEnlarged });
+ return ValueReferenceLine({ viewContent, isExporting });
};
diff --git a/packages/ui-chart-components/src/types.ts b/packages/ui-chart-components/src/types.ts
index 66515798eb..3f5007347f 100644
--- a/packages/ui-chart-components/src/types.ts
+++ b/packages/ui-chart-components/src/types.ts
@@ -2,9 +2,9 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-import { BaseChartConfig } from '@tupaia/types';
+import { BaseChartConfig, ValueType } from '@tupaia/types';
import { ReferenceAreaProps } from 'recharts';
-import { ConfirmModal } from '@tupaia/ui-components';
+import { GRANULARITY_SHAPE } from '@tupaia/utils';
// Todo: move some of these types to @tupaia/types and integrate
export interface DataProps {
@@ -47,17 +47,7 @@ export type LegendPosition = 'top' | 'bottom';
* }
*/
-export type VizPeriodGranularity =
- | 'day'
- | 'one_day_at_a_time'
- | 'week'
- | 'one_week_at_a_time'
- | 'month'
- | 'one_month_at_a_time'
- | 'quarter'
- | 'one_quarter_at_a_time'
- | 'year'
- | 'one_year_at_a_time';
+export type VizPeriodGranularity = typeof GRANULARITY_SHAPE;
type ConditionalMatrixConditionShape = {
key: string;
@@ -76,13 +66,16 @@ export type PresentationOptions = {
hideAverage?: boolean;
valueFormat?: string;
conditions?: ConditionalMatrixConditionShape[];
+ referenceLines?: any;
};
-export type ViewContent = {
+export interface ViewContent {
chartType: ChartType;
valueType?: ValueType;
name?: string;
xName?: string;
+ yName?: string;
+ ticks?: string;
noDataMessage?: string;
source?: string;
startDate?: string;
@@ -91,20 +84,8 @@ export type ViewContent = {
periodGranularity?: VizPeriodGranularity;
labelType?: string;
data: DataProps[];
- chartConfig?: BaseChartConfig;
+ chartConfig: T;
presentationOptions?: PresentationOptions;
renderLegendForOneItem?: boolean;
referenceAreas?: ReferenceAreaProps[];
-};
-
-export type ValueType =
- | 'boolean'
- | 'fractionAndPercentage'
- | 'percentage'
- | 'text'
- | 'number'
- | 'color'
- | 'currency'
- | 'view'
- | 'oneDecimalPlace'
- | 'fraction';
+}
diff --git a/packages/ui-chart-components/src/utils/getChartTableData.tsx b/packages/ui-chart-components/src/utils/getChartTableData.tsx
index 82b18b269d..abbf6aa463 100644
--- a/packages/ui-chart-components/src/utils/getChartTableData.tsx
+++ b/packages/ui-chart-components/src/utils/getChartTableData.tsx
@@ -5,11 +5,12 @@
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { formatDataValueByType } from '@tupaia/utils';
+import { ValueType } from '@tupaia/types';
import { DEFAULT_DATA_KEY } from '../constants';
import { ChartType, LooseObject, TableAccessor } from '../types';
import { formatTimestampForChart, getIsTimeSeries } from './utils';
import { parseChartConfig } from './parseChartConfig';
-import { ValueType, ViewContent } from '../types';
+import { ViewContent } from '../types';
// For the rowData, ignore labelType and use percentage instead of fractionAndPercentage as
// we don't want to show multiple values a table cell
From d3076a9c0922c7a844740572ac1aa6e200b6ed2d Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Mon, 22 May 2023 16:33:53 +1200
Subject: [PATCH 015/251] cartesian chart
---
.../models-extra/dashboard-item/charts.ts | 2 +-
.../models-extra/dashboard-item/index.ts | 1 +
.../types/src/types/models-extra/index.ts | 1 +
packages/types/src/types/models.ts | 1 +
.../src/components/Axes/XAxis.tsx | 3 +-
.../src/components/CartesianChart.tsx | 17 +++++----
.../src/components/Charts/PieChart.tsx | 5 ++-
.../src/components/Reference/ChartTooltip.tsx | 10 +++--
.../src/components/Reference/Legend.tsx | 16 ++++----
packages/ui-chart-components/src/types.ts | 4 +-
.../src/utils/parseChartConfig.ts | 37 ++++++++++++++-----
11 files changed, 63 insertions(+), 34 deletions(-)
diff --git a/packages/types/src/types/models-extra/dashboard-item/charts.ts b/packages/types/src/types/models-extra/dashboard-item/charts.ts
index b21e8309c8..6b03e577ae 100644
--- a/packages/types/src/types/models-extra/dashboard-item/charts.ts
+++ b/packages/types/src/types/models-extra/dashboard-item/charts.ts
@@ -103,7 +103,7 @@ type CommonChartChartConfig = {
/**
* A Cartesian chart has an area with axes e.g. bar, line.
*/
-type CartesianChartConfig = {
+export type CartesianChartConfig = {
/**
* @description The label on the x-axis
*/
diff --git a/packages/types/src/types/models-extra/dashboard-item/index.ts b/packages/types/src/types/models-extra/dashboard-item/index.ts
index 4a574781b5..ed47881761 100644
--- a/packages/types/src/types/models-extra/dashboard-item/index.ts
+++ b/packages/types/src/types/models-extra/dashboard-item/index.ts
@@ -32,6 +32,7 @@ export type {
LineChartConfig,
PieChartConfig,
BaseChartConfig,
+ CartesianChartConfig,
} from './charts';
/**
* The master list of viz types.
diff --git a/packages/types/src/types/models-extra/index.ts b/packages/types/src/types/models-extra/index.ts
index 79f9defc01..8c517ff9eb 100644
--- a/packages/types/src/types/models-extra/index.ts
+++ b/packages/types/src/types/models-extra/index.ts
@@ -12,5 +12,6 @@ export type {
LineChartConfig,
PieChartConfig,
BaseChartConfig,
+ CartesianChartConfig,
ValueType,
} from './dashboard-item';
diff --git a/packages/types/src/types/models.ts b/packages/types/src/types/models.ts
index aca1b4bc9a..710e319297 100644
--- a/packages/types/src/types/models.ts
+++ b/packages/types/src/types/models.ts
@@ -19,6 +19,7 @@ export {
LineChartConfig,
PieChartConfig,
BaseChartConfig,
+ CartesianChartConfig,
ValueType,
} from './models-extra';
diff --git a/packages/ui-chart-components/src/components/Axes/XAxis.tsx b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
index 27183729e5..759c1e4939 100644
--- a/packages/ui-chart-components/src/components/Axes/XAxis.tsx
+++ b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
@@ -9,6 +9,7 @@ import { formatTimestampForChart, getIsTimeSeries, getContrastTextColor } from '
import { VerticalTick } from './VerticalTick';
import { DARK_BLUE } from '../../constants';
import { ChartType, DataProps, ViewContent } from '../../types';
+import { CartesianChartConfig } from '@tupaia/types/src';
const AXIS_TIME_PROPS = {
dataKey: 'timestamp',
@@ -63,7 +64,7 @@ const calculateXAxisHeight = (data: DataProps[], isExporting: boolean) => {
};
interface XAxisProps {
- viewContent: ViewContent;
+ viewContent: ViewContent;
isEnlarged?: boolean;
isExporting?: boolean;
}
diff --git a/packages/ui-chart-components/src/components/CartesianChart.tsx b/packages/ui-chart-components/src/components/CartesianChart.tsx
index 0db789c372..f52f6f6c44 100644
--- a/packages/ui-chart-components/src/components/CartesianChart.tsx
+++ b/packages/ui-chart-components/src/components/CartesianChart.tsx
@@ -2,7 +2,7 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-
+// @ts-nocheck
import React, { useEffect, useState } from 'react';
import get from 'lodash.get';
import {
@@ -16,7 +16,7 @@ import {
Tooltip,
Brush,
} from 'recharts';
-import { BaseChartConfig } from '@tupaia/types';
+import { CartesianChartConfig } from '@tupaia/types';
import { CHART_BLUES, DEFAULT_DATA_KEY } from '../constants';
import { ChartType, ViewContent, LegendPosition } from '../types';
import {
@@ -70,7 +70,7 @@ const CHART_TYPE_TO_CHART = {
[Line]: LineChartComponent,
};
-const getRealDataKeys = (chartConfig: BaseChartConfig | {}) =>
+const getRealDataKeys = (chartConfig: CartesianChartConfig | {}) =>
Object.keys(chartConfig).filter(key => key !== LEGEND_ALL_DATA_KEY);
const getLegendAlignment = (legendPosition: LegendPosition, isExporting: boolean) => {
@@ -102,8 +102,10 @@ const getMargin = (isExporting: boolean, isEnlarged: boolean) => {
return { left: 0, right: 0, top: 0, bottom: 0 };
};
+type CartesianChartConfigWithAll = CartesianChartConfig & { [LEGEND_ALL_DATA_KEY]?: any };
+
interface CartesianChartProps {
- viewContent: ViewContent;
+ viewContent: ViewContent;
legendPosition: LegendPosition;
isEnlarged?: boolean;
isExporting?: boolean;
@@ -115,7 +117,7 @@ export const CartesianChart = ({
isExporting = false,
legendPosition = 'bottom',
}: CartesianChartProps) => {
- const [chartConfig, setChartConfig] = useState(
+ const [chartConfig, setChartConfig] = useState(
viewContent.chartConfig || {},
);
const [activeDataKeys, setActiveDataKeys] = useState([]);
@@ -148,7 +150,7 @@ export const CartesianChart = ({
const updateChartConfig = (hasDisabledData: boolean) => {
const newChartConfig = { ...chartConfig };
- if (hasDisabledData && !chartConfig.hasOwnProperty(LEGEND_ALL_DATA_KEY)) {
+ if (hasDisabledData && LEGEND_ALL_DATA_KEY in newChartConfig) {
const allChartType = Object.values(chartConfig)[0].chartType || defaultChartType || 'line';
newChartConfig[LEGEND_ALL_DATA_KEY] = { ...LEGEND_ALL_DATA, chartType: allChartType };
setChartConfig(newChartConfig);
@@ -245,12 +247,13 @@ export const CartesianChart = ({
{Object.entries(chartDataConfig)
.filter(([, { hideFromLegend }]) => !hideFromLegend)
.map(([dataKey, { chartType = defaultChartType }]) => {
- const Chart = CHART_TYPE_TO_CHART[chartType];
+ const Chart = CHART_TYPE_TO_CHART[chartType as keyof typeof CHART_TYPE_TO_CONTAINER];
const yAxisOrientation = get(chartConfig, [dataKey, 'yAxisOrientation']);
const yAxisId = orientationToYAxisId(yAxisOrientation);
return Chart({
valueType,
+ // @ts-ignore
...chartConfig[dataKey],
chartConfig,
dataKey,
diff --git a/packages/ui-chart-components/src/components/Charts/PieChart.tsx b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
index abad44e641..cc99f816ca 100644
--- a/packages/ui-chart-components/src/components/Charts/PieChart.tsx
+++ b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
@@ -2,6 +2,7 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
+// @ts-nocheck
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import Typography from '@material-ui/core/Typography';
@@ -19,7 +20,7 @@ import { OFF_WHITE, CHART_COLOR_PALETTE } from '../../constants';
import { getPieLegend } from '../Reference/Legend';
import { isMobile } from '../../utils';
import { TooltipContainer } from '../Reference';
-import { ViewContent, LegendPosition } from '../../types';
+import { ViewContent, LegendPosition, PresentationOptions } from '../../types';
const Heading = styled(Typography)`
font-weight: 500;
@@ -135,7 +136,7 @@ export const PieChart = ({
setActiveIndex(-1);
};
- const getPresentationOption = (key: string, option: string) =>
+ const getPresentationOption = (key: keyof PresentationOptions | string, option: string) =>
!!presentationOptions &&
presentationOptions.hasOwnProperty(key) &&
presentationOptions[key][option];
diff --git a/packages/ui-chart-components/src/components/Reference/ChartTooltip.tsx b/packages/ui-chart-components/src/components/Reference/ChartTooltip.tsx
index 8482bd6b5d..4322281c1a 100644
--- a/packages/ui-chart-components/src/components/Reference/ChartTooltip.tsx
+++ b/packages/ui-chart-components/src/components/Reference/ChartTooltip.tsx
@@ -56,7 +56,7 @@ const Box = styled.div`
`;
interface ChartTooltipProps {
- payload: any[];
+ payload?: any[];
active?: boolean;
presentationOptions?: PresentationOptions;
valueType: ValueType;
@@ -66,6 +66,10 @@ interface ChartTooltipProps {
periodGranularity?: VizPeriodGranularity;
}
+interface ChartTooltipPropsWithData extends ChartTooltipProps {
+ payload: any[];
+}
+
const MultiValueTooltip = ({
valueType,
chartConfig,
@@ -74,7 +78,7 @@ const MultiValueTooltip = ({
periodGranularity,
labelType,
chartType,
-}: ChartTooltipProps) => {
+}: ChartTooltipPropsWithData) => {
const data = payload[0].payload;
const { name: headline, timestamp } = data;
@@ -128,7 +132,7 @@ const SingleValueTooltip = ({
payload,
periodGranularity,
labelType,
-}: ChartTooltipProps) => {
+}: ChartTooltipPropsWithData) => {
const data = payload[0].payload;
const { name, value, timestamp } = data;
const metadata = data.value_metadata;
diff --git a/packages/ui-chart-components/src/components/Reference/Legend.tsx b/packages/ui-chart-components/src/components/Reference/Legend.tsx
index 5b8e6dcf59..705396d9dd 100644
--- a/packages/ui-chart-components/src/components/Reference/Legend.tsx
+++ b/packages/ui-chart-components/src/components/Reference/Legend.tsx
@@ -102,14 +102,6 @@ const Text = styled.span`
line-height: 1.4;
`;
-interface PieLegendProps {
- chartConfig: PieChartConfig;
- isEnlarged?: boolean;
- isExporting?: boolean;
- legendPosition?: LegendPosition;
- viewContent: ViewContent;
-}
-
const getPieLegendDisplayValue = (
chartConfig: PieChartConfig,
value: string,
@@ -130,6 +122,14 @@ const getPieLegendDisplayValue = (
return isMobile() && isEnlarged ? `${value} ${labelSuffix}` : value;
};
+interface PieLegendProps {
+ chartConfig: PieChartConfig;
+ isEnlarged?: boolean;
+ isExporting?: boolean;
+ legendPosition?: LegendPosition;
+ viewContent: ViewContent;
+}
+
export const getPieLegend = ({
chartConfig,
isEnlarged,
diff --git a/packages/ui-chart-components/src/types.ts b/packages/ui-chart-components/src/types.ts
index 3f5007347f..46de72246a 100644
--- a/packages/ui-chart-components/src/types.ts
+++ b/packages/ui-chart-components/src/types.ts
@@ -69,8 +69,8 @@ export type PresentationOptions = {
referenceLines?: any;
};
-export interface ViewContent {
- chartType: ChartType;
+export interface ViewContent {
+ chartType: CT;
valueType?: ValueType;
name?: string;
xName?: string;
diff --git a/packages/ui-chart-components/src/utils/parseChartConfig.ts b/packages/ui-chart-components/src/utils/parseChartConfig.ts
index 30bcee3f2f..a19283bd0a 100644
--- a/packages/ui-chart-components/src/utils/parseChartConfig.ts
+++ b/packages/ui-chart-components/src/utils/parseChartConfig.ts
@@ -16,8 +16,14 @@ export const getLayeredOpacity = (
ascending: boolean = false,
) => (ascending ? (index + 1) / numberOfLayers : 1 - index / numberOfLayers);
-export const parseChartConfig = (viewContent: ViewContent) => {
- const { chartType, chartConfig = {}, data, colorPalette: paletteName } = viewContent;
+interface ChartConfig extends BaseChartConfig {
+ [ADD_TO_ALL_KEY]?: any;
+}
+
+type ColorPalette = keyof typeof COLOR_PALETTES;
+
+export const parseChartConfig = (viewContent: ViewContent) => {
+ const { chartType, chartConfig, data, colorPalette: paletteName } = viewContent;
const { [ADD_TO_ALL_KEY]: configForAllKeys, ...restOfConfig } = chartConfig;
const baseConfig = configForAllKeys
@@ -25,14 +31,19 @@ export const parseChartConfig = (viewContent: ViewContent) => {
: restOfConfig;
const addDefaultColors = (config: BaseChartConfig) =>
- addDefaultColorsToConfig(config, paletteName, chartType);
+ addDefaultColorsToConfig(config, paletteName as ColorPalette, chartType);
const chartConfigs = [baseConfig];
- return chartConfigs
- .map(sortChartConfigByLegendOrder)
- .map(addDefaultColors)
- .map(setOpacityValues)[0]; // must remove from array after mapping
+ return (
+ chartConfigs
+ // @ts-ignore
+ .map(sortChartConfigByLegendOrder)
+ // @ts-ignore
+ .map(addDefaultColors)
+ // @ts-ignore
+ .map(setOpacityValues)[0]
+ ); // must remove from array after mapping
};
/**
@@ -44,19 +55,22 @@ const setOpacityValues = (chartConfig: BaseChartConfig): BaseChartConfig => {
Object.entries(chartConfig).forEach(([key, configItem], index, array) => {
const { opacity } = configItem;
if (!opacity || typeof opacity === 'number') {
+ // @ts-ignore
newConfig[key] = configItem;
return;
}
const newOpacity = getLayeredOpacity(array.length, index, opacity === 'ascending');
+ // @ts-ignore
newConfig[key] = { ...configItem, opacity: newOpacity };
});
+ // @ts-ignore
return newConfig;
};
// Adds default colors for every element with no color defined
const addDefaultColorsToConfig = (
chartConfig: BaseChartConfig,
- paletteName?: string,
+ paletteName: ColorPalette,
chartType: ChartType,
) => {
const newConfig = {};
@@ -72,6 +86,7 @@ const addDefaultColorsToConfig = (
colorId = (colorId + 1) % colors.length;
}
+ // @ts-ignore
newConfig[key] = { ...configItem, color };
});
@@ -93,7 +108,8 @@ const CHART_SORT_ORDER = {
[ChartType.Bar]: 1,
};
-const defaultSort = (a, b) => {
+const defaultSort = (a: { chartType: string | number }[], b: { chartType: string | number }[]) => {
+ // @ts-ignore
return CHART_SORT_ORDER[b[1].chartType] - CHART_SORT_ORDER[a[1].chartType];
};
@@ -120,7 +136,7 @@ const createDynamicConfig = (
chartConfig: BaseChartConfig,
dynamicChartConfig: BaseChartConfig,
data: DataProps[],
-): BaseChartConfig => {
+) => {
// Just find keys. Doesn't include keys which end in _metadata.
// @ts-ignore
const dataKeys = data.map(dataPoint => Object.keys(dataPoint).filter(isDataKey)).flat();
@@ -129,6 +145,7 @@ const createDynamicConfig = (
// Add config to each key
const newChartConfig = {};
keys.forEach(key => {
+ // @ts-ignore
newChartConfig[key] = { ...dynamicChartConfig, ...chartConfig[key] };
});
return newChartConfig;
From 4250267e228b68cfc62fbe1aa2c7f743b56e89ed Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Mon, 22 May 2023 16:57:47 +1200
Subject: [PATCH 016/251] get chart table
---
.../src/components/Axes/YAxes.tsx | 11 +++++-
.../src/utils/getChartTableData.tsx | 4 +-
.../DataTable/useDataTableExport.tsx | 4 +-
yarn.lock | 38 +++++++++++++++++++
4 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/packages/ui-chart-components/src/components/Axes/YAxes.tsx b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
index 6f74f8e1c3..91d251e5e1 100644
--- a/packages/ui-chart-components/src/components/Axes/YAxes.tsx
+++ b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
@@ -160,13 +160,20 @@ const YAxis = ({
);
};
+interface YAxesProps {
+ yAxisConfigs: any[];
+ orientation: 'left' | 'right';
+ valueType: string;
+ yName: string;
+}
+
export const YAxes = ({
viewContent,
chartDataConfig,
isExporting = false,
isEnlarged = false,
}: any) => {
- const { chartConfig = {} } = viewContent;
+ const { chartConfig }: { chartConfig: YAxesProps } = viewContent;
const axisPropsById: { [p: number]: LooseObject } = {
[Y_AXIS_IDS.left]: { yAxisId: Y_AXIS_IDS.left, dataKeys: [], orientation: 'left' },
@@ -175,7 +182,7 @@ export const YAxes = ({
Object.entries(chartConfig).forEach(
([dataKey, { yAxisOrientation: orientation, valueType, yAxisDomain, yName }]) => {
- const axisId = Y_AXIS_IDS[orientation] || DEFAULT_Y_AXIS.id;
+ const axisId = Y_AXIS_IDS[orientation as 'left' | 'right'] || DEFAULT_Y_AXIS.id;
axisPropsById[axisId].dataKeys.push(dataKey);
if (valueType) {
axisPropsById[axisId].valueType = valueType;
diff --git a/packages/ui-chart-components/src/utils/getChartTableData.tsx b/packages/ui-chart-components/src/utils/getChartTableData.tsx
index abbf6aa463..42fd73c663 100644
--- a/packages/ui-chart-components/src/utils/getChartTableData.tsx
+++ b/packages/ui-chart-components/src/utils/getChartTableData.tsx
@@ -43,7 +43,7 @@ const makeFirstColumn = (header: string, accessor: TableAccessor, sortRows?: str
* Use the keys in chartConfig to determine which columns to render, and if chartConfig doesn't exist
* use value as the only column
*/
-const processColumns = (viewContent: ViewContent, sortByTimestamp: string) => {
+const processColumns = (viewContent: ViewContent, sortByTimestamp: Function) => {
if (!viewContent?.data) {
return [];
}
@@ -75,6 +75,7 @@ const processColumns = (viewContent: ViewContent, sortByTimestamp: string) => {
id: columnKey,
Header: (props: LooseObject) => {
const columnId = props.column.id;
+ // @ts-ignore
return chartConfig[columnId]?.label || columnId;
},
accessor: (row: LooseObject) => {
@@ -115,6 +116,7 @@ const processData = (viewContent: ViewContent) => {
export const getChartTableData = (viewContent: ViewContent) => {
// Because react-table wants its sort function to be memoized, it needs to live here, outside of
// the other useMemo hooks
+ // @ts-ignore
const sortByTimestamp = useMemo(() => (rowA: any, rowB: any) =>
sortDates(rowA.original.timestamp, rowB.original.timestamp),
);
diff --git a/packages/ui-components/src/components/DataTable/useDataTableExport.tsx b/packages/ui-components/src/components/DataTable/useDataTableExport.tsx
index f3eb3e390d..e0faf4f09a 100644
--- a/packages/ui-components/src/components/DataTable/useDataTableExport.tsx
+++ b/packages/ui-components/src/components/DataTable/useDataTableExport.tsx
@@ -12,8 +12,8 @@ export const useDataTableExport = (
columns: any[],
data: any[],
title: string,
- startDate: Moment | string | Date,
- endDate: Moment | string | Date,
+ startDate: Moment | string | Date | undefined,
+ endDate: Moment | string | Date | undefined,
) => {
const { headerGroups, rows: tableData, columns: tableColumns } = useTable({
columns,
diff --git a/yarn.lock b/yarn.lock
index 36baf15723..f2dfe6532a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5814,8 +5814,11 @@ __metadata:
"@material-ui/core": ^4.9.8
"@material-ui/styles": ^4.9.10
"@storybook/react": ^6.3.9
+ "@tupaia/types": 1.0.0
"@tupaia/ui-components": 1.0.0
"@tupaia/utils": 1.0.0
+ "@types/lodash.get": ^4.4.7
+ "@types/recharts": ^1.8.24
lodash.get: ^4.4.2
moment: ^2.29.1
prop-types: ^15.7.2
@@ -6222,6 +6225,22 @@ __metadata:
languageName: node
linkType: hard
+"@types/d3-path@npm:^1":
+ version: 1.0.9
+ resolution: "@types/d3-path@npm:1.0.9"
+ checksum: acbf7376fd7bef61701bce915bf5a9cb5eaa9741b7919d3e644f841a65faf1aea3cf63ba949c21ddda8c9849221394856a2054805aa698d3bb5ac3fe7d029817
+ languageName: node
+ linkType: hard
+
+"@types/d3-shape@npm:^1":
+ version: 1.3.8
+ resolution: "@types/d3-shape@npm:1.3.8"
+ dependencies:
+ "@types/d3-path": ^1
+ checksum: a7f78a3f0be1215b512efb636ba381768ab4104ef9b72b7fcc2ab9810e7d6fc2ee062f3103ef99236f4462deabac60d2fd96375315ec7ad33278757918c94592
+ languageName: node
+ linkType: hard
+
"@types/eslint-visitor-keys@npm:^1.0.0":
version: 1.0.0
resolution: "@types/eslint-visitor-keys@npm:1.0.0"
@@ -6511,6 +6530,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/lodash.get@npm:^4.4.7":
+ version: 4.4.7
+ resolution: "@types/lodash.get@npm:4.4.7"
+ dependencies:
+ "@types/lodash": "*"
+ checksum: 0dbf1960606e4707c34e8ffbe97ffaad0e47fc5df7a6e24ea6e4fe5838d2468aa13360f38815c77b06e3c9932631ae15662b4139036a69ee16aeb54827a21405
+ languageName: node
+ linkType: hard
+
"@types/lodash.groupby@npm:^4.6.0":
version: 4.6.6
resolution: "@types/lodash.groupby@npm:4.6.6"
@@ -6915,6 +6943,16 @@ __metadata:
languageName: node
linkType: hard
+"@types/recharts@npm:^1.8.24":
+ version: 1.8.24
+ resolution: "@types/recharts@npm:1.8.24"
+ dependencies:
+ "@types/d3-shape": ^1
+ "@types/react": "*"
+ checksum: 1341e5472bf62a83ab98648bc5c14a9a81fba16af9255203ef12a21caa21a988fac3198d9771703394eb876d4fbefb42e818865e35ecfe0d105aee1d1164aa6e
+ languageName: node
+ linkType: hard
+
"@types/resolve@npm:0.0.8":
version: 0.0.8
resolution: "@types/resolve@npm:0.0.8"
From 67e311af5cf0a361935203d7648d3e04c2760163 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 11:50:02 +1200
Subject: [PATCH 017/251] WAITP-1259 setup ts build for ui-map-components
---
.eslintrc | 7 +++-
packages/ui-map-components/package.json | 14 +++++--
.../ui-map-components/tsconfig-build.json | 14 +++++++
packages/ui-map-components/tsconfig.json | 21 ++++++++++
packages/web-frontend/package.json | 4 +-
yarn.lock | 40 +++++++++++++++++++
6 files changed, 93 insertions(+), 7 deletions(-)
create mode 100644 packages/ui-map-components/tsconfig-build.json
create mode 100644 packages/ui-map-components/tsconfig.json
diff --git a/.eslintrc b/.eslintrc
index b8e57010dd..5d6ef64693 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -228,7 +228,12 @@
"packages/ui-map-components/**"
],
"rules": {
- "import/no-extraneous-dependencies": "off"
+ "import/no-extraneous-dependencies": "off",
+ "react/prop-types": "off",
+ "import/no-unresolved": 0, // Turn off linting error for imports
+ "import/extensions": 0, // Turn off linting error for imports
+ "react/require-default-props": "off",
+ "no-bitwise": "off" // Turn off linting error for bitwise operators because of generic style types using '>>'
}
},
{
diff --git a/packages/ui-map-components/package.json b/packages/ui-map-components/package.json
index 09a277c2f1..96a29a0cc1 100644
--- a/packages/ui-map-components/package.json
+++ b/packages/ui-map-components/package.json
@@ -11,16 +11,16 @@
"author": "Beyond Essential Systems (https://beyondessential.com.au)",
"source": "src/index.js",
"main": "dist/index.js",
+ "types": "dist/index.d.ts",
"scripts": {
- "build": "rm -rf dist && npm run --prefix ../../ package:build:js",
+ "build": "rm -rf dist && npm run --prefix ../../ package:build:ts",
"build-dev": "npm run build",
"lint": "yarn package:lint:js",
"lint:fix": "yarn lint --fix",
"storybook": "start-storybook -s public -p 6006",
"test": "yarn package:test --env=jsdom",
"test:coverage": "yarn test --coverage",
- "test:watch": "yarn test --watch",
- "build-dev:watch": "yarn run package:build:js -w"
+ "test:watch": "yarn test --watch"
},
"dependencies": {
"@material-ui/core": "^4.9.8",
@@ -38,6 +38,12 @@
},
"devDependencies": {
"@material-ui/styles": "^4.9.10",
- "@storybook/react": "^6.3.9"
+ "@mui/types": "^7.2.4",
+ "@storybook/react": "^6.3.9",
+ "@types/jest": "^29.5.1",
+ "@types/leaflet": "^1.9.3",
+ "@types/react": "^18.2.7",
+ "@types/react-dom": "^18.2.4",
+ "@types/styled-components": "^5.1.26"
}
}
diff --git a/packages/ui-map-components/tsconfig-build.json b/packages/ui-map-components/tsconfig-build.json
new file mode 100644
index 0000000000..2b8b93fde2
--- /dev/null
+++ b/packages/ui-map-components/tsconfig-build.json
@@ -0,0 +1,14 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "declaration": true,
+ "noEmit": false,
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "src/__tests__",
+ "src/stories/**/*"
+ ]
+}
\ No newline at end of file
diff --git a/packages/ui-map-components/tsconfig.json b/packages/ui-map-components/tsconfig.json
new file mode 100644
index 0000000000..c1a5ac85da
--- /dev/null
+++ b/packages/ui-map-components/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "extends": "../../tsconfig-ts.json",
+ "compileOnSave": true,
+ "compilerOptions": {
+ "jsx": "react",
+ "allowJs": true,
+ "outDir": "dist",
+ "lib": [
+ "es6",
+ "dom"
+ ],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true
+ },
+ "include": [
+ "src/**/*",
+ "jest.config.ts",
+ "helpers/**/*"
+ ]
+}
diff --git a/packages/web-frontend/package.json b/packages/web-frontend/package.json
index c3b9200376..dce6898311 100644
--- a/packages/web-frontend/package.json
+++ b/packages/web-frontend/package.json
@@ -28,8 +28,8 @@
"storybook": "start-storybook -s public -p 6007",
"test": "node scripts/test.js --env=jsdom",
"start-ui-components": "yarn workspace @tupaia/ui-components build-dev:watch",
- "start-ui-chart-components": "yarn workspace @tupaia/ui-chart-components build-dev:watch",
- "start-ui-map-components": "yarn workspace @tupaia/ui-map-components build-dev:watch",
+ "start-ui-chart-components": "yarn workspace @tupaia/ui-chart-components build-dev -w",
+ "start-ui-map-components": "yarn workspace @tupaia/ui-map-components build-dev -w",
"start-frontend": "npm-run-all -c -l -p start-ui-components start-ui-chart-components start-ui-map-components start-dev"
},
"resolutions": {
diff --git a/yarn.lock b/yarn.lock
index 36baf15723..d5928f3f8c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5881,9 +5881,15 @@ __metadata:
"@material-ui/core": ^4.9.8
"@material-ui/icons": ^4.9.1
"@material-ui/styles": ^4.9.10
+ "@mui/types": ^7.2.4
"@storybook/react": ^6.3.9
"@tupaia/ui-components": 1.0.0
"@tupaia/utils": 1.0.0
+ "@types/jest": ^29.5.1
+ "@types/leaflet": ^1.9.3
+ "@types/react": ^18.2.7
+ "@types/react-dom": ^18.2.4
+ "@types/styled-components": ^5.1.26
leaflet: ^1.7.1
moment: ^2.29.1
prop-types: ^15.7.2
@@ -6288,6 +6294,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/geojson@npm:*":
+ version: 7946.0.10
+ resolution: "@types/geojson@npm:7946.0.10"
+ checksum: 12c407c2dc93ecb26c08af533ee732f1506a9b29456616ba7ba1d525df96206c28ddf44a528f6a5415d7d22893e9d967420940a9c095ee5e539c1eba5fefc1f4
+ languageName: node
+ linkType: hard
+
"@types/glob-base@npm:^0.3.0":
version: 0.3.0
resolution: "@types/glob-base@npm:0.3.0"
@@ -6493,6 +6506,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/leaflet@npm:^1.9.3":
+ version: 1.9.3
+ resolution: "@types/leaflet@npm:1.9.3"
+ dependencies:
+ "@types/geojson": "*"
+ checksum: d12042edc3a043d074b4fd3b4c4800f479dfb01db3980d8c1151edbc70b23ca9e84ab7da72ce0d1c36c040f89ba1421bd36d9d9796ec3704a0d3c942985a87ae
+ languageName: node
+ linkType: hard
+
"@types/lodash.clonedeep@npm:^4.5.0":
version: 4.5.7
resolution: "@types/lodash.clonedeep@npm:4.5.7"
@@ -6915,6 +6937,17 @@ __metadata:
languageName: node
linkType: hard
+"@types/react@npm:^18.2.7":
+ version: 18.2.7
+ resolution: "@types/react@npm:18.2.7"
+ dependencies:
+ "@types/prop-types": "*"
+ "@types/scheduler": "*"
+ csstype: ^3.0.2
+ checksum: caa5da4cf929766738ec789301dc6fb6624bd48dd317d851c4c9b84b1f47cd8ebe17fe01398cadaa0bc938cd4d502d67f4b9de9ff771dc132096bdc86228efba
+ languageName: node
+ linkType: hard
+
"@types/resolve@npm:0.0.8":
version: 0.0.8
resolution: "@types/resolve@npm:0.0.8"
@@ -6933,6 +6966,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/scheduler@npm:*":
+ version: 0.16.3
+ resolution: "@types/scheduler@npm:0.16.3"
+ checksum: 2b0aec39c24268e3ce938c5db2f2e77f5c3dd280e05c262d9c2fe7d890929e4632a6b8e94334017b66b45e4f92a5aa42ba3356640c2a1175fa37bef2f5200767
+ languageName: node
+ linkType: hard
+
"@types/semver-compare@npm:^1.0.1":
version: 1.0.1
resolution: "@types/semver-compare@npm:1.0.1"
From e98a7f033b7c5fd50182e9452a4d5c5cc678f029 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 11:51:13 +1200
Subject: [PATCH 018/251] WAITP-1259 Update build script to allow watch
---
packages/ui-map-components/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/ui-map-components/package.json b/packages/ui-map-components/package.json
index 96a29a0cc1..1e484be710 100644
--- a/packages/ui-map-components/package.json
+++ b/packages/ui-map-components/package.json
@@ -13,7 +13,7 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
- "build": "rm -rf dist && npm run --prefix ../../ package:build:ts",
+ "build": "rm -rf dist && yarn package:build:ts",
"build-dev": "npm run build",
"lint": "yarn package:lint:js",
"lint:fix": "yarn lint --fix",
From 2b9f6d89b4b8ed1d23874284427f95eac286f1c5 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 12:01:16 +1200
Subject: [PATCH 019/251] WAITP-1259 Change index to ts
---
packages/ui-map-components/src/{index.js => index.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename packages/ui-map-components/src/{index.js => index.ts} (100%)
diff --git a/packages/ui-map-components/src/index.js b/packages/ui-map-components/src/index.ts
similarity index 100%
rename from packages/ui-map-components/src/index.js
rename to packages/ui-map-components/src/index.ts
From 62e9d7539fcced440f7147ba06804c73866b1425 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 12:01:36 +1200
Subject: [PATCH 020/251] WAITP-1259 ActivePolygon to ts
---
.../{ActivePolygon.js => ActivePolygon.tsx} | 36 +++++++++----------
1 file changed, 17 insertions(+), 19 deletions(-)
rename packages/ui-map-components/src/components/{ActivePolygon.js => ActivePolygon.tsx} (60%)
diff --git a/packages/ui-map-components/src/components/ActivePolygon.js b/packages/ui-map-components/src/components/ActivePolygon.tsx
similarity index 60%
rename from packages/ui-map-components/src/components/ActivePolygon.js
rename to packages/ui-map-components/src/components/ActivePolygon.tsx
index 243199c5da..bc5cdbf3d1 100644
--- a/packages/ui-map-components/src/components/ActivePolygon.js
+++ b/packages/ui-map-components/src/components/ActivePolygon.tsx
@@ -4,14 +4,19 @@
*/
import React from 'react';
-import PropTypes from 'prop-types';
-import { Polygon } from 'react-leaflet';
+import { Polygon, PolygonProps as LeafletPolygonProps } from 'react-leaflet';
import styled from 'styled-components';
import { MAP_COLORS } from '../constants';
const { POLYGON_HIGHLIGHT } = MAP_COLORS;
-const StyledPolygon = styled(Polygon)`
+interface PolygonProps {
+ shade?: string;
+ hasChildren?: boolean;
+ hasShadedChildren?: boolean;
+}
+
+const StyledPolygon = styled(Polygon)`
stroke: ${props => props.shade || POLYGON_HIGHLIGHT};
opacity: 1;
fill: ${props => props.shade || 'none'};
@@ -27,7 +32,15 @@ const StyledPolygon = styled(Polygon)`
/**
* ActivePolygon: The polygon that is selected on the map. This handles the style logic
*/
-const ActivePolygon = ({ coordinates, shade, hasChildren, hasShadedChildren }) => (
+interface ActivePolygonProps extends PolygonProps {
+ coordinates: LeafletPolygonProps['positions'];
+}
+const ActivePolygon = ({
+ coordinates,
+ shade,
+ hasChildren = false,
+ hasShadedChildren = false,
+}: ActivePolygonProps) => (
);
-ActivePolygon.propTypes = {
- coordinates: PropTypes.arrayOf(
- PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number))),
- ).isRequired,
- shade: PropTypes.string,
- hasChildren: PropTypes.bool,
- hasShadedChildren: PropTypes.bool,
-};
-
-ActivePolygon.defaultProps = {
- shade: null,
- hasChildren: false,
- hasShadedChildren: false,
-};
-
export default ActivePolygon;
From 3d32219372541872fa3df8f4228d9b48c9d562af Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 13:19:08 +1200
Subject: [PATCH 021/251] WAITP-1259 AreaTooltip to ts
---
.../{AreaTooltip.js => AreaTooltip.tsx} | 48 ++++++++-----------
.../src/types/data-types.d.ts | 9 ++++
.../ui-map-components/src/types/index.d.ts | 1 +
3 files changed, 30 insertions(+), 28 deletions(-)
rename packages/ui-map-components/src/components/{AreaTooltip.js => AreaTooltip.tsx} (62%)
create mode 100644 packages/ui-map-components/src/types/data-types.d.ts
create mode 100644 packages/ui-map-components/src/types/index.d.ts
diff --git a/packages/ui-map-components/src/components/AreaTooltip.js b/packages/ui-map-components/src/components/AreaTooltip.tsx
similarity index 62%
rename from packages/ui-map-components/src/components/AreaTooltip.js
rename to packages/ui-map-components/src/components/AreaTooltip.tsx
index cec7152976..670d1911cc 100644
--- a/packages/ui-map-components/src/components/AreaTooltip.js
+++ b/packages/ui-map-components/src/components/AreaTooltip.tsx
@@ -5,12 +5,14 @@
*/
import React from 'react';
-import PropTypes from 'prop-types';
import { Tooltip } from 'react-leaflet';
import styled from 'styled-components';
import { PopupDataItemList } from './PopupDataItemList';
+import { Series } from '../types';
-const Heading = styled.span`
+const Heading = styled.span<{
+ hasMeasureValue: boolean;
+}>`
text-align: center;
font-weight: ${props => (props.hasMeasureValue ? 'bold' : 'normal')};
`;
@@ -19,15 +21,25 @@ const Grid = styled.div`
display: grid;
`;
+interface AreaTooltipProps {
+ permanent?: boolean;
+ sticky?: boolean;
+ orgUnitName?: string;
+ hasMeasureValue?: boolean;
+ serieses?: Series[];
+ orgUnitMeasureData?: object;
+ text?: string;
+}
+
export const AreaTooltip = ({
- permanent,
- sticky,
+ permanent = false,
+ sticky = false,
orgUnitName,
- hasMeasureValue,
- serieses,
- orgUnitMeasureData,
+ hasMeasureValue = false,
+ serieses = [],
+ orgUnitMeasureData = {},
text,
-}) => {
+}: AreaTooltipProps) => {
return (
);
};
-
-AreaTooltip.propTypes = {
- permanent: PropTypes.bool,
- sticky: PropTypes.bool,
- hasMeasureValue: PropTypes.bool,
- serieses: PropTypes.arrayOf(PropTypes.object),
- orgUnitMeasureData: PropTypes.object,
- orgUnitName: PropTypes.string,
- text: PropTypes.string,
-};
-
-AreaTooltip.defaultProps = {
- permanent: false,
- sticky: false,
- hasMeasureValue: false,
- serieses: [],
- orgUnitMeasureData: {},
- orgUnitName: null,
- text: null,
-};
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
new file mode 100644
index 0000000000..ea5eb488c7
--- /dev/null
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -0,0 +1,9 @@
+export type Series = {
+ key: string;
+ name: string;
+ hideFromPopup?: boolean;
+ metadata: object;
+ value: string | number;
+ organisationUnit?: string;
+ sortOrder: number;
+};
diff --git a/packages/ui-map-components/src/types/index.d.ts b/packages/ui-map-components/src/types/index.d.ts
new file mode 100644
index 0000000000..ea98209e1c
--- /dev/null
+++ b/packages/ui-map-components/src/types/index.d.ts
@@ -0,0 +1 @@
+export * from './data-types';
From 6f0c1909c746f8ca82c8b01f41a7e8b5b7e032e8 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 13:19:23 +1200
Subject: [PATCH 022/251] WAITP-1259 PopupDataItemList to ts
---
.../src/components/PopupDataItemList.js | 63 -------------------
.../src/components/PopupDataItemList.tsx | 44 +++++++++++++
2 files changed, 44 insertions(+), 63 deletions(-)
delete mode 100644 packages/ui-map-components/src/components/PopupDataItemList.js
create mode 100644 packages/ui-map-components/src/components/PopupDataItemList.tsx
diff --git a/packages/ui-map-components/src/components/PopupDataItemList.js b/packages/ui-map-components/src/components/PopupDataItemList.js
deleted file mode 100644
index 05e4eab251..0000000000
--- a/packages/ui-map-components/src/components/PopupDataItemList.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Tupaia
- * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
- *
- */
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import { getFormattedInfo } from '../utils';
-
-const getMetadata = (data, key) => {
- if (data.metadata) {
- return data.metadata;
- }
- const metadataKeys = Object.keys(data).filter(k => k.includes(`${key}_metadata`));
- return Object.fromEntries(metadataKeys.map(k => [k.replace(`${key}_metadata`, ''), data[k]]));
-};
-
-const PopupDataItem = ({ measureName, value }) => (
-
- {`${measureName}: `}
- {value}
-
-);
-
-PopupDataItem.propTypes = {
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
- measureName: PropTypes.string.isRequired,
-};
-
-export const PopupDataItemList = ({ serieses, data }) => {
- return serieses
- .filter(series => !series.hideFromPopup)
- .sort((measure1, measure2) => measure1.sortOrder - measure2.sortOrder)
- .map(series => {
- const { key, name, organisationUnit, ...otherConfigs } = series;
- const metadata = getMetadata(data, key);
- const { formattedValue, valueInfo } = getFormattedInfo(data, series, {
- key,
- metadata,
- ...otherConfigs,
- });
- return valueInfo.hideFromPopup ? null : (
-
- );
- })
- .filter(popupItem => popupItem !== null);
-};
-
-PopupDataItemList.propTypes = {
- data: PropTypes.object.isRequired,
- serieses: PropTypes.arrayOf(
- PropTypes.shape({
- key: PropTypes.string.isRequired,
- name: PropTypes.string,
- hideFromPopup: PropTypes.bool,
- metadata: PropTypes.object,
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- }),
- ).isRequired,
-};
-
-PopupDataItemList.defaultTypes = { data: {} };
diff --git a/packages/ui-map-components/src/components/PopupDataItemList.tsx b/packages/ui-map-components/src/components/PopupDataItemList.tsx
new file mode 100644
index 0000000000..169188d6c8
--- /dev/null
+++ b/packages/ui-map-components/src/components/PopupDataItemList.tsx
@@ -0,0 +1,44 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ *
+ */
+
+import React from 'react';
+import { getFormattedInfo } from '../utils';
+import { Series } from '../types';
+
+interface PopupDataItemProps {
+ measureName: Series['name'];
+ value: Series['value'];
+}
+
+const PopupDataItem = ({ measureName, value }: PopupDataItemProps) => (
+
+ {`${measureName}: `}
+ {value}
+
+);
+
+interface PopupDataItemListProps {
+ serieses: Series[];
+ data?: object;
+}
+
+export const PopupDataItemList = ({ serieses, data = {} }: PopupDataItemListProps) => {
+ return (
+ <>
+ {serieses
+ .filter(series => !series.hideFromPopup)
+ .sort((measure1, measure2) => measure1.sortOrder - measure2.sortOrder)
+ .map(series => {
+ const { name } = series;
+ const { formattedValue, valueInfo } = getFormattedInfo(data, series);
+ return valueInfo.hideFromPopup ? null : (
+
+ );
+ })
+ .filter(popupItem => popupItem !== null)}
+ >
+ );
+};
From dee800f72cf6d7f0071c7b352aed6b1ba997617d Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 13:22:33 +1200
Subject: [PATCH 023/251] WAITP-1259 EntityPolygon to ts
---
.../{EntityPolygon.js => EntityPolygon.tsx} | 15 ++-------------
.../ui-map-components/src/types/data-types.d.ts | 7 +++++++
2 files changed, 9 insertions(+), 13 deletions(-)
rename packages/ui-map-components/src/components/{EntityPolygon.js => EntityPolygon.tsx} (75%)
diff --git a/packages/ui-map-components/src/components/EntityPolygon.js b/packages/ui-map-components/src/components/EntityPolygon.tsx
similarity index 75%
rename from packages/ui-map-components/src/components/EntityPolygon.js
rename to packages/ui-map-components/src/components/EntityPolygon.tsx
index c3a8099f34..a3d3cfab91 100644
--- a/packages/ui-map-components/src/components/EntityPolygon.js
+++ b/packages/ui-map-components/src/components/EntityPolygon.tsx
@@ -4,11 +4,11 @@
*
*/
import React from 'react';
-import PropTypes from 'prop-types';
import { Polygon as PolygonComponent } from 'react-leaflet';
import styled from 'styled-components';
import { blue } from '@material-ui/core/colors';
import { AreaTooltip } from './AreaTooltip';
+import { Entity } from '../types';
export const POLYGON_COLOR = '#EE6230';
@@ -23,7 +23,7 @@ const BasicPolygon = styled(PolygonComponent)`
}
`;
-export const EntityPolygon = ({ entity }) => {
+export const EntityPolygon = ({ entity }: { entity?: Entity }) => {
if (!entity || !Array.isArray(entity.region)) {
return null;
}
@@ -36,14 +36,3 @@ export const EntityPolygon = ({ entity }) => {
);
};
-
-EntityPolygon.propTypes = {
- entity: PropTypes.shape({
- name: PropTypes.string,
- region: PropTypes.array,
- }),
-};
-
-EntityPolygon.defaultProps = {
- entity: null,
-};
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index ea5eb488c7..ab45080453 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -1,3 +1,5 @@
+import { PolygonProps } from 'react-leaflet';
+
export type Series = {
key: string;
name: string;
@@ -7,3 +9,8 @@ export type Series = {
organisationUnit?: string;
sortOrder: number;
};
+
+export type Entity = {
+ region?: PolygonProps['positions'];
+ name: string;
+};
From 96308672abf9b37dddbeb35bebf584e9f97f500f Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Thu, 25 May 2023 13:29:58 +1200
Subject: [PATCH 024/251] fix linting
---
.eslintrc | 18 +-----------------
.../.storybook/AppProviders.js | 2 +-
.../ui-chart-components/.storybook/main.js | 2 +-
packages/ui-chart-components/package.json | 1 +
.../src/__tests__/parseChartConfig.test.js | 2 +-
.../src/{index.js => index.ts} | 0
packages/ui-chart-components/src/types.ts | 1 -
.../stories/barChart.stories.js | 2 +-
.../ui-chart-components/tsconfig-build.json | 11 +++++++++--
packages/ui-chart-components/tsconfig.json | 18 +++++++++++-------
10 files changed, 26 insertions(+), 31 deletions(-)
rename packages/ui-chart-components/src/{index.js => index.ts} (100%)
diff --git a/.eslintrc b/.eslintrc
index b8e57010dd..1b0dd39049 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -204,7 +204,7 @@
},
{
"files": [
- "packages/ui-components/**"
+ "packages/ui-components/**", "packages/ui-chart-components/**", "packages/ui-map-components/**"
],
"rules": {
"import/no-extraneous-dependencies": "off",
@@ -215,22 +215,6 @@
"no-bitwise": "off" // Turn off linting error for bitwise operators because of generic style types using '>>'
}
},
- {
- "files": [
- "packages/ui-chart-components/**"
- ],
- "rules": {
- "import/no-extraneous-dependencies": "off"
- }
- },
- {
- "files": [
- "packages/ui-map-components/**"
- ],
- "rules": {
- "import/no-extraneous-dependencies": "off"
- }
- },
{
"files": [
"packages/web-config-server/**"
diff --git a/packages/ui-chart-components/.storybook/AppProviders.js b/packages/ui-chart-components/.storybook/AppProviders.js
index 276eb96bb8..bef63eb75c 100644
--- a/packages/ui-chart-components/.storybook/AppProviders.js
+++ b/packages/ui-chart-components/.storybook/AppProviders.js
@@ -8,7 +8,7 @@ import { MuiThemeProvider, StylesProvider } from '@material-ui/core/styles';
import { ThemeProvider } from 'styled-components';
import CssBaseline from '@material-ui/core/CssBaseline';
import PropTypes from 'prop-types';
-import { lightTheme, darkTheme } from '../stories/story-utils/theme';
+import { lightTheme, darkTheme } from '../stories/theme';
export const AppProviders = ({ params, children }) => {
const theme = params?.theme === 'dark' ? darkTheme : lightTheme;
diff --git a/packages/ui-chart-components/.storybook/main.js b/packages/ui-chart-components/.storybook/main.js
index e731ebcce9..e723272433 100644
--- a/packages/ui-chart-components/.storybook/main.js
+++ b/packages/ui-chart-components/.storybook/main.js
@@ -1,5 +1,5 @@
// import the build chain webpack config and merge it with storybook config
module.exports = {
- stories: ['../stories/**/*.stories.js'],
+ stories: ['../stories/**/*.stories.js', '../stories/**/*.stories.ts'],
addons: ['@storybook/addon-essentials'],
};
diff --git a/packages/ui-chart-components/package.json b/packages/ui-chart-components/package.json
index 26a1b07b26..48dc3ba136 100644
--- a/packages/ui-chart-components/package.json
+++ b/packages/ui-chart-components/package.json
@@ -11,6 +11,7 @@
"author": "Beyond Essential Systems (https://beyondessential.com.au)",
"source": "src/index.js",
"main": "dist/index.js",
+ "types": "dist/index.d.ts",
"scripts": {
"build": "rm -rf dist && yarn package:build:ts",
"build-dev": "npm run build",
diff --git a/packages/ui-chart-components/src/__tests__/parseChartConfig.test.js b/packages/ui-chart-components/src/__tests__/parseChartConfig.test.js
index 04a9efc684..7d7e394c69 100644
--- a/packages/ui-chart-components/src/__tests__/parseChartConfig.test.js
+++ b/packages/ui-chart-components/src/__tests__/parseChartConfig.test.js
@@ -4,7 +4,7 @@
*
*/
-import { parseChartConfig } from '../utils/parseChartConfig';
+import { parseChartConfig } from '../utils';
import { CHART_COLOR_PALETTE, EXPANDED_CHART_COLOR_PALETTE } from '../constants';
const testViewJson = {
diff --git a/packages/ui-chart-components/src/index.js b/packages/ui-chart-components/src/index.ts
similarity index 100%
rename from packages/ui-chart-components/src/index.js
rename to packages/ui-chart-components/src/index.ts
diff --git a/packages/ui-chart-components/src/types.ts b/packages/ui-chart-components/src/types.ts
index 46de72246a..2bd4fe7d35 100644
--- a/packages/ui-chart-components/src/types.ts
+++ b/packages/ui-chart-components/src/types.ts
@@ -6,7 +6,6 @@ import { BaseChartConfig, ValueType } from '@tupaia/types';
import { ReferenceAreaProps } from 'recharts';
import { GRANULARITY_SHAPE } from '@tupaia/utils';
-// Todo: move some of these types to @tupaia/types and integrate
export interface DataProps {
name: string;
value: string | number;
diff --git a/packages/ui-chart-components/stories/barChart.stories.js b/packages/ui-chart-components/stories/barChart.stories.js
index e0fdfaaa91..b8eb3ad3c2 100644
--- a/packages/ui-chart-components/stories/barChart.stories.js
+++ b/packages/ui-chart-components/stories/barChart.stories.js
@@ -3,7 +3,7 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*
*/
-import { Chart } from '../src/components/Chart';
+import { Chart } from '../src';
import { DarkThemeTemplate, LightThemeChartTemplate } from './helpers';
import viewContent from './data/barChartViewContent.json';
diff --git a/packages/ui-chart-components/tsconfig-build.json b/packages/ui-chart-components/tsconfig-build.json
index df76f9c4ca..2b8b93fde2 100644
--- a/packages/ui-chart-components/tsconfig-build.json
+++ b/packages/ui-chart-components/tsconfig-build.json
@@ -3,5 +3,12 @@
"compilerOptions": {
"declaration": true,
"noEmit": false,
- }
-}
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "src/__tests__",
+ "src/stories/**/*"
+ ]
+}
\ No newline at end of file
diff --git a/packages/ui-chart-components/tsconfig.json b/packages/ui-chart-components/tsconfig.json
index 3c416cc281..c1a5ac85da 100644
--- a/packages/ui-chart-components/tsconfig.json
+++ b/packages/ui-chart-components/tsconfig.json
@@ -3,15 +3,19 @@
"compileOnSave": true,
"compilerOptions": {
"jsx": "react",
- "target": "es5",
"allowJs": true,
- "outDir": "dist"
+ "outDir": "dist",
+ "lib": [
+ "es6",
+ "dom"
+ ],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true
},
"include": [
- "src/**/*"
- ],
- "exclude": [
- "src/__tests__",
- "src/stories/**/*"
+ "src/**/*",
+ "jest.config.ts",
+ "helpers/**/*"
]
}
From 2005f14159f15269626fe090c7b60e0f15d0241a Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 14:07:46 +1200
Subject: [PATCH 025/251] WAITP-1259 InteractivePolygon to TS
---
.../src/components/AreaTooltip.tsx | 4 +-
...ctivePolygon.js => InteractivePolygon.tsx} | 84 ++++++++-----------
.../src/components/{index.js => index.ts} | 0
.../src/types/data-types.d.ts | 27 +++++-
4 files changed, 64 insertions(+), 51 deletions(-)
rename packages/ui-map-components/src/components/{InteractivePolygon.js => InteractivePolygon.tsx} (78%)
rename packages/ui-map-components/src/components/{index.js => index.ts} (100%)
diff --git a/packages/ui-map-components/src/components/AreaTooltip.tsx b/packages/ui-map-components/src/components/AreaTooltip.tsx
index 670d1911cc..d12c36e475 100644
--- a/packages/ui-map-components/src/components/AreaTooltip.tsx
+++ b/packages/ui-map-components/src/components/AreaTooltip.tsx
@@ -8,7 +8,7 @@ import React from 'react';
import { Tooltip } from 'react-leaflet';
import styled from 'styled-components';
import { PopupDataItemList } from './PopupDataItemList';
-import { Series } from '../types';
+import { GenericDataItem, Series } from '../types';
const Heading = styled.span<{
hasMeasureValue: boolean;
@@ -27,7 +27,7 @@ interface AreaTooltipProps {
orgUnitName?: string;
hasMeasureValue?: boolean;
serieses?: Series[];
- orgUnitMeasureData?: object;
+ orgUnitMeasureData?: GenericDataItem;
text?: string;
}
diff --git a/packages/ui-map-components/src/components/InteractivePolygon.js b/packages/ui-map-components/src/components/InteractivePolygon.tsx
similarity index 78%
rename from packages/ui-map-components/src/components/InteractivePolygon.js
rename to packages/ui-map-components/src/components/InteractivePolygon.tsx
index d6c44290b2..8a7aaa7054 100644
--- a/packages/ui-map-components/src/components/InteractivePolygon.js
+++ b/packages/ui-map-components/src/components/InteractivePolygon.tsx
@@ -4,12 +4,12 @@
*/
import React from 'react';
-import PropTypes from 'prop-types';
import { Polygon } from 'react-leaflet';
import styled from 'styled-components';
import { AreaTooltip } from './AreaTooltip';
import { MAP_COLORS, BREWER_PALETTE } from '../constants';
import ActivePolygon from './ActivePolygon';
+import { Entity, GenericDataItem, MeasureOrgUnit, Series } from '../types';
const { POLYGON_BLUE, POLYGON_HIGHLIGHT } = MAP_COLORS;
@@ -39,12 +39,20 @@ const TransparentShadedPolygon = styled(Polygon)`
}
`;
+type ParsedPropsResult = {
+ shade?: MeasureOrgUnit['color'];
+ isHidden?: boolean;
+ hasShadedChildren: boolean;
+ orgUnitMeasureData?: MeasureOrgUnit;
+ orgUnitMultiOverlayMeasureData?: GenericDataItem;
+};
+
const parseProps = (
- organisationUnitCode,
- organisationUnitChildren,
- measureOrgUnits,
- multiOverlayMeasureData,
-) => {
+ organisationUnitCode: string,
+ organisationUnitChildren: GenericDataItem[],
+ measureOrgUnits: MeasureOrgUnit[],
+ multiOverlayMeasureData: GenericDataItem[],
+): ParsedPropsResult => {
let shade;
let isHidden;
let orgUnitMeasureData;
@@ -79,19 +87,32 @@ const parseProps = (
return { shade, isHidden, hasShadedChildren, orgUnitMeasureData, orgUnitMultiOverlayMeasureData };
};
+interface InteractivePolygonProps {
+ isChildArea?: boolean;
+ hasMeasureData?: boolean;
+ multiOverlaySerieses?: Series[];
+ multiOverlayMeasureData?: GenericDataItem[];
+ permanentLabels?: boolean;
+ onChangeOrgUnit?: (organisationUnitCode: string) => void;
+ area: Entity;
+ isActive?: boolean;
+ measureOrgUnits?: MeasureOrgUnit[];
+ organisationUnitChildren?: GenericDataItem[];
+}
+
export const InteractivePolygon = React.memo(
({
- isChildArea,
- hasMeasureData,
- multiOverlaySerieses,
- multiOverlayMeasureData,
- permanentLabels,
- onChangeOrgUnit,
+ isChildArea = false,
+ hasMeasureData = false,
+ multiOverlaySerieses = [],
+ multiOverlayMeasureData = [],
+ permanentLabels = true,
+ onChangeOrgUnit = () => {},
area,
- isActive,
- measureOrgUnits,
- organisationUnitChildren,
- }) => {
+ isActive = false,
+ measureOrgUnits = [],
+ organisationUnitChildren = [],
+ }: InteractivePolygonProps) => {
const { organisationUnitCode } = area;
const coordinates = area.location?.region;
const hasChildren = organisationUnitChildren && organisationUnitChildren.length > 0;
@@ -135,7 +156,6 @@ export const InteractivePolygon = React.memo(
// Render all measure data even it is not selected on switch button to display.
return (
{tooltip};
},
);
-
-InteractivePolygon.propTypes = {
- area: PropTypes.shape({
- name: PropTypes.string,
- type: PropTypes.string,
- location: PropTypes.object,
- organisationUnitCode: PropTypes.string,
- }).isRequired,
- isActive: PropTypes.bool,
- permanentLabels: PropTypes.bool,
- isChildArea: PropTypes.bool,
- onChangeOrgUnit: PropTypes.func,
- hasMeasureData: PropTypes.bool,
- multiOverlaySerieses: PropTypes.arrayOf(PropTypes.object),
- measureOrgUnits: PropTypes.arrayOf(PropTypes.object),
- multiOverlayMeasureData: PropTypes.arrayOf(PropTypes.object),
- organisationUnitChildren: PropTypes.arrayOf(PropTypes.object),
-};
-
-InteractivePolygon.defaultProps = {
- isActive: false,
- permanentLabels: true,
- isChildArea: false,
- onChangeOrgUnit: () => {},
- hasMeasureData: false,
- multiOverlaySerieses: [],
- organisationUnitChildren: [],
- measureOrgUnits: [],
- multiOverlayMeasureData: [],
-};
diff --git a/packages/ui-map-components/src/components/index.js b/packages/ui-map-components/src/components/index.ts
similarity index 100%
rename from packages/ui-map-components/src/components/index.js
rename to packages/ui-map-components/src/components/index.ts
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index ab45080453..2cdc03da81 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -1,4 +1,7 @@
import { PolygonProps } from 'react-leaflet';
+import { LatLngExpression, LatLngBoundsExpression } from 'leaflet';
+import { Entity as TupaiaEntity } from '@tupaia/types';
+import { BREWER_PALETTE } from '../constants';
export type Series = {
key: string;
@@ -9,8 +12,28 @@ export type Series = {
organisationUnit?: string;
sortOrder: number;
};
+export type Location = {
+ bounds: LatLngBoundsExpression;
+ type?: string | null;
+ point?: LatLngExpression;
+ region: PolygonProps['positions'];
+};
-export type Entity = {
+// Extend the base TupaiaEntity type with more details about the entity, including leaflet specific formatting
+export type Entity = TupaiaEntity & {
region?: PolygonProps['positions'];
- name: string;
+ organisationUnitCode: string;
+ location?: Location;
+};
+
+export type GenericDataItem = {
+ [key: string]: any;
+ organisationUnitCode?: string;
+};
+
+export type MeasureOrgUnit = {
+ [key: string]: any;
+ organisationUnitCode?: string;
+ isHidden?: boolean;
+ color?: keyof typeof BREWER_PALETTE | 'transparent';
};
From a3022e78f17cad11c3f240e90bb4ed78ff2739b4 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Thu, 25 May 2023 14:13:29 +1200
Subject: [PATCH 026/251] WAITP-1259 UnversePolygonMask to ts
---
...sePolygonMask.js => InversePolygonMask.tsx} | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
rename packages/ui-map-components/src/components/{InversePolygonMask.js => InversePolygonMask.tsx} (64%)
diff --git a/packages/ui-map-components/src/components/InversePolygonMask.js b/packages/ui-map-components/src/components/InversePolygonMask.tsx
similarity index 64%
rename from packages/ui-map-components/src/components/InversePolygonMask.js
rename to packages/ui-map-components/src/components/InversePolygonMask.tsx
index 5deeaed6dd..0a72404be4 100644
--- a/packages/ui-map-components/src/components/InversePolygonMask.js
+++ b/packages/ui-map-components/src/components/InversePolygonMask.tsx
@@ -4,8 +4,8 @@
*/
import React from 'react';
-import PropTypes from 'prop-types';
-import { Polygon as PolygonComponent } from 'react-leaflet';
+import { Polygon as PolygonComponent, PolygonProps } from 'react-leaflet';
+import { LatLngExpression } from 'leaflet';
import styled from 'styled-components';
const BasicPolygon = styled(PolygonComponent)`
@@ -14,7 +14,9 @@ const BasicPolygon = styled(PolygonComponent)`
stroke-width: 0;
`;
-const getOuterPolygon = region => {
+type Region = LatLngExpression[];
+
+const getOuterPolygon = (region: Region): PolygonProps['positions'] => {
return [
[
[90, -180],
@@ -26,7 +28,7 @@ const getOuterPolygon = region => {
];
};
-export const InversePolygonMask = ({ region }) => {
+export const InversePolygonMask = ({ region }: { region: Region | null }) => {
if (!Array.isArray(region)) {
return null;
}
@@ -35,11 +37,3 @@ export const InversePolygonMask = ({ region }) => {
return ;
};
-
-InversePolygonMask.propTypes = {
- region: PropTypes.array,
-};
-
-InversePolygonMask.defaultProps = {
- region: null,
-};
From 41779316d803bb08c47d83c4599417eb977d8cdd Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Thu, 25 May 2023 15:18:11 +1200
Subject: [PATCH 027/251] remove ts ignores
---
.../src/components/Axes/XAxis.tsx | 1 -
.../src/components/Axes/YAxes.tsx | 1 -
.../src/components/CartesianChart.tsx | 35 +++++++++++++------
.../src/components/Charts/GaugeChart.tsx | 32 +++++++++--------
.../src/components/Charts/PieChart.tsx | 10 +++---
.../src/components/Reference/ChartTooltip.tsx | 3 +-
.../src/components/Reference/Legend.tsx | 20 +++++------
packages/ui-chart-components/src/types.ts | 1 +
.../src/utils/getChartTableData.tsx | 15 ++++----
.../src/utils/parseChartConfig.ts | 16 +++------
packages/ui-chart-components/tsconfig.json | 5 ++-
11 files changed, 75 insertions(+), 64 deletions(-)
diff --git a/packages/ui-chart-components/src/components/Axes/XAxis.tsx b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
index 759c1e4939..027412ecfe 100644
--- a/packages/ui-chart-components/src/components/Axes/XAxis.tsx
+++ b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
@@ -128,7 +128,6 @@ export const XAxis = ({ viewContent, isExporting = false, isEnlarged = false }:
const getXAxisPadding = () => {
const hasBars =
chartType === Bar ||
- // @ts-ignore
Object.values(chartConfig).some(({ chartType: composedType }) => composedType === Bar);
if (hasBars && data.length > 1 && isTimeSeries) {
diff --git a/packages/ui-chart-components/src/components/Axes/YAxes.tsx b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
index 91d251e5e1..8bce8a8d6e 100644
--- a/packages/ui-chart-components/src/components/Axes/YAxes.tsx
+++ b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
@@ -86,7 +86,6 @@ const renderYAxisLabel = (
const getAxisWidth = (data: any[], dataKeys: string[], valueType: ValueType) => {
// Only use a dynamic width for number types. Otherwise fallback to the recharts default
if (valueType === 'number' || valueType === undefined) {
- // @ts-ignore
const values = data.map(item => dataKeys.map(key => item[key])).flat();
const maxValue = Math.max(...values);
diff --git a/packages/ui-chart-components/src/components/CartesianChart.tsx b/packages/ui-chart-components/src/components/CartesianChart.tsx
index f52f6f6c44..843fa84f74 100644
--- a/packages/ui-chart-components/src/components/CartesianChart.tsx
+++ b/packages/ui-chart-components/src/components/CartesianChart.tsx
@@ -2,7 +2,6 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-// @ts-nocheck
import React, { useEffect, useState } from 'react';
import get from 'lodash.get';
import {
@@ -15,10 +14,17 @@ import {
ResponsiveContainer,
Tooltip,
Brush,
+ ReferenceAreaProps,
} from 'recharts';
-import { CartesianChartConfig } from '@tupaia/types';
+import { BaseChartConfig, CartesianChartConfig, ValueType } from '@tupaia/types';
import { CHART_BLUES, DEFAULT_DATA_KEY } from '../constants';
-import { ChartType, ViewContent, LegendPosition } from '../types';
+import {
+ ChartType,
+ ViewContent,
+ LegendPosition,
+ VizPeriodGranularity,
+ PresentationOptions,
+} from '../types';
import {
BarChart as BarChartComponent,
LineChart as LineChartComponent,
@@ -83,7 +89,7 @@ const getLegendAlignment = (legendPosition: LegendPosition, isExporting: boolean
return { verticalAlign: 'top', align: 'left' };
};
-const getHeight = (isExporting: boolean, isEnlarged: boolean, hasLegend: boolean) => {
+const getHeight = (isExporting: boolean, isEnlarged: boolean, hasLegend?: boolean) => {
if (isExporting) {
return 500;
}
@@ -104,6 +110,14 @@ const getMargin = (isExporting: boolean, isEnlarged: boolean) => {
type CartesianChartConfigWithAll = CartesianChartConfig & { [LEGEND_ALL_DATA_KEY]?: any };
+type CartesianChartType = keyof typeof CHART_TYPE_TO_CONTAINER;
+
+interface CustomViewContent extends Omit {
+ chartConfig: CartesianChartConfig;
+ valueType: ValueType;
+ labelType: ValueType;
+}
+
interface CartesianChartProps {
viewContent: ViewContent;
legendPosition: LegendPosition;
@@ -117,7 +131,7 @@ export const CartesianChart = ({
isExporting = false,
legendPosition = 'bottom',
}: CartesianChartProps) => {
- const [chartConfig, setChartConfig] = useState(
+ const [chartConfig, setChartConfig] = useState(
viewContent.chartConfig || {},
);
const [activeDataKeys, setActiveDataKeys] = useState([]);
@@ -140,7 +154,7 @@ export const CartesianChart = ({
presentationOptions,
renderLegendForOneItem,
referenceAreas,
- } = viewContent;
+ } = viewContent as CustomViewContent;
const getIsActiveKey = (legendDataKey: string) =>
activeDataKeys.length === 0 ||
@@ -197,7 +211,7 @@ export const CartesianChart = ({
: data;
};
- const ChartContainer = CHART_TYPE_TO_CONTAINER[defaultChartType];
+ const ChartContainer = CHART_TYPE_TO_CONTAINER[defaultChartType as CartesianChartType];
const hasDataSeries = chartConfig && Object.keys(chartConfig).length > 1;
const chartDataConfig =
Object.keys(chartConfig).length > 0 ? chartConfig : { [DEFAULT_DATA_KEY]: {} };
@@ -226,13 +240,14 @@ export const CartesianChart = ({
valueType={valueType}
labelType={labelType}
periodGranularity={viewContent.periodGranularity}
- chartConfig={chartConfig}
+ chartConfig={chartConfig as BaseChartConfig}
presentationOptions={presentationOptions}
chartType={defaultChartType}
/>
}
/>
{hasLegend && isEnlarged && (
+ // @ts-ignore
diff --git a/packages/ui-chart-components/src/components/Reference/Legend.tsx b/packages/ui-chart-components/src/components/Reference/Legend.tsx
index b7777bc6ab..ff703b993c 100644
--- a/packages/ui-chart-components/src/components/Reference/Legend.tsx
+++ b/packages/ui-chart-components/src/components/Reference/Legend.tsx
@@ -8,7 +8,7 @@ import styled from 'styled-components';
import MuiButton from '@material-ui/core/Button';
import Tooltip from '@material-ui/core/Tooltip';
import { formatDataValueByType } from '@tupaia/utils';
-import { LegendPosition, ViewContent, isPieChartConfig } from '../../types';
+import { LegendPosition, ViewContent } from '../../types';
import { isMobile } from '../../utils';
import { CartesianChartConfig, PieChartConfig } from '@tupaia/types';
@@ -102,6 +102,10 @@ const Text = styled.span`
line-height: 1.4;
`;
+function isPieChartConfig(config: PieChartConfig | {}): config is PieChartConfig {
+ return (config as PieChartConfig).chartType === 'pie';
+}
+
const getPieLegendDisplayValue = (
chartConfig: PieChartConfig | {},
value: string,
diff --git a/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx b/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
index 8fd7fd5253..52d778bfbb 100644
--- a/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
+++ b/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
@@ -19,7 +19,7 @@ const ReferenceLineLabel = ({
referenceLineLabel: string;
isExporting?: boolean;
}) => {
- if (referenceLineLabel === undefined) return null;
+ if (referenceLineLabel === undefined) return undefined;
return (
);
@@ -43,9 +43,9 @@ const orientationToYAxisId = (orientation: 'left' | 'right'): number =>
Y_AXIS_IDS[orientation] || DEFAULT_Y_AXIS.id;
interface ChartConfig extends BaseChartConfig {
- referenceValue: string | number;
- yAxisOrientation: string | number;
- referenceLabel: string | number;
+ referenceValue?: string | number;
+ yAxisOrientation?: string | number;
+ referenceLabel?: string | number;
}
function isChartConfig(config: ChartConfig | {}): config is ChartConfig {
@@ -78,7 +78,6 @@ const ValueReferenceLine = ({
;
+ viewContent: ViewContent;
isExporting?: boolean;
isEnlarged?: boolean;
}
-const AverageReferenceLine = ({ viewContent, isExporting, isEnlarged }: ReferenceLineProps) => {
+const AverageReferenceLine = ({ viewContent }: ReferenceLineProps) => {
const { valueType, data, presentationOptions } = viewContent;
// show reference line by default
const shouldHideReferenceLine = presentationOptions && presentationOptions.hideAverage;
// average is null for stacked charts that don't have a "value" key in data
- // @ts-ignore
- const average = data.reduce((acc: number, row: DataProps) => acc + row.value, 0) / data.length;
+ const average = data.reduce((acc: number, row) => acc + (row.value as number), 0) / data.length;
if (!average || shouldHideReferenceLine) {
return null;
@@ -115,8 +113,6 @@ const AverageReferenceLine = ({ viewContent, isExporting, isEnlarged }: Referenc
fill={TUPAIA_ORANGE}
/>
}
- // @ts-ignore
- isAnimationActive={isEnlarged && !isExporting}
/>
);
};
diff --git a/packages/ui-chart-components/src/types.ts b/packages/ui-chart-components/src/types.ts
index e02289ab85..0b27c626b1 100644
--- a/packages/ui-chart-components/src/types.ts
+++ b/packages/ui-chart-components/src/types.ts
@@ -2,10 +2,9 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-import { BaseChartConfig, PieChartConfig, ValueType } from '@tupaia/types';
+import { BaseChartConfig, ValueType } from '@tupaia/types';
import { ReferenceAreaProps } from 'recharts';
import { GRANULARITY_SHAPE } from '@tupaia/utils';
-import { CartesianChartConfig } from '@tupaia/types/src';
export interface DataProps {
name: string;
@@ -28,24 +27,10 @@ export enum ChartType {
Gauge = 'gauge',
}
-export type LegendPosition = 'top' | 'bottom';
-
/**
- * {
- * "type":"chart",
- * "chartType":"pie",
- * "name":"% Stock on Hand",
- * "valueType": "percentage",
- * "presentationOptions": {
- * "sectorKey1": { "color": "#111111", "label": "Satanic" },
- * "sectorKey2": { "color": "#222222", "label": "Nesting" },
- * "sectorKey3": { "color": "#333333", "label": "HelpMe" }
- * },
- * "data":[{ name: "Total value stock consumables", value:24063409.4 },
- * { name: "Total value stock medicines", value:24565440.6 },
- * ...]
- * }
+ * This is a tupaia specific setting rather than a recharts config option.
*/
+export type LegendPosition = 'top' | 'bottom';
export type VizPeriodGranularity = typeof GRANULARITY_SHAPE;
@@ -58,6 +43,9 @@ type ConditionalMatrixConditionShape = {
description?: string;
};
+/**
+ * This type is a work in progress. It is not complete. @see WAITP-1262
+ */
export type PresentationOptions = {
type?: string;
showRawValue?: boolean;
@@ -69,6 +57,10 @@ export type PresentationOptions = {
referenceLines?: any;
};
+/**
+ * View Content is the data structure that is passed to the chart components. It contains both the
+ * data and the configuration for the chart. It only exists on the front end.
+ */
export interface ViewContent {
chartType: CT;
valueType?: ValueType;
@@ -90,7 +82,3 @@ export interface ViewContent {
renderLegendForOneItem?: boolean;
referenceAreas?: ReferenceAreaProps[];
}
-
-export function isPieChartConfig(config: PieChartConfig | {}): config is PieChartConfig {
- return (config as PieChartConfig).chartType === 'pie';
-}
From 705b5d78c721c717ab7f02ada373574e826a09a1 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Fri, 26 May 2023 12:15:29 +1200
Subject: [PATCH 038/251] WAITP-1259 Update types
---
.../src/components/InteractivePolygon.tsx | 4 ++--
.../src/components/Markers/MeasurePopup.tsx | 2 +-
.../src/types/data-types.d.ts | 23 ++++++++-----------
3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/packages/ui-map-components/src/components/InteractivePolygon.tsx b/packages/ui-map-components/src/components/InteractivePolygon.tsx
index a7eb9fcc63..57760a5f4f 100644
--- a/packages/ui-map-components/src/components/InteractivePolygon.tsx
+++ b/packages/ui-map-components/src/components/InteractivePolygon.tsx
@@ -48,7 +48,7 @@ type ParsedPropsResult = {
};
const parseProps = (
- organisationUnitCode: string,
+ organisationUnitCode: string | undefined = undefined,
organisationUnitChildren: GenericDataItem[],
measureOrgUnits: MeasureOrgUnit[],
multiOverlayMeasureData: GenericDataItem[],
@@ -93,7 +93,7 @@ interface InteractivePolygonProps {
multiOverlaySerieses?: Series[];
multiOverlayMeasureData?: GenericDataItem[];
permanentLabels?: boolean;
- onChangeOrgUnit?: (organisationUnitCode: string) => void;
+ onChangeOrgUnit?: (organisationUnitCode?: string) => void;
area: Entity;
isActive?: boolean;
measureOrgUnits?: MeasureOrgUnit[];
diff --git a/packages/ui-map-components/src/components/Markers/MeasurePopup.tsx b/packages/ui-map-components/src/components/Markers/MeasurePopup.tsx
index cb96adea73..930be0b9e2 100644
--- a/packages/ui-map-components/src/components/Markers/MeasurePopup.tsx
+++ b/packages/ui-map-components/src/components/Markers/MeasurePopup.tsx
@@ -37,7 +37,7 @@ export const MeasurePopup = React.memo(
let onDetailButtonClick;
if (onSeeOrgUnitDashboard) {
- onDetailButtonClick = () => onSeeOrgUnitDashboard(organisationUnitCode);
+ onDetailButtonClick = () => onSeeOrgUnitDashboard(organisationUnitCode!);
}
return (
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index 808e090934..8cc8200317 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -23,33 +23,30 @@ export type Location = {
region: PolygonProps['positions'];
};
-// Extend the base TupaiaEntity type with more details about the entity, including leaflet specific formatting
-export type Entity = TupaiaEntity & {
- region?: PolygonProps['positions'];
- organisationUnitCode: string;
- location?: Location;
-};
-
export type GenericDataItem = {
[key: string]: any;
organisationUnitCode?: string;
};
+// Extend the base TupaiaEntity type with more details about the entity, including leaflet specific formatting
+export type Entity = TupaiaEntity &
+ GenericDataItem & {
+ region?: PolygonProps['positions'];
+ location?: Location;
+ };
+
export type MeasureOrgUnit = GenericDataItem & {
[key: string]: any;
- organisationUnitCode?: string;
isHidden?: boolean;
color?: Color;
};
export type MeasureData = MeasureOrgUnit &
PolygonProps &
- MarkerProps & {
- coordinates: PolygonProps['positions'];
- region?: PolygonProps['positions'];
+ MarkerProps &
+ Entity & {
+ coordinates?: PolygonProps['positions'];
icon?: string;
- code?: string;
- name?: string;
photoUrl?: string;
value?: number | string;
};
From b3d8055f10505fa9df778014ad0d0db45e84f606 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Fri, 26 May 2023 12:18:44 +1200
Subject: [PATCH 039/251] WAITP-1259 PolygonLayer to ts
---
.../src/components/PolygonLayer.js | 32 -------------------
.../src/components/PolygonLayer.tsx | 21 ++++++++++++
2 files changed, 21 insertions(+), 32 deletions(-)
delete mode 100644 packages/ui-map-components/src/components/PolygonLayer.js
create mode 100644 packages/ui-map-components/src/components/PolygonLayer.tsx
diff --git a/packages/ui-map-components/src/components/PolygonLayer.js b/packages/ui-map-components/src/components/PolygonLayer.js
deleted file mode 100644
index 4fe8a2a284..0000000000
--- a/packages/ui-map-components/src/components/PolygonLayer.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Tupaia
- * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
- *
- */
-import React from 'react';
-import PropTypes from 'prop-types';
-import { EntityPolygon } from './EntityPolygon';
-
-export const PolygonLayer = ({ entities, Polygon }) => {
- if (!entities) return null;
-
- return entities
- .filter(e => Array.isArray(e.region))
- .map(e => );
-};
-
-PolygonLayer.propTypes = {
- Polygon: PropTypes.func,
- entities: PropTypes.arrayOf(
- PropTypes.shape({
- code: PropTypes.string,
- name: PropTypes.string,
- region: PropTypes.array,
- }),
- ),
-};
-
-PolygonLayer.defaultProps = {
- entities: [],
- Polygon: EntityPolygon,
-};
diff --git a/packages/ui-map-components/src/components/PolygonLayer.tsx b/packages/ui-map-components/src/components/PolygonLayer.tsx
new file mode 100644
index 0000000000..dfda64a1cb
--- /dev/null
+++ b/packages/ui-map-components/src/components/PolygonLayer.tsx
@@ -0,0 +1,21 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ *
+ */
+import React from 'react';
+import { EntityPolygon } from './EntityPolygon';
+import { Entity } from '../types';
+
+interface PolygonLayerProps {
+ entities?: Entity[];
+ Polygon?: React.ComponentType<{ entity: Entity }>;
+}
+
+export const PolygonLayer = ({ entities = [], Polygon = EntityPolygon }: PolygonLayerProps) => {
+ if (!entities) return null;
+
+ return entities
+ .filter(e => Array.isArray(e.region))
+ .map(e => );
+};
From bf9689255ad7c74fcd473b57b8e2737889909a56 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Fri, 26 May 2023 12:24:21 +1200
Subject: [PATCH 040/251] WAITP-1259 TIleLayer to TS
---
.../{TileLayer.js => TileLayer.tsx} | 32 +++++++++----------
1 file changed, 15 insertions(+), 17 deletions(-)
rename packages/ui-map-components/src/components/{TileLayer.js => TileLayer.tsx} (57%)
diff --git a/packages/ui-map-components/src/components/TileLayer.js b/packages/ui-map-components/src/components/TileLayer.tsx
similarity index 57%
rename from packages/ui-map-components/src/components/TileLayer.js
rename to packages/ui-map-components/src/components/TileLayer.tsx
index 2a4154bc6b..23a041a9fd 100644
--- a/packages/ui-map-components/src/components/TileLayer.js
+++ b/packages/ui-map-components/src/components/TileLayer.tsx
@@ -5,40 +5,38 @@
*/
import React, { useRef, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { TileLayer as LeafletTileLayer, LayerGroup, AttributionControl } from 'react-leaflet';
+import { TileLayer as LeafletTileLayer } from 'leaflet';
+import { TileLayer as ReactLeafletTileLayer, LayerGroup, AttributionControl } from 'react-leaflet';
// Taken from https://www.mapbox.com/help/how-attribution-works/#other-mapping-frameworks.
const attribution =
'Leaflet © Mapbox © OpenStreetMap Improve this map';
-export const TileLayer = ({ tileSetUrl, showAttribution }) => {
- const tileLayer = useRef(null);
+interface TileLayerProps {
+ showAttribution?: boolean;
+ tileSetUrl?: string;
+}
+
+export const TileLayer = ({
+ tileSetUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
+ showAttribution = true,
+}: TileLayerProps) => {
+ const tileLayer = useRef(null);
useEffect(() => {
if (tileLayer) {
- tileLayer.current.setUrl(tileSetUrl);
+ tileLayer?.current?.setUrl(tileSetUrl);
}
}, [tileSetUrl]);
return (
-
);
};
-
-TileLayer.propTypes = {
- showAttribution: PropTypes.bool,
- tileSetUrl: PropTypes.string,
-};
-
-TileLayer.defaultProps = {
- showAttribution: true,
- tileSetUrl: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
-};
From 8f92eec3b16361edb90cd2170009fae90110a84e Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Fri, 26 May 2023 13:05:42 +1200
Subject: [PATCH 041/251] remove ts-ignores
---
.../src/components/Axes/YAxes.tsx | 14 +++++++----
.../src/components/CartesianChart.tsx | 8 +++++--
.../src/components/Charts/GaugeChart.tsx | 3 +--
.../src/components/Charts/PieChart.tsx | 11 +++++----
.../src/utils/parseChartConfig.ts | 24 +++++++------------
5 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/packages/ui-chart-components/src/components/Axes/YAxes.tsx b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
index 8e271a2931..57d39e88e8 100644
--- a/packages/ui-chart-components/src/components/Axes/YAxes.tsx
+++ b/packages/ui-chart-components/src/components/Axes/YAxes.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import { formatDataValueByType } from '@tupaia/utils';
import { ValueType } from '@tupaia/types';
-import { YAxis as YAxisComponent } from 'recharts';
+import { YAxis as YAxisComponent, YAxisProps } from 'recharts';
import { DARK_BLUE } from '../../constants';
import { LooseObject, ViewContent } from '../../types';
import { getContrastTextColor } from '../../utils';
@@ -56,7 +56,13 @@ const parseDomainConfig = (config: AxisDomainProps) => {
const getDefaultYAxisDomain = (viewContent: ViewContent) =>
viewContent.valueType === 'percentage' ? PERCENTAGE_Y_DOMAIN : DEFAULT_Y_AXIS.yAxisDomain;
-const calculateYAxisDomain = ({ min, max }: { min: AxisDomainProps; max: AxisDomainProps }) => {
+const calculateYAxisDomain = ({
+ min,
+ max,
+}: {
+ min: AxisDomainProps;
+ max: AxisDomainProps;
+}): YAxisProps['domain'] => {
return [parseDomainConfig(min), parseDomainConfig(max)];
};
@@ -77,7 +83,7 @@ const renderYAxisLabel = (
style: { textAnchor: 'middle', fontSize: isEnlarged ? '1em' : '0.8em' },
position: orientation === 'right' ? 'insideRight' : 'insideLeft',
};
- return null;
+ return undefined;
};
/**
@@ -126,7 +132,6 @@ const YAxis = ({
const width = getAxisWidth(viewContent.data, dataKeys, valueType);
return (
- // @ts-ignore
formatDataValueByType(
diff --git a/packages/ui-chart-components/src/components/CartesianChart.tsx b/packages/ui-chart-components/src/components/CartesianChart.tsx
index c12fcc5e9b..630bcc433b 100644
--- a/packages/ui-chart-components/src/components/CartesianChart.tsx
+++ b/packages/ui-chart-components/src/components/CartesianChart.tsx
@@ -14,6 +14,7 @@ import {
ResponsiveContainer,
Tooltip,
Brush,
+ LegendProps,
} from 'recharts';
import { BaseChartConfig, CartesianChartConfig, ValueType } from '@tupaia/types';
import { CHART_BLUES, DEFAULT_DATA_KEY } from '../constants';
@@ -212,6 +213,8 @@ export const CartesianChart = ({
const aspect = !isEnlarged && !isMobile() && !isExporting ? 1.6 : undefined;
const height = getHeight(isExporting, isEnlarged, hasLegend);
+ const { verticalAlign, align, layout } = getLegendAlignment(legendPosition, isExporting);
+
/**
* Unfortunately, recharts does not work with wrapped components called as jsx for some reason,
* so they are called as functions below
@@ -240,9 +243,10 @@ export const CartesianChart = ({
}
/>
{hasLegend && isEnlarged && (
- // @ts-ignore
];
- // @ts-ignore
- const numOfElements = Math.floor((1 - data[0].value) / denominator);
+ const numOfElements = Math.floor(1 - (data[0].value as number) / denominator);
for (let i = 0; i < numOfElements; i++) {
elements.push({ value: denominator });
diff --git a/packages/ui-chart-components/src/components/Charts/PieChart.tsx b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
index cf56f38a3a..d02b425aa2 100644
--- a/packages/ui-chart-components/src/components/Charts/PieChart.tsx
+++ b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
@@ -167,7 +167,8 @@ export const PieChart = ({
// about 20px below the visual center when displaying in enlarged mode.
// This makes the tooltips touch the bottom of the container
// (and just looks a bit weird). So, bump it up by 20px.
- const offsetStyle = isEnlarged && !isMobile() && !isExporting ? { position: 'relative' } : null;
+ const offsetStyle =
+ isEnlarged && !isMobile() && !isExporting ? { position: 'relative' } : undefined;
const responsiveStyle = !isEnlarged && !isMobile() && !isExporting ? 1.6 : undefined;
const height = getHeight(isExporting, isEnlarged);
@@ -175,19 +176,19 @@ export const PieChart = ({
return (
- {/* @ts-ignore */}
- {/* @ts-ignore */}
{
onItemClick(item.originalItem);
}}
label={
- isExporting && presentationOptions?.exportWithLabels ? makeLabel(viewContent) : null
+ isExporting && presentationOptions?.exportWithLabels
+ ? makeLabel(viewContent)
+ : undefined
}
startAngle={360 + 90}
endAngle={90}
diff --git a/packages/ui-chart-components/src/utils/parseChartConfig.ts b/packages/ui-chart-components/src/utils/parseChartConfig.ts
index 7c1f195e43..8b40a7f072 100644
--- a/packages/ui-chart-components/src/utils/parseChartConfig.ts
+++ b/packages/ui-chart-components/src/utils/parseChartConfig.ts
@@ -35,26 +35,21 @@ export const parseChartConfig = (viewContent: ViewContent) => {
? createDynamicConfig(restOfConfig as BaseChartConfig, configForAllKeys, data)
: restOfConfig;
- const addDefaultColors = (config: BaseChartConfig) =>
+ const addDefaultColors = (config: any) =>
addDefaultColorsToConfig(config, paletteName as ColorPalette, chartType);
const chartConfigs = [baseConfig];
- return (
- chartConfigs
- // @ts-ignore
- .map(sortChartConfigByLegendOrder)
- // @ts-ignore
- .map(addDefaultColors)
- // @ts-ignore
- .map(setOpacityValues)[0]
- ); // must remove from array after mapping
+ return chartConfigs
+ .map(sortChartConfigByLegendOrder)
+ .map(addDefaultColors)
+ .map(setOpacityValues)[0]; // must remove from array after mapping
};
/**
* Sets numeric values for each chart config opacity
*/
-const setOpacityValues = (chartConfig: BaseChartConfig): BaseChartConfig => {
+const setOpacityValues = (chartConfig: LooseObject) => {
const newConfig: LooseObject = {};
Object.entries(chartConfig).forEach(([key, configItem], index, array) => {
@@ -114,7 +109,7 @@ const defaultSort = (a: { chartType: 'bar' | 'line' }[], b: { chartType: 'bar' |
};
// Bad practice to rely on object ordering: https://stackoverflow.com/questions/9179680/is-it-acceptable-style-for-node-js-libraries-to-rely-on-object-key-order
-const sortChartConfigByLegendOrder = (chartConfig: BaseChartConfig) => {
+const sortChartConfigByLegendOrder = (chartConfig: LooseObject) => {
return Object.entries(chartConfig)
.sort(defaultSort)
.sort(([, cfg1], [, cfg2]) => {
@@ -142,10 +137,9 @@ const createDynamicConfig = (
const keys = new Set(dataKeys);
// Add config to each key
- const newChartConfig = {};
+ const newChartConfig: LooseObject = {};
keys.forEach(key => {
- // @ts-ignore
- newChartConfig[key] = { ...dynamicChartConfig, ...chartConfig[key] };
+ newChartConfig[key] = { ...dynamicChartConfig, ...chartConfig[key as keyof BaseChartConfig] };
});
return newChartConfig;
};
From 055859af2ff99f7c1251757cb5e9bdf1928560ff Mon Sep 17 00:00:00 2001
From: acdunham
Date: Fri, 26 May 2023 17:01:17 +1200
Subject: [PATCH 042/251] WAITP-1259 Legends to ts
---
packages/ui-map-components/package.json | 4 +-
.../Legend/{Legend.js => Legend.tsx} | 105 ++++++++--------
.../{LegendEntry.js => LegendEntry.tsx} | 44 +++----
.../{MarkerLegend.js => MarkerLegend.tsx} | 54 ++++----
.../{SpectrumLegend.js => SpectrumLegend.tsx} | 118 ++++++++++--------
.../components/Legend/{index.js => index.ts} | 0
.../src/components/Markers/markerIcons.tsx | 26 ++--
.../src/constants/constants.ts | 26 ++--
.../ui-map-components/src/types/index.d.ts | 1 +
.../src/types/legend-types.d.ts | 59 +++++++++
.../ui-map-components/src/types/types.d.ts | 3 +-
packages/ui-map-components/tsconfig.json | 5 +-
yarn.lock | 21 +++-
13 files changed, 278 insertions(+), 188 deletions(-)
rename packages/ui-map-components/src/components/Legend/{Legend.js => Legend.tsx} (66%)
rename packages/ui-map-components/src/components/Legend/{LegendEntry.js => LegendEntry.tsx} (63%)
rename packages/ui-map-components/src/components/Legend/{MarkerLegend.js => MarkerLegend.tsx} (84%)
rename packages/ui-map-components/src/components/Legend/{SpectrumLegend.js => SpectrumLegend.tsx} (66%)
rename packages/ui-map-components/src/components/Legend/{index.js => index.ts} (100%)
create mode 100644 packages/ui-map-components/src/types/legend-types.d.ts
diff --git a/packages/ui-map-components/package.json b/packages/ui-map-components/package.json
index e097c0cd7e..a42e62ccb9 100644
--- a/packages/ui-map-components/package.json
+++ b/packages/ui-map-components/package.json
@@ -42,8 +42,8 @@
"@storybook/react": "^6.3.9",
"@types/jest": "^29.5.1",
"@types/leaflet": "^1.7.1",
- "@types/react": "^18.2.7",
- "@types/react-dom": "^18.2.4",
+ "@types/react": "^16.14.0",
+ "@types/react-dom": "^16.9.18",
"@types/styled-components": "^5.1.26"
}
}
diff --git a/packages/ui-map-components/src/components/Legend/Legend.js b/packages/ui-map-components/src/components/Legend/Legend.tsx
similarity index 66%
rename from packages/ui-map-components/src/components/Legend/Legend.js
rename to packages/ui-map-components/src/components/Legend/Legend.tsx
index 2fd4daa6f9..a06f52053b 100644
--- a/packages/ui-map-components/src/components/Legend/Legend.js
+++ b/packages/ui-map-components/src/components/Legend/Legend.tsx
@@ -3,21 +3,16 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-import PropTypes from 'prop-types';
import React from 'react';
import styled from 'styled-components';
-import {
- MEASURE_TYPE_COLOR,
- MEASURE_TYPE_ICON,
- MEASURE_TYPE_RADIUS,
- MEASURE_TYPE_SHADED_SPECTRUM,
- MEASURE_TYPE_SPECTRUM,
- MEASURE_TYPE_POPUP_ONLY,
-} from '../../utils';
import { MarkerLegend } from './MarkerLegend';
import { SpectrumLegend } from './SpectrumLegend';
+import { MEASURE_TYPES } from '../../constants';
+import { LegendProps as BaseLegendProps, LegendSeriesItem, MeasureType } from '../../types';
-const LegendFrame = styled.div`
+const LegendFrame = styled.div<{
+ isDisplayed: boolean;
+}>`
display: flex;
width: fit-content;
padding: 0.6rem;
@@ -39,37 +34,55 @@ const LegendName = styled.div`
`;
const coloredMeasureTypes = [
- MEASURE_TYPE_COLOR,
- MEASURE_TYPE_SPECTRUM,
- MEASURE_TYPE_SHADED_SPECTRUM,
+ MEASURE_TYPES.COLOR,
+ MEASURE_TYPES.SPECTRUM,
+ MEASURE_TYPES.SHADED_SPECTRUM,
];
+// This is a workaround for type errors we get when trying to use Array.includes with a subset of a union type. This solution comes from https://github.com/microsoft/TypeScript/issues/51881
+const checkMeasureType = (item: MeasureType, subset: MeasureType[]) =>
+ (subset as ReadonlyArray).includes(item);
+
const NullLegend = () => null;
-const getLegendComponent = measureType => {
+const getLegendComponent = (measureType: MeasureType) => {
switch (measureType) {
- case MEASURE_TYPE_SHADED_SPECTRUM:
- case MEASURE_TYPE_SPECTRUM:
+ case MEASURE_TYPES.SHADED_SPECTRUM:
+ case MEASURE_TYPES.SPECTRUM:
return SpectrumLegend;
- case MEASURE_TYPE_RADIUS:
+ case MEASURE_TYPES.RADIUS:
return NullLegend;
default:
return MarkerLegend;
}
};
+interface LegendProps extends BaseLegendProps {
+ className?: string;
+ measureInfo: {
+ [mapOverlayCode: string]: {
+ [seriesesKey: string]: LegendSeriesItem[];
+ };
+ };
+ currentMapOverlayCodes: string[];
+ displayedMapOverlayCodes?: string[];
+ seriesesKey?: string;
+ SeriesContainer?: React.ComponentType;
+ SeriesDivider?: React.ComponentType;
+}
+
export const Legend = React.memo(
({
className,
measureInfo: baseMeasureInfo,
setValueHidden,
- hiddenValues,
+ hiddenValues = {},
currentMapOverlayCodes,
displayedMapOverlayCodes,
- seriesesKey,
- SeriesContainer,
+ seriesesKey = 'serieses',
+ SeriesContainer = LegendFrame,
SeriesDivider,
- }) => {
+ }: LegendProps) => {
if (Object.keys(baseMeasureInfo).length === 0) {
return null;
}
@@ -78,13 +91,17 @@ export const Legend = React.memo(
// measure info for mapOverlayCode may not exist when location changes.
const baseSerieses = baseMeasureInfo[mapOverlayCode]?.[seriesesKey] || [];
const serieses = baseSerieses.filter(
- ({ type, hideFromLegend, values = [], min, max, noDataColour }) => {
+ ({ type, hideFromLegend, values = [], min, max, noDataColour }: LegendSeriesItem) => {
+ const seriesType = type as MeasureType;
// if type is radius or popup-only, don't create a legend
- if ([MEASURE_TYPE_RADIUS, MEASURE_TYPE_POPUP_ONLY].includes(type)) return false;
+ if (checkMeasureType(seriesType, [MEASURE_TYPES.RADIUS, MEASURE_TYPES.POPUP_ONLY]))
+ return false;
+
// if hideFromLegend is true, don't create a legend
if (hideFromLegend) return false;
+
// if type is spectrum or shaded-spectrum, only create a legend if min and max are set OR noDataColour is set. If noDataColour is not set, that means hideNullFromLegend has been set as true in the map overlay config. Spectrum legends 'values' property will always be []
- if ([MEASURE_TYPE_SHADED_SPECTRUM, MEASURE_TYPE_SPECTRUM].includes(type))
+ if (checkMeasureType(seriesType, [MEASURE_TYPES.SHADED_SPECTRUM, MEASURE_TYPES.SPECTRUM]))
return noDataColour
? true
: !(min === null || min === undefined || max === null || max === undefined);
@@ -92,7 +109,11 @@ export const Legend = React.memo(
},
);
return { ...results, [mapOverlayCode]: { serieses } };
- }, {});
+ }, {}) as {
+ [mapOverlayCode: string]: {
+ serieses: LegendSeriesItem[];
+ };
+ };
const legendTypes = currentMapOverlayCodes
.map(mapOverlayCode => measureInfo[mapOverlayCode].serieses)
@@ -105,17 +126,19 @@ export const Legend = React.memo(
{currentMapOverlayCodes.map(mapOverlayCode => {
const { serieses } = measureInfo[mapOverlayCode];
const baseSerieses = baseMeasureInfo[mapOverlayCode]?.[seriesesKey] || [];
- const hasIconLayer = baseSerieses.some(l => l.type === MEASURE_TYPE_ICON);
- const hasRadiusLayer = baseSerieses.some(l => l.type === MEASURE_TYPE_RADIUS);
- const hasColorLayer = baseSerieses.some(l => coloredMeasureTypes.includes(l.type));
+ const hasIconLayer = baseSerieses.some(l => l.type === MEASURE_TYPES.ICON);
+ const hasRadiusLayer = baseSerieses.some(l => l.type === MEASURE_TYPES.RADIUS);
+ const hasColorLayer = baseSerieses.some(l =>
+ checkMeasureType(l.type as MeasureType, coloredMeasureTypes),
+ );
const isDisplayed =
!displayedMapOverlayCodes || displayedMapOverlayCodes.includes(mapOverlayCode);
return serieses
- .sort(a => (a.type === MEASURE_TYPE_COLOR ? -1 : 1)) // color series should sit at the top
+ .sort(a => (a.type === MEASURE_TYPES.COLOR ? -1 : 1)) // color series should sit at the top
.map((series, index) => {
const { type } = series;
- const LegendComponent = getLegendComponent(type);
+ const LegendComponent = getLegendComponent(type as MeasureType);
return (
<>
@@ -139,25 +162,3 @@ export const Legend = React.memo(
);
},
);
-
-Legend.propTypes = {
- measureInfo: PropTypes.object.isRequired,
- className: PropTypes.string,
- hiddenValues: PropTypes.object,
- setValueHidden: PropTypes.func,
- displayedMapOverlayCodes: PropTypes.arrayOf(PropTypes.string),
- currentMapOverlayCodes: PropTypes.arrayOf(PropTypes.string).isRequired,
- seriesesKey: PropTypes.string,
- SeriesContainer: PropTypes.node,
- SeriesDivider: PropTypes.node,
-};
-
-Legend.defaultProps = {
- className: null,
- displayedMapOverlayCodes: null,
- hiddenValues: {},
- setValueHidden: null,
- seriesesKey: 'serieses',
- SeriesContainer: LegendFrame,
- SeriesDivider: null,
-};
diff --git a/packages/ui-map-components/src/components/Legend/LegendEntry.js b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
similarity index 63%
rename from packages/ui-map-components/src/components/Legend/LegendEntry.js
rename to packages/ui-map-components/src/components/Legend/LegendEntry.tsx
index 317744f23d..181b187d41 100644
--- a/packages/ui-map-components/src/components/Legend/LegendEntry.js
+++ b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
@@ -4,9 +4,9 @@
*/
import React from 'react';
-import PropTypes from 'prop-types';
import styled from 'styled-components';
import MuiButton from '@material-ui/core/Button';
+import { LegendProps, ValueType } from '../../types';
const Button = styled(MuiButton)`
display: flex;
@@ -34,9 +34,29 @@ const Label = styled.div`
}
`;
+interface LegendEntryProps {
+ marker: React.ReactNode;
+ label: string;
+ value: ValueType;
+ dataKey?: string;
+ onClick?: LegendProps['setValueHidden'];
+ hiddenValues?: LegendProps['hiddenValues'];
+ unClickable?: boolean;
+}
+
export const LegendEntry = React.memo(
- ({ marker, label, value, dataKey, onClick, hiddenValues, unClickable }) => {
- const hidden = (hiddenValues[dataKey] || {})[value];
+ ({
+ marker,
+ label,
+ value,
+ dataKey,
+ onClick,
+ hiddenValues = {},
+ unClickable = false,
+ }: LegendEntryProps) => {
+ const hidden = dataKey
+ ? (hiddenValues[dataKey] || {})[value as keyof typeof hiddenValues]
+ : false;
const handleClick = () => {
if (!unClickable && onClick) {
@@ -52,21 +72,3 @@ export const LegendEntry = React.memo(
);
},
);
-
-LegendEntry.propTypes = {
- marker: PropTypes.element.isRequired,
- label: PropTypes.string.isRequired,
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
- dataKey: PropTypes.string,
- hiddenValues: PropTypes.object,
- onClick: PropTypes.func,
- unClickable: PropTypes.bool,
-};
-
-LegendEntry.defaultProps = {
- hiddenValues: {},
- unClickable: false,
- onClick: null,
- value: null,
- dataKey: null,
-};
diff --git a/packages/ui-map-components/src/components/Legend/MarkerLegend.js b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
similarity index 84%
rename from packages/ui-map-components/src/components/Legend/MarkerLegend.js
rename to packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
index 2d1dd31136..37f771ed3c 100644
--- a/packages/ui-map-components/src/components/Legend/MarkerLegend.js
+++ b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
@@ -3,7 +3,6 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-import PropTypes from 'prop-types';
import React from 'react';
import styled from 'styled-components';
import { useTheme } from '@material-ui/core/styles';
@@ -12,6 +11,7 @@ import { UNKNOWN_COLOR } from '../../constants';
import {
DEFAULT_ICON,
HIDDEN_ICON,
+ IconKey,
LEGEND_COLOR_ICON,
LEGEND_RADIUS_ICON,
LEGEND_SHADING_ICON,
@@ -25,6 +25,7 @@ import {
MEASURE_VALUE_OTHER,
} from '../../utils';
import { LegendEntry } from './LegendEntry';
+import { LegendItemValue, MarkerLegendSeriesItem, MarkerLegendProps } from '../../types';
const Container = styled(MuiBox)`
display: flex;
@@ -45,11 +46,15 @@ const Container = styled(MuiBox)`
* and hide the radius as well. But, if the hidden icon is 'other', go ahead and add it to
* the legend and show the radius.
*/
-const isHiddenOtherIcon = ({ value, icon }) => {
+const isHiddenOtherIcon = ({ value, icon }: LegendItemValue) => {
return value === MEASURE_VALUE_OTHER && icon === HIDDEN_ICON;
};
-const getMarkerColor = (value, type, hasColorLayer) => {
+const getMarkerColor = (
+ value: LegendItemValue,
+ type: MarkerLegendSeriesItem['type'],
+ hasColorLayer: boolean,
+) => {
const theme = useTheme();
if (type === MEASURE_TYPE_COLOR) {
@@ -66,12 +71,12 @@ const getMarkerColor = (value, type, hasColorLayer) => {
};
const getLegendMarkerForValue = (
- value,
- type,
- hasIconLayer,
- hasRadiusLayer,
- hasColorLayer,
- defaultIcon = null,
+ value: LegendItemValue,
+ type: MarkerLegendSeriesItem['type'],
+ hasIconLayer: MarkerLegendProps['hasIconLayer'],
+ hasRadiusLayer: MarkerLegendProps['hasRadiusLayer'],
+ hasColorLayer: MarkerLegendProps['hasColorLayer'],
+ defaultIcon: IconKey | null = null,
) => {
const { icon } = value;
const color = getMarkerColor(value, type, hasColorLayer);
@@ -109,7 +114,14 @@ const getLegendMarkerForValue = (
};
export const MarkerLegend = React.memo(
- ({ series, setValueHidden, hiddenValues, hasIconLayer, hasRadiusLayer, hasColorLayer }) => {
+ ({
+ series,
+ setValueHidden,
+ hiddenValues = {},
+ hasIconLayer,
+ hasRadiusLayer,
+ hasColorLayer,
+ }: MarkerLegendProps) => {
const { type, values, key: dataKey, valueMapping, icon } = series;
const keys = values
@@ -149,7 +161,7 @@ export const MarkerLegend = React.memo(
});
let nullKey = null;
- const nullItem = valueMapping.null;
+ const nullItem = valueMapping?.null;
if (!hasGroupedLegendIncludingNull && nullItem && !nullItem.hideFromLegend) {
nullKey = (
@@ -179,23 +191,3 @@ export const MarkerLegend = React.memo(
);
},
);
-
-MarkerLegend.propTypes = {
- series: PropTypes.shape({
- name: PropTypes.string,
- key: PropTypes.string,
- type: PropTypes.string,
- values: PropTypes.array,
- valueMapping: PropTypes.object,
- }).isRequired,
- hasIconLayer: PropTypes.bool.isRequired,
- setValueHidden: PropTypes.func,
- hiddenValues: PropTypes.object,
- hasRadiusLayer: PropTypes.bool.isRequired,
- hasColorLayer: PropTypes.bool.isRequired,
-};
-
-MarkerLegend.defaultProps = {
- hiddenValues: {},
- setValueHidden: null,
-};
diff --git a/packages/ui-map-components/src/components/Legend/SpectrumLegend.js b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
similarity index 66%
rename from packages/ui-map-components/src/components/Legend/SpectrumLegend.js
rename to packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
index 76f62b58c0..f519dbabb6 100644
--- a/packages/ui-map-components/src/components/Legend/SpectrumLegend.js
+++ b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
@@ -5,7 +5,6 @@
import moment from 'moment';
import React from 'react';
-import PropTypes from 'prop-types';
import MuiBox from '@material-ui/core/Box';
import styled from 'styled-components';
import { formatDataValueByType } from '@tupaia/utils';
@@ -13,6 +12,7 @@ import { resolveSpectrumColour } from '../../utils';
import { LEGEND_SHADING_ICON, getMarkerForOption } from '../Markers/markerIcons';
import { SCALE_TYPES } from '../../constants';
import { LegendEntry } from './LegendEntry';
+import { ScaleType, SpectrumLegendProps, SpectrumLegendSeriesItem } from '../../types';
const FlexCenter = styled(MuiBox)`
display: flex;
@@ -20,7 +20,9 @@ const FlexCenter = styled(MuiBox)`
justify-content: center;
`;
-const SpectrumContainer = styled.div`
+const SpectrumContainer = styled.div<{
+ $hasNoData: boolean;
+}>`
max-width: ${p => (p.$hasNoData ? '70%' : '100%')};
`;
@@ -43,7 +45,15 @@ const LabelRight = styled.div`
margin-left: 0.625rem;
`;
-const getSpectrumLabels = (scaleType, min, max, valueType) => {
+const getSpectrumLabels = (
+ scaleType: ScaleType,
+ min: number,
+ max: number,
+ valueType: string,
+): {
+ left: string;
+ right: string;
+} => {
switch (scaleType) {
case SCALE_TYPES.GPI:
case SCALE_TYPES.PERFORMANCE:
@@ -60,13 +70,21 @@ const getSpectrumLabels = (scaleType, min, max, valueType) => {
}
};
-const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }) => {
+const renderSpectrum = ({
+ min,
+ max,
+ scaleType,
+ scaleColorScheme,
+ valueType,
+}: SpectrumLegendSeriesItem) => {
if (min == null || max == null) return null;
const spectrumDivs = [];
if (min === max) {
// There will only be a single value displayed, let's just default it to the middle color (50 % of the way from 0 to 1):
+
+ // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, 0.5, 0, 1);
const { left: label } = getSpectrumLabels(scaleType, min, min, valueType);
@@ -83,6 +101,7 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }) =>
switch (scaleType) {
case SCALE_TYPES.TIME:
for (let i = 0; i < 1; i += 0.01) {
+ // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, i, min, max);
spectrumDivs.push();
}
@@ -95,6 +114,7 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }) =>
const increment = (max - min) / 100;
for (let i = min; i < max; i += increment) {
+ // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, i, min, max);
spectrumDivs.push();
}
@@ -111,55 +131,43 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }) =>
);
};
-export const SpectrumLegend = React.memo(({ series, setValueHidden, hiddenValues }) => {
- const {
- valueMapping,
- noDataColour,
- min,
- max,
- scaleType,
- scaleColorScheme,
- valueType,
- key: dataKey,
- } = series;
-
- const { value } = valueMapping.null;
+export const SpectrumLegend = React.memo(
+ ({ series, setValueHidden, hiddenValues = {} }: SpectrumLegendProps) => {
+ const {
+ valueMapping,
+ noDataColour,
+ min,
+ max,
+ scaleType,
+ scaleColorScheme,
+ valueType,
+ key: dataKey,
+ } = series;
+
+ const { value } = valueMapping.null;
- return (
-
-
- {renderSpectrum({ min, max, scaleType, scaleColorScheme, valueType })}
-
- {noDataColour && (
-
- )}
-
- );
-});
-
-SpectrumLegend.propTypes = {
- series: PropTypes.shape({
- valueMapping: PropTypes.object,
- scaleColorScheme: PropTypes.object,
- min: PropTypes.number,
- max: PropTypes.number,
- scaleType: PropTypes.string,
- valueType: PropTypes.string,
- dataKey: PropTypes.string,
- noDataColour: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- }).isRequired,
- setValueHidden: PropTypes.func,
- hiddenValues: PropTypes.object,
-};
-
-SpectrumLegend.defaultProps = {
- hiddenValues: {},
- setValueHidden: null,
-};
+ return (
+
+
+ {renderSpectrum({
+ min,
+ max,
+ scaleType,
+ scaleColorScheme,
+ valueType,
+ } as SpectrumLegendSeriesItem)}
+
+ {noDataColour && (
+
+ )}
+
+ );
+ },
+);
diff --git a/packages/ui-map-components/src/components/Legend/index.js b/packages/ui-map-components/src/components/Legend/index.ts
similarity index 100%
rename from packages/ui-map-components/src/components/Legend/index.js
rename to packages/ui-map-components/src/components/Legend/index.ts
diff --git a/packages/ui-map-components/src/components/Markers/markerIcons.tsx b/packages/ui-map-components/src/components/Markers/markerIcons.tsx
index f6dcc72990..c83c482218 100644
--- a/packages/ui-map-components/src/components/Markers/markerIcons.tsx
+++ b/packages/ui-map-components/src/components/Markers/markerIcons.tsx
@@ -21,7 +21,7 @@ import { Cyclone, Earthquake, Tsunami, Volcano, Flood } from './disasterIcons';
import { UpArrow, DownArrow, RightArrow } from './arrowIcons';
import { BREWER_PALETTE, WHITE } from '../../constants';
import { IconContainer } from './IconContainer';
-import { Color } from '../../types';
+import { Color, ColorKey } from '../../types';
import { CssColor } from '@tupaia/types';
// allows passing a color to a material icon & scales it down a bit
@@ -352,7 +352,7 @@ export const LEGEND_SHADING_ICON = 'square';
export const LEGEND_RADIUS_ICON = 'radius';
export const HIDDEN_ICON = 'hidden';
-function toLeaflet(icon: IconType, color: CssColor, scale: number = 1): L.DivIcon {
+function toLeaflet(icon: IconType, color?: string, scale: number = 1): L.DivIcon {
const {
Component,
iconAnchor = [0.5 * ICON_BASE_SIZE, 0.5 * ICON_BASE_SIZE], // default to center point
@@ -374,17 +374,23 @@ function toLeaflet(icon: IconType, color: CssColor, scale: number = 1): L.DivIco
}
// Returns jsx version of marker (for Legend rendering)
-export function getMarkerForOption(iconKey: IconKey, colorName: Color, stroke: CssColor) {
- const icon = icons[iconKey] || icons.pin;
- // @ts-ignore - because technically shade can be a string that is not in the BREWER_PALETTE, so TS throws an error about type not being able to be an index
- const color = BREWER_PALETTE[colorName] || colorName;
+export function getMarkerForOption(
+ iconKey: IconKey | undefined,
+ colorName: Color,
+ stroke?: CssColor,
+) {
+ const icon = icons[iconKey as IconKey] || icons.pin;
+ const color = BREWER_PALETTE[colorName as ColorKey] || colorName;
return ;
}
// Return html version of marker (for Map rendering)
-export function getMarkerForValue(iconKey: IconKey, colorName?: Color, scale: number = 1) {
- const icon = icons[iconKey] || icons.pin;
- // @ts-ignore - because technically shade can be a string that is not in the BREWER_PALETTE, so TS throws an error about type not being able to be an index
- const color = BREWER_PALETTE[colorName] || colorName;
+export function getMarkerForValue(
+ iconKey: IconKey | undefined,
+ colorName?: Color,
+ scale: number = 1,
+) {
+ const icon = icons[iconKey as IconKey] || icons.pin;
+ const color = BREWER_PALETTE[colorName as ColorKey] || colorName;
return toLeaflet(icon, color, scale);
}
diff --git a/packages/ui-map-components/src/constants/constants.ts b/packages/ui-map-components/src/constants/constants.ts
index 90ea8a5a1d..568a9a3344 100644
--- a/packages/ui-map-components/src/constants/constants.ts
+++ b/packages/ui-map-components/src/constants/constants.ts
@@ -32,11 +32,21 @@ export const TILE_SETS = [
},
];
-export const SCALE_TYPES = {
- PERFORMANCE: 'performance',
- PERFORMANCE_DESC: 'performanceDesc',
- NEUTRAL: 'neutral',
- NEUTRAL_REVERSE: 'neutralReverse',
- TIME: 'time',
- GPI: 'gpi',
-};
+export enum SCALE_TYPES {
+ PERFORMANCE = 'performance',
+ PERFORMANCE_DESC = 'performanceDesc',
+ NEUTRAL = 'neutral',
+ NEUTRAL_REVERSE = 'neutralReverse',
+ TIME = 'time',
+ GPI = 'gpi',
+}
+
+export enum MEASURE_TYPES {
+ ICON = 'icon',
+ COLOR = 'color',
+ RADIUS = 'radius',
+ SPECTRUM = 'spectrum',
+ SHADING = 'shading',
+ SHADED_SPECTRUM = 'shaded-spectrum',
+ POPUP_ONLY = 'popup-only',
+}
diff --git a/packages/ui-map-components/src/types/index.d.ts b/packages/ui-map-components/src/types/index.d.ts
index 9c3ff8b439..aae8f06e7b 100644
--- a/packages/ui-map-components/src/types/index.d.ts
+++ b/packages/ui-map-components/src/types/index.d.ts
@@ -1,5 +1,6 @@
export * from './data-types';
export * from './helpers';
export * from './leaflet-config';
+export * from './legend-types';
export * from './marker-types';
export * from './types';
diff --git a/packages/ui-map-components/src/types/legend-types.d.ts b/packages/ui-map-components/src/types/legend-types.d.ts
new file mode 100644
index 0000000000..a6f0c3b0a4
--- /dev/null
+++ b/packages/ui-map-components/src/types/legend-types.d.ts
@@ -0,0 +1,59 @@
+import { IconKey } from '../components';
+import { SCALE_TYPES, MEASURE_TYPES } from '../constants';
+
+export type ValueType = string | number | null | undefined;
+export type ScaleType = `${SCALE_TYPES}`;
+export type MeasureType = `${MEASURE_TYPES}`;
+
+export type LegendItemValue = {
+ value: ValueType;
+ name: string;
+ hideFromLegend?: boolean;
+ icon?: IconKey;
+ color: string;
+};
+
+export type ValueMappingType = {
+ null: LegendItemValue;
+ [key: string]: LegendItemValue;
+};
+
+export type BaseLegendSeriesItem = {
+ name: string;
+ key: string;
+ type: string;
+ values: LegendItemValue[];
+ valueMapping: ValueMappingType;
+ hideFromLegend?: boolean;
+ type: MeasureType;
+};
+
+export type MarkerLegendSeriesItem = BaseLegendSeriesItem & {
+ icon?: IconKey;
+};
+
+export type SpectrumLegendSeriesItem = BaseLegendSeriesItem & {
+ scaleColorScheme: object;
+ min: number;
+ max: number;
+ scaleType: ScaleType;
+ valueType: string;
+ dataKey?: string;
+ noDataColour?: string;
+};
+export type LegendSeriesItem = MarkerLegendSeriesItem & SpectrumLegendSeriesItem;
+export type LegendProps = {
+ setValueHidden: (dataKey?: string, value: ValueType, hidden: boolean) => void;
+ hiddenValues: Record>;
+};
+
+export type MarkerLegendProps = LegendProps & {
+ series: MarkerLegendSeriesItem;
+ hasIconLayer: boolean;
+ hasRadiusLayer: boolean;
+ hasColorLayer: boolean;
+};
+
+export type SpectrumLegendProps = LegendProps & {
+ series: SpectrumLegendSeriesItem;
+};
diff --git a/packages/ui-map-components/src/types/types.d.ts b/packages/ui-map-components/src/types/types.d.ts
index bb13122b9c..3b3753ece7 100644
--- a/packages/ui-map-components/src/types/types.d.ts
+++ b/packages/ui-map-components/src/types/types.d.ts
@@ -1,4 +1,5 @@
import { CssColor } from '@tupaia/types';
import { BREWER_PALETTE } from '../constants';
-export type Color = keyof typeof BREWER_PALETTE | 'transparent' | CssColor;
+export type ColorKey = keyof typeof BREWER_PALETTE;
+export type Color = ColorKey | 'transparent' | CssColor;
diff --git a/packages/ui-map-components/tsconfig.json b/packages/ui-map-components/tsconfig.json
index c1a5ac85da..bae917428c 100644
--- a/packages/ui-map-components/tsconfig.json
+++ b/packages/ui-map-components/tsconfig.json
@@ -7,7 +7,8 @@
"outDir": "dist",
"lib": [
"es6",
- "dom"
+ "dom",
+ "es2019"
],
"noImplicitAny": true,
"noImplicitThis": true,
@@ -18,4 +19,4 @@
"jest.config.ts",
"helpers/**/*"
]
-}
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 3347e4effc..3603b99ef4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5887,8 +5887,8 @@ __metadata:
"@tupaia/utils": 1.0.0
"@types/jest": ^29.5.1
"@types/leaflet": ^1.7.1
- "@types/react": ^18.2.7
- "@types/react-dom": ^18.2.4
+ "@types/react": ^16.14.0
+ "@types/react-dom": ^16.9.18
"@types/styled-components": ^5.1.26
leaflet: ^1.7.1
moment: ^2.29.1
@@ -6839,6 +6839,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-dom@npm:^16.9.18":
+ version: 16.9.19
+ resolution: "@types/react-dom@npm:16.9.19"
+ dependencies:
+ "@types/react": ^16
+ checksum: c696f137aba09be0ea87ad6e99a083607b4fc574857d92c264cc6518ee929ef7e94855362436c2ef5fefb70ebfc9b7413634bb3a2f3a8c2b7522521faaac7d62
+ languageName: node
+ linkType: hard
+
"@types/react-dom@npm:^18.2.4":
version: 18.2.4
resolution: "@types/react-dom@npm:18.2.4"
@@ -6937,14 +6946,14 @@ __metadata:
languageName: node
linkType: hard
-"@types/react@npm:^18.2.7":
- version: 18.2.7
- resolution: "@types/react@npm:18.2.7"
+"@types/react@npm:^16, @types/react@npm:^16.14.0":
+ version: 16.14.42
+ resolution: "@types/react@npm:16.14.42"
dependencies:
"@types/prop-types": "*"
"@types/scheduler": "*"
csstype: ^3.0.2
- checksum: caa5da4cf929766738ec789301dc6fb6624bd48dd317d851c4c9b84b1f47cd8ebe17fe01398cadaa0bc938cd4d502d67f4b9de9ff771dc132096bdc86228efba
+ checksum: b28d101c5811907927ed5a42bde0a4b55e19d2f4303bab6a57014faace55bc3d3d58d1194c2e95bae7d36951ac27e3645cb829f7c532c554a73f606ca1e22897
languageName: node
linkType: hard
From 66a9ac7bc75b36c192495bf842e8ac99e2d83718 Mon Sep 17 00:00:00 2001
From: Tom Caiger
Date: Fri, 26 May 2023 17:21:19 +1200
Subject: [PATCH 043/251] review improvements
---
.../ui-chart-components/src/components/Axes/XAxis.tsx | 2 +-
.../src/components/Charts/PieChart.tsx | 5 ++---
.../src/components/Reference/Legend.tsx | 11 ++++++-----
.../src/components/Reference/ReferenceLines.tsx | 4 +---
.../src/utils/getChartTableData.tsx | 2 +-
packages/web-frontend/src/components/View/View.js | 2 +-
6 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/packages/ui-chart-components/src/components/Axes/XAxis.tsx b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
index 046f1c95ca..1d126cef65 100644
--- a/packages/ui-chart-components/src/components/Axes/XAxis.tsx
+++ b/packages/ui-chart-components/src/components/Axes/XAxis.tsx
@@ -9,7 +9,7 @@ import { formatTimestampForChart, getIsTimeSeries, getContrastTextColor } from '
import { VerticalTick } from './VerticalTick';
import { DARK_BLUE } from '../../constants';
import { ChartType, DataProps, ViewContent } from '../../types';
-import { CartesianChartConfig } from '@tupaia/types/src';
+import { CartesianChartConfig } from '@tupaia/types';
const AXIS_TIME_PROPS = {
dataKey: 'timestamp',
diff --git a/packages/ui-chart-components/src/components/Charts/PieChart.tsx b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
index d02b425aa2..1b54e8da65 100644
--- a/packages/ui-chart-components/src/components/Charts/PieChart.tsx
+++ b/packages/ui-chart-components/src/components/Charts/PieChart.tsx
@@ -2,7 +2,7 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, MouseEvent } from 'react';
import styled from 'styled-components';
import Typography from '@material-ui/core/Typography';
import { formatDataValueByType } from '@tupaia/utils';
@@ -14,7 +14,6 @@ import {
ResponsiveContainer,
Tooltip,
TooltipProps,
- LayoutType,
LegendProps,
} from 'recharts';
import { OFF_WHITE, CHART_COLOR_PALETTE } from '../../constants';
@@ -130,7 +129,7 @@ export const PieChart = ({
}, 50);
}, []);
- const handleMouseEnter = (event: any, index: number) => {
+ const handleMouseEnter = (event: MouseEvent, index: number) => {
setActiveIndex(index);
};
diff --git a/packages/ui-chart-components/src/components/Reference/Legend.tsx b/packages/ui-chart-components/src/components/Reference/Legend.tsx
index ff703b993c..1fa085f18c 100644
--- a/packages/ui-chart-components/src/components/Reference/Legend.tsx
+++ b/packages/ui-chart-components/src/components/Reference/Legend.tsx
@@ -7,6 +7,7 @@ import React from 'react';
import styled from 'styled-components';
import MuiButton from '@material-ui/core/Button';
import Tooltip from '@material-ui/core/Tooltip';
+import { TooltipPayload } from 'recharts';
import { formatDataValueByType } from '@tupaia/utils';
import { LegendPosition, ViewContent } from '../../types';
import { isMobile } from '../../utils';
@@ -139,10 +140,10 @@ export const getPieLegend = ({
viewContent,
}: PieLegendProps) => ({ payload }: any) => (
- {payload.map(({ color, value, payload: item }: any) => {
+ {payload.map(({ color, value, payload: item }: TooltipPayload) => {
const displayValue = getPieLegendDisplayValue(
chartConfig,
- value,
+ value as string,
item,
viewContent,
isEnlarged,
@@ -150,7 +151,7 @@ export const getPieLegend = ({
return (
({ payload }: any) => (
- {payload.map(({ color, value, dataKey }: any) => {
+ {payload.map(({ color, value, dataKey }: TooltipPayload) => {
const displayValue = chartConfig[value as keyof CartesianChartConfig]?.label || value;
return (
onClick(dataKey)}
isExporting={isExporting}
className={isMobile() ? 'small' : 'enlarged'}
diff --git a/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx b/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
index 52d778bfbb..e1410cbdfc 100644
--- a/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
+++ b/packages/ui-chart-components/src/components/Reference/ReferenceLines.tsx
@@ -20,9 +20,7 @@ const ReferenceLineLabel = ({
isExporting?: boolean;
}) => {
if (referenceLineLabel === undefined) return undefined;
- return (
-
- );
+ return ;
};
enum Y_AXIS_IDS {
diff --git a/packages/ui-chart-components/src/utils/getChartTableData.tsx b/packages/ui-chart-components/src/utils/getChartTableData.tsx
index f6e2294f3e..bcc4c9aa44 100644
--- a/packages/ui-chart-components/src/utils/getChartTableData.tsx
+++ b/packages/ui-chart-components/src/utils/getChartTableData.tsx
@@ -29,7 +29,7 @@ const makeFirstColumn = (header: string, accessor: TableAccessor, sortRows?: Fun
const firstColumn: LooseObject = {
Header: header,
accessor,
- Cell: ({ value }: { value: string }) => {String(value)},
+ Cell: ({ value }: { value: any }) => {String(value)},
};
if (sortRows) {
firstColumn.sortType = sortRows;
diff --git a/packages/web-frontend/src/components/View/View.js b/packages/web-frontend/src/components/View/View.js
index 396511bcb9..5c0bbf50df 100644
--- a/packages/web-frontend/src/components/View/View.js
+++ b/packages/web-frontend/src/components/View/View.js
@@ -26,7 +26,7 @@ const viewHasData = viewContent => {
}
// If all segments of a pie chart are "0", display the no data message
- if (chartType === ChartType.PIE && data && data.every(segment => segment.value === 0)) {
+ if (chartType === ChartType.Pie && data && data.every(segment => segment.value === 0)) {
return false;
}
From 9d7c53922505abeae99c47444a3477a90576b5d1 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 09:05:15 +1200
Subject: [PATCH 044/251] WAITP-1259 Table to ts
---
.../src/components/Table/MapTable.js | 35 -------------------
.../src/components/Table/MapTable.tsx | 20 +++++++++++
...getMapTableData.js => getMapTableData.tsx} | 11 +++---
.../components/Table/{index.js => index.ts} | 0
...eMapDataExport.js => useMapDataExport.tsx} | 9 ++++-
.../src/types/data-types.d.ts | 7 ++++
6 files changed, 42 insertions(+), 40 deletions(-)
delete mode 100644 packages/ui-map-components/src/components/Table/MapTable.js
create mode 100644 packages/ui-map-components/src/components/Table/MapTable.tsx
rename packages/ui-map-components/src/components/Table/{getMapTableData.js => getMapTableData.tsx} (76%)
rename packages/ui-map-components/src/components/Table/{index.js => index.ts} (100%)
rename packages/ui-map-components/src/components/Table/{useMapDataExport.js => useMapDataExport.tsx} (59%)
diff --git a/packages/ui-map-components/src/components/Table/MapTable.js b/packages/ui-map-components/src/components/Table/MapTable.js
deleted file mode 100644
index ed9a11446d..0000000000
--- a/packages/ui-map-components/src/components/Table/MapTable.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Tupaia
- * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
- */
-import React from 'react';
-import PropTypes from 'prop-types';
-import { DataTable } from '@tupaia/ui-components';
-import { getMapTableData } from './getMapTableData';
-
-export const MapTable = ({ serieses, measureData, className }) => {
- const { columns, data } = getMapTableData(serieses, measureData);
-
- return ;
-};
-
-MapTable.propTypes = {
- measureData: PropTypes.arrayOf(
- PropTypes.shape({
- value: PropTypes.string,
- }),
- ),
- serieses: PropTypes.arrayOf(
- PropTypes.shape({
- name: PropTypes.string,
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- }),
- ),
- className: PropTypes.string,
-};
-
-MapTable.defaultProps = {
- measureData: [],
- serieses: [],
- className: null,
-};
diff --git a/packages/ui-map-components/src/components/Table/MapTable.tsx b/packages/ui-map-components/src/components/Table/MapTable.tsx
new file mode 100644
index 0000000000..95d2f6fc69
--- /dev/null
+++ b/packages/ui-map-components/src/components/Table/MapTable.tsx
@@ -0,0 +1,20 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+import React from 'react';
+import { DataTable } from '@tupaia/ui-components';
+import { getMapTableData } from './getMapTableData';
+import { Series, TableMeasureData } from '../../types';
+
+interface MapTableProps {
+ serieses: Series[];
+ measureData: TableMeasureData[];
+ className?: string;
+}
+
+export const MapTable = ({ serieses = [], measureData = [], className }: MapTableProps) => {
+ const { columns, data } = getMapTableData(serieses, measureData);
+
+ return ;
+};
diff --git a/packages/ui-map-components/src/components/Table/getMapTableData.js b/packages/ui-map-components/src/components/Table/getMapTableData.tsx
similarity index 76%
rename from packages/ui-map-components/src/components/Table/getMapTableData.js
rename to packages/ui-map-components/src/components/Table/getMapTableData.tsx
index 76afe10dea..9bab7fcec5 100644
--- a/packages/ui-map-components/src/components/Table/getMapTableData.js
+++ b/packages/ui-map-components/src/components/Table/getMapTableData.tsx
@@ -5,13 +5,14 @@
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { getFormattedInfo } from '../../utils';
+import { Series, TableMeasureData } from '../../types';
const FirstColumnCell = styled.span`
font-weight: 500;
text-align: left;
`;
-const processColumns = serieses => {
+const processColumns = (serieses: Series[]) => {
if (!serieses) {
return [];
}
@@ -25,14 +26,16 @@ const processColumns = serieses => {
Header: 'Name',
accessor: 'name',
// eslint-disable-next-line react/prop-types
- Cell: ({ value }) => {String(value)},
+ Cell: ({ value }: { value: string | number | boolean | undefined }) => (
+ {String(value)}
+ ),
},
...configColumns,
{ Header: 'Most Recent Data Date', accessor: 'submissionDate' },
];
};
-const processData = (serieses, measureData) => {
+const processData = (serieses: Series[], measureData: TableMeasureData[]) => {
if (!measureData || !serieses) {
return [];
}
@@ -51,7 +54,7 @@ const processData = (serieses, measureData) => {
});
};
-export const getMapTableData = (serieses, measureData) => {
+export const getMapTableData = (serieses: Series[], measureData: TableMeasureData[]) => {
const columns = useMemo(() => processColumns(serieses), [JSON.stringify(serieses)]);
const data = useMemo(() => processData(serieses, measureData), [
JSON.stringify(serieses),
diff --git a/packages/ui-map-components/src/components/Table/index.js b/packages/ui-map-components/src/components/Table/index.ts
similarity index 100%
rename from packages/ui-map-components/src/components/Table/index.js
rename to packages/ui-map-components/src/components/Table/index.ts
diff --git a/packages/ui-map-components/src/components/Table/useMapDataExport.js b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
similarity index 59%
rename from packages/ui-map-components/src/components/Table/useMapDataExport.js
rename to packages/ui-map-components/src/components/Table/useMapDataExport.tsx
index 3bed1d2908..e441e89b89 100644
--- a/packages/ui-map-components/src/components/Table/useMapDataExport.js
+++ b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
@@ -5,8 +5,15 @@
import { useDataTableExport } from '@tupaia/ui-components';
import { getMapTableData } from './getMapTableData';
+import { Series, TableMeasureData } from '../../types';
-export const useMapDataExport = (serieses, measureData, title, startDate, endDate) => {
+export const useMapDataExport = (
+ serieses: Series[],
+ measureData: TableMeasureData[],
+ title: string,
+ startDate: string | Date,
+ endDate: string | Date,
+) => {
const { columns, data } = getMapTableData(serieses, measureData);
return useDataTableExport(columns, data, title, startDate, endDate);
};
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index 8cc8200317..4095bf2bf8 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -50,3 +50,10 @@ export type MeasureData = MeasureOrgUnit &
photoUrl?: string;
value?: number | string;
};
+
+export type TableMeasureData = {
+ [key: string]: any;
+ name: string;
+ value: string | number;
+ submissionDate?: string | Date;
+};
From c2c99835700779b11367a7c6fc6a315b512095df Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 09:43:50 +1200
Subject: [PATCH 045/251] WAITP-1259 fix react types version mismatch
---
packages/ui-components/package.json | 4 ++--
packages/ui-map-components/package.json | 1 -
yarn.lock | 19 ++++---------------
3 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json
index e106c2ce00..34bda678c6 100644
--- a/packages/ui-components/package.json
+++ b/packages/ui-components/package.json
@@ -55,10 +55,10 @@
"@storybook/react": "^6.3.9",
"@types/jest": "^29.5.1",
"@types/lodash.throttle": "^4.1.7",
- "@types/react-dom": "^18.2.4",
+ "@types/react-dom": "^16.9.18",
"@types/react-router-dom": "^5.3.3",
"@types/react-table": "^7.7.14",
- "@types/styled-components": "^5.1.26",
+ "@types/styled-components": "^5.0.0",
"faker": "^4.1.0",
"fast-glob": "^3.2.5",
"react-docgen-typescript-plugin": "^1.0.5",
diff --git a/packages/ui-map-components/package.json b/packages/ui-map-components/package.json
index a42e62ccb9..cda2e8c15b 100644
--- a/packages/ui-map-components/package.json
+++ b/packages/ui-map-components/package.json
@@ -42,7 +42,6 @@
"@storybook/react": "^6.3.9",
"@types/jest": "^29.5.1",
"@types/leaflet": "^1.7.1",
- "@types/react": "^16.14.0",
"@types/react-dom": "^16.9.18",
"@types/styled-components": "^5.1.26"
}
diff --git a/yarn.lock b/yarn.lock
index 58ed8d1661..96a339fa5e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5845,10 +5845,10 @@ __metadata:
"@tupaia/utils": 1.0.0
"@types/jest": ^29.5.1
"@types/lodash.throttle": ^4.1.7
- "@types/react-dom": ^18.2.4
+ "@types/react-dom": ^16.9.18
"@types/react-router-dom": ^5.3.3
"@types/react-table": ^7.7.14
- "@types/styled-components": ^5.1.26
+ "@types/styled-components": ^5.0.0
ace-builds: ^1.4.13
date-fns: ^2.12.0
faker: ^4.1.0
@@ -5890,7 +5890,6 @@ __metadata:
"@tupaia/utils": 1.0.0
"@types/jest": ^29.5.1
"@types/leaflet": ^1.7.1
- "@types/react": ^16.14.0
"@types/react-dom": ^16.9.18
"@types/styled-components": ^5.1.26
leaflet: ^1.7.1
@@ -6876,15 +6875,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/react-dom@npm:^18.2.4":
- version: 18.2.4
- resolution: "@types/react-dom@npm:18.2.4"
- dependencies:
- "@types/react": "*"
- checksum: 8301f35cf1cbfec8c723e9477aecf87774e3c168bd457d353b23c45064737213d3e8008b067c6767b7b08e4f2b3823ee239242a6c225fc91e7f8725ef8734124
- languageName: node
- linkType: hard
-
"@types/react-native@npm:>=0.50.0":
version: 0.60.26
resolution: "@types/react-native@npm:0.60.26"
@@ -6974,7 +6964,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/react@npm:^16, @types/react@npm:^16.14.0":
+"@types/react@npm:^16":
version: 16.14.42
resolution: "@types/react@npm:16.14.42"
dependencies:
@@ -6985,7 +6975,6 @@ __metadata:
languageName: node
linkType: hard
-
"@types/recharts@npm:^1.8.24":
version: 1.8.24
resolution: "@types/recharts@npm:1.8.24"
@@ -7073,7 +7062,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/styled-components@npm:^5.1.26":
+"@types/styled-components@npm:^5.0.0, @types/styled-components@npm:^5.1.26":
version: 5.1.26
resolution: "@types/styled-components@npm:5.1.26"
dependencies:
From 8371226b0c156fa6f2d7286332e1a676b9bdcf35 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 09:57:02 +1200
Subject: [PATCH 046/251] WAITP-1259 TilePicker to ts
---
.../src/components/ReferenceTooltip.tsx | 6 +-
.../{TileButton.js => TileButton.tsx} | 21 +++---
.../{TileControl.js => TileControl.tsx} | 64 ++++++++---------
.../{TilePicker.js => TilePicker.tsx} | 71 +++++++++----------
.../TilePicker/{index.js => index.ts} | 0
.../TilePicker/{keyFrames.js => keyFrames.ts} | 2 +-
.../src/types/data-types.d.ts | 10 +++
.../src/types/legend-types.d.ts | 1 +
8 files changed, 90 insertions(+), 85 deletions(-)
rename packages/ui-map-components/src/components/TilePicker/{TileButton.js => TileButton.tsx} (85%)
rename packages/ui-map-components/src/components/TilePicker/{TileControl.js => TileControl.tsx} (71%)
rename packages/ui-map-components/src/components/TilePicker/{TilePicker.js => TilePicker.tsx} (58%)
rename packages/ui-map-components/src/components/TilePicker/{index.js => index.ts} (100%)
rename packages/ui-map-components/src/components/TilePicker/{keyFrames.js => keyFrames.ts} (96%)
diff --git a/packages/ui-components/src/components/ReferenceTooltip.tsx b/packages/ui-components/src/components/ReferenceTooltip.tsx
index 91e17d8091..f2d46bed03 100644
--- a/packages/ui-components/src/components/ReferenceTooltip.tsx
+++ b/packages/ui-components/src/components/ReferenceTooltip.tsx
@@ -46,13 +46,13 @@ const StyledToolTip = withStyles(theme => ({
},
}))(Tooltip);
-interface Reference {
+export interface ReferenceProps {
text?: string;
name?: string;
link?: string;
}
-const Content = ({ text = '', name = '', link = '' }: Reference) => {
+const Content = ({ text = '', name = '', link = '' }: ReferenceProps) => {
if (text) {
return (
@@ -72,7 +72,7 @@ const Content = ({ text = '', name = '', link = '' }: Reference) => {
interface ReferenceTooltipProps {
iconStyleOption?: string;
- reference?: Reference;
+ reference?: ReferenceProps;
}
export const ReferenceTooltip = ({
diff --git a/packages/ui-map-components/src/components/TilePicker/TileButton.js b/packages/ui-map-components/src/components/TilePicker/TileButton.tsx
similarity index 85%
rename from packages/ui-map-components/src/components/TilePicker/TileButton.js
rename to packages/ui-map-components/src/components/TilePicker/TileButton.tsx
index 7e897b6440..cc567da2d0 100644
--- a/packages/ui-map-components/src/components/TilePicker/TileButton.js
+++ b/packages/ui-map-components/src/components/TilePicker/TileButton.tsx
@@ -6,11 +6,10 @@
import React from 'react';
import styled from 'styled-components';
-import PropTypes from 'prop-types';
import { ReferenceTooltip } from '@tupaia/ui-components';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
-import { tileSetShape } from './constants';
+import { TileSet } from '../../types';
const StyledButton = styled(Button)`
position: relative;
@@ -80,7 +79,13 @@ const TileLabel = styled(Typography)`
padding: 0.5rem 0.75rem;
`;
-export const TileButton = React.memo(({ tileSet, isActive, onChange }) => (
+interface TileButtonProps {
+ tileSet: TileSet;
+ isActive?: boolean;
+ onChange: (tileSetKey: string) => void;
+}
+
+export const TileButton = React.memo(({ tileSet, isActive = false, onChange }: TileButtonProps) => (
onChange(tileSet.key)} className={isActive ? 'active' : ''}>
@@ -91,13 +96,3 @@ export const TileButton = React.memo(({ tileSet, isActive, onChange }) => (
));
-
-TileButton.propTypes = {
- tileSet: PropTypes.shape(tileSetShape).isRequired,
- isActive: PropTypes.bool,
- onChange: PropTypes.func.isRequired,
-};
-
-TileButton.defaultProps = {
- isActive: false,
-};
diff --git a/packages/ui-map-components/src/components/TilePicker/TileControl.js b/packages/ui-map-components/src/components/TilePicker/TileControl.tsx
similarity index 71%
rename from packages/ui-map-components/src/components/TilePicker/TileControl.js
rename to packages/ui-map-components/src/components/TilePicker/TileControl.tsx
index f136f83ad3..8f9f5771d0 100644
--- a/packages/ui-map-components/src/components/TilePicker/TileControl.js
+++ b/packages/ui-map-components/src/components/TilePicker/TileControl.tsx
@@ -6,14 +6,15 @@
import React from 'react';
import styled from 'styled-components';
-import PropTypes from 'prop-types';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';
import Typography from '@material-ui/core/Typography';
import RightIcon from '@material-ui/icons/KeyboardArrowRight';
-import { tileSetShape } from './constants';
+import { TileSet } from '../../types';
-const StyledButton = styled(Button)`
+const StyledButton = styled(Button)<{
+ active: string;
+}>`
display: block;
pointer-events: auto;
box-shadow: none;
@@ -91,33 +92,32 @@ const LegendLabel = styled(Typography)`
margin-bottom: 0.3rem;
`;
-export const TileControl = React.memo(({ tileSet, isActive, ...props }) => (
-
-
-
-
-
-
-
-
- {tileSet.legendItems && (
-
- {tileSet.legendItems.map(item => (
-
- ))}
-
- )}
-
-));
-
-TileControl.propTypes = {
- tileSet: PropTypes.shape(tileSetShape).isRequired,
- isActive: PropTypes.bool,
-};
+interface TileControlProps {
+ tileSet: TileSet;
+ isActive?: boolean;
+ [key: string]: any;
+}
-TileControl.defaultProps = {
- isActive: false,
-};
+export const TileControl = React.memo(
+ ({ tileSet, isActive = false, ...props }: TileControlProps) => (
+
+
+
+
+
+
+
+
+ {tileSet.legendItems && (
+
+ {tileSet.legendItems.map(item => (
+
+ ))}
+
+ )}
+
+ ),
+);
diff --git a/packages/ui-map-components/src/components/TilePicker/TilePicker.js b/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
similarity index 58%
rename from packages/ui-map-components/src/components/TilePicker/TilePicker.js
rename to packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
index 4ac7cb9fdb..f6b160a185 100644
--- a/packages/ui-map-components/src/components/TilePicker/TilePicker.js
+++ b/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
@@ -11,6 +11,7 @@ import { TileButton } from './TileButton';
import { TileControl } from './TileControl';
import { tileSetShape } from './constants';
import { createScaleKeyFrameAnimation } from './keyFrames';
+import { TileSet } from '../../types';
const Container = styled.div`
height: 100%;
@@ -65,40 +66,38 @@ const TileList = styled.div`
}
`;
-export const TilePicker = React.memo(({ tileSets, activeTileSet, onChange, className }) => {
- const [open, setOpen] = useState(false);
- return (
- setOpen(false)}>
-
-
- setOpen(current => !current)}
- />
-
-
- {tileSets.map(tileSet => (
-
- ))}
-
-
-
- );
-});
-
-TilePicker.propTypes = {
- tileSets: PropTypes.arrayOf(PropTypes.shape(tileSetShape)).isRequired,
- activeTileSet: PropTypes.shape(tileSetShape).isRequired,
- onChange: PropTypes.func.isRequired,
- className: PropTypes.string,
-};
+interface TilePickerProps {
+ tileSets: TileSet[];
+ activeTileSet: TileSet;
+ onChange: (tileSetKey: TileSet['key']) => void;
+ className?: string;
+}
-TilePicker.defaultProps = {
- className: null,
-};
+export const TilePicker = React.memo(
+ ({ tileSets, activeTileSet, onChange, className }: TilePickerProps) => {
+ const [open, setOpen] = useState(false);
+ return (
+ setOpen(false)}>
+
+
+ setOpen(current => !current)}
+ />
+
+
+ {tileSets.map(tileSet => (
+
+ ))}
+
+
+
+ );
+ },
+);
diff --git a/packages/ui-map-components/src/components/TilePicker/index.js b/packages/ui-map-components/src/components/TilePicker/index.ts
similarity index 100%
rename from packages/ui-map-components/src/components/TilePicker/index.js
rename to packages/ui-map-components/src/components/TilePicker/index.ts
diff --git a/packages/ui-map-components/src/components/TilePicker/keyFrames.js b/packages/ui-map-components/src/components/TilePicker/keyFrames.ts
similarity index 96%
rename from packages/ui-map-components/src/components/TilePicker/keyFrames.js
rename to packages/ui-map-components/src/components/TilePicker/keyFrames.ts
index 7259fb3399..5eb3f5e3d1 100644
--- a/packages/ui-map-components/src/components/TilePicker/keyFrames.js
+++ b/packages/ui-map-components/src/components/TilePicker/keyFrames.ts
@@ -4,7 +4,7 @@
*
*/
-function ease(v, pow = 3) {
+function ease(v: number, pow = 3) {
return 1 - Math.pow(1 - v, pow);
}
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index 4095bf2bf8..8773a99eff 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -1,8 +1,10 @@
import { PolygonProps } from 'react-leaflet';
import { LatLngExpression, LatLngBoundsExpression } from 'leaflet';
import { Entity as TupaiaEntity } from '@tupaia/types';
+import { ReferenceProps } from '@tupaia/ui-components';
import { Color } from './types';
import { MarkerProps } from './marker-types';
+import { LegendItemValue } from './legend-types';
export type Series = {
key: string;
@@ -57,3 +59,11 @@ export type TableMeasureData = {
value: string | number;
submissionDate?: string | Date;
};
+
+export type TileSet = {
+ key: string;
+ label: string;
+ thumbnail: string;
+ reference?: ReferenceProps;
+ legendItems?: LegendItemValue[];
+};
diff --git a/packages/ui-map-components/src/types/legend-types.d.ts b/packages/ui-map-components/src/types/legend-types.d.ts
index a6f0c3b0a4..8563627d8f 100644
--- a/packages/ui-map-components/src/types/legend-types.d.ts
+++ b/packages/ui-map-components/src/types/legend-types.d.ts
@@ -11,6 +11,7 @@ export type LegendItemValue = {
hideFromLegend?: boolean;
icon?: IconKey;
color: string;
+ label: string;
};
export type ValueMappingType = {
From 0b6df8182f791cdf6522586bda80eb57f04231f5 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 09:57:48 +1200
Subject: [PATCH 047/251] WAITP-1259 colors to ts
---
packages/ui-map-components/src/constants/{colors.js => colors.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename packages/ui-map-components/src/constants/{colors.js => colors.ts} (100%)
diff --git a/packages/ui-map-components/src/constants/colors.js b/packages/ui-map-components/src/constants/colors.ts
similarity index 100%
rename from packages/ui-map-components/src/constants/colors.js
rename to packages/ui-map-components/src/constants/colors.ts
From 54d0052cba2955e4c9dab10d0db45d0e5ad107ab Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 12:02:53 +1200
Subject: [PATCH 048/251] WAITP-1259 utils and fixes to types
---
.../src/components/Legend/Legend.tsx | 8 +-
.../src/components/Legend/LegendEntry.tsx | 4 +-
.../src/components/Legend/MarkerLegend.tsx | 12 +-
.../src/components/Legend/SpectrumLegend.tsx | 6 +-
.../Markers/CircleProportionMarker.tsx | 2 +-
.../src/components/PopupDataItemList.tsx | 2 +-
.../src/components/Table/MapTable.tsx | 4 +-
.../src/components/Table/getMapTableData.tsx | 6 +-
.../src/components/Table/useMapDataExport.tsx | 4 +-
.../src/types/data-types.d.ts | 76 +++++++++--
.../src/types/legend-types.d.ts | 51 +-------
.../src/utils/{index.js => index.ts} | 0
.../{markerColors.js => markerColors.ts} | 91 +++++++------
.../{markerFormats.js => markerFormats.ts} | 120 ++++++++++++------
14 files changed, 227 insertions(+), 159 deletions(-)
rename packages/ui-map-components/src/utils/{index.js => index.ts} (100%)
rename packages/ui-map-components/src/utils/{markerColors.js => markerColors.ts} (66%)
rename packages/ui-map-components/src/utils/{markerFormats.js => markerFormats.ts} (75%)
diff --git a/packages/ui-map-components/src/components/Legend/Legend.tsx b/packages/ui-map-components/src/components/Legend/Legend.tsx
index a06f52053b..53d1acc678 100644
--- a/packages/ui-map-components/src/components/Legend/Legend.tsx
+++ b/packages/ui-map-components/src/components/Legend/Legend.tsx
@@ -8,7 +8,7 @@ import styled from 'styled-components';
import { MarkerLegend } from './MarkerLegend';
import { SpectrumLegend } from './SpectrumLegend';
import { MEASURE_TYPES } from '../../constants';
-import { LegendProps as BaseLegendProps, LegendSeriesItem, MeasureType } from '../../types';
+import { LegendProps as BaseLegendProps, Series, MeasureType } from '../../types';
const LegendFrame = styled.div<{
isDisplayed: boolean;
@@ -61,7 +61,7 @@ interface LegendProps extends BaseLegendProps {
className?: string;
measureInfo: {
[mapOverlayCode: string]: {
- [seriesesKey: string]: LegendSeriesItem[];
+ [seriesesKey: string]: Series[];
};
};
currentMapOverlayCodes: string[];
@@ -91,7 +91,7 @@ export const Legend = React.memo(
// measure info for mapOverlayCode may not exist when location changes.
const baseSerieses = baseMeasureInfo[mapOverlayCode]?.[seriesesKey] || [];
const serieses = baseSerieses.filter(
- ({ type, hideFromLegend, values = [], min, max, noDataColour }: LegendSeriesItem) => {
+ ({ type, hideFromLegend, values = [], min, max, noDataColour }: Series) => {
const seriesType = type as MeasureType;
// if type is radius or popup-only, don't create a legend
if (checkMeasureType(seriesType, [MEASURE_TYPES.RADIUS, MEASURE_TYPES.POPUP_ONLY]))
@@ -111,7 +111,7 @@ export const Legend = React.memo(
return { ...results, [mapOverlayCode]: { serieses } };
}, {}) as {
[mapOverlayCode: string]: {
- serieses: LegendSeriesItem[];
+ serieses: Series[];
};
};
diff --git a/packages/ui-map-components/src/components/Legend/LegendEntry.tsx b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
index 181b187d41..6c10c2e62f 100644
--- a/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
+++ b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import styled from 'styled-components';
import MuiButton from '@material-ui/core/Button';
-import { LegendProps, ValueType } from '../../types';
+import { LegendProps, DataValueType } from '../../types';
const Button = styled(MuiButton)`
display: flex;
@@ -37,7 +37,7 @@ const Label = styled.div`
interface LegendEntryProps {
marker: React.ReactNode;
label: string;
- value: ValueType;
+ value: DataValueType;
dataKey?: string;
onClick?: LegendProps['setValueHidden'];
hiddenValues?: LegendProps['hiddenValues'];
diff --git a/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
index 37f771ed3c..be00963bec 100644
--- a/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
+++ b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
@@ -25,7 +25,7 @@ import {
MEASURE_VALUE_OTHER,
} from '../../utils';
import { LegendEntry } from './LegendEntry';
-import { LegendItemValue, MarkerLegendSeriesItem, MarkerLegendProps } from '../../types';
+import { DataValue, MarkerLegendProps, MarkerSeriesItem } from '../../types';
const Container = styled(MuiBox)`
display: flex;
@@ -46,13 +46,13 @@ const Container = styled(MuiBox)`
* and hide the radius as well. But, if the hidden icon is 'other', go ahead and add it to
* the legend and show the radius.
*/
-const isHiddenOtherIcon = ({ value, icon }: LegendItemValue) => {
+const isHiddenOtherIcon = ({ value, icon }: DataValue) => {
return value === MEASURE_VALUE_OTHER && icon === HIDDEN_ICON;
};
const getMarkerColor = (
- value: LegendItemValue,
- type: MarkerLegendSeriesItem['type'],
+ value: DataValue,
+ type: MarkerSeriesItem['type'],
hasColorLayer: boolean,
) => {
const theme = useTheme();
@@ -71,8 +71,8 @@ const getMarkerColor = (
};
const getLegendMarkerForValue = (
- value: LegendItemValue,
- type: MarkerLegendSeriesItem['type'],
+ value: DataValue,
+ type: MarkerSeriesItem['type'],
hasIconLayer: MarkerLegendProps['hasIconLayer'],
hasRadiusLayer: MarkerLegendProps['hasRadiusLayer'],
hasColorLayer: MarkerLegendProps['hasColorLayer'],
diff --git a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
index f519dbabb6..8a17cfe787 100644
--- a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
+++ b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
@@ -12,7 +12,7 @@ import { resolveSpectrumColour } from '../../utils';
import { LEGEND_SHADING_ICON, getMarkerForOption } from '../Markers/markerIcons';
import { SCALE_TYPES } from '../../constants';
import { LegendEntry } from './LegendEntry';
-import { ScaleType, SpectrumLegendProps, SpectrumLegendSeriesItem } from '../../types';
+import { ScaleType, SpectrumLegendProps, SpectrumSeriesItem } from '../../types';
const FlexCenter = styled(MuiBox)`
display: flex;
@@ -76,7 +76,7 @@ const renderSpectrum = ({
scaleType,
scaleColorScheme,
valueType,
-}: SpectrumLegendSeriesItem) => {
+}: SpectrumSeriesItem) => {
if (min == null || max == null) return null;
const spectrumDivs = [];
@@ -155,7 +155,7 @@ export const SpectrumLegend = React.memo(
scaleType,
scaleColorScheme,
valueType,
- } as SpectrumLegendSeriesItem)}
+ } as SpectrumSeriesItem)}
{noDataColour && (
(
diff --git a/packages/ui-map-components/src/components/Table/MapTable.tsx b/packages/ui-map-components/src/components/Table/MapTable.tsx
index 95d2f6fc69..bf00b60299 100644
--- a/packages/ui-map-components/src/components/Table/MapTable.tsx
+++ b/packages/ui-map-components/src/components/Table/MapTable.tsx
@@ -5,11 +5,11 @@
import React from 'react';
import { DataTable } from '@tupaia/ui-components';
import { getMapTableData } from './getMapTableData';
-import { Series, TableMeasureData } from '../../types';
+import { MeasureData, Series } from '../../types';
interface MapTableProps {
serieses: Series[];
- measureData: TableMeasureData[];
+ measureData: MeasureData[];
className?: string;
}
diff --git a/packages/ui-map-components/src/components/Table/getMapTableData.tsx b/packages/ui-map-components/src/components/Table/getMapTableData.tsx
index 9bab7fcec5..c59f79e727 100644
--- a/packages/ui-map-components/src/components/Table/getMapTableData.tsx
+++ b/packages/ui-map-components/src/components/Table/getMapTableData.tsx
@@ -5,7 +5,7 @@
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { getFormattedInfo } from '../../utils';
-import { Series, TableMeasureData } from '../../types';
+import { MeasureData, Series } from '../../types';
const FirstColumnCell = styled.span`
font-weight: 500;
@@ -35,7 +35,7 @@ const processColumns = (serieses: Series[]) => {
];
};
-const processData = (serieses: Series[], measureData: TableMeasureData[]) => {
+const processData = (serieses: Series[], measureData: MeasureData[]) => {
if (!measureData || !serieses) {
return [];
}
@@ -54,7 +54,7 @@ const processData = (serieses: Series[], measureData: TableMeasureData[]) => {
});
};
-export const getMapTableData = (serieses: Series[], measureData: TableMeasureData[]) => {
+export const getMapTableData = (serieses: Series[], measureData: MeasureData[]) => {
const columns = useMemo(() => processColumns(serieses), [JSON.stringify(serieses)]);
const data = useMemo(() => processData(serieses, measureData), [
JSON.stringify(serieses),
diff --git a/packages/ui-map-components/src/components/Table/useMapDataExport.tsx b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
index e441e89b89..b09575e865 100644
--- a/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
+++ b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
@@ -5,11 +5,11 @@
import { useDataTableExport } from '@tupaia/ui-components';
import { getMapTableData } from './getMapTableData';
-import { Series, TableMeasureData } from '../../types';
+import { Series, MeasureData } from '../../types';
export const useMapDataExport = (
serieses: Series[],
- measureData: TableMeasureData[],
+ measureData: MeasureData[],
title: string,
startDate: string | Date,
endDate: string | Date,
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
index 8773a99eff..4a16fe028e 100644
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ b/packages/ui-map-components/src/types/data-types.d.ts
@@ -2,22 +2,78 @@ import { PolygonProps } from 'react-leaflet';
import { LatLngExpression, LatLngBoundsExpression } from 'leaflet';
import { Entity as TupaiaEntity } from '@tupaia/types';
import { ReferenceProps } from '@tupaia/ui-components';
+import { VALUE_TYPES } from '@tupaia/utils';
+import { MEASURE_TYPES, SCALE_TYPES } from '../constants';
import { Color } from './types';
import { MarkerProps } from './marker-types';
-import { LegendItemValue } from './legend-types';
+import { DataValue } from './legend-types';
+import { ValueOf } from './helpers';
-export type Series = {
- key: string;
+const ValueTypes = { ...VALUE_TYPES } as const;
+
+type ValueTypesKeys = keyof typeof ValueTypes;
+type ValueTypeValues = typeof VALUE_TYPES[ValueTypesKeys];
+
+export type DataValueType = string | number | null | undefined;
+export type ScaleType = `${SCALE_TYPES}`;
+export type MeasureType = `${MEASURE_TYPES}`;
+
+export type DataValue = {
+ value: DataValueType | DataValueType[];
+ name: string;
+ hideFromLegend?: boolean;
+ icon?: IconKey;
+ color: string;
+ label?: string;
+};
+
+export type ValueMappingType = {
+ null: DataValue;
+ [key: string]: DataValue;
+};
+
+export type BaseSeriesItem = {
name: string;
+ key: string;
+ values: DataValue[];
+ valueMapping: ValueMappingType;
+ hideFromLegend?: boolean;
+ type: MeasureType;
+ startDate?: string;
+ endDate?: string;
+ hideByDefault?: Record;
+ displayedValueKey?: string;
+ color: string;
+ icon?: IconKey;
+ radius?: number;
+ scaleBounds?: {
+ left: number;
+ right: number;
+ };
hideFromPopup?: boolean;
metadata: object;
- value: string | number;
organisationUnit?: string;
sortOrder: number;
- type?: string;
popupHeaderFormat?: string;
+ valueType?: ValueTypeValues;
+};
+
+export type MarkerSeriesItem = BaseSeriesItem & {
+ icon?: IconKey;
+};
+
+export type SpectrumSeriesItem = BaseSeriesItem & {
+ scaleColorScheme: ColorScheme;
+ min: number;
+ max: number;
+ scaleType: ScaleType;
+ valueType: string;
+ dataKey?: string;
+ noDataColour?: string;
};
+export type Series = MarkerSeriesItem & SpectrumSeriesItem;
+
export type Location = {
bounds: LatLngBoundsExpression;
type?: string | null;
@@ -51,19 +107,13 @@ export type MeasureData = MeasureOrgUnit &
icon?: string;
photoUrl?: string;
value?: number | string;
+ submissionDate?: string | Date;
};
-export type TableMeasureData = {
- [key: string]: any;
- name: string;
- value: string | number;
- submissionDate?: string | Date;
-};
-
export type TileSet = {
key: string;
label: string;
thumbnail: string;
reference?: ReferenceProps;
- legendItems?: LegendItemValue[];
+ legendItems?: DataValue[];
};
diff --git a/packages/ui-map-components/src/types/legend-types.d.ts b/packages/ui-map-components/src/types/legend-types.d.ts
index 8563627d8f..a3d459ff28 100644
--- a/packages/ui-map-components/src/types/legend-types.d.ts
+++ b/packages/ui-map-components/src/types/legend-types.d.ts
@@ -1,60 +1,17 @@
-import { IconKey } from '../components';
-import { SCALE_TYPES, MEASURE_TYPES } from '../constants';
+import { DataValueType, MarkerSeriesItem, SpectrumSeriesItem } from './data-types';
-export type ValueType = string | number | null | undefined;
-export type ScaleType = `${SCALE_TYPES}`;
-export type MeasureType = `${MEASURE_TYPES}`;
-
-export type LegendItemValue = {
- value: ValueType;
- name: string;
- hideFromLegend?: boolean;
- icon?: IconKey;
- color: string;
- label: string;
-};
-
-export type ValueMappingType = {
- null: LegendItemValue;
- [key: string]: LegendItemValue;
-};
-
-export type BaseLegendSeriesItem = {
- name: string;
- key: string;
- type: string;
- values: LegendItemValue[];
- valueMapping: ValueMappingType;
- hideFromLegend?: boolean;
- type: MeasureType;
-};
-
-export type MarkerLegendSeriesItem = BaseLegendSeriesItem & {
- icon?: IconKey;
-};
-
-export type SpectrumLegendSeriesItem = BaseLegendSeriesItem & {
- scaleColorScheme: object;
- min: number;
- max: number;
- scaleType: ScaleType;
- valueType: string;
- dataKey?: string;
- noDataColour?: string;
-};
-export type LegendSeriesItem = MarkerLegendSeriesItem & SpectrumLegendSeriesItem;
export type LegendProps = {
- setValueHidden: (dataKey?: string, value: ValueType, hidden: boolean) => void;
+ setValueHidden: (dataKey?: string, value: DataValueType, hidden: boolean) => void;
hiddenValues: Record>;
};
export type MarkerLegendProps = LegendProps & {
- series: MarkerLegendSeriesItem;
+ series: MarkerSeriesItem;
hasIconLayer: boolean;
hasRadiusLayer: boolean;
hasColorLayer: boolean;
};
export type SpectrumLegendProps = LegendProps & {
- series: SpectrumLegendSeriesItem;
+ series: SpectrumSeriesItem;
};
diff --git a/packages/ui-map-components/src/utils/index.js b/packages/ui-map-components/src/utils/index.ts
similarity index 100%
rename from packages/ui-map-components/src/utils/index.js
rename to packages/ui-map-components/src/utils/index.ts
diff --git a/packages/ui-map-components/src/utils/markerColors.js b/packages/ui-map-components/src/utils/markerColors.ts
similarity index 66%
rename from packages/ui-map-components/src/utils/markerColors.js
rename to packages/ui-map-components/src/utils/markerColors.ts
index 55d1c3582e..7e8b661f24 100644
--- a/packages/ui-map-components/src/utils/markerColors.js
+++ b/packages/ui-map-components/src/utils/markerColors.ts
@@ -16,6 +16,7 @@ import {
TIME_COLOR_SCHEME,
GPI_COLOR_SCHEME,
} from '../constants';
+import { Color, ColorKey, ScaleType } from '../types';
const COLOR_SCHEME_TO_FUNCTION = {
[DEFAULT_COLOR_SCHEME]: getHeatmapColor,
@@ -34,34 +35,42 @@ const SCALE_TYPE_TO_COLOR_SCHEME = {
[SCALE_TYPES.GPI]: GPI_COLOR_SCHEME,
};
+type ColorScheme = keyof typeof COLOR_SCHEME_TO_FUNCTION;
+
/**
* Helper function just to point the spectrum type to the correct colours
*
- * @param {constant} scaleType one of the SCALE_TYPE* constants
- * @param {number | string} value a number in range [0..1] representing percentage or
- * a string of a date within a range specified by [min, max]
- * @param {number | string} min the lowest number or a string representing earliest date in a range
- * @param {number | string} max the highest number or a string representing lastest date in a range
- * @param {string} noDataColour css hsl string, e.g. `hsl(value, 100%, 50%)` for null value
- * @returns {style} css hsl string, e.g. `hsl(value, 100%, 50%)`
*/
-export function resolveSpectrumColour(scaleType, scaleColorScheme, value, min, max, noDataColour) {
+export function resolveSpectrumColour(
+ scaleType: ScaleType,
+ scaleColorScheme: ColorScheme,
+ value: number | null, // a number in range [0..1] representing percentage or a string of a date within a range specified by [min, max]
+ min: number | string, // the lowest number or a string representing earliest date in a range
+ max: number | string, // the highest number or a string representing latest date in a range
+ noDataColour?: string, // css hsl string, e.g. `hsl(value, 100%, 50%)` for null value
+): string {
if (value === null || (isNaN(value) && scaleType !== SCALE_TYPES.TIME))
return noDataColour || HEATMAP_UNKNOWN_COLOR;
- const valueToColor =
- COLOR_SCHEME_TO_FUNCTION[scaleColorScheme] ||
- COLOR_SCHEME_TO_FUNCTION[SCALE_TYPE_TO_COLOR_SCHEME[scaleType]] ||
- COLOR_SCHEME_TO_FUNCTION[DEFAULT_COLOR_SCHEME];
+ const valueToColor = (COLOR_SCHEME_TO_FUNCTION[scaleColorScheme] ||
+ COLOR_SCHEME_TO_FUNCTION[SCALE_TYPE_TO_COLOR_SCHEME[scaleType] as ColorScheme] ||
+ COLOR_SCHEME_TO_FUNCTION[DEFAULT_COLOR_SCHEME]) as (
+ value: number | null,
+ ...args: any[]
+ ) => string;
switch (scaleType) {
case SCALE_TYPES.PERFORMANCE_DESC: {
- const percentage = value || value === 0 ? 1 - normaliseToPercentage(value, min, max) : null;
- return valueToColor(percentage);
+ const percentage =
+ value || value === 0
+ ? 1 - normaliseToPercentage(value, min as number, max as number)
+ : null;
+ return valueToColor(percentage as number);
}
case SCALE_TYPES.TIME:
// if the value passed is a date locate it in the [min, max] range
- if (isNaN(value)) return valueToColor(getTimeProportion(value, min, max), noDataColour);
+ if (isNaN(value))
+ return valueToColor(getTimeProportion(value, min as string, max as string), noDataColour);
return valueToColor(value, noDataColour);
case SCALE_TYPES.GPI:
@@ -70,11 +79,13 @@ export function resolveSpectrumColour(scaleType, scaleColorScheme, value, min, m
case SCALE_TYPES.NEUTRAL:
case SCALE_TYPES.NEUTRAL_REVERSE:
default:
- return valueToColor((value || value === 0) && normaliseToPercentage(value, min, max));
+ return valueToColor(
+ value || value === 0 ? normaliseToPercentage(value, min as number, max as number) : null,
+ );
}
}
-const normaliseToPercentage = (value, min = 0, max = 1) => {
+const normaliseToPercentage = (value: number, min: number = 0, max: number = 1) => {
// Always clamp the result between 0 and 1
if (value < min) return 0;
if (value > max) return 1;
@@ -84,15 +95,14 @@ const normaliseToPercentage = (value, min = 0, max = 1) => {
};
/**
* Takes a value and return a hsl color string for use as a style
- *
- * @param {number} value Number in range [0..1] representing percentage
- * @returns {style} css hsl string, e.g. `hsl(value, 100%, 50%)`
*/
-export function getPerformanceHeatmapColor(value) {
+export function getPerformanceHeatmapColor(
+ value: number, // Number in range [0..1] representing percentage
+): string {
return `hsl(${Math.floor(value * 100)}, 100%, 50%)`;
}
-const getTimeProportion = (value, min, max) => {
+const getTimeProportion = (value: number, min: string, max: string) => {
if (!value || !isNaN(value)) return null;
const range = moment(max).diff(min, 'days');
const valueAsMoment = moment(value);
@@ -102,11 +112,11 @@ const getTimeProportion = (value, min, max) => {
/**
* Takes a value and return a hsl color string for use as a style
- *
- * @param {number} value Number in range [0..1] representing percentage
- * @returns {style} css hsl string, e.g. `hsl(value, 100%, 50%)`
*/
-export function getTimeHeatmapColor(value, noDataColour) {
+export function getTimeHeatmapColor(
+ value: number, // Number in range [0..1] representing percentage
+ noDataColour?: string,
+): string {
if (value === null || isNaN(value)) return noDataColour || HEATMAP_UNKNOWN_COLOR;
return `hsl(${100 - Math.floor(value * 100)}, 100%, 50%)`;
}
@@ -127,30 +137,34 @@ const HEATMAP_DEFAULT_RGB_SET = [
* Takes a value and returns color string for use as a style
* to match the map/legend style shown here:
* https://commons.wikimedia.org/wiki/File:South_Africa_2011_population_density_map.svg
- *
- * @param {number} value A value in the range [0..1] representing a percentage
- * @param {default} if default is true, return lightest to darkest colour, otherwise return darkest to lightest
- * @returns {style} css rgb string, e.g. `rgb(0,0,0)`
*/
-function getHeatmapColorByOrder({ value, swapColor = false, colorSet = HEATMAP_DEFAULT_RGB_SET }) {
+function getHeatmapColorByOrder({
+ value,
+ swapColor = false,
+ colorSet = HEATMAP_DEFAULT_RGB_SET,
+}: {
+ value: number;
+ swapColor?: boolean;
+ colorSet?: string[];
+}): string {
const difference = value - 0.15;
const index = difference < 0 ? 0 : Math.floor(difference / 0.1) + 1;
const indexInRange = index > colorSet.length - 1 ? colorSet.length - 1 : index;
return !swapColor ? colorSet[indexInRange] : colorSet[colorSet.length - indexInRange - 1];
}
-export function getHeatmapColor(value) {
+export function getHeatmapColor(value: number) {
return getHeatmapColorByOrder({ value, swapColor: false });
}
-export function getReverseHeatmapColor(value) {
+export function getReverseHeatmapColor(value: number) {
return getHeatmapColorByOrder({ value, swapColor: true });
}
// Use a palette color if named, otherwise just return the name.
// This allows measures to still use hex codes and named colors not in the palette.
-export function getColor(colorName) {
- return BREWER_PALETTE[colorName] || colorName;
+export function getColor(colorName: Color) {
+ return BREWER_PALETTE[colorName as ColorKey] || colorName;
}
/**
@@ -184,15 +198,14 @@ const RED_COLOR_SET = [
*
* A GPI between 0.97 - 1.03 is considered gender parity
*/
-const GPI_PARITY_UPPER_LIMIT = '1.03';
-const GPI_PARITY_LOWER_LIMIT = '0.97';
+const GPI_PARITY_UPPER_LIMIT = 1.03;
+const GPI_PARITY_LOWER_LIMIT = 0.97;
/**
*
- * @param value - GPI value type is number between 0 and 2.
* @returns {string}
*/
-export function getGPIColor(value, min, max) {
+export function getGPIColor(value: number, min?: number, max?: number): string {
if (value > GPI_PARITY_UPPER_LIMIT) {
const normalisedValue = normaliseToPercentage(Math.min(value, 2), GPI_PARITY_UPPER_LIMIT, max);
return getHeatmapColorByOrder({ value: normalisedValue, colorSet: RED_COLOR_SET });
diff --git a/packages/ui-map-components/src/utils/markerFormats.js b/packages/ui-map-components/src/utils/markerFormats.ts
similarity index 75%
rename from packages/ui-map-components/src/utils/markerFormats.js
rename to packages/ui-map-components/src/utils/markerFormats.ts
index 7119541949..43ef95537d 100644
--- a/packages/ui-map-components/src/utils/markerFormats.js
+++ b/packages/ui-map-components/src/utils/markerFormats.ts
@@ -4,7 +4,7 @@
*
*/
-import { formatDataValueByType } from '@tupaia/utils';
+import { VALUE_TYPES, formatDataValueByType } from '@tupaia/utils';
import { resolveSpectrumColour } from './markerColors';
import {
YES_COLOR,
@@ -15,6 +15,16 @@ import {
SCALE_TYPES,
} from '../constants';
import { SPECTRUM_ICON, DEFAULT_ICON, UNKNOWN_ICON } from '../components/Markers/markerIcons';
+import {
+ DataValue,
+ LegendProps,
+ MeasureData,
+ ScaleType,
+ Series,
+ ValueMappingType,
+ DataValueType,
+ MeasureType,
+} from '../types';
export const MEASURE_TYPE_ICON = 'icon';
export const MEASURE_TYPE_COLOR = 'color';
@@ -33,11 +43,11 @@ export const SPECTRUM_MEASURE_TYPES = [MEASURE_TYPE_SPECTRUM, MEASURE_TYPE_SHADE
const SPECTRUM_SCALE_DEFAULT = { left: {}, right: {} };
const PERCENTAGE_SPECTRUM_SCALE_DEFAULT = { left: { max: 0 }, right: { min: 1 } };
-export function autoAssignColors(values) {
+export function autoAssignColors(values: DataValue[]) {
if (!values) return [];
let autoIndex = 0;
- const getColor = valueObject => {
+ const getColor = (valueObject: DataValue) => {
if (!valueObject.name) {
return BREWER_AUTO[autoIndex++];
}
@@ -58,17 +68,19 @@ export function autoAssignColors(values) {
}));
}
-export function createValueMapping(valueObjects, type) {
- const mapping = {};
+export function createValueMapping(valueObjects: DataValue[], type: string) {
+ const mapping = {} as ValueMappingType;
valueObjects.forEach(valueObject => {
const { value } = valueObject;
if (Array.isArray(value)) {
value.forEach(v => {
+ // @ts-ignore TODO: fix this
mapping[v] = valueObject;
});
} else {
+ // @ts-ignore TODO: fix this
mapping[value] = valueObject;
}
});
@@ -82,11 +94,11 @@ export function createValueMapping(valueObjects, type) {
return mapping;
}
-const getNullValueMapping = type => {
+const getNullValueMapping = (type: string) => {
const baseMapping = {
name: 'No data',
value: MEASURE_VALUE_NULL,
- };
+ } as DataValue;
switch (type) {
case MEASURE_TYPE_ICON:
@@ -103,7 +115,14 @@ const getNullValueMapping = type => {
return baseMapping;
};
-function getFormattedValue(value, type, valueInfo, scaleType, valueType, submissionDate) {
+function getFormattedValue(
+ value: DataValueType,
+ type: MeasureType,
+ valueInfo: DataValue,
+ scaleType: ScaleType,
+ valueType: Series['valueType'],
+ submissionDate: string,
+) {
switch (type) {
case MEASURE_TYPE_SPECTRUM:
case MEASURE_TYPE_SHADED_SPECTRUM:
@@ -124,7 +143,7 @@ function getFormattedValue(value, type, valueInfo, scaleType, valueType, submiss
}
}
-export const getSpectrumScaleValues = (measureData, series) => {
+export const getSpectrumScaleValues = (measureData: MeasureData[], series: Series) => {
const { key, scaleType, startDate, endDate } = series;
if (scaleType === SCALE_TYPES.TIME) {
@@ -143,14 +162,20 @@ export const getSpectrumScaleValues = (measureData, series) => {
return { min, max };
};
-const clampScaleValues = (dataBounds, series) => {
- const { valueType, scaleBounds = {} } = series;
+const clampScaleValues = (
+ dataBounds: {
+ min: number;
+ max: number;
+ },
+ series: Series,
+) => {
+ const { valueType, scaleBounds } = series;
const defaultScale =
valueType === 'percentage' ? PERCENTAGE_SPECTRUM_SCALE_DEFAULT : SPECTRUM_SCALE_DEFAULT;
- const leftBoundConfig = scaleBounds.left || defaultScale.left;
- const rightBoundConfig = scaleBounds.right || defaultScale.right;
+ const leftBoundConfig = scaleBounds?.left || defaultScale.left;
+ const rightBoundConfig = scaleBounds?.right || defaultScale.right;
const { min: minDataValue, max: maxDataValue } = dataBounds;
return {
@@ -159,7 +184,13 @@ const clampScaleValues = (dataBounds, series) => {
};
};
-const clampValue = (value, config) => {
+const clampValue = (
+ value: number,
+ config: {
+ min?: number | 'auto';
+ max?: number | 'auto';
+ },
+) => {
const { min, max } = config;
let clampedValue = value;
@@ -169,12 +200,19 @@ const clampValue = (value, config) => {
return clampedValue;
};
-export function flattenMeasureHierarchy(mapOverlayHierarchy) {
- const results = [];
- const flattenGroupedMeasure = ({ children }) => {
+type Measure = {
+ children?: object[];
+};
+
+interface MapOverlayHierarchyItem {
+ children: Measure[] | MapOverlayHierarchyItem[];
+}
+export function flattenMeasureHierarchy(mapOverlayHierarchy: MapOverlayHierarchyItem[]) {
+ const results = [] as object[];
+ const flattenGroupedMeasure = ({ children }: MapOverlayHierarchyItem) => {
children.forEach(childObject => {
if (childObject.children && childObject.children.length) {
- flattenGroupedMeasure(childObject);
+ flattenGroupedMeasure(childObject as MapOverlayHierarchyItem);
} else {
results.push(childObject);
}
@@ -191,7 +229,11 @@ export function flattenMeasureHierarchy(mapOverlayHierarchy) {
return results;
}
-const getIsHidden = (measureData, serieses, allHiddenValues) =>
+const getIsHidden = (
+ measureData: MeasureData,
+ serieses: Series[],
+ allHiddenValues: Record>,
+) =>
serieses
.map(({ key, valueMapping, hideByDefault }) => {
const value = measureData[key];
@@ -202,7 +244,7 @@ const getIsHidden = (measureData, serieses, allHiddenValues) =>
// use 'no data' value if value is null and there is a null mapping defined
if (!value && typeof value !== 'number' && valueMapping.null) {
- return hiddenValues.null || hiddenValues[valueMapping.null.value];
+ return hiddenValues.null || hiddenValues[valueMapping.null.value as string];
}
const matchedValue = valueMapping[value];
@@ -212,11 +254,11 @@ const getIsHidden = (measureData, serieses, allHiddenValues) =>
return hiddenValues.other;
}
- return hiddenValues[matchedValue.value];
+ return hiddenValues[matchedValue.value as string];
})
.some(isHidden => isHidden);
-function getValueInfo(value, valueMapping) {
+function getValueInfo(value: DataValueType, valueMapping: ValueMappingType) {
// use 'no data' value if value is null and there is a null mapping defined
if (!value && typeof value !== 'number' && valueMapping.null) {
return {
@@ -224,7 +266,7 @@ function getValueInfo(value, valueMapping) {
};
}
- const matchedValue = valueMapping[value];
+ const matchedValue = valueMapping[value as string];
if (!matchedValue) {
// use 'other' value
@@ -238,13 +280,13 @@ function getValueInfo(value, valueMapping) {
...matchedValue,
};
}
-
+type MarkerData = Record;
// For situations where we can only show one value, just show the value
// of the first measure.
-export const getSingleFormattedValue = (markerData, series) =>
+export const getSingleFormattedValue = (markerData: MarkerData, series: Series[]) =>
getFormattedInfo(markerData, series[0]).formattedValue;
-export function getFormattedInfo(markerData, series) {
+export function getFormattedInfo(markerData: MarkerData, series: Series) {
const { key, valueMapping, type, displayedValueKey, scaleType, valueType } = series;
const value = markerData[key];
const valueInfo = getValueInfo(value, valueMapping);
@@ -278,17 +320,23 @@ export function getFormattedInfo(markerData, series) {
}
export function getMeasureDisplayInfo(
- measureData = {},
- serieses,
- hiddenValues = {},
- radiusScaleFactor = 1,
+ measureData: MeasureData, // TODO: handle default becaus eof required `positions` prop
+ serieses: Series[],
+ hiddenValues: LegendProps['hiddenValues'] = {},
+ radiusScaleFactor: number = 1,
) {
const isHidden = getIsHidden(measureData, serieses, hiddenValues);
const displayInfo = {
isHidden,
+ } as {
+ color?: string;
+ icon?: string;
+ radius?: number;
+ isHidden: boolean;
+ originalValue?: DataValue['value'];
};
- serieses.forEach(({ color, icon, radius }) => {
+ serieses.forEach(({ color, icon, radius }: Series) => {
if (color) {
displayInfo.color = color;
}
@@ -312,7 +360,7 @@ export function getMeasureDisplayInfo(
displayInfo.color = displayInfo.color || valueInfo.color;
break;
case MEASURE_TYPE_RADIUS:
- displayInfo.radius = valueInfo.value * radiusScaleFactor || 0;
+ displayInfo.radius = (valueInfo.value as number) * radiusScaleFactor || 0;
displayInfo.color = displayInfo.color || valueInfo.color;
break;
case MEASURE_TYPE_SPECTRUM:
@@ -322,7 +370,7 @@ export function getMeasureDisplayInfo(
displayInfo.color = resolveSpectrumColour(
scaleType,
scaleColorScheme,
- valueInfo.value || (valueInfo.value === 0 ? 0 : null),
+ (valueInfo.value as number) || (valueInfo.value === 0 ? 0 : null),
min,
max,
noDataColour,
@@ -355,19 +403,19 @@ export function getMeasureDisplayInfo(
const MAX_ALLOWED_RADIUS = 1000;
-export const calculateRadiusScaleFactor = measureData => {
+export const calculateRadiusScaleFactor = (measureData: MeasureData[]) => {
// Check if any of the radii in the dataset are larger than the max allowed
// radius, and scale everything down proportionally if so.
// (this needs to happen here instead of inside the circle marker component
// because it needs to operate on the dataset level, not the datapoint level)
const maxRadius = measureData
- .map(d => parseInt(d.radius, 10) || 1)
+ .map(d => parseInt(d.radius as string, 10) || 1)
.reduce((state, current) => Math.max(state, current), 0);
return maxRadius < MAX_ALLOWED_RADIUS ? 1 : (1 / maxRadius) * MAX_ALLOWED_RADIUS;
};
// Take a measureData array where the [key]: value is a number
// and filters NaN values (e.g. undefined).
-export function flattenNumericalMeasureData(measureData, key) {
+export function flattenNumericalMeasureData(measureData: MeasureData[], key: string) {
return measureData.map(v => parseFloat(v[key])).filter(x => !isNaN(x));
}
From 211337258d8619528a7f8fff33963c3e439e9fe5 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 13:54:36 +1200
Subject: [PATCH 049/251] WAITP-1259 Update type arrangement
---
.../src/components/AreaTooltip.tsx | 6 +-
.../src/components/InteractivePolygon.tsx | 20 +--
.../src/components/Legend/LegendEntry.tsx | 4 +-
.../src/components/Legend/MarkerLegend.tsx | 16 +--
.../src/components/Legend/SpectrumLegend.tsx | 16 +--
.../Markers/CircleProportionMarker.tsx | 2 +-
.../src/components/PopupDataItemList.tsx | 9 +-
.../src/components/Table/useMapDataExport.tsx | 4 +-
.../src/components/TilePicker/TileButton.tsx | 13 +-
.../src/components/TilePicker/TileControl.tsx | 2 +-
.../src/components/TilePicker/TilePicker.tsx | 5 +-
.../TilePicker/{constants.js => constants.ts} | 0
.../src/types/data-types.d.ts | 119 ------------------
.../ui-map-components/src/types/helpers.ts | 5 +
.../ui-map-components/src/types/index.d.ts | 5 +-
.../src/types/leaflet-config.d.ts | 8 ++
.../types/{legend-types.d.ts => legend.d.ts} | 13 +-
.../src/types/marker-types.d.ts | 13 --
.../src/types/react-leaflet-config.d.ts | 8 ++
.../ui-map-components/src/types/series.d.ts | 62 +++++++++
.../ui-map-components/src/types/types.d.ts | 66 +++++++++-
.../src/utils/markerColors.ts | 2 +-
.../src/utils/markerFormats.ts | 31 +++--
23 files changed, 224 insertions(+), 205 deletions(-)
rename packages/ui-map-components/src/components/TilePicker/{constants.js => constants.ts} (100%)
delete mode 100644 packages/ui-map-components/src/types/data-types.d.ts
rename packages/ui-map-components/src/types/{legend-types.d.ts => legend.d.ts} (50%)
delete mode 100644 packages/ui-map-components/src/types/marker-types.d.ts
create mode 100644 packages/ui-map-components/src/types/series.d.ts
diff --git a/packages/ui-map-components/src/components/AreaTooltip.tsx b/packages/ui-map-components/src/components/AreaTooltip.tsx
index d12c36e475..31ec52ce95 100644
--- a/packages/ui-map-components/src/components/AreaTooltip.tsx
+++ b/packages/ui-map-components/src/components/AreaTooltip.tsx
@@ -8,7 +8,7 @@ import React from 'react';
import { Tooltip } from 'react-leaflet';
import styled from 'styled-components';
import { PopupDataItemList } from './PopupDataItemList';
-import { GenericDataItem, Series } from '../types';
+import { MeasureData, Series } from '../types';
const Heading = styled.span<{
hasMeasureValue: boolean;
@@ -27,7 +27,7 @@ interface AreaTooltipProps {
orgUnitName?: string;
hasMeasureValue?: boolean;
serieses?: Series[];
- orgUnitMeasureData?: GenericDataItem;
+ orgUnitMeasureData?: MeasureData;
text?: string;
}
@@ -37,7 +37,7 @@ export const AreaTooltip = ({
orgUnitName,
hasMeasureValue = false,
serieses = [],
- orgUnitMeasureData = {},
+ orgUnitMeasureData = {} as MeasureData,
text,
}: AreaTooltipProps) => {
return (
diff --git a/packages/ui-map-components/src/components/InteractivePolygon.tsx b/packages/ui-map-components/src/components/InteractivePolygon.tsx
index 57760a5f4f..69ffbc2a55 100644
--- a/packages/ui-map-components/src/components/InteractivePolygon.tsx
+++ b/packages/ui-map-components/src/components/InteractivePolygon.tsx
@@ -9,7 +9,7 @@ import styled from 'styled-components';
import { AreaTooltip } from './AreaTooltip';
import { MAP_COLORS, BREWER_PALETTE } from '../constants';
import ActivePolygon from './ActivePolygon';
-import { Entity, GenericDataItem, MeasureOrgUnit, Series } from '../types';
+import { Color, Entity, GenericDataItem, MeasureData, OrgUnitCode, Series } from '../types';
const { POLYGON_BLUE, POLYGON_HIGHLIGHT } = MAP_COLORS;
@@ -39,19 +39,23 @@ const TransparentShadedPolygon = styled(Polygon)`
}
`;
+type OrgUnit = GenericDataItem & {
+ isHidden?: boolean;
+};
+
type ParsedPropsResult = {
- shade?: MeasureOrgUnit['color'];
+ shade?: Color;
isHidden?: boolean;
hasShadedChildren: boolean;
- orgUnitMeasureData?: MeasureOrgUnit;
+ orgUnitMeasureData?: OrgUnit;
orgUnitMultiOverlayMeasureData?: GenericDataItem;
};
const parseProps = (
- organisationUnitCode: string | undefined = undefined,
- organisationUnitChildren: GenericDataItem[],
- measureOrgUnits: MeasureOrgUnit[],
- multiOverlayMeasureData: GenericDataItem[],
+ organisationUnitCode: OrgUnitCode = undefined,
+ organisationUnitChildren: OrgUnit[],
+ measureOrgUnits: OrgUnit[],
+ multiOverlayMeasureData: MeasureData[],
): ParsedPropsResult => {
let shade;
let isHidden;
@@ -96,7 +100,7 @@ interface InteractivePolygonProps {
onChangeOrgUnit?: (organisationUnitCode?: string) => void;
area: Entity;
isActive?: boolean;
- measureOrgUnits?: MeasureOrgUnit[];
+ measureOrgUnits?: OrgUnit[];
organisationUnitChildren?: GenericDataItem[];
}
diff --git a/packages/ui-map-components/src/components/Legend/LegendEntry.tsx b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
index 6c10c2e62f..9212c56788 100644
--- a/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
+++ b/packages/ui-map-components/src/components/Legend/LegendEntry.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import styled from 'styled-components';
import MuiButton from '@material-ui/core/Button';
-import { LegendProps, DataValueType } from '../../types';
+import { LegendProps, Value } from '../../types';
const Button = styled(MuiButton)`
display: flex;
@@ -37,7 +37,7 @@ const Label = styled.div`
interface LegendEntryProps {
marker: React.ReactNode;
label: string;
- value: DataValueType;
+ value: Value;
dataKey?: string;
onClick?: LegendProps['setValueHidden'];
hiddenValues?: LegendProps['hiddenValues'];
diff --git a/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
index be00963bec..fab17bc81e 100644
--- a/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
+++ b/packages/ui-map-components/src/components/Legend/MarkerLegend.tsx
@@ -25,7 +25,7 @@ import {
MEASURE_VALUE_OTHER,
} from '../../utils';
import { LegendEntry } from './LegendEntry';
-import { DataValue, MarkerLegendProps, MarkerSeriesItem } from '../../types';
+import { SeriesValue, MarkerLegendProps, MarkerSeries, Value } from '../../types';
const Container = styled(MuiBox)`
display: flex;
@@ -46,15 +46,11 @@ const Container = styled(MuiBox)`
* and hide the radius as well. But, if the hidden icon is 'other', go ahead and add it to
* the legend and show the radius.
*/
-const isHiddenOtherIcon = ({ value, icon }: DataValue) => {
+const isHiddenOtherIcon = ({ value, icon }: SeriesValue) => {
return value === MEASURE_VALUE_OTHER && icon === HIDDEN_ICON;
};
-const getMarkerColor = (
- value: DataValue,
- type: MarkerSeriesItem['type'],
- hasColorLayer: boolean,
-) => {
+const getMarkerColor = (value: SeriesValue, type: MarkerSeries['type'], hasColorLayer: boolean) => {
const theme = useTheme();
if (type === MEASURE_TYPE_COLOR) {
@@ -71,8 +67,8 @@ const getMarkerColor = (
};
const getLegendMarkerForValue = (
- value: DataValue,
- type: MarkerSeriesItem['type'],
+ value: SeriesValue,
+ type: MarkerSeries['type'],
hasIconLayer: MarkerLegendProps['hasIconLayer'],
hasRadiusLayer: MarkerLegendProps['hasRadiusLayer'],
hasColorLayer: MarkerLegendProps['hasColorLayer'],
@@ -143,7 +139,7 @@ export const MarkerLegend = React.memo(
dataKey={dataKey}
marker={marker}
label={v.name}
- value={v.value}
+ value={v.value as Value}
hiddenValues={hiddenValues}
onClick={setValueHidden}
/>
diff --git a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
index 8a17cfe787..cd27e6d1c1 100644
--- a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
+++ b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
@@ -12,7 +12,7 @@ import { resolveSpectrumColour } from '../../utils';
import { LEGEND_SHADING_ICON, getMarkerForOption } from '../Markers/markerIcons';
import { SCALE_TYPES } from '../../constants';
import { LegendEntry } from './LegendEntry';
-import { ScaleType, SpectrumLegendProps, SpectrumSeriesItem } from '../../types';
+import { ScaleType, SpectrumLegendProps, SpectrumSeries, Value } from '../../types';
const FlexCenter = styled(MuiBox)`
display: flex;
@@ -49,7 +49,7 @@ const getSpectrumLabels = (
scaleType: ScaleType,
min: number,
max: number,
- valueType: string,
+ valueType?: SpectrumSeries['valueType'],
): {
left: string;
right: string;
@@ -70,13 +70,7 @@ const getSpectrumLabels = (
}
};
-const renderSpectrum = ({
- min,
- max,
- scaleType,
- scaleColorScheme,
- valueType,
-}: SpectrumSeriesItem) => {
+const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }: SpectrumSeries) => {
if (min == null || max == null) return null;
const spectrumDivs = [];
@@ -155,7 +149,7 @@ export const SpectrumLegend = React.memo(
scaleType,
scaleColorScheme,
valueType,
- } as SpectrumSeriesItem)}
+ } as SpectrumSeries)}
{noDataColour && (
)}
diff --git a/packages/ui-map-components/src/components/Markers/CircleProportionMarker.tsx b/packages/ui-map-components/src/components/Markers/CircleProportionMarker.tsx
index adb3802cca..66ee7af9a8 100644
--- a/packages/ui-map-components/src/components/Markers/CircleProportionMarker.tsx
+++ b/packages/ui-map-components/src/components/Markers/CircleProportionMarker.tsx
@@ -18,7 +18,7 @@ const HoverCircle = styled(CircleMarker)`
export const CircleProportionMarker = React.memo(
({ radius, children, coordinates, color }: MarkerProps) => {
- if (coordinates?.length !== 2) return null;
+ if ((coordinates as number[])?.length !== 2) return null;
const AREA_MULTIPLIER = 100; // just tuned by hand
const numberValue = parseFloat(String(radius)) || 0;
diff --git a/packages/ui-map-components/src/components/PopupDataItemList.tsx b/packages/ui-map-components/src/components/PopupDataItemList.tsx
index 126928a678..6b6a6c4fa2 100644
--- a/packages/ui-map-components/src/components/PopupDataItemList.tsx
+++ b/packages/ui-map-components/src/components/PopupDataItemList.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import { getFormattedInfo } from '../utils';
-import { Series } from '../types';
+import { Series, MeasureData } from '../types';
interface PopupDataItemProps {
measureName: Series['name'];
@@ -22,10 +22,13 @@ const PopupDataItem = ({ measureName, value }: PopupDataItemProps) => (
interface PopupDataItemListProps {
serieses: Series[];
- data?: object;
+ data?: MeasureData;
}
-export const PopupDataItemList = ({ serieses, data = {} }: PopupDataItemListProps) => {
+export const PopupDataItemList = ({
+ serieses,
+ data = {} as MeasureData,
+}: PopupDataItemListProps) => {
return (
<>
{serieses
diff --git a/packages/ui-map-components/src/components/Table/useMapDataExport.tsx b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
index b09575e865..fef3969166 100644
--- a/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
+++ b/packages/ui-map-components/src/components/Table/useMapDataExport.tsx
@@ -11,8 +11,8 @@ export const useMapDataExport = (
serieses: Series[],
measureData: MeasureData[],
title: string,
- startDate: string | Date,
- endDate: string | Date,
+ startDate: Series['startDate'],
+ endDate: Series['endDate'],
) => {
const { columns, data } = getMapTableData(serieses, measureData);
return useDataTableExport(columns, data, title, startDate, endDate);
diff --git a/packages/ui-map-components/src/components/TilePicker/TileButton.tsx b/packages/ui-map-components/src/components/TilePicker/TileButton.tsx
index cc567da2d0..d260a88a0e 100644
--- a/packages/ui-map-components/src/components/TilePicker/TileButton.tsx
+++ b/packages/ui-map-components/src/components/TilePicker/TileButton.tsx
@@ -6,10 +6,10 @@
import React from 'react';
import styled from 'styled-components';
-import { ReferenceTooltip } from '@tupaia/ui-components';
+import { ReferenceProps, ReferenceTooltip } from '@tupaia/ui-components';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
-import { TileSet } from '../../types';
+import { SeriesValue } from '../../types';
const StyledButton = styled(Button)`
position: relative;
@@ -79,6 +79,15 @@ const TileLabel = styled(Typography)`
padding: 0.5rem 0.75rem;
`;
+// Types for a tileset
+export type TileSet = {
+ key: string;
+ label: string;
+ thumbnail: string;
+ reference?: ReferenceProps;
+ legendItems?: SeriesValue[];
+};
+
interface TileButtonProps {
tileSet: TileSet;
isActive?: boolean;
diff --git a/packages/ui-map-components/src/components/TilePicker/TileControl.tsx b/packages/ui-map-components/src/components/TilePicker/TileControl.tsx
index 8f9f5771d0..ad05d92818 100644
--- a/packages/ui-map-components/src/components/TilePicker/TileControl.tsx
+++ b/packages/ui-map-components/src/components/TilePicker/TileControl.tsx
@@ -10,7 +10,7 @@ import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';
import Typography from '@material-ui/core/Typography';
import RightIcon from '@material-ui/icons/KeyboardArrowRight';
-import { TileSet } from '../../types';
+import { TileSet } from './TileButton';
const StyledButton = styled(Button)<{
active: string;
diff --git a/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx b/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
index f6b160a185..d4c57d90a5 100644
--- a/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
+++ b/packages/ui-map-components/src/components/TilePicker/TilePicker.tsx
@@ -5,13 +5,10 @@
import React, { useState } from 'react';
import styled from 'styled-components';
-import PropTypes from 'prop-types';
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
-import { TileButton } from './TileButton';
+import { TileButton, TileSet } from './TileButton';
import { TileControl } from './TileControl';
-import { tileSetShape } from './constants';
import { createScaleKeyFrameAnimation } from './keyFrames';
-import { TileSet } from '../../types';
const Container = styled.div`
height: 100%;
diff --git a/packages/ui-map-components/src/components/TilePicker/constants.js b/packages/ui-map-components/src/components/TilePicker/constants.ts
similarity index 100%
rename from packages/ui-map-components/src/components/TilePicker/constants.js
rename to packages/ui-map-components/src/components/TilePicker/constants.ts
diff --git a/packages/ui-map-components/src/types/data-types.d.ts b/packages/ui-map-components/src/types/data-types.d.ts
deleted file mode 100644
index 4a16fe028e..0000000000
--- a/packages/ui-map-components/src/types/data-types.d.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { PolygonProps } from 'react-leaflet';
-import { LatLngExpression, LatLngBoundsExpression } from 'leaflet';
-import { Entity as TupaiaEntity } from '@tupaia/types';
-import { ReferenceProps } from '@tupaia/ui-components';
-import { VALUE_TYPES } from '@tupaia/utils';
-import { MEASURE_TYPES, SCALE_TYPES } from '../constants';
-import { Color } from './types';
-import { MarkerProps } from './marker-types';
-import { DataValue } from './legend-types';
-import { ValueOf } from './helpers';
-
-const ValueTypes = { ...VALUE_TYPES } as const;
-
-type ValueTypesKeys = keyof typeof ValueTypes;
-type ValueTypeValues = typeof VALUE_TYPES[ValueTypesKeys];
-
-export type DataValueType = string | number | null | undefined;
-export type ScaleType = `${SCALE_TYPES}`;
-export type MeasureType = `${MEASURE_TYPES}`;
-
-export type DataValue = {
- value: DataValueType | DataValueType[];
- name: string;
- hideFromLegend?: boolean;
- icon?: IconKey;
- color: string;
- label?: string;
-};
-
-export type ValueMappingType = {
- null: DataValue;
- [key: string]: DataValue;
-};
-
-export type BaseSeriesItem = {
- name: string;
- key: string;
- values: DataValue[];
- valueMapping: ValueMappingType;
- hideFromLegend?: boolean;
- type: MeasureType;
- startDate?: string;
- endDate?: string;
- hideByDefault?: Record;
- displayedValueKey?: string;
- color: string;
- icon?: IconKey;
- radius?: number;
- scaleBounds?: {
- left: number;
- right: number;
- };
- hideFromPopup?: boolean;
- metadata: object;
- organisationUnit?: string;
- sortOrder: number;
- popupHeaderFormat?: string;
- valueType?: ValueTypeValues;
-};
-
-export type MarkerSeriesItem = BaseSeriesItem & {
- icon?: IconKey;
-};
-
-export type SpectrumSeriesItem = BaseSeriesItem & {
- scaleColorScheme: ColorScheme;
- min: number;
- max: number;
- scaleType: ScaleType;
- valueType: string;
- dataKey?: string;
- noDataColour?: string;
-};
-
-export type Series = MarkerSeriesItem & SpectrumSeriesItem;
-
-export type Location = {
- bounds: LatLngBoundsExpression;
- type?: string | null;
- point?: LatLngExpression;
- region: PolygonProps['positions'];
-};
-
-export type GenericDataItem = {
- [key: string]: any;
- organisationUnitCode?: string;
-};
-
-// Extend the base TupaiaEntity type with more details about the entity, including leaflet specific formatting
-export type Entity = TupaiaEntity &
- GenericDataItem & {
- region?: PolygonProps['positions'];
- location?: Location;
- };
-
-export type MeasureOrgUnit = GenericDataItem & {
- [key: string]: any;
- isHidden?: boolean;
- color?: Color;
-};
-
-export type MeasureData = MeasureOrgUnit &
- PolygonProps &
- MarkerProps &
- Entity & {
- coordinates?: PolygonProps['positions'];
- icon?: string;
- photoUrl?: string;
- value?: number | string;
- submissionDate?: string | Date;
- };
-
-export type TileSet = {
- key: string;
- label: string;
- thumbnail: string;
- reference?: ReferenceProps;
- legendItems?: DataValue[];
-};
diff --git a/packages/ui-map-components/src/types/helpers.ts b/packages/ui-map-components/src/types/helpers.ts
index 5f2cf2cf07..c9cbd71921 100644
--- a/packages/ui-map-components/src/types/helpers.ts
+++ b/packages/ui-map-components/src/types/helpers.ts
@@ -1 +1,6 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+
export type ValueOf = T[keyof T];
diff --git a/packages/ui-map-components/src/types/index.d.ts b/packages/ui-map-components/src/types/index.d.ts
index aae8f06e7b..d4141560ad 100644
--- a/packages/ui-map-components/src/types/index.d.ts
+++ b/packages/ui-map-components/src/types/index.d.ts
@@ -1,6 +1,5 @@
-export * from './data-types';
export * from './helpers';
export * from './leaflet-config';
-export * from './legend-types';
-export * from './marker-types';
+export * from './legend';
+export * from './series';
export * from './types';
diff --git a/packages/ui-map-components/src/types/leaflet-config.d.ts b/packages/ui-map-components/src/types/leaflet-config.d.ts
index 8ef609f7bd..02152179bd 100644
--- a/packages/ui-map-components/src/types/leaflet-config.d.ts
+++ b/packages/ui-map-components/src/types/leaflet-config.d.ts
@@ -1,5 +1,13 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+
import { Layer as LeafletLayer, LayerOptions as LeafletLayerOptions } from 'leaflet';
+/**
+ * Overrides to leaflet types to handle anything not covered by the built in types
+ */
declare module 'leaflet' {
export interface LayerOptions extends LeafletLayerOptions {
direction?: string;
diff --git a/packages/ui-map-components/src/types/legend-types.d.ts b/packages/ui-map-components/src/types/legend.d.ts
similarity index 50%
rename from packages/ui-map-components/src/types/legend-types.d.ts
rename to packages/ui-map-components/src/types/legend.d.ts
index a3d459ff28..d0b106c6d6 100644
--- a/packages/ui-map-components/src/types/legend-types.d.ts
+++ b/packages/ui-map-components/src/types/legend.d.ts
@@ -1,17 +1,22 @@
-import { DataValueType, MarkerSeriesItem, SpectrumSeriesItem } from './data-types';
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+
+import { MarkerSeries, SpectrumSeries, Value } from './series';
export type LegendProps = {
- setValueHidden: (dataKey?: string, value: DataValueType, hidden: boolean) => void;
+ setValueHidden: (dataKey?: string, value: Value, hidden: boolean) => void;
hiddenValues: Record>;
};
export type MarkerLegendProps = LegendProps & {
- series: MarkerSeriesItem;
+ series: MarkerSeries;
hasIconLayer: boolean;
hasRadiusLayer: boolean;
hasColorLayer: boolean;
};
export type SpectrumLegendProps = LegendProps & {
- series: SpectrumSeriesItem;
+ series: SpectrumSeries;
};
diff --git a/packages/ui-map-components/src/types/marker-types.d.ts b/packages/ui-map-components/src/types/marker-types.d.ts
deleted file mode 100644
index a951a5c4be..0000000000
--- a/packages/ui-map-components/src/types/marker-types.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ReactNode } from 'react';
-import { Color } from './types';
-import { IconKey } from '../components';
-
-export type MarkerProps = {
- radius?: number | string;
- color?: Color;
- children?: ReactNode;
- coordinates: [number, number];
- scale?: number;
- handleClick?: (e: any) => void;
- icon?: IconKey;
-};
diff --git a/packages/ui-map-components/src/types/react-leaflet-config.d.ts b/packages/ui-map-components/src/types/react-leaflet-config.d.ts
index 6e27b3d62a..a3950238fd 100644
--- a/packages/ui-map-components/src/types/react-leaflet-config.d.ts
+++ b/packages/ui-map-components/src/types/react-leaflet-config.d.ts
@@ -1,5 +1,13 @@
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+
import { MapContainerProps as ReactLeafletMapContainerProps } from 'react-leaflet';
+/**
+ * Overrides to react-leaflet types to handle anything not covered by the built in types
+ */
declare module 'react-leaflet' {
export interface MapContainerProps extends ReactLeafletMapContainerProps {
onClick?: (event: any) => void;
diff --git a/packages/ui-map-components/src/types/series.d.ts b/packages/ui-map-components/src/types/series.d.ts
new file mode 100644
index 0000000000..f30fa3d634
--- /dev/null
+++ b/packages/ui-map-components/src/types/series.d.ts
@@ -0,0 +1,62 @@
+import { VALUE_TYPES } from '@tupaia/utils';
+import { IconKey } from '../components';
+import { ColorScheme } from '../utils';
+import { MeasureType, OrgUnitCode, ScaleType } from './types';
+
+const ValueTypes = { ...VALUE_TYPES } as const;
+export type Value = string | number | null | undefined;
+
+export type SeriesValue = {
+ value: Value | Value[];
+ name: string;
+ hideFromLegend?: boolean;
+ icon?: IconKey;
+ color: string;
+ label?: string;
+ hideFromPopup?: boolean;
+};
+
+export type SeriesValueMapping = {
+ null: SeriesValue;
+ [key: string]: SeriesValue;
+};
+
+export type BaseSeries = {
+ name: string;
+ key: string;
+ values: SeriesValue[];
+ valueMapping: SeriesValueMapping;
+ hideFromLegend?: boolean;
+ type: MeasureType;
+ hideByDefault?: Record;
+ displayedValueKey?: string;
+ color: string;
+ radius?: number;
+ hideFromPopup?: boolean;
+ metadata: object;
+ organisationUnit?: OrgUnitCode;
+ sortOrder: number;
+ popupHeaderFormat?: string;
+ valueType?: ValueOf;
+ startDate: string;
+ endDate: string;
+};
+
+export type MarkerSeries = BaseSeries & {
+ icon?: IconKey;
+};
+
+export type SpectrumSeries = BaseSeries & {
+ scaleColorScheme: ColorScheme;
+ min: number;
+ max: number;
+ scaleType: ScaleType;
+ dataKey?: string;
+ noDataColour?: string;
+ scaleBounds?: {
+ left: number;
+ right: number;
+ };
+};
+
+export type Series = MarkerSeries & SpectrumSeries;
diff --git a/packages/ui-map-components/src/types/types.d.ts b/packages/ui-map-components/src/types/types.d.ts
index 3b3753ece7..73c590b6e1 100644
--- a/packages/ui-map-components/src/types/types.d.ts
+++ b/packages/ui-map-components/src/types/types.d.ts
@@ -1,5 +1,67 @@
-import { CssColor } from '@tupaia/types';
-import { BREWER_PALETTE } from '../constants';
+/*
+ * Tupaia
+ * Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
+ */
+
+import { CircleMarkerProps, PolygonProps } from 'react-leaflet';
+import { LatLngExpression, LatLngBoundsExpression } from 'leaflet';
+import { Entity as TupaiaEntity, CssColor } from '@tupaia/types';
+import { ReferenceProps } from '@tupaia/ui-components';
+import { VALUE_TYPES } from '@tupaia/utils';
+import { MEASURE_TYPES, SCALE_TYPES, BREWER_PALETTE } from '../constants';
+import { Color } from './types';
+import { MarkerProps } from './marker-types';
+import { DataValue } from './legend';
+import { ValueOf } from './helpers';
+import { ReactNode } from 'react';
+import { IconKey } from '../components';
export type ColorKey = keyof typeof BREWER_PALETTE;
export type Color = ColorKey | 'transparent' | CssColor;
+
+export type ScaleType = `${SCALE_TYPES}`;
+export type MeasureType = `${MEASURE_TYPES}`;
+export type OrgUnitCode = string | undefined;
+
+export type Location = {
+ bounds: LatLngBoundsExpression;
+ type?: string | null;
+ point?: LatLngExpression;
+ region: PolygonProps['positions'];
+};
+
+// A generic data item for anything that has an 'organisationUnitCode' property
+export type GenericDataItem = {
+ [key: string]: any;
+ organisationUnitCode: OrgUnitCode;
+};
+
+// Extend the base TupaiaEntity type with more details about the entity, including leaflet specific formatting
+export type Entity = TupaiaEntity &
+ GenericDataItem & {
+ region?: PolygonProps['positions'];
+ location?: Location;
+ };
+
+// Types for markers
+export type MarkerProps = {
+ radius?: number | string;
+ color?: Color;
+ children?: ReactNode;
+ coordinates: CircleMarkerProps['center'];
+ scale?: number;
+ handleClick?: (e: any) => void;
+ icon?: IconKey;
+};
+
+// Types for general measure data, with geometry
+export type MeasureData = Omit &
+ MarkerProps &
+ Entity & {
+ isHidden?: boolean;
+ icon?: string;
+ photoUrl?: string;
+ value?: number | string;
+ submissionDate?: string | Date;
+ positions?: PolygonProps['positions']; //allow this to be optional because of the loose types of measure data
+ };
diff --git a/packages/ui-map-components/src/utils/markerColors.ts b/packages/ui-map-components/src/utils/markerColors.ts
index 7e8b661f24..b136591851 100644
--- a/packages/ui-map-components/src/utils/markerColors.ts
+++ b/packages/ui-map-components/src/utils/markerColors.ts
@@ -35,7 +35,7 @@ const SCALE_TYPE_TO_COLOR_SCHEME = {
[SCALE_TYPES.GPI]: GPI_COLOR_SCHEME,
};
-type ColorScheme = keyof typeof COLOR_SCHEME_TO_FUNCTION;
+export type ColorScheme = keyof typeof COLOR_SCHEME_TO_FUNCTION;
/**
* Helper function just to point the spectrum type to the correct colours
diff --git a/packages/ui-map-components/src/utils/markerFormats.ts b/packages/ui-map-components/src/utils/markerFormats.ts
index 43ef95537d..6819f4f687 100644
--- a/packages/ui-map-components/src/utils/markerFormats.ts
+++ b/packages/ui-map-components/src/utils/markerFormats.ts
@@ -16,13 +16,13 @@ import {
} from '../constants';
import { SPECTRUM_ICON, DEFAULT_ICON, UNKNOWN_ICON } from '../components/Markers/markerIcons';
import {
- DataValue,
+ SeriesValue,
LegendProps,
MeasureData,
ScaleType,
Series,
- ValueMappingType,
- DataValueType,
+ SeriesValueMapping,
+ Value,
MeasureType,
} from '../types';
@@ -43,11 +43,11 @@ export const SPECTRUM_MEASURE_TYPES = [MEASURE_TYPE_SPECTRUM, MEASURE_TYPE_SHADE
const SPECTRUM_SCALE_DEFAULT = { left: {}, right: {} };
const PERCENTAGE_SPECTRUM_SCALE_DEFAULT = { left: { max: 0 }, right: { min: 1 } };
-export function autoAssignColors(values: DataValue[]) {
+export function autoAssignColors(values: SeriesValue[]) {
if (!values) return [];
let autoIndex = 0;
- const getColor = (valueObject: DataValue) => {
+ const getColor = (valueObject: SeriesValue) => {
if (!valueObject.name) {
return BREWER_AUTO[autoIndex++];
}
@@ -68,8 +68,8 @@ export function autoAssignColors(values: DataValue[]) {
}));
}
-export function createValueMapping(valueObjects: DataValue[], type: string) {
- const mapping = {} as ValueMappingType;
+export function createValueMapping(valueObjects: SeriesValue[], type: string) {
+ const mapping = {} as SeriesValueMapping;
valueObjects.forEach(valueObject => {
const { value } = valueObject;
@@ -98,7 +98,7 @@ const getNullValueMapping = (type: string) => {
const baseMapping = {
name: 'No data',
value: MEASURE_VALUE_NULL,
- } as DataValue;
+ } as SeriesValue;
switch (type) {
case MEASURE_TYPE_ICON:
@@ -116,12 +116,12 @@ const getNullValueMapping = (type: string) => {
};
function getFormattedValue(
- value: DataValueType,
+ value: Value,
type: MeasureType,
- valueInfo: DataValue,
+ valueInfo: SeriesValue,
scaleType: ScaleType,
valueType: Series['valueType'],
- submissionDate: string,
+ submissionDate: MeasureData['submissionDate'],
) {
switch (type) {
case MEASURE_TYPE_SPECTRUM:
@@ -258,7 +258,7 @@ const getIsHidden = (
})
.some(isHidden => isHidden);
-function getValueInfo(value: DataValueType, valueMapping: ValueMappingType) {
+function getValueInfo(value: Value, valueMapping: SeriesValueMapping) {
// use 'no data' value if value is null and there is a null mapping defined
if (!value && typeof value !== 'number' && valueMapping.null) {
return {
@@ -280,13 +280,12 @@ function getValueInfo(value: DataValueType, valueMapping: ValueMappingType) {
...matchedValue,
};
}
-type MarkerData = Record;
// For situations where we can only show one value, just show the value
// of the first measure.
-export const getSingleFormattedValue = (markerData: MarkerData, series: Series[]) =>
+export const getSingleFormattedValue = (markerData: MeasureData, series: Series[]) =>
getFormattedInfo(markerData, series[0]).formattedValue;
-export function getFormattedInfo(markerData: MarkerData, series: Series) {
+export function getFormattedInfo(markerData: MeasureData, series: Series) {
const { key, valueMapping, type, displayedValueKey, scaleType, valueType } = series;
const value = markerData[key];
const valueInfo = getValueInfo(value, valueMapping);
@@ -333,7 +332,7 @@ export function getMeasureDisplayInfo(
icon?: string;
radius?: number;
isHidden: boolean;
- originalValue?: DataValue['value'];
+ originalValue?: SeriesValue['value'];
};
serieses.forEach(({ color, icon, radius }: Series) => {
From 280fb4e83e3df5a50c1fb495a077011e51629f0a Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 13:56:38 +1200
Subject: [PATCH 050/251] WAITP-1259 remove ts-ignores
---
.../src/components/InteractivePolygon.tsx | 14 ++++++++++----
.../src/components/Legend/SpectrumLegend.tsx | 3 ---
.../ui-map-components/src/utils/markerFormats.ts | 6 ++----
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/packages/ui-map-components/src/components/InteractivePolygon.tsx b/packages/ui-map-components/src/components/InteractivePolygon.tsx
index 69ffbc2a55..44ca465b3a 100644
--- a/packages/ui-map-components/src/components/InteractivePolygon.tsx
+++ b/packages/ui-map-components/src/components/InteractivePolygon.tsx
@@ -9,7 +9,15 @@ import styled from 'styled-components';
import { AreaTooltip } from './AreaTooltip';
import { MAP_COLORS, BREWER_PALETTE } from '../constants';
import ActivePolygon from './ActivePolygon';
-import { Color, Entity, GenericDataItem, MeasureData, OrgUnitCode, Series } from '../types';
+import {
+ Color,
+ ColorKey,
+ Entity,
+ GenericDataItem,
+ MeasureData,
+ OrgUnitCode,
+ Series,
+} from '../types';
const { POLYGON_BLUE, POLYGON_HIGHLIGHT } = MAP_COLORS;
@@ -187,9 +195,7 @@ export const InteractivePolygon = React.memo(
}
// To match with the color in markerIcon.js which uses BREWER_PALETTE
- // @ts-ignore - because technically shade can be a string that is not in the BREWER_PALETTE, so TS throws an error about type not being able to be an index
-
- const color = BREWER_PALETTE[shade] || shade;
+ const color = BREWER_PALETTE[shade as ColorKey] || shade;
// Work around: color should go through the styled components
// but there is a rendering bug between Styled Components + Leaflet
diff --git a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
index cd27e6d1c1..a9cad99b9e 100644
--- a/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
+++ b/packages/ui-map-components/src/components/Legend/SpectrumLegend.tsx
@@ -78,7 +78,6 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }: Sp
if (min === max) {
// There will only be a single value displayed, let's just default it to the middle color (50 % of the way from 0 to 1):
- // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, 0.5, 0, 1);
const { left: label } = getSpectrumLabels(scaleType, min, min, valueType);
@@ -95,7 +94,6 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }: Sp
switch (scaleType) {
case SCALE_TYPES.TIME:
for (let i = 0; i < 1; i += 0.01) {
- // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, i, min, max);
spectrumDivs.push();
}
@@ -108,7 +106,6 @@ const renderSpectrum = ({ min, max, scaleType, scaleColorScheme, valueType }: Sp
const increment = (max - min) / 100;
for (let i = min; i < max; i += increment) {
- // @ts-ignore
const colour = resolveSpectrumColour(scaleType, scaleColorScheme, i, min, max);
spectrumDivs.push();
}
diff --git a/packages/ui-map-components/src/utils/markerFormats.ts b/packages/ui-map-components/src/utils/markerFormats.ts
index 6819f4f687..f9acc23fdb 100644
--- a/packages/ui-map-components/src/utils/markerFormats.ts
+++ b/packages/ui-map-components/src/utils/markerFormats.ts
@@ -76,12 +76,10 @@ export function createValueMapping(valueObjects: SeriesValue[], type: string) {
if (Array.isArray(value)) {
value.forEach(v => {
- // @ts-ignore TODO: fix this
- mapping[v] = valueObject;
+ mapping[v as string] = valueObject;
});
} else {
- // @ts-ignore TODO: fix this
- mapping[value] = valueObject;
+ mapping[value as string] = valueObject;
}
});
From 42181ee244168db561317abf4df02d7db2f4b626 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 13:58:49 +1200
Subject: [PATCH 051/251] WAITP-1259 handle default value
---
packages/ui-map-components/src/utils/markerFormats.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/ui-map-components/src/utils/markerFormats.ts b/packages/ui-map-components/src/utils/markerFormats.ts
index f9acc23fdb..f893065a03 100644
--- a/packages/ui-map-components/src/utils/markerFormats.ts
+++ b/packages/ui-map-components/src/utils/markerFormats.ts
@@ -317,7 +317,7 @@ export function getFormattedInfo(markerData: MeasureData, series: Series) {
}
export function getMeasureDisplayInfo(
- measureData: MeasureData, // TODO: handle default becaus eof required `positions` prop
+ measureData: MeasureData = {},
serieses: Series[],
hiddenValues: LegendProps['hiddenValues'] = {},
radiusScaleFactor: number = 1,
From 7362e8254804dd6365092af7cd431004f3e58092 Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 14:05:20 +1200
Subject: [PATCH 052/251] WAITP-1259 Update storybook config
---
packages/ui-map-components/.storybook/main.js | 3 +++
packages/ui-map-components/package.json | 3 ++-
yarn.lock | 1 +
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/packages/ui-map-components/.storybook/main.js b/packages/ui-map-components/.storybook/main.js
index e731ebcce9..e32f7873ab 100644
--- a/packages/ui-map-components/.storybook/main.js
+++ b/packages/ui-map-components/.storybook/main.js
@@ -2,4 +2,7 @@
module.exports = {
stories: ['../stories/**/*.stories.js'],
addons: ['@storybook/addon-essentials'],
+ typescript: {
+ reactDocgen: 'react-docgen-typescript-plugin',
+ },
};
diff --git a/packages/ui-map-components/package.json b/packages/ui-map-components/package.json
index cda2e8c15b..f9a3db80ea 100644
--- a/packages/ui-map-components/package.json
+++ b/packages/ui-map-components/package.json
@@ -43,6 +43,7 @@
"@types/jest": "^29.5.1",
"@types/leaflet": "^1.7.1",
"@types/react-dom": "^16.9.18",
- "@types/styled-components": "^5.1.26"
+ "@types/styled-components": "^5.1.26",
+ "react-docgen-typescript-plugin": "^1.0.5"
}
}
diff --git a/yarn.lock b/yarn.lock
index 96a339fa5e..8e779e71dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5896,6 +5896,7 @@ __metadata:
moment: ^2.29.1
prop-types: ^15.7.2
react: ^16.13.1
+ react-docgen-typescript-plugin: ^1.0.5
react-dom: ^16.13.1
react-leaflet: ^3.2.1
react-table: ^7.7.0
From e31052bc2ad146e747385d5b7e2f96dff097453f Mon Sep 17 00:00:00 2001
From: acdunham
Date: Mon, 29 May 2023 14:21:42 +1200
Subject: [PATCH 053/251] Revert commit 'merge epic-landing-pages into
waitp-1259-map-components-ts'
---
.dockerignore | 1 -
README.md | 87 +----
packages/access-policy/README.md | 2 +-
packages/admin-panel-server/README.md | 2 +-
packages/admin-panel/README.md | 15 +-
packages/admin-panel/src/editor/EditModal.js | 4 +-
packages/admin-panel/src/editor/Editor.js | 116 ++----
packages/admin-panel/src/editor/actions.js | 18 +-
packages/admin-panel/src/editor/constants.js | 2 -
packages/admin-panel/src/pages/ProfilePage.js | 16 +-
.../pages/resources/CustomLandingPagesPage.js | 301 ---------------
.../src/pages/resources/ProjectsPage.js | 34 +-
.../src/pages/resources/ResourcePage.js | 4 +-
.../admin-panel/src/pages/resources/index.js | 1 -
packages/admin-panel/src/routes.js | 6 -
.../admin-panel/src/utilities/getFields.js | 14 -
packages/admin-panel/src/utilities/index.js | 1 -
.../src/widgets/InputField/InputField.js | 2 +-
.../widgets/InputField/registerInputFields.js | 105 ------
packages/aggregator/README.md | 2 +-
packages/api-client/README.md | 6 +-
packages/auth/README.md | 2 +-
packages/central-server/README.md | 21 +-
.../doc/importingNewGeojson.md | 0
.../src/apiV2/{projects => }/GETProjects.js | 7 +-
packages/central-server/src/apiV2/index.js | 11 +-
.../apiV2/landingPages/CreateLandingPage.js | 58 ---
.../src/apiV2/landingPages/EditLandingPage.js | 52 ---
.../src/apiV2/landingPages/index.js | 7 -
.../src/apiV2/projects/CreateProject.js | 46 +--
.../src/apiV2/projects/EditProject.js | 56 ---
.../src/apiV2/projects/index.js | 2 -
.../constructNewRecordValidationRules.js | 31 --
.../src/apiV2/utilities/index.js | 1 -
.../src/apiV2/utilities/uploadImage.js | 43 ---
.../landingPages/CreateLandingPage.test.js | 114 ------
.../landingPages/EditLandingPage.test.js | 127 -------
.../apiV2/projects/CreateProject.test.js | 63 ++--
.../tests/apiV2/projects/EditProject.test.js | 136 -------
.../tests/apiV2/projects/GETProjects.test.js | 171 ---------
.../submitMeditrakSurveyResponse.test.js | 2 +-
.../tests/apiV2/utilities/uploadImage.test.js | 66 ----
.../src/tests/testData/testImageData.js | 2 +-
.../getStandardisedImageName.test.js | 12 -
.../src/utilities/getStandardisedImageName.js | 8 -
.../central-server/src/utilities/index.js | 1 -
packages/data-api/README.md | 2 +-
packages/data-broker/README.md | 18 +-
packages/data-lake-api/README.md | 2 +-
packages/data-table-server/README.md | 2 +-
packages/database/README.md | 2 +-
...ddTablesForLandingPages-modifies-schema.js | 45 ---
.../database/src/modelClasses/LandingPage.js | 18 -
packages/database/src/modelClasses/index.js | 2 -
packages/database/src/types.js | 1 -
packages/devops/README.md | 4 +-
packages/devops/ci/tupaia-ci-cd.Dockerfile | 2 +-
packages/devops/ci/validation.Dockerfile | 2 +-
packages/devops/docker/downloadenv.Dockerfile | 13 -
.../deployment/buildDeployablePackages.sh | 2 +-
packages/dhis-api/README.md | 2 +-
packages/e2e/README.md | 2 +-
packages/entity-server/README.md | 15 +-
packages/indicators/README.md | 4 +-
packages/kobo-api/README.md | 3 -
packages/lesmis-server/README.md | 2 +-
packages/lesmis/README.md | 9 +-
packages/meditrak-app-server/README.md | 2 +-
.../sync/PushChangesRoute.test.ts | 2 +-
.../__integration__/sync/testImageData.ts | 2 +-
packages/meditrak-app/README.md | 2 +-
packages/meditrak-app/appcenter-post-clone.sh | 2 +-
packages/psss-server/README.md | 2 +-
packages/psss/README.md | 4 +-
.../psss/src/views/Tabs/ProfileTabView.js | 16 +-
packages/report-server/README.md | 12 +-
packages/superset-api/README.md | 3 -
packages/tsutils/README.md | 3 -
packages/types/README.md | 11 +-
.../.storybook/AppProviders.js | 2 +-
.../ui-chart-components/.storybook/main.js | 2 +-
packages/ui-chart-components/package.json | 8 +-
.../{VerticalTick.tsx => VerticalTick.js} | 0
.../components/Axes/{XAxis.tsx => XAxis.js} | 0
.../components/Axes/{YAxes.tsx => YAxes.js} | 0
.../components/Axes/{index.ts => index.js} | 0
.../{CartesianChart.tsx => CartesianChart.js} | 0
.../src/components/{Chart.tsx => Chart.js} | 0
.../{ChartTable.tsx => ChartTable.js} | 0
.../Charts/{AreaChart.tsx => AreaChart.js} | 0
.../Charts/{BarChart.tsx => BarChart.js} | 0
.../Charts/{GaugeChart.tsx => GaugeChart.js} | 0
.../Charts/{LineChart.tsx => LineChart.js} | 0
.../Charts/{PieChart.tsx => PieChart.js} | 0
.../components/Charts/{index.ts => index.js} | 0
.../{ChartTooltip.tsx => ChartTooltip.js} | 0
.../Reference/{Legend.tsx => Legend.js} | 0
.../{ReferenceLabel.tsx => ReferenceLabel.js} | 0
.../{ReferenceLines.tsx => ReferenceLines.js} | 0
...oltipContainer.tsx => TooltipContainer.js} | 0
.../Reference/{index.ts => index.js} | 0
.../src/components/{index.ts => index.js} | 0
.../src/constants/{colors.ts => colors.js} | 0
.../constants/{constants.ts => constants.js} | 0
.../src/constants/{index.ts => index.js} | 0
.../constants/{propTypes.ts => propTypes.js} | 0
.../src/{index.ts => index.js} | 0
...ChartTableData.ts => getChartTableData.js} | 0
.../src/utils/{index.ts => index.js} | 0
...arseChartConfig.ts => parseChartConfig.js} | 0
...artDataExport.ts => useChartDataExport.js} | 0
.../src/utils/{utils.ts => utils.js} | 0
.../ui-chart-components/tsconfig-build.json | 14 -
packages/ui-chart-components/tsconfig.json | 24 --
.../src/components/CheckboxList.tsx | 233 ++++++------
.../src/components/ConfirmDeleteModal.tsx | 2 +-
.../ui-components/src/components/Dialog.tsx | 10 +-
.../src/components/Inputs/Autocomplete.tsx | 3 -
.../src/components/Inputs/Checkbox.tsx | 10 +-
.../src/components/Inputs/FileUploadField.tsx | 40 +-
.../src/components/Inputs/GroupedSelect.tsx | 14 +-
.../src/components/Inputs/HexcodeField.tsx | 82 ----
.../components/Inputs/ImageUploadField.tsx | 211 -----------
.../src/components/Inputs/InputGroup.tsx | 51 ---
.../src/components/Inputs/InputLabel.tsx | 73 ----
.../components/Inputs/ProfileImageField.tsx | 117 ++++++
.../src/components/Inputs/RadioGroup.tsx | 38 +-
.../src/components/Inputs/Select.tsx | 4 +-
.../src/components/Inputs/TextField.tsx | 26 +-
.../src/components/Inputs/index.ts | 5 +-
.../stories/inputs/autocomplete.stories.js | 12 -
.../stories/inputs/checkbox.stories.js | 5 -
.../stories/inputs/checkboxList.stories.js | 7 +-
.../stories/inputs/datePicker.stories.js | 12 -
.../stories/inputs/fileUploadField.stories.js | 18 -
.../stories/inputs/groupedSelect.stories.js | 11 -
.../stories/inputs/hexcodeField.stories.js | 84 -----
.../inputs/imageUploadField.stories.js | 59 ---
.../stories/inputs/inputGroup.stories.js | 72 ----
.../stories/inputs/inputLabel.stories.js | 29 --
.../stories/inputs/multiSelect.stories.js | 17 -
.../inputs/profileImageField.stories.js | 25 ++
.../stories/inputs/radioGroup.stories.js | 18 -
.../stories/inputs/select.stories.js | 13 -
.../stories/inputs/textField.stories.js | 1 -
packages/utils/README.md | 2 +-
.../validation/validatorFunctions.test.js | 56 ---
packages/utils/src/s3/S3Client.js | 61 +--
.../src/validation/validatorFunctions.js | 33 +-
packages/weather-api/README.md | 3 -
packages/web-config-server/README.md | 12 +-
packages/web-config-server/src/apiV1/index.js | 2 -
.../src/apiV1/landingPages.js | 76 ----
.../src/apiV1/measureData.js | 5 +-
packages/web-frontend/README.md | 12 +-
.../images/custom-landing-page-default.png | Bin 398369 -> 0 bytes
packages/web-frontend/public/index.html | 19 +-
packages/web-frontend/src/actions.js | 24 --
.../web-frontend/src/components/Buttons.js | 5 +-
.../src/components/mobile/Overlay/index.js | 1 +
.../web-frontend/src/constants/constants.js | 6 -
.../src/containers/DashboardExportModal.js | 93 ++---
.../components/LandingPage/LoginPage.js | 72 ++--
.../components/LandingPage/index.js | 15 +-
.../components/ProjectPage/ProjectCard.js | 60 ++-
.../components/ProjectPage/ProjectCardList.js | 112 ------
.../components/ProjectPage/index.js | 61 ++-
.../components/RequestProjectAccessDialog.js | 108 +++---
.../src/containers/OverlayDiv/constants.js | 4 -
.../src/containers/OverlayDiv/index.js | 3 +-
.../src/containers/TopBar/index.js | 73 ++--
.../src/containers/TopBarLogo/index.js | 112 ------
.../src/containers/TupaiaHome/index.js | 56 +++
.../src/containers/UserBar/index.js | 62 ++-
.../src/containers/UserMenu/DrawerMenu.js | 129 -------
.../src/containers/UserMenu/MenuList.js | 89 -----
.../src/containers/UserMenu/PopoverMenu.js | 42 ---
.../src/containers/UserMenu/UserInfo.js | 80 ----
.../src/containers/UserMenu/index.js | 355 ++++++++++--------
packages/web-frontend/src/projects/actions.js | 7 -
.../web-frontend/src/projects/reducers.js | 32 +-
packages/web-frontend/src/projects/sagas.js | 46 +--
packages/web-frontend/src/reducers.js | 9 +-
.../src/reducers/orgUnitReducers.js | 2 -
.../sagas/watchUser/watchAttemptUserLogout.js | 23 +-
.../sagas/watchUser/watchFetchInitialData.js | 19 +-
.../src/screens/LandingPage/LandingPage.js | 73 ----
.../screens/LandingPage/LandingPageFooter.js | 159 --------
.../LandingPage/MultiProjectLandingPage.js | 96 -----
.../LandingPage/SingleProjectLandingPage.js | 105 ------
.../src/screens/LandingPage/index.js | 6 -
.../src/screens/LandingPage/useAuth.js | 10 -
.../LandingPage/useCustomLandingPages.js | 36 --
.../src/screens/LandingPage/useNavigation.js | 47 ---
.../src/screens/LoadingScreen/index.js | 40 +-
.../screens/desktop/RootScreen/MainPage.js | 50 +--
.../desktop/RootScreen/PDFExportPage.js | 10 +-
.../src/screens/mobile/RootScreen/index.js | 8 +-
packages/web-frontend/src/styles/index.js | 19 +-
.../src/utils/getProjectAccessType.js | 13 -
packages/web-frontend/src/utils/index.js | 1 -
packages/web-frontend/src/utils/request.js | 4 +-
scripts/bash/downloadEnvironmentVariables.sh | 4 +-
.../docker/downloadEnvironmentVariables.sh | 70 ----
tupaia-packages.code-workspace | 4 -
yarn.lock | 38 --
206 files changed, 1123 insertions(+), 4994 deletions(-)
delete mode 100644 packages/admin-panel/src/pages/resources/CustomLandingPagesPage.js
delete mode 100644 packages/admin-panel/src/utilities/getFields.js
rename packages/{admin-panel => central-server}/doc/importingNewGeojson.md (100%)
rename packages/central-server/src/apiV2/{projects => }/GETProjects.js (95%)
delete mode 100644 packages/central-server/src/apiV2/landingPages/CreateLandingPage.js
delete mode 100644 packages/central-server/src/apiV2/landingPages/EditLandingPage.js
delete mode 100644 packages/central-server/src/apiV2/landingPages/index.js
delete mode 100644 packages/central-server/src/apiV2/projects/EditProject.js
delete mode 100644 packages/central-server/src/apiV2/utilities/uploadImage.js
delete mode 100644 packages/central-server/src/tests/apiV2/landingPages/CreateLandingPage.test.js
delete mode 100644 packages/central-server/src/tests/apiV2/landingPages/EditLandingPage.test.js
delete mode 100644 packages/central-server/src/tests/apiV2/projects/EditProject.test.js
delete mode 100644 packages/central-server/src/tests/apiV2/projects/GETProjects.test.js
delete mode 100644 packages/central-server/src/tests/apiV2/utilities/uploadImage.test.js
delete mode 100644 packages/central-server/src/tests/utilities/getStandardisedImageName.test.js
delete mode 100644 packages/central-server/src/utilities/getStandardisedImageName.js
delete mode 100644 packages/database/src/migrations/20230430221850-AddTablesForLandingPages-modifies-schema.js
delete mode 100644 packages/database/src/modelClasses/LandingPage.js
delete mode 100644 packages/devops/docker/downloadenv.Dockerfile
delete mode 100644 packages/kobo-api/README.md
delete mode 100644 packages/superset-api/README.md
delete mode 100644 packages/tsutils/README.md
rename packages/ui-chart-components/src/components/Axes/{VerticalTick.tsx => VerticalTick.js} (100%)
rename packages/ui-chart-components/src/components/Axes/{XAxis.tsx => XAxis.js} (100%)
rename packages/ui-chart-components/src/components/Axes/{YAxes.tsx => YAxes.js} (100%)
rename packages/ui-chart-components/src/components/Axes/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/components/{CartesianChart.tsx => CartesianChart.js} (100%)
rename packages/ui-chart-components/src/components/{Chart.tsx => Chart.js} (100%)
rename packages/ui-chart-components/src/components/{ChartTable.tsx => ChartTable.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{AreaChart.tsx => AreaChart.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{BarChart.tsx => BarChart.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{GaugeChart.tsx => GaugeChart.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{LineChart.tsx => LineChart.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{PieChart.tsx => PieChart.js} (100%)
rename packages/ui-chart-components/src/components/Charts/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{ChartTooltip.tsx => ChartTooltip.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{Legend.tsx => Legend.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{ReferenceLabel.tsx => ReferenceLabel.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{ReferenceLines.tsx => ReferenceLines.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{TooltipContainer.tsx => TooltipContainer.js} (100%)
rename packages/ui-chart-components/src/components/Reference/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/components/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/constants/{colors.ts => colors.js} (100%)
rename packages/ui-chart-components/src/constants/{constants.ts => constants.js} (100%)
rename packages/ui-chart-components/src/constants/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/constants/{propTypes.ts => propTypes.js} (100%)
rename packages/ui-chart-components/src/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/utils/{getChartTableData.ts => getChartTableData.js} (100%)
rename packages/ui-chart-components/src/utils/{index.ts => index.js} (100%)
rename packages/ui-chart-components/src/utils/{parseChartConfig.ts => parseChartConfig.js} (100%)
rename packages/ui-chart-components/src/utils/{useChartDataExport.ts => useChartDataExport.js} (100%)
rename packages/ui-chart-components/src/utils/{utils.ts => utils.js} (100%)
delete mode 100644 packages/ui-chart-components/tsconfig-build.json
delete mode 100644 packages/ui-chart-components/tsconfig.json
delete mode 100644 packages/ui-components/src/components/Inputs/HexcodeField.tsx
delete mode 100644 packages/ui-components/src/components/Inputs/ImageUploadField.tsx
delete mode 100644 packages/ui-components/src/components/Inputs/InputGroup.tsx
delete mode 100644 packages/ui-components/src/components/Inputs/InputLabel.tsx
create mode 100644 packages/ui-components/src/components/Inputs/ProfileImageField.tsx
delete mode 100644 packages/ui-components/stories/inputs/hexcodeField.stories.js
delete mode 100644 packages/ui-components/stories/inputs/imageUploadField.stories.js
delete mode 100644 packages/ui-components/stories/inputs/inputGroup.stories.js
delete mode 100644 packages/ui-components/stories/inputs/inputLabel.stories.js
create mode 100644 packages/ui-components/stories/inputs/profileImageField.stories.js
delete mode 100644 packages/weather-api/README.md
delete mode 100644 packages/web-config-server/src/apiV1/landingPages.js
delete mode 100644 packages/web-frontend/public/images/custom-landing-page-default.png
delete mode 100644 packages/web-frontend/src/containers/OverlayDiv/components/ProjectPage/ProjectCardList.js
delete mode 100644 packages/web-frontend/src/containers/TopBarLogo/index.js
create mode 100644 packages/web-frontend/src/containers/TupaiaHome/index.js
delete mode 100644 packages/web-frontend/src/containers/UserMenu/DrawerMenu.js
delete mode 100644 packages/web-frontend/src/containers/UserMenu/MenuList.js
delete mode 100644 packages/web-frontend/src/containers/UserMenu/PopoverMenu.js
delete mode 100644 packages/web-frontend/src/containers/UserMenu/UserInfo.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/LandingPage.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/LandingPageFooter.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/MultiProjectLandingPage.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/SingleProjectLandingPage.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/index.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/useAuth.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/useCustomLandingPages.js
delete mode 100644 packages/web-frontend/src/screens/LandingPage/useNavigation.js
delete mode 100644 packages/web-frontend/src/utils/getProjectAccessType.js
delete mode 100755 scripts/docker/downloadEnvironmentVariables.sh
diff --git a/.dockerignore b/.dockerignore
index f795eab19a..dc516fa295 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -22,7 +22,6 @@ dump.sql
/snapshots.js
.idea
packages/.vscode/settings.json
-packages/devops/docker
**/testRequests/*.http
*:Zone.Identifier
diff --git a/README.md b/README.md
index 9b962651b4..e71634579c 100644
--- a/README.md
+++ b/README.md
@@ -2,105 +2,52 @@
[![Codeship Status for beyondessential/tupaia#dev](https://app.codeship.com/projects/70159bc0-0dac-0138-fdcb-260b82737f4e/status?branch=dev)](https://app.codeship.com/projects/379708)
-## Open Source Info
-
-### Open Source Mission statement
-
-> By engaging and collaborating with our community we can deliver a more robust product that bridges cultural differences and empowers decision making within health systems worldwide.
-
-### Code of Conduct
-
-For contributor's code of conduct - see the [code-of-conduct.md](https://gitlab.com/beyond-essential/tupaia/blob/master/code-of-conduct.md) published in the repo.
-
-## Packages
-
> This is a [mono-repo](https://github.com/babel/babel/blob/master/doc/design/monorepo.md)
It is set up using `yarn workspaces`, meaning any command you would normally run inside a package can
be run from the root directory using `yarn workspace @tupaia/package-name command`, e.g.
`yarn workspace @tupaia/central-server start-dev`
+## Packages
+
The easiest way to open the packages in vscode is to double click 'tupaia-packages.code-workspace'.
This opens all packages as roots in the workspace, and means linting etc. will work correctly.
-### Package structure
-
-The Tupaia mono-repo is comprised for 3 types of packages:
-
-- Platform interfaces (Frontend React applications that the user interacts with)
-- Servers
- - Orchestration servers (dedicated backend applications for each platform interface)
- - Micro servers (applications which are used by the orchestration servers to perform common system functions)
-- Libraries (various utility and common libraries that are used throughout the mono-repo)
-
-While each package type has their own structure, there are a few common standards:
-
-- `/package.json` - package definition
-- `/src/` - contains source code
-- `/.env.example` - file showing what environment variables are required by the package
-- `/.env` - environment variables used by package (ignored in git)
-- `/src/__tests__/` - contains unit tests
-
-### Platform interfaces
+### Main packages
-- [Tupaia](https://github.com/beyondessential/tupaia/blob/dev/packages/web-frontend/README.md) (for legacy reasons referred to as web-frontend)
-- [Admin Panel](https://github.com/beyondessential/tupaia/blob/dev/packages/admin-panel/README.md)
-- [LESMIS](https://github.com/beyondessential/tupaia/blob/dev/packages/lesmis/README.md)
-- [PSSS](https://github.com/beyondessential/tupaia/blob/dev/packages/psss/README.md)
-- [Meditrak](https://github.com/beyondessential/tupaia/blob/dev/packages/meditrak-app/README.md)
-
-### Servers
-
-#### Orchestration servers
-
-- [web-config-server](https://github.com/beyondessential/tupaia/blob/dev/packages/web-config-server/README.md) (Tupaia's orchestration server, referred to as web-config-server for legacy reasons)
+- [admin-panel](https://github.com/beyondessential/tupaia/blob/dev/packages/admin-panel/README.md)
- [admin-panel-server](https://github.com/beyondessential/tupaia/blob/dev/packages/admin-panel-server/README.md)
+- [central-server](https://github.com/beyondessential/tupaia/blob/dev/packages/central-server/README.md)
+- [lesmis](https://github.com/beyondessential/tupaia/blob/dev/packages/lesmis/README.md)
- [lesmis-server](https://github.com/beyondessential/tupaia/blob/dev/packages/lesmis-server/README.md)
-- [psss-server](https://github.com/beyondessential/tupaia/blob/dev/packages/psss-server/README.md)
+- [meditrak-app](https://github.com/beyondessential/tupaia/blob/dev/packages/meditrak-app/README.md)
- [meditrak-app-server](https://github.com/beyondessential/tupaia/blob/dev/packages/meditrak-app-server/README.md)
+- [psss](https://github.com/beyondessential/tupaia/blob/dev/packages/psss/README.md)
+- [psss-server](https://github.com/beyondessential/tupaia/blob/dev/packages/psss-server/README.md)
+- [web-config-server](https://github.com/beyondessential/tupaia/blob/dev/packages/web-config-server/README.md)
+- [web-frontend](https://github.com/beyondessential/tupaia/blob/dev/packages/web-frontend/README.md)
-#### Micro servers
-
-- [central-server](https://github.com/beyondessential/tupaia/blob/dev/packages/central-server/README.md)
-- [entity-server](https://github.com/beyondessential/tupaia/blob/dev/packages/entity-server/README.md)
-- [report-server](https://github.com/beyondessential/tupaia/blob/dev/packages/report-server/README.md)
-- [data-table-server](https://github.com/beyondessential/tupaia/blob/dev/packages/data-table-server/README.md)
-
-Server packages can be built by running `yarn workspace @tupaia/package-name build`.
-Server packages can then be started by running `yarn workspace @tupaia/package-name start`.
-
-All servers are NodeJS express applications, and the packages follow the same basic structure:
-
-- `/examples.http` - example queries showing the server interface
-- `/src/index.ts` - server entrypoint
-- `/src/app/createApp.ts` - express router definition
-- `/src/routes/` - route definitions
+Any of the main packages can be run using `yarn workspace @tupaia/package-name start-dev`.
+In the case of the two servers, this will also build and watch all of the internal dependencies, so
+that hot reload detects changes to other packages within the mono-repo. As this delays startup time,
+if you prefer to pre-build internal dependencies, add `--skip-internal` to the above command.
-### Libraries
+### Internal dependencies
- [access-policy](https://github.com/beyondessential/tupaia/blob/dev/packages/access-policy/README.md)
- [aggregator](https://github.com/beyondessential/tupaia/blob/dev/packages/aggregator/README.md)
-- [api-client](https://github.com/beyondessential/tupaia/blob/dev/packages/api-client/README.md)
- [auth](https://github.com/beyondessential/tupaia/blob/dev/packages/auth/README.md)
-- [data-api](https://github.com/beyondessential/tupaia/blob/dev/packages/data-api/README.md)
-- [data-broker](https://github.com/beyondessential/tupaia/blob/dev/packages/data-broker/README.md)
-- [data-lake-api](https://github.com/beyondessential/tupaia/blob/dev/packages/data-lake-api/README.md)
- [database](https://github.com/beyondessential/tupaia/blob/dev/packages/database/README.md)
+- [data-broker](https://github.com/beyondessential/tupaia/blob/dev/packages/data-broker/README.md)
- [devops](https://github.com/beyondessential/tupaia/blob/dev/packages/devops/README.md)
- [dhis-api](https://github.com/beyondessential/tupaia/blob/dev/packages/dhis-api/README.md)
-- [e2e](https://github.com/beyondessential/tupaia/blob/dev/packages/e2e/README.md)
- [expression-parser](https://github.com/beyondessential/tupaia/blob/dev/packages/expression-parser/README.md)
- [indicators](https://github.com/beyondessential/tupaia/blob/dev/packages/indicators/README.md)
- [ui-components](https://github.com/beyondessential/tupaia/blob/dev/packages/ui-components/README.md)
- [ui-chart-components](https://github.com/beyondessential/tupaia/blob/dev/packages/ui-chart-components/README.md)
- [ui-map-components](https://github.com/beyondessential/tupaia/blob/dev/packages/ui-map-components/README.md)
- [server-boilerplate](https://github.com/beyondessential/tupaia/blob/dev/packages/server-boilerplate/README.md)
-- [superset-api](https://github.com/beyondessential/tupaia/blob/dev/packages/superset-api/README.md)
-- [ui-components](https://github.com/beyondessential/tupaia/blob/dev/packages/ui-components/README.md)
- [utils](https://github.com/beyondessential/tupaia/blob/dev/packages/utils/README.md)
-- [tsutils](https://github.com/beyondessential/tupaia/blob/dev/packages/tsutils/README.md)
-- [types](https://github.com/beyondessential/tupaia/blob/dev/packages/types/README.md)
-- [weather-api](https://github.com/beyondessential/tupaia/blob/dev/packages/weather-api/README.md)
## Getting started
diff --git a/packages/access-policy/README.md b/packages/access-policy/README.md
index b4843151ac..faab38ff20 100644
--- a/packages/access-policy/README.md
+++ b/packages/access-policy/README.md
@@ -1,4 +1,4 @@
-# @tupaia/access-policy
+# Tupaia Access Policy
Methods for parsing the access policy that is received by Tupaia projects during authentication.
diff --git a/packages/admin-panel-server/README.md b/packages/admin-panel-server/README.md
index e58426a012..516f0eca85 100644
--- a/packages/admin-panel-server/README.md
+++ b/packages/admin-panel-server/README.md
@@ -1,3 +1,3 @@
# @tupaia/admin-panel-server
-Orchestration server for the Admin Panel web app.
+Back end server for the Admin Panel web app.
\ No newline at end of file
diff --git a/packages/admin-panel/README.md b/packages/admin-panel/README.md
index 491f588af3..c1c358daad 100644
--- a/packages/admin-panel/README.md
+++ b/packages/admin-panel/README.md
@@ -1,15 +1,9 @@
-# @tupaia/admin-panel
-
-Frontend interface for the [Admin Panel](https://admin.tupaia.org/) web app.
+# Tupaia Admin
## User Guide
Most aspects are fairly self explanatory, but this guide should cover any tricky bits as they get added
-### Importing geojson
-
-Documentation for importing geojson can be found [here](doc/importingNewGeojson.md)
-
### Creating an Api Client
When creating a new user, you have the option to create them as an api client. When you do this, you have one chance only to retrieve the client secret. The steps for Google Chrome are:
@@ -23,9 +17,8 @@ When creating a new user, you have the option to create them as an api client. W
This secret key is used as the password in Basic Auth headers sent by api clients. Their permissions are verified based on the user the api client is attached to.
### Viz Builder App
-
-The Viz Builder App is an interface for creating Tupaia visualisations such as cartesian charts and pie charts.
+The Viz Builder App is an interface for creating Tupaia visualisations such as cartesian charts and pie charts.
It is a standalone app that sits inside the admin panel on the `viz-builder` route.
-It is inside the admin panel so that it can use the admin panel authentication and to give a more seamless user experience.
+It is inside the admin panel so that it can use the admin panel authentication and to give a more seamless user experience.
The Viz Builder App code is contained from the admin panel code so that it can be exported and imported into other apps such as Lesmis if required.
-It is also separated from the admin panel code so that we can use modern react techniques such as react-query.
+It is also separated from the admin panel code so that we can use modern react techniques such as react-query.
\ No newline at end of file
diff --git a/packages/admin-panel/src/editor/EditModal.js b/packages/admin-panel/src/editor/EditModal.js
index 6b2cc19e6b..57a0ee81a6 100644
--- a/packages/admin-panel/src/editor/EditModal.js
+++ b/packages/admin-panel/src/editor/EditModal.js
@@ -13,7 +13,6 @@ import { getEditorState, getIsUnchanged } from './selectors';
import { Editor } from './Editor';
import { ModalContentProvider } from '../widgets';
import { UsedBy } from '../usedBy/UsedBy';
-import { getExplodedFields } from '../utilities';
const getFieldSourceToEdit = field => {
const { source, editConfig = {} } = field;
@@ -49,8 +48,7 @@ export const EditModalComponent = ({
saveButtonText,
extraDialogProps,
}) => {
- // key the fields by their source so we can easily find the field to edit. Use the exploded fields so that any subfields are placed into the top level of the array
- const fieldsBySource = keyBy(getExplodedFields(fields), 'source');
+ const fieldsBySource = keyBy(fields, 'source');
return (