From 37dc524f218936af3959465b0b40f7668588269b Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Tue, 28 Jan 2025 20:46:56 +0200 Subject: [PATCH 01/15] enable duckDB plugin in demo-app Signed-off-by: Ihor Dykhta --- examples/demo-app/src/reducers/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/demo-app/src/reducers/index.js b/examples/demo-app/src/reducers/index.js index 282ab87a22..7f4565d654 100644 --- a/examples/demo-app/src/reducers/index.js +++ b/examples/demo-app/src/reducers/index.js @@ -11,7 +11,8 @@ import {processGeojson, processRowObject, processArrowTable} from '@kepler.gl/pr import keplerGlReducer, {combinedUpdaters, uiStateUpdaters} from '@kepler.gl/reducers'; import KeplerGlSchema from '@kepler.gl/schemas'; import {KeplerTable} from '@kepler.gl/table'; -import {getApplicationConfig} from '@kepler.gl/utils'; +import {getApplicationConfig, initApplicationConfig} from '@kepler.gl/utils'; +import keplerGlDuckdbPlugin, {KeplerGlDuckDbTable} from '@kepler.gl/duckdb'; import { INIT, @@ -26,6 +27,13 @@ import { import {CLOUD_PROVIDERS_CONFIGURATION} from '../constants/default-settings'; import {generateHashId} from '../utils/strings'; +// initialize kepler application with duckdb plugin +initApplicationConfig({ + plugins: [keplerGlDuckdbPlugin], + table: KeplerGlDuckDbTable, + useArrowProgressiveLoading: false +}); + const {DEFAULT_MAP_CONTROLS} = uiStateUpdaters; // INITIAL_APP_STATE From 652ab3002d76d22fafb521d4483fd1558909da8a Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Tue, 28 Jan 2025 21:07:02 +0200 Subject: [PATCH 02/15] nit Signed-off-by: Ihor Dykhta --- examples/demo-app/src/reducers/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/demo-app/src/reducers/index.js b/examples/demo-app/src/reducers/index.js index 7f4565d654..6154434cf5 100644 --- a/examples/demo-app/src/reducers/index.js +++ b/examples/demo-app/src/reducers/index.js @@ -27,7 +27,7 @@ import { import {CLOUD_PROVIDERS_CONFIGURATION} from '../constants/default-settings'; import {generateHashId} from '../utils/strings'; -// initialize kepler application with duckdb plugin +// initialize kepler demo-app with duckdb plugin initApplicationConfig({ plugins: [keplerGlDuckdbPlugin], table: KeplerGlDuckDbTable, From 2cc9ad948d8b2c6f4e3678b2a4f2ab633b9589c3 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Wed, 29 Jan 2025 11:42:13 +0200 Subject: [PATCH 03/15] hide not configured cloud storage providers Signed-off-by: Ihor Dykhta --- examples/demo-app/src/cloud-providers/index.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/demo-app/src/cloud-providers/index.js b/examples/demo-app/src/cloud-providers/index.js index c1ea2e3dc6..0e2e37433c 100644 --- a/examples/demo-app/src/cloud-providers/index.js +++ b/examples/demo-app/src/cloud-providers/index.js @@ -3,8 +3,8 @@ import {CLOUD_PROVIDERS_CONFIGURATION} from '../constants/default-settings'; -import DropboxProvider from './dropbox/dropbox-provider'; -import CartoProvider from './carto/carto-provider'; +// import DropboxProvider from './dropbox/dropbox-provider'; +// import CartoProvider from './carto/carto-provider'; import FoursquareProvider from './foursquare/foursquare-provider'; const { @@ -26,9 +26,11 @@ export const CLOUD_PROVIDERS = [ authDomain: FOURSQUARE_DOMAIN, apiURL: FOURSQUARE_API_URL, userMapsURL: FOURSQUARE_USER_MAPS_URL - }), - new DropboxProvider(DROPBOX_CLIENT_ID, DROPBOX_CLIENT_NAME), - new CartoProvider(CARTO_CLIENT_ID) + }) + // TODO DuckDB preview only + // Disable Dropbox and Carto providers in DuckDb-preview as the domain isn't whitelisted for them. + // new DropboxProvider(DROPBOX_CLIENT_ID, DROPBOX_CLIENT_NAME), + // new CartoProvider(CARTO_CLIENT_ID) ]; export function getCloudProvider(providerName) { From 95e4a5e5aec2bdff6c5bd079543fb176889c3d5e Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Wed, 29 Jan 2025 12:00:36 +0200 Subject: [PATCH 04/15] nit Signed-off-by: Ihor Dykhta --- examples/demo-app/src/cloud-providers/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/demo-app/src/cloud-providers/index.js b/examples/demo-app/src/cloud-providers/index.js index 0e2e37433c..05d284e250 100644 --- a/examples/demo-app/src/cloud-providers/index.js +++ b/examples/demo-app/src/cloud-providers/index.js @@ -8,15 +8,15 @@ import {CLOUD_PROVIDERS_CONFIGURATION} from '../constants/default-settings'; import FoursquareProvider from './foursquare/foursquare-provider'; const { - DROPBOX_CLIENT_ID, - CARTO_CLIENT_ID, + // DROPBOX_CLIENT_ID, + // CARTO_CLIENT_ID, FOURSQUARE_CLIENT_ID, FOURSQUARE_DOMAIN, FOURSQUARE_API_URL, FOURSQUARE_USER_MAPS_URL } = CLOUD_PROVIDERS_CONFIGURATION; -const DROPBOX_CLIENT_NAME = 'Kepler.gl Demo App'; +// const DROPBOX_CLIENT_NAME = 'Kepler.gl Demo App'; export const DEFAULT_CLOUD_PROVIDER = 'dropbox'; From 474fa16e6c563a0eafb6221d9e764b34011d4226 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Wed, 29 Jan 2025 15:28:37 +0200 Subject: [PATCH 05/15] disable banner Signed-off-by: Ihor Dykhta --- examples/demo-app/src/reducers/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/demo-app/src/reducers/index.js b/examples/demo-app/src/reducers/index.js index 6154434cf5..4bdfc520c0 100644 --- a/examples/demo-app/src/reducers/index.js +++ b/examples/demo-app/src/reducers/index.js @@ -31,7 +31,8 @@ import {generateHashId} from '../utils/strings'; initApplicationConfig({ plugins: [keplerGlDuckdbPlugin], table: KeplerGlDuckDbTable, - useArrowProgressiveLoading: false + useArrowProgressiveLoading: false, + showReleaseBanner: false }); const {DEFAULT_MAP_CONTROLS} = uiStateUpdaters; From bcb169d68a80cb71bbfd78b038e4e6b3e74e27ac Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Thu, 6 Feb 2025 15:35:30 +0200 Subject: [PATCH 06/15] nit Signed-off-by: Ihor Dykhta --- examples/demo-app/src/reducers/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/demo-app/src/reducers/index.js b/examples/demo-app/src/reducers/index.js index 4bdfc520c0..94453826d3 100644 --- a/examples/demo-app/src/reducers/index.js +++ b/examples/demo-app/src/reducers/index.js @@ -29,8 +29,11 @@ import {generateHashId} from '../utils/strings'; // initialize kepler demo-app with duckdb plugin initApplicationConfig({ + // Custom UI for DuckDB plugins: [keplerGlDuckdbPlugin], + // async data ingestion to DuckDb table: KeplerGlDuckDbTable, + // progressive loading is sync, doesn't wait properly for a dataset to be created in DuckDB useArrowProgressiveLoading: false, showReleaseBanner: false }); From e788f563ffa47c016430450cb95996a65532334d Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Thu, 20 Feb 2025 15:00:35 +0200 Subject: [PATCH 07/15] Show examples tab by default; css changes; move tiled examples to the top; filter out trips example Signed-off-by: Ihor Dykhta --- examples/demo-app/src/actions.js | 9 +++++++++ .../components/load-data-modal/sample-maps-tab.js | 15 ++++++++++++--- src/components/src/modals/load-data-modal.tsx | 9 +++++++-- src/components/src/modals/modal-tabs.tsx | 8 +++++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/examples/demo-app/src/actions.js b/examples/demo-app/src/actions.js index 4f4352ebbd..491a19e454 100644 --- a/examples/demo-app/src/actions.js +++ b/examples/demo-app/src/actions.js @@ -303,6 +303,15 @@ export function loadSampleConfigurations(sampleMapId = null) { } }) .then(samples => { + if (samples.length > 10) { + // For DuckDB preview: move tiled examples to the top + let removed = samples.splice(4, 2); + samples.splice(1, 0, ...removed); + + // For DuckDB preview: filter out the example with trips as 4th timecoordinate is dropped in GEOMETRY + samples = samples.filter(s => s.id !== 'world_flights'); + } + dispatch(loadMapSampleFile(samples)); // Load the specified map const map = sampleMapId && samples.find(s => s.id === sampleMapId); diff --git a/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js b/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js index 0692e7c49f..92b8d034a4 100644 --- a/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js +++ b/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js @@ -2,6 +2,7 @@ // Copyright contributors to the kepler.gl project import React from 'react'; +import classnames from 'classnames'; import styled from 'styled-components'; import {Icons} from '@kepler.gl/components'; import {media} from '@kepler.gl/styles'; @@ -25,7 +26,9 @@ const StyledMapIcon = styled.div` const StyledTrySampleData = styled.div` display: flex; - margin-bottom: 12px; + margin-bottom: 0px; + margin-left: 84px; + padding-bottom: 12px; flex-grow: 1; justify-content: flex-end; color: ${props => props.theme.subtextColorLT}; @@ -37,6 +40,12 @@ const StyledTrySampleData = styled.div` justify-content: flex-end; } + .load-data-modal__tab__item.active { + color: ${props => props.theme.textColorLT}; + border-bottom: 3px solid ${props => props.theme.textColorLT}; + font-weight: 500; + } + .demo-map-label { font-size: 11px; @@ -70,9 +79,9 @@ const StyledTrySampleData = styled.div` } `; -const SampleMapsTab = ({onClick}) => { +const SampleMapsTab = ({onClick, className}) => { return ( - +
diff --git a/src/components/src/modals/load-data-modal.tsx b/src/components/src/modals/load-data-modal.tsx index 7fb9148a2d..98eb162c79 100644 --- a/src/components/src/modals/load-data-modal.tsx +++ b/src/components/src/modals/load-data-modal.tsx @@ -28,12 +28,17 @@ const noop = () => { return; }; const getDefaultMethod = (methods: T[] = []) => - Array.isArray(methods) ? get(methods, [0]) : null; + // Try sample data modal by default for DuckDB preview + Array.isArray(methods) ? get(methods, [4]) : null; export interface LoadingMethod { id: string; label: string; elementType: React.ComponentType; - tabElementType?: React.ComponentType<{onClick: React.MouseEventHandler; intl: IntlShape}>; + tabElementType?: React.ComponentType<{ + onClick: React.MouseEventHandler; + intl: IntlShape; + className?: string; + }>; } type LoadDataModalProps = { diff --git a/src/components/src/modals/modal-tabs.tsx b/src/components/src/modals/modal-tabs.tsx index 61c3f342bf..a437f6b858 100644 --- a/src/components/src/modals/modal-tabs.tsx +++ b/src/components/src/modals/modal-tabs.tsx @@ -79,7 +79,13 @@ export const ModalTabItem: React.FC = ({ const intl = useIntl(); return method.tabElementType ? ( - + ) : ( Date: Thu, 20 Feb 2025 18:00:06 +0200 Subject: [PATCH 08/15] fix tests Signed-off-by: Ihor Dykhta --- src/components/src/modals/load-data-modal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/src/modals/load-data-modal.tsx b/src/components/src/modals/load-data-modal.tsx index 98eb162c79..dce059d264 100644 --- a/src/components/src/modals/load-data-modal.tsx +++ b/src/components/src/modals/load-data-modal.tsx @@ -14,6 +14,7 @@ import LoadingDialog from './loading-dialog'; import {LOADING_METHODS} from '@kepler.gl/constants'; import {FileLoading, FileLoadingProgress, LoadFiles} from '@kepler.gl/types'; +import {isTest} from '@kepler.gl/utils'; const StyledLoadDataModal = styled.div.attrs({ className: 'load-data-modal' @@ -29,7 +30,8 @@ const noop = () => { }; const getDefaultMethod = (methods: T[] = []) => // Try sample data modal by default for DuckDB preview - Array.isArray(methods) ? get(methods, [4]) : null; + // Note: In tests only 3 methods are available + Array.isArray(methods) ? get(methods, [isTest() ? 0 : 4]) : null; export interface LoadingMethod { id: string; label: string; From 2bc825ca708de66ff68d2a3478f661aa16965946 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Thu, 20 Feb 2025 19:10:46 +0200 Subject: [PATCH 09/15] test - redirects to allow custom urls for SPA Signed-off-by: Ihor Dykhta --- examples/demo-app/esbuild.config.mjs | 9 ++++++++ examples/demo-app/package.json | 3 ++- examples/demo-app/src/static/_redirects | 1 + package.json | 1 + yarn.lock | 28 ++++++++++++++++++++++++- 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 examples/demo-app/src/static/_redirects diff --git a/examples/demo-app/esbuild.config.mjs b/examples/demo-app/esbuild.config.mjs index 1ae1c6e922..e9aaccc89c 100644 --- a/examples/demo-app/esbuild.config.mjs +++ b/examples/demo-app/esbuild.config.mjs @@ -3,6 +3,7 @@ import esbuild from 'esbuild'; import {replace} from 'esbuild-plugin-replace'; +import copy from 'esbuild-plugin-copy'; import {dotenvRun} from '@dotenv-run/esbuild'; import process from 'node:process'; @@ -105,6 +106,14 @@ const config = { replace({ __PACKAGE_VERSION__: KeplerPackage.version, include: /constants\/src\/default-settings\.ts/ + }), + // copy files to dist + copy({ + resolveFrom: 'cwd', + assets: { + from: ['./src/static/_redirects'], + to: ['./dist/'] + } }) ] }; diff --git a/examples/demo-app/package.json b/examples/demo-app/package.json index 7cab1a4f9a..8aed5592ec 100644 --- a/examples/demo-app/package.json +++ b/examples/demo-app/package.json @@ -75,6 +75,7 @@ "packageManager": "yarn@4.4.0", "devDependencies": { "@dotenv-run/esbuild": "^1.5.0", - "esbuild-plugin-replace": "^1.4.0" + "esbuild-plugin-replace": "^1.4.0", + "esbuild-plugin-copy": "^2.1.1" } } diff --git a/examples/demo-app/src/static/_redirects b/examples/demo-app/src/static/_redirects new file mode 100644 index 0000000000..952ebf0ce0 --- /dev/null +++ b/examples/demo-app/src/static/_redirects @@ -0,0 +1 @@ +/* / 200 diff --git a/package.json b/package.json index 62769c841c..ed34e63577 100644 --- a/package.json +++ b/package.json @@ -165,6 +165,7 @@ "dts-bundle-webpack": "^1.0.2", "enzyme": "^3.11.0", "esbuild": "^0.23.1", + "esbuild-plugin-copy": "^2.1.1", "esbuild-plugin-replace": "^1.4.0", "esbuild-plugin-umd-wrapper": "3.0.0", "eslint": "~8.53.0", diff --git a/yarn.lock b/yarn.lock index a45e9e2445..8c6e372e3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12738,7 +12738,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.4.0, chokidar@npm:^3.4.1, chokidar@npm:^3.6.0": +"chokidar@npm:^3.4.0, chokidar@npm:^3.4.1, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -15488,6 +15488,20 @@ __metadata: languageName: node linkType: hard +"esbuild-plugin-copy@npm:^2.1.1": + version: 2.1.1 + resolution: "esbuild-plugin-copy@npm:2.1.1" + dependencies: + chalk: "npm:^4.1.2" + chokidar: "npm:^3.5.3" + fs-extra: "npm:^10.0.1" + globby: "npm:^11.0.3" + peerDependencies: + esbuild: ">= 0.14.0" + checksum: 10c0/ae0cb7cbac7328de54cbdfbfc9d47a600a16ee7fff20d8b77afaa8c2999921fff21506db3be2c20e05fd76448f098ae76d1aaae4ccfa73293247a07931c9c3e2 + languageName: node + linkType: hard + "esbuild-plugin-replace@npm:^1.4.0": version: 1.4.0 resolution: "esbuild-plugin-replace@npm:1.4.0" @@ -16882,6 +16896,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^10.0.1": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + "fs-extra@npm:^11.2.0": version: 11.2.0 resolution: "fs-extra@npm:11.2.0" @@ -20460,6 +20485,7 @@ __metadata: dts-bundle-webpack: "npm:^1.0.2" enzyme: "npm:^3.11.0" esbuild: "npm:^0.23.1" + esbuild-plugin-copy: "npm:^2.1.1" esbuild-plugin-replace: "npm:^1.4.0" esbuild-plugin-umd-wrapper: "npm:3.0.0" eslint: "npm:~8.53.0" From bb560d03fc9d78292dfb0852b6df9c79319559e2 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Thu, 20 Feb 2025 19:15:02 +0200 Subject: [PATCH 10/15] yarn lock; nit Signed-off-by: Ihor Dykhta --- examples/demo-app/package.json | 4 +- examples/demo-app/yarn.lock | 105 +++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/examples/demo-app/package.json b/examples/demo-app/package.json index 8aed5592ec..2ab982e6a5 100644 --- a/examples/demo-app/package.json +++ b/examples/demo-app/package.json @@ -75,7 +75,7 @@ "packageManager": "yarn@4.4.0", "devDependencies": { "@dotenv-run/esbuild": "^1.5.0", - "esbuild-plugin-replace": "^1.4.0", - "esbuild-plugin-copy": "^2.1.1" + "esbuild-plugin-copy": "^2.1.1", + "esbuild-plugin-replace": "^1.4.0" } } diff --git a/examples/demo-app/yarn.lock b/examples/demo-app/yarn.lock index 1c1721a889..435262271d 100644 --- a/examples/demo-app/yarn.lock +++ b/examples/demo-app/yarn.lock @@ -7662,6 +7662,13 @@ __metadata: languageName: node linkType: hard +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 + languageName: node + linkType: hard + "arraybuffer.prototype.slice@npm:^1.0.3": version: 1.0.3 resolution: "arraybuffer.prototype.slice@npm:1.0.3" @@ -8022,7 +8029,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.6.0": +"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -8871,6 +8878,15 @@ __metadata: languageName: node linkType: hard +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c + languageName: node + linkType: hard + "dlv@npm:^1.1.3": version: 1.1.3 resolution: "dlv@npm:1.1.3" @@ -9103,6 +9119,20 @@ __metadata: languageName: node linkType: hard +"esbuild-plugin-copy@npm:^2.1.1": + version: 2.1.1 + resolution: "esbuild-plugin-copy@npm:2.1.1" + dependencies: + chalk: "npm:^4.1.2" + chokidar: "npm:^3.5.3" + fs-extra: "npm:^10.0.1" + globby: "npm:^11.0.3" + peerDependencies: + esbuild: ">= 0.14.0" + checksum: 10c0/ae0cb7cbac7328de54cbdfbfc9d47a600a16ee7fff20d8b77afaa8c2999921fff21506db3be2c20e05fd76448f098ae76d1aaae4ccfa73293247a07931c9c3e2 + languageName: node + linkType: hard + "esbuild-plugin-replace@npm:^1.4.0": version: 1.4.0 resolution: "esbuild-plugin-replace@npm:1.4.0" @@ -9270,7 +9300,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.3.2": +"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -9488,6 +9518,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^10.0.1": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + "fs-extra@npm:^7.0.0": version: 7.0.1 resolution: "fs-extra@npm:7.0.1" @@ -9709,6 +9750,20 @@ __metadata: languageName: node linkType: hard +"globby@npm:^11.0.3": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 + languageName: node + linkType: hard + "gopd@npm:^1.0.1": version: 1.0.1 resolution: "gopd@npm:1.0.1" @@ -9737,7 +9792,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -9966,6 +10021,13 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.2.0": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 + languageName: node + linkType: hard + "image-size@npm:^0.7.4": version: 0.7.5 resolution: "image-size@npm:0.7.5" @@ -10559,6 +10621,19 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/4f95b5e8a5622b1e9e8f33c96b7ef3158122f595998114d1e7f03985649ea99cb3cd99ce1ed1831ae94c8c8543ab45ebd044207612f31a56fd08462140e46865 + languageName: node + linkType: hard + "jsts@npm:2.7.1": version: 2.7.1 resolution: "jsts@npm:2.7.1" @@ -11091,7 +11166,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.3.0": +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb @@ -11815,6 +11890,13 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + "pbf@npm:^3.1.0, pbf@npm:^3.2.1": version: 3.3.0 resolution: "pbf@npm:3.3.0" @@ -13028,6 +13110,7 @@ __metadata: d3-format: "npm:^2.0.0" dropbox: "npm:^4.0.12" esbuild: "npm:^0.23.1" + esbuild-plugin-copy: "npm:^2.1.1" esbuild-plugin-replace: "npm:^1.4.0" global: "npm:^4.3.0" keymirror: "npm:^0.1.1" @@ -13254,6 +13337,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -14173,6 +14263,13 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + "update-input-width@npm:^1.4.0": version: 1.4.2 resolution: "update-input-width@npm:1.4.2" From f3848eeb8ea73ce8817cadc969b322a502bc7ce0 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Fri, 21 Feb 2025 04:33:04 +0200 Subject: [PATCH 11/15] add to load data modal + shortcut Signed-off-by: Ihor Dykhta --- .../load-data-modal/sample-data-viewer.js | 72 +++++++++++++------ .../load-data-modal/sample-maps-tab.js | 3 +- src/components/src/modals/load-data-modal.tsx | 22 ++++-- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/examples/demo-app/src/components/load-data-modal/sample-data-viewer.js b/examples/demo-app/src/components/load-data-modal/sample-data-viewer.js index 37280fc2db..97a26b04f9 100644 --- a/examples/demo-app/src/components/load-data-modal/sample-data-viewer.js +++ b/examples/demo-app/src/components/load-data-modal/sample-data-viewer.js @@ -5,7 +5,7 @@ import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import {format} from 'd3-format'; -import {LoadingDialog} from '@kepler.gl/components'; +import {LoadingDialog, Icons} from '@kepler.gl/components'; import {FormattedMessage} from 'react-intl'; const numFormat = format(','); @@ -72,6 +72,24 @@ const StyledError = styled.div` margin-bottom: 16px; `; +const AddDataHelper = styled.div` + margin-left: auto; + margin-right: auto; + margin-top: -25px; + margin-bottom: 6px; + cursor: pointer; + + color: ${props => props.theme.subtextColorLT}; + &:hover { + color: ${props => props.theme.textColorLT}; + } +`; + +const StyledAddIcon = styled(Icons.Add)` + display: inline; + margin-top: -3px; +`; + const SampleMap = ({id, sample, onClick}) => (
@@ -98,7 +116,8 @@ const SampleMapGallery = ({ error, isMapLoading, locale, - loadSampleConfigurations + loadSampleConfigurations, + enableLoadDataModal }) => { useEffect(() => { if (!sampleMaps.length) { @@ -107,27 +126,34 @@ const SampleMapGallery = ({ }, [sampleMaps, loadSampleConfigurations]); return ( -
- {error ? ( - {error.message} - ) : isMapLoading ? ( - - ) : ( - - {sampleMaps - .filter(sp => sp.visible) - .map(sp => ( - onLoadSample(sp)} - locale={locale} - /> - ))} - - )} -
+ <> + {!error && !isMapLoading ? ( + + Add data + + ) : null} +
+ {error ? ( + {error.message} + ) : isMapLoading ? ( + + ) : ( + + {sampleMaps + .filter(sp => sp.visible) + .map(sp => ( + onLoadSample(sp)} + locale={locale} + /> + ))} + + )} +
+ ); }; diff --git a/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js b/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js index 92b8d034a4..eedd1a31f6 100644 --- a/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js +++ b/examples/demo-app/src/components/load-data-modal/sample-maps-tab.js @@ -28,10 +28,11 @@ const StyledTrySampleData = styled.div` display: flex; margin-bottom: 0px; margin-left: 84px; - padding-bottom: 12px; + padding-bottom: 9px; flex-grow: 1; justify-content: flex-end; color: ${props => props.theme.subtextColorLT}; + border-bottom: 3px solid transparent; .demo-map-title { margin-left: 16px; diff --git a/src/components/src/modals/load-data-modal.tsx b/src/components/src/modals/load-data-modal.tsx index dce059d264..8742d625bf 100644 --- a/src/components/src/modals/load-data-modal.tsx +++ b/src/components/src/modals/load-data-modal.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project -import React, {useState} from 'react'; +import React, {useState, useCallback} from 'react'; import styled from 'styled-components'; import get from 'lodash.get'; import {IntlShape, useIntl} from 'react-intl'; @@ -30,8 +30,8 @@ const noop = () => { }; const getDefaultMethod = (methods: T[] = []) => // Try sample data modal by default for DuckDB preview - // Note: In tests only 3 methods are available - Array.isArray(methods) ? get(methods, [isTest() ? 0 : 4]) : null; + // Note: In tests only 3 loading methods are available + Array.isArray(methods) ? get(methods, [isTest() && methods.length > 4 ? 0 : 4]) : null; export interface LoadingMethod { id: string; label: string; @@ -108,15 +108,25 @@ export function LoadDataModalFactory( ...restProps }) => { const intl = useIntl(); + + // const {loadingMethods, isCloudMapLoading} = props; + const [currentMethod, toggleMethod] = useState(getDefaultMethod(loadingMethods)); + + const loadDataMethod = loadingMethods.find(ldm => ldm.id === 'upload'); + const enableLoadDataModal = useCallback(() => { + if (loadDataMethod) { + toggleMethod(loadDataMethod); + } + }, [loadDataMethod, toggleMethod]); + const currentModalProps = { ...restProps, onFileUpload, onTilesetAdded, fileLoading, - isCloudMapLoading + isCloudMapLoading, + enableLoadDataModal }; - // const {loadingMethods, isCloudMapLoading} = props; - const [currentMethod, toggleMethod] = useState(getDefaultMethod(loadingMethods)); const ElementType = currentMethod?.elementType; From b2e690d812b9b642847993b087d2378410f6bbce Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Fri, 21 Feb 2025 05:16:19 +0200 Subject: [PATCH 12/15] lint Signed-off-by: Ihor Dykhta --- src/components/src/modals/load-data-modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/src/modals/load-data-modal.tsx b/src/components/src/modals/load-data-modal.tsx index 8742d625bf..c5ea0e522d 100644 --- a/src/components/src/modals/load-data-modal.tsx +++ b/src/components/src/modals/load-data-modal.tsx @@ -106,7 +106,7 @@ export function LoadDataModalFactory( loadingMethods = defaultLoadingMethods, isCloudMapLoading, ...restProps - }) => { + }: LoadDataModalProps) => { const intl = useIntl(); // const {loadingMethods, isCloudMapLoading} = props; From c8f3c866d8358beba9430a1837733b88acaed1c0 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Fri, 21 Feb 2025 05:31:57 +0200 Subject: [PATCH 13/15] nit Signed-off-by: Ihor Dykhta --- src/components/src/modals/load-data-modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/src/modals/load-data-modal.tsx b/src/components/src/modals/load-data-modal.tsx index c5ea0e522d..85c8a2ebaa 100644 --- a/src/components/src/modals/load-data-modal.tsx +++ b/src/components/src/modals/load-data-modal.tsx @@ -31,7 +31,7 @@ const noop = () => { const getDefaultMethod = (methods: T[] = []) => // Try sample data modal by default for DuckDB preview // Note: In tests only 3 loading methods are available - Array.isArray(methods) ? get(methods, [isTest() && methods.length > 4 ? 0 : 4]) : null; + Array.isArray(methods) ? get(methods, [isTest() && methods.length > 4 ? 4 : 0]) : null; export interface LoadingMethod { id: string; label: string; From cc10cbe2e32062189f52cc04a63cd86a6f3f9256 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Sat, 8 Aug 2026 06:10:52 +0300 Subject: [PATCH 14/15] fix upgrade to 3.3 Signed-off-by: Ihor Dykhta --- examples/demo-app/esbuild.config.mjs | 19 +++++++++++++++++++ examples/demo-app/src/app.tsx | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/examples/demo-app/esbuild.config.mjs b/examples/demo-app/esbuild.config.mjs index 3450ec2bfd..1a043d78c4 100644 --- a/examples/demo-app/esbuild.config.mjs +++ b/examples/demo-app/esbuild.config.mjs @@ -148,6 +148,25 @@ const config = { }); } }, + // @kepler.gl/* must resolve to a single copy (and a single module format). + // demo-app/node_modules has published tarballs while the monorepo root links + // workspace packages; without deduping, initApplicationConfig() and SqlPanel + // can see different applicationConfig singletons (database stays null). + // Always use the "import" condition so CJS+ESM dual packages don't both bundle. + { + name: 'dedupe-kepler', + setup(build) { + build.onResolve({filter: /^@kepler\.gl\//}, async args => { + if (args.pluginData?.deduped) return; + const result = await build.resolve(args.path, { + resolveDir: NODE_MODULES_DIR, + kind: 'import-statement', + pluginData: {deduped: true} + }); + return result; + }); + } + }, // copy files to dist copy({ resolveFrom: 'cwd', diff --git a/examples/demo-app/src/app.tsx b/examples/demo-app/src/app.tsx index 6a61abdced..18e421513f 100644 --- a/examples/demo-app/src/app.tsx +++ b/examples/demo-app/src/app.tsx @@ -20,6 +20,7 @@ import { import {panelBorderColor, theme} from '@kepler.gl/styles'; import {ParsedConfig} from '@kepler.gl/types'; import {getApplicationConfig} from '@kepler.gl/utils'; +import {injectComponents} from '@kepler.gl/components'; import {SqlPanel} from '@kepler.gl/duckdb/components'; import Banner from './components/banner'; import Announcement, {FormLink} from './components/announcement'; @@ -46,7 +47,7 @@ import { import {CLOUD_PROVIDERS} from './cloud-providers'; import {Panel, PanelGroup, PanelResizeHandle} from 'react-resizable-panels'; -const KeplerGl = require('@kepler.gl/components').injectComponents([ +const KeplerGl = injectComponents([ replaceLoadDataModal(), replaceMapControl(), replacePanelHeader() From 4435158179218891af300a9c84b5359163ec61e6 Mon Sep 17 00:00:00 2001 From: Ihor Dykhta Date: Sat, 8 Aug 2026 06:20:01 +0300 Subject: [PATCH 15/15] try to resolve deployments Signed-off-by: Ihor Dykhta --- examples/demo-app/esbuild.config.mjs | 59 ++++++++++++++++++++++++---- examples/demo-app/tsconfig.json | 17 ++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 examples/demo-app/tsconfig.json diff --git a/examples/demo-app/esbuild.config.mjs b/examples/demo-app/esbuild.config.mjs index 1a043d78c4..106bca7dfd 100644 --- a/examples/demo-app/esbuild.config.mjs +++ b/examples/demo-app/esbuild.config.mjs @@ -63,6 +63,44 @@ const getProductionReactAliases = nodeModulesDir => ({ 'react-dom/client': `${nodeModulesDir}/react-dom/cjs/react-dom-client.production.js` }); +// Workspace packages to load from source when NODE_ENV=local. +// Must include package subpaths (e.g. duckdb/components) — the monorepo +// tsconfig only maps `@kepler.gl/*` (one segment), so subpath imports would +// otherwise resolve to demo-app/node_modules and create a second utils singleton. +const KEPLER_WORKSPACE_PACKAGES = [ + 'actions', + 'ai-assistant', + 'cloud-providers', + 'common-utils', + 'components', + 'constants', + 'deckgl-arrow-layers', + 'deckgl-layers', + 'duckdb', + 'effects', + 'layers', + 'localization', + 'processors', + 'reducers', + 'schemas', + 'styles', + 'table', + 'tasks', + 'utils' +]; + +const getKeplerLocalAliases = () => { + const aliases = {}; + for (const pkg of KEPLER_WORKSPACE_PACKAGES) { + aliases[`@kepler.gl/${pkg}`] = join(SRC_DIR, pkg, 'src'); + } + aliases['@kepler.gl/duckdb/components'] = join(SRC_DIR, 'duckdb/src/components'); + aliases['@kepler.gl/duckdb/table'] = join(SRC_DIR, 'duckdb/src/table'); + return aliases; +}; + +const isLocalEnv = process.env.NODE_ENV === 'local'; + // Env variables required for demo app const requiredEnvVariables = [ 'MapboxAccessToken', @@ -96,6 +134,10 @@ const config = { logOverride: { 'unsupported-jsx-comment': 'silent' }, + // Use demo-app tsconfig (no path mappings). Walking up to the monorepo + // tsconfig would rewrite `@kepler.gl/pkg` → `src/pkg/src` but not subpaths + // like `@kepler.gl/duckdb/components`, splitting the applicationConfig singleton. + tsconfig: join(__dirname, 'tsconfig.json'), inject: ['src/react19-shim.js'], loader: { '.js': 'jsx', @@ -148,18 +190,18 @@ const config = { }); } }, - // @kepler.gl/* must resolve to a single copy (and a single module format). - // demo-app/node_modules has published tarballs while the monorepo root links - // workspace packages; without deduping, initApplicationConfig() and SqlPanel - // can see different applicationConfig singletons (database stays null). - // Always use the "import" condition so CJS+ESM dual packages don't both bundle. + // Force a single @kepler.gl/* copy from demo-app/node_modules (published + // packages on Netlify/production). Local monorepo source is handled via + // getKeplerLocalAliases() instead — do not resolve from the repo root + // node_modules here (workspace dist/ is often missing on CI). { name: 'dedupe-kepler', setup(build) { + if (isLocalEnv) return; build.onResolve({filter: /^@kepler\.gl\//}, async args => { if (args.pluginData?.deduped) return; const result = await build.resolve(args.path, { - resolveDir: NODE_MODULES_DIR, + resolveDir: __dirname, kind: 'import-statement', pluginData: {deduped: true} }); @@ -337,7 +379,8 @@ function openURL(url) { sourcemap: false, // Add alias resolution for build alias: { - ...getThirdPartyLibraryAliases(true) + ...getThirdPartyLibraryAliases(true), + ...(isLocalEnv ? getKeplerLocalAliases() : {}) }, // Add these production optimizations define: { @@ -376,7 +419,7 @@ function openURL(url) { if (args.includes('--start')) { const isLocal = process.env.NODE_ENV === 'local'; const baseAliases = isLocal - ? localAliases + ? {...localAliases, ...getKeplerLocalAliases()} : getThirdPartyLibraryAliases(false); const nodeModulesDir = isLocal ? NODE_MODULES_DIR : BASE_NODE_MODULES_DIR; // Skip dedupe-webgl when a local deck.gl source override is active so that diff --git a/examples/demo-app/tsconfig.json b/examples/demo-app/tsconfig.json new file mode 100644 index 0000000000..02473f16d0 --- /dev/null +++ b/examples/demo-app/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "strict": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "baseUrl": "." + }, + "include": ["src"] +}