@sqlrooms/deck 0.29.0-rc.7 → 0.29.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +2 -1
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +5 -1
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/MapSettings.js +2 -1
- package/dist/MapSettings.js.map +1 -1
- package/dist/dashboard.d.ts +8 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +13 -9
- package/dist/dashboard.js.map +1 -1
- package/package.json +6 -6
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright
|
|
3
|
+
Copyright 2024-2026 SQLRooms Contributors
|
|
4
|
+
Copyright Vis.gl contributors
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeckJsonMap.d.ts","sourceRoot":"","sources":["../src/DeckJsonMap.tsx"],"names":[],"mappings":"AAIA,OAAO,kCAAkC,CAAC;AAW1C,OAAO,KAAK,EAAC,gBAAgB,EAA2B,MAAM,SAAS,CAAC;AAoIxE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,WAAmB,EACnB,SAAS,EACT,QAAQ,EACR,WAAkB,EAClB,SAAS,EACT,QAAQ,EACR,qBAAqB,GACtB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"DeckJsonMap.d.ts","sourceRoot":"","sources":["../src/DeckJsonMap.tsx"],"names":[],"mappings":"AAIA,OAAO,kCAAkC,CAAC;AAW1C,OAAO,KAAK,EAAC,gBAAgB,EAA2B,MAAM,SAAS,CAAC;AAoIxE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,WAAmB,EACnB,SAAS,EACT,QAAQ,EACR,WAAkB,EAClB,SAAS,EACT,QAAQ,EACR,qBAAqB,GACtB,EAAE,gBAAgB,2CAkJlB"}
|
package/dist/DeckJsonMap.js
CHANGED
|
@@ -158,6 +158,8 @@ export function DeckJsonMap({ spec, datasets, mapStyle, interleaved = false, dec
|
|
|
158
158
|
...extraDeckProps,
|
|
159
159
|
layers: mergedLayers,
|
|
160
160
|
};
|
|
161
|
+
// overlayDeckProps should not contain viewState/initialViewState
|
|
162
|
+
const { initialViewState, viewState: _viewState, ...overlayDeckProps } = mergedDeckProps;
|
|
161
163
|
const { resolvedTheme } = useTheme();
|
|
162
164
|
const mergedMapProps = {
|
|
163
165
|
...extraMapProps,
|
|
@@ -170,6 +172,8 @@ export function DeckJsonMap({ spec, datasets, mapStyle, interleaved = false, dec
|
|
|
170
172
|
datasetStates,
|
|
171
173
|
})
|
|
172
174
|
: [], [availableSpec, datasetIds, datasetStates, showLegends]);
|
|
173
|
-
return (_jsxs("div", { className: cn('relative h-full w-full', className), children: [hasRenderingError ? (_jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center p-4", children: _jsx("div", { className: "max-w-sm rounded-md border border-red-200 bg-red-50/95 p-4 text-sm text-red-700 shadow-sm", children: `Map couldn't be rendered. Check the console for details.` }) })) : null, _jsxs(Map, { ...mergedMapProps,
|
|
175
|
+
return (_jsxs("div", { className: cn('relative h-full w-full', className), children: [hasRenderingError ? (_jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center p-4", children: _jsx("div", { className: "max-w-sm rounded-md border border-red-200 bg-red-50/95 p-4 text-sm text-red-700 shadow-sm", children: `Map couldn't be rendered. Check the console for details.` }) })) : null, _jsxs(Map, { ...mergedMapProps, ...(initialViewState
|
|
176
|
+
? { initialViewState: initialViewState }
|
|
177
|
+
: {}), style: { width: '100%', height: '100%', ...mapProps?.style }, children: [_jsx(DeckOverlayControl, { interleaved: interleaved, ...overlayDeckProps }), children] }), renderDatasetErrorOverlay(datasetStates), !hasRenderingError && showLegends ? (_jsx("div", { className: "pointer-events-none absolute bottom-2 left-2 z-10 max-w-56", children: _jsx(ColorScaleLegend, { legends: legends }) })) : null] }));
|
|
174
178
|
}
|
|
175
179
|
//# sourceMappingURL=DeckJsonMap.js.map
|
package/dist/DeckJsonMap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeckJsonMap.js","sourceRoot":"","sources":["../src/DeckJsonMap.tsx"],"names":[],"mappings":"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","sourcesContent":["import {JSONConverter} from '@deck.gl/json';\nimport {MapboxOverlay} from '@deck.gl/mapbox';\nimport {ColorScaleLegend} from '@sqlrooms/color-scales';\nimport {cn, ResolvedTheme, useTheme} from '@sqlrooms/ui';\nimport 'maplibre-gl/dist/maplibre-gl.css';\nimport {useEffect, useMemo, useRef} from 'react';\nimport Map, {useControl} from 'react-map-gl/maplibre';\nimport {ZodError} from 'zod';\nimport {DeckJsonMapSpec} from './DeckJsonMapSpec';\nimport {normalizeDatasets} from './datasets/normalizeDatasets';\nimport {usePreparedDatasetStates} from './datasets/usePreparedDatasetStates';\nimport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nimport {extractColorScaleLegends} from './json/extractColorScaleLegends';\nimport {getLayerCompatibility} from './json/layerCompatibility';\nimport {resolveDatasetId} from './json/layerConfig';\nimport type {DeckJsonMapProps, PreparedDeckDatasetState} from './types';\n\nconst DEFAULT_MAP_STYLES: Record<ResolvedTheme, string> = {\n light: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',\n dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',\n};\n\nfunction parseSpec(spec: DeckJsonMapProps['spec']) {\n try {\n const parsedValue = typeof spec === 'string' ? JSON.parse(spec) : spec;\n const validatedSpec = DeckJsonMapSpec.safeParse(parsedValue);\n if (!validatedSpec.success) {\n return {\n spec: null,\n error: new Error(formatSpecValidationError(validatedSpec.error)),\n };\n }\n\n return {\n spec: validatedSpec.data,\n error: null,\n };\n } catch (error) {\n return {\n spec: null,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n\nfunction formatSpecValidationError(error: ZodError) {\n const issues = error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : 'spec';\n return `${path}: ${issue.message}`;\n });\n\n return `Invalid DeckJsonMap spec. ${issues.join('; ')}`;\n}\n\nfunction extractFallbackDeckProps(spec: Record<string, unknown> | null) {\n if (!spec) {\n return {};\n }\n\n const fallbackProps: Record<string, unknown> = {};\n for (const key of ['initialViewState', 'viewState', 'controller']) {\n if (key in spec) {\n fallbackProps[key] = spec[key];\n }\n }\n\n return fallbackProps;\n}\n\nfunction filterUnavailableLayers(\n spec: Record<string, unknown>,\n datasetIds: string[],\n datasetStates: Record<string, PreparedDeckDatasetState>,\n) {\n const layers = Array.isArray(spec.layers) ? spec.layers : [];\n const filteredLayers = layers.filter((layer) => {\n if (!layer || typeof layer !== 'object') {\n return true;\n }\n\n const layerProps = layer as Record<string, unknown>;\n const layerName = String(layerProps['@@type'] ?? '');\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility) {\n return true;\n }\n\n const datasetId = resolveDatasetId(layerProps, datasetIds);\n if (!datasetId) {\n return true;\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState) {\n return false;\n }\n\n return datasetState.status === 'ready';\n });\n\n return {\n ...spec,\n layers: filteredLayers,\n };\n}\n\nfunction renderDatasetErrorOverlay(\n datasetStates: Record<string, PreparedDeckDatasetState>,\n) {\n const failedDatasets = Object.entries(datasetStates).filter(\n (\n entry,\n ): entry is [\n string,\n Extract<PreparedDeckDatasetState, {status: 'error'}>,\n ] => entry[1].status === 'error',\n );\n\n if (!failedDatasets.length) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-x-4 top-4 z-10 space-y-2\">\n {failedDatasets.map(([datasetId, state]) => (\n <div\n key={datasetId}\n className=\"rounded-md border border-red-200 bg-red-50/95 px-3 py-2 text-sm text-red-700 shadow-sm\"\n >\n {`Dataset \"${datasetId}\" failed: ${state.error.message}`}\n </div>\n ))}\n </div>\n );\n}\n\nfunction DeckOverlayControl({\n interleaved,\n ...deckProps\n}: {interleaved: boolean} & Record<string, unknown>) {\n const overlay = useControl<MapboxOverlay>(\n () => new MapboxOverlay({interleaved}),\n );\n overlay.setProps(deckProps);\n return null;\n}\n\nexport function DeckJsonMap({\n spec,\n datasets,\n mapStyle,\n interleaved = false,\n deckProps,\n mapProps,\n showLegends = true,\n className,\n children,\n onDatasetStatesChange,\n}: DeckJsonMapProps) {\n const normalizedDatasets = useMemo(\n () => normalizeDatasets(datasets),\n [datasets],\n );\n const datasetIds = useMemo(\n () => Object.keys(normalizedDatasets),\n [normalizedDatasets],\n );\n const datasetStates = usePreparedDatasetStates(normalizedDatasets);\n const onDatasetStatesChangeRef = useRef(onDatasetStatesChange);\n\n const {spec: parsedSpec, error: specError} = useMemo(\n () => parseSpec(spec),\n [spec],\n );\n\n const availableSpec = useMemo(\n () =>\n parsedSpec\n ? filterUnavailableLayers(parsedSpec, datasetIds, datasetStates)\n : null,\n [parsedSpec, datasetIds, datasetStates],\n );\n\n const converter = useMemo(\n () =>\n new JSONConverter({\n configuration: createDeckJsonConfiguration({\n datasetStates,\n datasetIds,\n }),\n onJSONChange: () => {},\n }),\n [datasetIds, datasetStates],\n );\n\n const convertedDeckPropsResult = useMemo(() => {\n if (!availableSpec) {\n return {props: null, error: specError};\n }\n\n try {\n return {\n props: converter.convert(availableSpec) as Record<string, unknown>,\n error: null,\n };\n } catch (error) {\n return {\n props: null,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }, [availableSpec, converter, specError]);\n\n useEffect(() => {\n if (convertedDeckPropsResult.error) {\n console.error(convertedDeckPropsResult.error);\n }\n }, [convertedDeckPropsResult.error]);\n\n useEffect(() => {\n onDatasetStatesChangeRef.current = onDatasetStatesChange;\n }, [onDatasetStatesChange]);\n\n useEffect(() => {\n onDatasetStatesChangeRef.current?.(datasetStates);\n }, [datasetStates]);\n\n const fallbackDeckProps = useMemo(\n () => extractFallbackDeckProps(availableSpec),\n [availableSpec],\n );\n const convertedDeckProps = (convertedDeckPropsResult.props ??\n fallbackDeckProps ??\n {}) as Record<string, unknown>;\n const extraDeckProps = (deckProps ?? {}) as Record<string, unknown>;\n const extraMapProps = (mapProps ?? {}) as Record<string, unknown>;\n const hasRenderingError = Boolean(convertedDeckPropsResult.error);\n const mergedLayers = hasRenderingError\n ? []\n : (deckProps?.layers ??\n (convertedDeckProps.layers as unknown[] | undefined) ??\n []);\n\n const mergedDeckProps = {\n ...convertedDeckProps,\n ...extraDeckProps,\n layers: mergedLayers,\n };\n\n const {resolvedTheme} = useTheme();\n\n const mergedMapProps = {\n ...extraMapProps,\n mapStyle:\n mapStyle ?? mapProps?.mapStyle ?? DEFAULT_MAP_STYLES[resolvedTheme],\n };\n const legends = useMemo(\n () =>\n showLegends\n ? extractColorScaleLegends({\n spec: availableSpec,\n datasetIds,\n datasetStates,\n })\n : [],\n [availableSpec, datasetIds, datasetStates, showLegends],\n );\n\n return (\n <div className={cn('relative h-full w-full', className)}>\n {hasRenderingError ? (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center p-4\">\n <div className=\"max-w-sm rounded-md border border-red-200 bg-red-50/95 p-4 text-sm text-red-700 shadow-sm\">\n {`Map couldn't be rendered. Check the console for details.`}\n </div>\n </div>\n ) : null}\n\n <Map\n {...(mergedMapProps as object)}\n style={{width: '100%', height: '100%', ...mapProps?.style}}\n >\n <DeckOverlayControl interleaved={interleaved} {...mergedDeckProps} />\n {children}\n </Map>\n\n {renderDatasetErrorOverlay(datasetStates)}\n {!hasRenderingError && showLegends ? (\n <div className=\"pointer-events-none absolute bottom-2 left-2 z-10 max-w-56\">\n <ColorScaleLegend legends={legends} />\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DeckJsonMap.js","sourceRoot":"","sources":["../src/DeckJsonMap.tsx"],"names":[],"mappings":"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","sourcesContent":["import {JSONConverter} from '@deck.gl/json';\nimport {MapboxOverlay} from '@deck.gl/mapbox';\nimport {ColorScaleLegend} from '@sqlrooms/color-scales';\nimport {cn, ResolvedTheme, useTheme} from '@sqlrooms/ui';\nimport 'maplibre-gl/dist/maplibre-gl.css';\nimport {useEffect, useMemo, useRef} from 'react';\nimport Map, {useControl} from 'react-map-gl/maplibre';\nimport {ZodError} from 'zod';\nimport {DeckJsonMapSpec} from './DeckJsonMapSpec';\nimport {normalizeDatasets} from './datasets/normalizeDatasets';\nimport {usePreparedDatasetStates} from './datasets/usePreparedDatasetStates';\nimport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nimport {extractColorScaleLegends} from './json/extractColorScaleLegends';\nimport {getLayerCompatibility} from './json/layerCompatibility';\nimport {resolveDatasetId} from './json/layerConfig';\nimport type {DeckJsonMapProps, PreparedDeckDatasetState} from './types';\n\nconst DEFAULT_MAP_STYLES: Record<ResolvedTheme, string> = {\n light: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',\n dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',\n};\n\nfunction parseSpec(spec: DeckJsonMapProps['spec']) {\n try {\n const parsedValue = typeof spec === 'string' ? JSON.parse(spec) : spec;\n const validatedSpec = DeckJsonMapSpec.safeParse(parsedValue);\n if (!validatedSpec.success) {\n return {\n spec: null,\n error: new Error(formatSpecValidationError(validatedSpec.error)),\n };\n }\n\n return {\n spec: validatedSpec.data,\n error: null,\n };\n } catch (error) {\n return {\n spec: null,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n\nfunction formatSpecValidationError(error: ZodError) {\n const issues = error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : 'spec';\n return `${path}: ${issue.message}`;\n });\n\n return `Invalid DeckJsonMap spec. ${issues.join('; ')}`;\n}\n\nfunction extractFallbackDeckProps(spec: Record<string, unknown> | null) {\n if (!spec) {\n return {};\n }\n\n const fallbackProps: Record<string, unknown> = {};\n for (const key of ['initialViewState', 'viewState', 'controller']) {\n if (key in spec) {\n fallbackProps[key] = spec[key];\n }\n }\n\n return fallbackProps;\n}\n\nfunction filterUnavailableLayers(\n spec: Record<string, unknown>,\n datasetIds: string[],\n datasetStates: Record<string, PreparedDeckDatasetState>,\n) {\n const layers = Array.isArray(spec.layers) ? spec.layers : [];\n const filteredLayers = layers.filter((layer) => {\n if (!layer || typeof layer !== 'object') {\n return true;\n }\n\n const layerProps = layer as Record<string, unknown>;\n const layerName = String(layerProps['@@type'] ?? '');\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility) {\n return true;\n }\n\n const datasetId = resolveDatasetId(layerProps, datasetIds);\n if (!datasetId) {\n return true;\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState) {\n return false;\n }\n\n return datasetState.status === 'ready';\n });\n\n return {\n ...spec,\n layers: filteredLayers,\n };\n}\n\nfunction renderDatasetErrorOverlay(\n datasetStates: Record<string, PreparedDeckDatasetState>,\n) {\n const failedDatasets = Object.entries(datasetStates).filter(\n (\n entry,\n ): entry is [\n string,\n Extract<PreparedDeckDatasetState, {status: 'error'}>,\n ] => entry[1].status === 'error',\n );\n\n if (!failedDatasets.length) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-x-4 top-4 z-10 space-y-2\">\n {failedDatasets.map(([datasetId, state]) => (\n <div\n key={datasetId}\n className=\"rounded-md border border-red-200 bg-red-50/95 px-3 py-2 text-sm text-red-700 shadow-sm\"\n >\n {`Dataset \"${datasetId}\" failed: ${state.error.message}`}\n </div>\n ))}\n </div>\n );\n}\n\nfunction DeckOverlayControl({\n interleaved,\n ...deckProps\n}: {interleaved: boolean} & Record<string, unknown>) {\n const overlay = useControl<MapboxOverlay>(\n () => new MapboxOverlay({interleaved}),\n );\n overlay.setProps(deckProps);\n return null;\n}\n\nexport function DeckJsonMap({\n spec,\n datasets,\n mapStyle,\n interleaved = false,\n deckProps,\n mapProps,\n showLegends = true,\n className,\n children,\n onDatasetStatesChange,\n}: DeckJsonMapProps) {\n const normalizedDatasets = useMemo(\n () => normalizeDatasets(datasets),\n [datasets],\n );\n const datasetIds = useMemo(\n () => Object.keys(normalizedDatasets),\n [normalizedDatasets],\n );\n const datasetStates = usePreparedDatasetStates(normalizedDatasets);\n const onDatasetStatesChangeRef = useRef(onDatasetStatesChange);\n\n const {spec: parsedSpec, error: specError} = useMemo(\n () => parseSpec(spec),\n [spec],\n );\n\n const availableSpec = useMemo(\n () =>\n parsedSpec\n ? filterUnavailableLayers(parsedSpec, datasetIds, datasetStates)\n : null,\n [parsedSpec, datasetIds, datasetStates],\n );\n\n const converter = useMemo(\n () =>\n new JSONConverter({\n configuration: createDeckJsonConfiguration({\n datasetStates,\n datasetIds,\n }),\n onJSONChange: () => {},\n }),\n [datasetIds, datasetStates],\n );\n\n const convertedDeckPropsResult = useMemo(() => {\n if (!availableSpec) {\n return {props: null, error: specError};\n }\n\n try {\n return {\n props: converter.convert(availableSpec) as Record<string, unknown>,\n error: null,\n };\n } catch (error) {\n return {\n props: null,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }, [availableSpec, converter, specError]);\n\n useEffect(() => {\n if (convertedDeckPropsResult.error) {\n console.error(convertedDeckPropsResult.error);\n }\n }, [convertedDeckPropsResult.error]);\n\n useEffect(() => {\n onDatasetStatesChangeRef.current = onDatasetStatesChange;\n }, [onDatasetStatesChange]);\n\n useEffect(() => {\n onDatasetStatesChangeRef.current?.(datasetStates);\n }, [datasetStates]);\n\n const fallbackDeckProps = useMemo(\n () => extractFallbackDeckProps(availableSpec),\n [availableSpec],\n );\n const convertedDeckProps = (convertedDeckPropsResult.props ??\n fallbackDeckProps ??\n {}) as Record<string, unknown>;\n const extraDeckProps = (deckProps ?? {}) as Record<string, unknown>;\n const extraMapProps = (mapProps ?? {}) as Record<string, unknown>;\n const hasRenderingError = Boolean(convertedDeckPropsResult.error);\n const mergedLayers = hasRenderingError\n ? []\n : (deckProps?.layers ??\n (convertedDeckProps.layers as unknown[] | undefined) ??\n []);\n\n const mergedDeckProps = {\n ...convertedDeckProps,\n ...extraDeckProps,\n layers: mergedLayers,\n };\n\n // overlayDeckProps should not contain viewState/initialViewState\n const {\n initialViewState,\n viewState: _viewState,\n ...overlayDeckProps\n } = mergedDeckProps as Record<string, unknown>;\n\n const {resolvedTheme} = useTheme();\n\n const mergedMapProps = {\n ...extraMapProps,\n mapStyle:\n mapStyle ?? mapProps?.mapStyle ?? DEFAULT_MAP_STYLES[resolvedTheme],\n };\n const legends = useMemo(\n () =>\n showLegends\n ? extractColorScaleLegends({\n spec: availableSpec,\n datasetIds,\n datasetStates,\n })\n : [],\n [availableSpec, datasetIds, datasetStates, showLegends],\n );\n\n return (\n <div className={cn('relative h-full w-full', className)}>\n {hasRenderingError ? (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center p-4\">\n <div className=\"max-w-sm rounded-md border border-red-200 bg-red-50/95 p-4 text-sm text-red-700 shadow-sm\">\n {`Map couldn't be rendered. Check the console for details.`}\n </div>\n </div>\n ) : null}\n\n <Map\n {...(mergedMapProps as object)}\n {...(initialViewState\n ? {initialViewState: initialViewState as object}\n : {})}\n style={{width: '100%', height: '100%', ...mapProps?.style}}\n >\n <DeckOverlayControl interleaved={interleaved} {...overlayDeckProps} />\n {children}\n </Map>\n\n {renderDatasetErrorOverlay(datasetStates)}\n {!hasRenderingError && showLegends ? (\n <div className=\"pointer-events-none absolute bottom-2 left-2 z-10 max-w-56\">\n <ColorScaleLegend legends={legends} />\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|
package/dist/MapSettings.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState } from 'react';
|
|
3
|
-
import { Field, ColumnSelector, ColumnsProvider, useStoreWithMosaicDashboard,
|
|
3
|
+
import { Field, ColumnSelector, ColumnsProvider, useStoreWithMosaicDashboard, } from '@sqlrooms/mosaic';
|
|
4
|
+
import { useDataTable } from '@sqlrooms/duckdb';
|
|
4
5
|
import { binnedNumericSchemes, categoricalSchemes, continuousDivergingSchemes, continuousSequentialSchemes, } from '@sqlrooms/color-scales';
|
|
5
6
|
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Switch, } from '@sqlrooms/ui';
|
|
6
7
|
import { XIcon } from 'lucide-react';
|
package/dist/MapSettings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapSettings.js","sourceRoot":"","sources":["../src/MapSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useCallback, useState} from 'react';\nimport {\n Field,\n ColumnSelector,\n ColumnsProvider,\n useStoreWithMosaicDashboard,\n useDataTable,\n} from '@sqlrooms/mosaic';\nimport type {MosaicDashboardPanelConfigType} from '@sqlrooms/mosaic';\nimport {\n binnedNumericSchemes,\n categoricalSchemes,\n continuousDivergingSchemes,\n continuousSequentialSchemes,\n} from '@sqlrooms/color-scales';\nimport type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport {\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n} from '@sqlrooms/ui';\nimport {XIcon} from 'lucide-react';\nimport {LatitudeSelector} from './LatitudeSelector';\nimport {LongitudeSelector} from './LongitudeSelector';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport {DEFAULT_DECK_MAP_MAX_DATA_POINTS} from './dashboardConfig';\nimport {\n clearDeckMapLayerColorScale,\n createDeckMapLayerColorScale,\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS,\n DECK_MAP_LAYER_TYPE_OPTIONS,\n getDeckMapColorAccessorOptions,\n getDeckMapLayerDatasetId,\n getDeckMapLayerColorScale,\n getDeckMapLayerRecords,\n setDeckMapLayerColorScale,\n setDeckMapLayerGeometryColumn,\n setDeckMapLayerType,\n type DeckMapLayerColorAccessor,\n usesGeometryColumnSetting,\n} from './mapLayerConfigUtils';\n\ninterface MapSettingsPanelProps {\n dashboardId: string;\n panel: MosaicDashboardPanelConfigType;\n onClose?: () => void;\n}\n\nfunction getSchemeOptions(type: ColorScaleConfig['type']) {\n if (type === 'categorical') {\n return categoricalSchemes;\n }\n if (type === 'diverging') {\n return continuousDivergingSchemes;\n }\n if (type === 'sequential') {\n return continuousSequentialSchemes;\n }\n return binnedNumericSchemes;\n}\n\nexport const MapSettingsPanel: FC<MapSettingsPanelProps> = ({\n dashboardId,\n panel,\n onClose,\n}) => {\n const [layerIndex, setLayerIndex] = useState(0);\n const [colorAccessor, setColorAccessor] =\n useState<DeckMapLayerColorAccessor>('getFillColor');\n\n const tableName = useStoreWithMosaicDashboard(\n (state) =>\n state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable,\n );\n\n const dataTable = useDataTable(tableName);\n\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n\n const mapConfig = panel.config as DeckMapDashboardPanelConfig;\n const layers = getDeckMapLayerRecords(mapConfig);\n const activeLayerIndex = Math.min(layerIndex, Math.max(layers.length - 1, 0));\n const activeLayer = layers[activeLayerIndex];\n const activeLayerDatasetId = getDeckMapLayerDatasetId(activeLayer);\n const activeLayerDataset = activeLayerDatasetId\n ? mapConfig.datasets?.[activeLayerDatasetId]\n : undefined;\n const showGeometryColumnSetting = usesGeometryColumnSetting(\n activeLayer?.['@@type'],\n );\n const colorAccessorOptions = getDeckMapColorAccessorOptions(\n activeLayer?.['@@type'],\n );\n const effectiveColorAccessor =\n colorAccessorOptions.find((option) => option.value === colorAccessor)\n ?.value ?? colorAccessorOptions[0]?.value;\n const colorScale = effectiveColorAccessor\n ? getDeckMapLayerColorScale(activeLayer, effectiveColorAccessor)\n : undefined;\n const colorScaleType = colorScale?.type ?? 'sequential';\n const schemeOptions = getSchemeOptions(colorScaleType);\n const firstColumnName = dataTable?.columns[0]?.name;\n const maxRows =\n mapConfig.dataPolicy?.maxRows ?? DEFAULT_DECK_MAP_MAX_DATA_POINTS;\n\n const applyConfig = useCallback(\n (config: DeckMapDashboardPanelConfig) => {\n updatePanel(dashboardId, panel.id, {\n config: {...config, settingsOpen: mapConfig.settingsOpen} as any,\n });\n },\n [dashboardId, mapConfig.settingsOpen, panel.id, updatePanel],\n );\n\n const updateColorScale = (patch: {\n field?: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n }) => {\n const field = patch.field ?? colorScale?.field ?? firstColumnName;\n if (!field || !effectiveColorAccessor) return;\n\n const type = patch.type ?? colorScale?.type ?? 'sequential';\n const scheme =\n patch.scheme ??\n (patch.type && patch.type !== colorScale?.type\n ? undefined\n : colorScale?.scheme);\n\n applyConfig(\n setDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n createDeckMapLayerColorScale({\n field,\n type,\n scheme,\n title: field,\n }),\n ),\n );\n };\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium\">\n <div className=\"flex items-center\">Map settings</div>\n {onClose && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-5 w-5\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2\">\n {layers.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {layers.length > 1 && (\n <Field label=\"Layer\">\n <Select\n value={String(activeLayerIndex)}\n onValueChange={(value) => setLayerIndex(Number(value))}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {layers.map((layer, index) => (\n <SelectItem key={index} value={String(index)}>\n {String(layer.id ?? `Layer ${index + 1}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n <Field label=\"Layer type\">\n <Select\n value={\n typeof activeLayer?.['@@type'] === 'string'\n ? activeLayer['@@type']\n : undefined\n }\n onValueChange={(value) =>\n applyConfig(\n setDeckMapLayerType(mapConfig, activeLayerIndex, value),\n )\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select layer type\" />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium\">Color scale</span>\n <Switch\n checked={Boolean(colorScale)}\n onCheckedChange={(checked) => {\n if (!effectiveColorAccessor) return;\n if (checked) {\n updateColorScale({});\n return;\n }\n applyConfig(\n clearDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n ),\n );\n }}\n disabled={!firstColumnName || !effectiveColorAccessor}\n />\n </div>\n\n {effectiveColorAccessor && (\n <Field label=\"Color property\">\n <Select\n value={effectiveColorAccessor}\n onValueChange={(value) =>\n setColorAccessor(value as DeckMapLayerColorAccessor)\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {colorAccessorOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n {colorScale && dataTable && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Color field\" required>\n {colorScaleType === 'categorical' ? (\n <ColumnSelector.Categorical\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n ) : (\n <ColumnSelector.Quantitative\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n )}\n </Field>\n </ColumnsProvider>\n )}\n\n {colorScale && (\n <>\n <Field label=\"Scale type\">\n <Select\n value={colorScaleType}\n onValueChange={(value) =>\n updateColorScale({\n type: value as ColorScaleConfig['type'],\n })\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <Field label=\"Scheme\">\n <Select\n value={colorScale.scheme}\n onValueChange={(value) =>\n updateColorScale({scheme: value as ColorScaleScheme})\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {schemeOptions.map((scheme) => (\n <SelectItem key={scheme} value={scheme}>\n {scheme}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </>\n )}\n </div>\n </div>\n )}\n\n {dataTable && showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Geometry column\" required>\n <ColumnSelector\n value={activeLayerDataset?.geometryColumn}\n onChange={(geometryColumn) =>\n applyConfig(\n setDeckMapLayerGeometryColumn(\n mapConfig,\n activeLayerIndex,\n geometryColumn,\n ),\n )\n }\n placeholder=\"Select geometry column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {dataTable && !showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Latitude column\" required>\n <LatitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n <Field label=\"Longitude column\" required>\n <LongitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n </ColumnsProvider>\n )}\n\n <Field label=\"Max rows\">\n <Input\n type=\"number\"\n min={1}\n value={maxRows}\n className=\"no-spinner\"\n onChange={(event) => {\n const parsed = Number.parseInt(event.target.value, 10);\n if (!Number.isFinite(parsed) || parsed < 1) return;\n applyConfig({\n ...mapConfig,\n dataPolicy: {\n ...mapConfig.dataPolicy,\n maxRows: parsed,\n },\n });\n }}\n placeholder={String(DEFAULT_DECK_MAP_MAX_DATA_POINTS)}\n />\n </Field>\n </div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"MapSettings.js","sourceRoot":"","sources":["../src/MapSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useCallback, useState} from 'react';\nimport {\n Field,\n ColumnSelector,\n ColumnsProvider,\n useStoreWithMosaicDashboard,\n} from '@sqlrooms/mosaic';\nimport {useDataTable} from '@sqlrooms/duckdb';\nimport type {MosaicDashboardPanelConfigType} from '@sqlrooms/mosaic';\nimport {\n binnedNumericSchemes,\n categoricalSchemes,\n continuousDivergingSchemes,\n continuousSequentialSchemes,\n} from '@sqlrooms/color-scales';\nimport type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport {\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n} from '@sqlrooms/ui';\nimport {XIcon} from 'lucide-react';\nimport {LatitudeSelector} from './LatitudeSelector';\nimport {LongitudeSelector} from './LongitudeSelector';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport {DEFAULT_DECK_MAP_MAX_DATA_POINTS} from './dashboardConfig';\nimport {\n clearDeckMapLayerColorScale,\n createDeckMapLayerColorScale,\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS,\n DECK_MAP_LAYER_TYPE_OPTIONS,\n getDeckMapColorAccessorOptions,\n getDeckMapLayerDatasetId,\n getDeckMapLayerColorScale,\n getDeckMapLayerRecords,\n setDeckMapLayerColorScale,\n setDeckMapLayerGeometryColumn,\n setDeckMapLayerType,\n type DeckMapLayerColorAccessor,\n usesGeometryColumnSetting,\n} from './mapLayerConfigUtils';\n\ninterface MapSettingsPanelProps {\n dashboardId: string;\n panel: MosaicDashboardPanelConfigType;\n onClose?: () => void;\n}\n\nfunction getSchemeOptions(type: ColorScaleConfig['type']) {\n if (type === 'categorical') {\n return categoricalSchemes;\n }\n if (type === 'diverging') {\n return continuousDivergingSchemes;\n }\n if (type === 'sequential') {\n return continuousSequentialSchemes;\n }\n return binnedNumericSchemes;\n}\n\nexport const MapSettingsPanel: FC<MapSettingsPanelProps> = ({\n dashboardId,\n panel,\n onClose,\n}) => {\n const [layerIndex, setLayerIndex] = useState(0);\n const [colorAccessor, setColorAccessor] =\n useState<DeckMapLayerColorAccessor>('getFillColor');\n\n const tableName = useStoreWithMosaicDashboard(\n (state) =>\n state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable,\n );\n\n const dataTable = useDataTable(tableName);\n\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n\n const mapConfig = panel.config as DeckMapDashboardPanelConfig;\n const layers = getDeckMapLayerRecords(mapConfig);\n const activeLayerIndex = Math.min(layerIndex, Math.max(layers.length - 1, 0));\n const activeLayer = layers[activeLayerIndex];\n const activeLayerDatasetId = getDeckMapLayerDatasetId(activeLayer);\n const activeLayerDataset = activeLayerDatasetId\n ? mapConfig.datasets?.[activeLayerDatasetId]\n : undefined;\n const showGeometryColumnSetting = usesGeometryColumnSetting(\n activeLayer?.['@@type'],\n );\n const colorAccessorOptions = getDeckMapColorAccessorOptions(\n activeLayer?.['@@type'],\n );\n const effectiveColorAccessor =\n colorAccessorOptions.find((option) => option.value === colorAccessor)\n ?.value ?? colorAccessorOptions[0]?.value;\n const colorScale = effectiveColorAccessor\n ? getDeckMapLayerColorScale(activeLayer, effectiveColorAccessor)\n : undefined;\n const colorScaleType = colorScale?.type ?? 'sequential';\n const schemeOptions = getSchemeOptions(colorScaleType);\n const firstColumnName = dataTable?.columns[0]?.name;\n const maxRows =\n mapConfig.dataPolicy?.maxRows ?? DEFAULT_DECK_MAP_MAX_DATA_POINTS;\n\n const applyConfig = useCallback(\n (config: DeckMapDashboardPanelConfig) => {\n updatePanel(dashboardId, panel.id, {\n config: {...config, settingsOpen: mapConfig.settingsOpen} as any,\n });\n },\n [dashboardId, mapConfig.settingsOpen, panel.id, updatePanel],\n );\n\n const updateColorScale = (patch: {\n field?: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n }) => {\n const field = patch.field ?? colorScale?.field ?? firstColumnName;\n if (!field || !effectiveColorAccessor) return;\n\n const type = patch.type ?? colorScale?.type ?? 'sequential';\n const scheme =\n patch.scheme ??\n (patch.type && patch.type !== colorScale?.type\n ? undefined\n : colorScale?.scheme);\n\n applyConfig(\n setDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n createDeckMapLayerColorScale({\n field,\n type,\n scheme,\n title: field,\n }),\n ),\n );\n };\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium\">\n <div className=\"flex items-center\">Map settings</div>\n {onClose && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-5 w-5\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2\">\n {layers.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {layers.length > 1 && (\n <Field label=\"Layer\">\n <Select\n value={String(activeLayerIndex)}\n onValueChange={(value) => setLayerIndex(Number(value))}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {layers.map((layer, index) => (\n <SelectItem key={index} value={String(index)}>\n {String(layer.id ?? `Layer ${index + 1}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n <Field label=\"Layer type\">\n <Select\n value={\n typeof activeLayer?.['@@type'] === 'string'\n ? activeLayer['@@type']\n : undefined\n }\n onValueChange={(value) =>\n applyConfig(\n setDeckMapLayerType(mapConfig, activeLayerIndex, value),\n )\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select layer type\" />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium\">Color scale</span>\n <Switch\n checked={Boolean(colorScale)}\n onCheckedChange={(checked) => {\n if (!effectiveColorAccessor) return;\n if (checked) {\n updateColorScale({});\n return;\n }\n applyConfig(\n clearDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n ),\n );\n }}\n disabled={!firstColumnName || !effectiveColorAccessor}\n />\n </div>\n\n {effectiveColorAccessor && (\n <Field label=\"Color property\">\n <Select\n value={effectiveColorAccessor}\n onValueChange={(value) =>\n setColorAccessor(value as DeckMapLayerColorAccessor)\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {colorAccessorOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n {colorScale && dataTable && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Color field\" required>\n {colorScaleType === 'categorical' ? (\n <ColumnSelector.Categorical\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n ) : (\n <ColumnSelector.Quantitative\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n )}\n </Field>\n </ColumnsProvider>\n )}\n\n {colorScale && (\n <>\n <Field label=\"Scale type\">\n <Select\n value={colorScaleType}\n onValueChange={(value) =>\n updateColorScale({\n type: value as ColorScaleConfig['type'],\n })\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <Field label=\"Scheme\">\n <Select\n value={colorScale.scheme}\n onValueChange={(value) =>\n updateColorScale({scheme: value as ColorScaleScheme})\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {schemeOptions.map((scheme) => (\n <SelectItem key={scheme} value={scheme}>\n {scheme}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </>\n )}\n </div>\n </div>\n )}\n\n {dataTable && showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Geometry column\" required>\n <ColumnSelector\n value={activeLayerDataset?.geometryColumn}\n onChange={(geometryColumn) =>\n applyConfig(\n setDeckMapLayerGeometryColumn(\n mapConfig,\n activeLayerIndex,\n geometryColumn,\n ),\n )\n }\n placeholder=\"Select geometry column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {dataTable && !showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Latitude column\" required>\n <LatitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n <Field label=\"Longitude column\" required>\n <LongitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n </ColumnsProvider>\n )}\n\n <Field label=\"Max rows\">\n <Input\n type=\"number\"\n min={1}\n value={maxRows}\n className=\"no-spinner\"\n onChange={(event) => {\n const parsed = Number.parseInt(event.target.value, 10);\n if (!Number.isFinite(parsed) || parsed < 1) return;\n applyConfig({\n ...mapConfig,\n dataPolicy: {\n ...mapConfig.dataPolicy,\n maxRows: parsed,\n },\n });\n }}\n placeholder={String(DEFAULT_DECK_MAP_MAX_DATA_POINTS)}\n />\n </Field>\n </div>\n </div>\n );\n};\n"]}
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { type MosaicDashboardPanelRenderer } from '@sqlrooms/mosaic';
|
|
2
|
+
import { type DeckMapDashboardFitToDataConfig } from './dashboardConfig';
|
|
3
|
+
export declare function createDeckMapBoundsQuery(options: {
|
|
4
|
+
source: {
|
|
5
|
+
tableName?: string;
|
|
6
|
+
sqlQuery?: string;
|
|
7
|
+
};
|
|
8
|
+
fitToData: DeckMapDashboardFitToDataConfig;
|
|
9
|
+
}): string;
|
|
2
10
|
export declare const deckMapDashboardPanelRenderer: MosaicDashboardPanelRenderer;
|
|
3
11
|
export declare const deckMapDashboardAddPanelAction: import('@sqlrooms/mosaic').MosaicDashboardAddPanelAction;
|
|
4
12
|
//# sourceMappingURL=dashboard.d.ts.map
|
package/dist/dashboard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"AAWA,OAAO,EAIL,KAAK,4BAA4B,EAalC,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAML,KAAK,+BAA+B,EAKrC,MAAM,mBAAmB,CAAC;AAyI3B,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,MAAM,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IAChD,SAAS,EAAE,+BAA+B,CAAC;CAC5C,UAqBA;AA6kBD,eAAO,MAAM,6BAA6B,EAAE,4BAI3C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,OAAO,kBAAkB,EAAE,6BAmBrE,CAAC"}
|
package/dist/dashboard.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { WebMercatorViewport } from '@deck.gl/core';
|
|
3
|
-
import { escapeId, getColValAsNumber, useStoreWithDuckDb, } from '@sqlrooms/duckdb';
|
|
4
|
-
import { column, sql, useMosaicClient, useStoreWithMosaicDashboard, } from '@sqlrooms/mosaic';
|
|
3
|
+
import { escapeId, getColValAsNumber, quoteTableReference, useStoreWithDuckDb, } from '@sqlrooms/duckdb';
|
|
4
|
+
import { column, sql, useMosaicClient, useStoreWithMosaicDashboard, usePanelClientRegistration, usePanelClients, usePanelResetFilters, ResetFiltersButton, } from '@sqlrooms/mosaic';
|
|
5
5
|
import { Button, Tooltip, TooltipContent, TooltipTrigger } from '@sqlrooms/ui';
|
|
6
6
|
import { FocusIcon, MapIcon, SettingsIcon } from 'lucide-react';
|
|
7
7
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
@@ -38,6 +38,8 @@ function DeckMapDashboardDatasetClient({ dashboard, dataset, datasetId, dataPoli
|
|
|
38
38
|
runtimeIssueContext,
|
|
39
39
|
runtimeIssueReporter,
|
|
40
40
|
});
|
|
41
|
+
// Register client for panel reset button
|
|
42
|
+
usePanelClientRegistration(dashboard.id, panel.id, client ? [client] : []);
|
|
41
43
|
useEffect(() => {
|
|
42
44
|
onDatasetState(datasetId, {
|
|
43
45
|
arrowTable: data ?? undefined,
|
|
@@ -70,14 +72,11 @@ function getCoordinate(info) {
|
|
|
70
72
|
function isPickedMapFeature(info) {
|
|
71
73
|
return Boolean(info.picked || info.object || (info.index ?? -1) >= 0);
|
|
72
74
|
}
|
|
73
|
-
function createDeckMapBoundsQuery(options) {
|
|
75
|
+
export function createDeckMapBoundsQuery(options) {
|
|
74
76
|
const { source, fitToData } = options;
|
|
75
77
|
const baseSourceSql = source.sqlQuery
|
|
76
78
|
? `SELECT * FROM (${source.sqlQuery}) AS "__sqlrooms_dashboard_map_source"`
|
|
77
|
-
: `SELECT * FROM ${(source.tableName ?? '')
|
|
78
|
-
.split('.')
|
|
79
|
-
.map(escapeId)
|
|
80
|
-
.join('.')}`;
|
|
79
|
+
: `SELECT * FROM ${quoteTableReference(source.tableName ?? '')}`;
|
|
81
80
|
const longitudeColumn = escapeId(fitToData.longitudeColumn);
|
|
82
81
|
const latitudeColumn = escapeId(fitToData.latitudeColumn);
|
|
83
82
|
return `
|
|
@@ -145,8 +144,13 @@ function createInitialDeckMapDashboardFitState(key) {
|
|
|
145
144
|
handledFitRequestVersion: 0,
|
|
146
145
|
};
|
|
147
146
|
}
|
|
148
|
-
function DeckMapDashboardHeaderActions({ dashboardId, panel, }) {
|
|
147
|
+
function DeckMapDashboardHeaderActions({ dashboardId, panel, selectionName, }) {
|
|
149
148
|
const updatePanel = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.updatePanel);
|
|
149
|
+
const panelClients = usePanelClients(dashboardId, panel.id);
|
|
150
|
+
const { hasActiveFilters, reset } = usePanelResetFilters({
|
|
151
|
+
panelClients,
|
|
152
|
+
selectionName,
|
|
153
|
+
});
|
|
150
154
|
const mapConfig = asDeckJsonMapConfig(panel.config);
|
|
151
155
|
const canFitView = Boolean(mapConfig?.fitToData);
|
|
152
156
|
const isSettingsOpen = Boolean(mapConfig?.settingsOpen);
|
|
@@ -160,7 +164,7 @@ function DeckMapDashboardHeaderActions({ dashboardId, panel, }) {
|
|
|
160
164
|
config: { ...panel.config, settingsOpen: !isSettingsOpen },
|
|
161
165
|
});
|
|
162
166
|
}, [dashboardId, isSettingsOpen, panel.config, panel.id, updatePanel]);
|
|
163
|
-
return (_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "data-[state=active]:bg-accent h-6 w-6", title: "Map settings", onClick: handleToggleSettings, "data-state": isSettingsOpen ? 'active' : 'inactive', children: _jsx(SettingsIcon, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Map settings" })] }), _jsx(DeckMapConfigPopoverEditor, { value: panel.config, onApply: handleConfigApply }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", title: canFitView
|
|
167
|
+
return (_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx(ResetFiltersButton, { disabled: !hasActiveFilters, onClick: reset, tooltip: "Reset panel filters" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "data-[state=active]:bg-accent h-6 w-6", title: "Map settings", onClick: handleToggleSettings, "data-state": isSettingsOpen ? 'active' : 'inactive', children: _jsx(SettingsIcon, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Map settings" })] }), _jsx(DeckMapConfigPopoverEditor, { value: panel.config, onApply: handleConfigApply }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", title: canFitView
|
|
164
168
|
? 'Fit map view to data'
|
|
165
169
|
: 'Fit view unavailable for this map', disabled: !canFitView, onClick: () => emitDeckMapDashboardFitRequest(panel.id), children: _jsx(FocusIcon, { className: "h-3.5 w-3.5" }) })] }));
|
|
166
170
|
}
|
package/dist/dashboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAKlD,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,MAAM,EAKN,GAAG,EAKH,eAAe,EACf,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AAI7E,OAAO,EAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACxE,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAC,0BAA0B,EAAC,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,mBAAmB,EACnB,kCAAkC,EAClC,8BAA8B,EAC9B,6BAA6B,EAC7B,oCAAoC,GAMrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EACL,yCAAyC,EACzC,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,SAAS,wBAAwB,CAAC,EAAC,KAAK,EAA6B;IACnE,MAAM,KAAK,GACT,KAAK,CAAC,IAAI,KAAK,eAAe;QAC5B,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW;YAC1B,CAAC,CAAC,kBAAkB;YACpB,CAAC,CAAC,uBAAuB,CAAC;IAEhC,OAAO,CACL,eAAK,SAAS,EAAC,oEAAoE,aACjF,cAAK,SAAS,EAAC,gCAAgC,YAAE,KAAK,GAAO,EAC7D,cAAK,SAAS,EAAC,yCAAyC,YACrD,KAAK,CAAC,OAAO,GACV,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,EACrC,SAAS,EACT,OAAO,EACP,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,GAcd;IACC,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CACH,oCAAoC,CAAC;QACnC,SAAS;QACT,KAAK;QACL,OAAO;KACR,CAAC,EACJ,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAC5B,CAAC;IACF,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,MAAe,EAAE,EAAE,CAClB,MAAM;QACJ,CAAC,CAAC,kCAAkC,CAAC,MAAM,EAAE,MAAM,CAAC;QACpD,CAAC,CAAC,kCAAkC,CAChC,EAAC,SAAS,EAAE,mCAAmC,EAAC,EAChD,MAAM,CACP,EACP,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,EAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAC,GAAG,eAAe,CAAC;QACvD,EAAE,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,SAAS,EAAE;QAC9B,aAAa;QACb,KAAK;QACL,UAAU;QACV,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC;QACxB,mBAAmB;QACnB,oBAAoB;KACrB,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,SAAS,EAAE;YACxB,UAAU,EAAE,IAAI,IAAI,SAAS;YAC7B,KAAK;YACL,SAAS;YACT,MAAM;SACP,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAEhE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,0BAA0B,CACjC,WAA8C,EAC9C,UAA4B;IAE5B,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC;IACzC,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,IAAI,GAAG,CAAC;IACrD,MAAM,eAAe,GAAG,OAAO,CAAC;IAChC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,YAAY,GAAG,YAAY,CAAC;IAElD,OAAO,GAAG,CAAA;WACD,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,MAAM,SAAS,OACvD,WAAW,GAAG,eAChB;WACO,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,QAAQ,OACrD,eACF;QACI,aAAa,EAAE,CAAC;AACxB,CAAC;AASD,SAAS,aAAa,CACpB,IAA6B;IAE7B,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;QACnD,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAC5C,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,kBAAkB,CAAC,IAA6B;IACvD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,wBAAwB,CAAC,OAGjC;IACC,MAAM,EAAC,MAAM,EAAE,SAAS,EAAC,GAAG,OAAO,CAAC;IACpC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ;QACnC,CAAC,CAAC,kBAAkB,MAAM,CAAC,QAAQ,wCAAwC;QAC3E,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;aACtC,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,QAAQ,CAAC;aACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACnB,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAE1D,OAAO;;;;;;;sCAO6B,eAAe,KAAK,cAAc;cAC1D,aAAa;cACb,eAAe,oBAAoB,cAAc;;;GAG5D,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,MAAkB;IACpD,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9D,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC9B,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC7B,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC9B,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC7B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL;YACE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY;YAClE,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW;SAC/D;QACD;YACE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY;YAClE,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW;SAC/D;KACO,CAAC;AACb,CAAC;AAED,SAAS,oBAAoB,CAAC,OAM7B;IACC,MAAM,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAC,GAAG,OAAO,CAAC;IACpE,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC;QACvC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACzB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAC/B;QACE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7B,EACD,EAAC,OAAO,EAAC,CAKV,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,gCAAgC,GAAG,IAAI,WAAW,EAAE,CAAC;AAE3D,SAAS,8BAA8B,CAAC,OAAe;IACrD,gCAAgC,CAAC,aAAa,CAC5C,IAAI,WAAW,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,EAAC,OAAO,EAAC,EAAC,CAAC,CACjD,CAAC;AACJ,CAAC;AAUD,SAAS,qCAAqC,CAC5C,GAAW;IAEX,OAAO;QACL,GAAG;QACH,SAAS,EAAE,SAAS;QACpB,UAAU,EAAE,KAAK;QACjB,iBAAiB,EAAE,CAAC;QACpB,wBAAwB,EAAE,CAAC;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,EACrC,WAAW,EACX,KAAK,GAC6B;IAClC,MAAM,WAAW,GAAG,2BAA2B,CAC7C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,WAAW,CAC7C,CAAC;IACF,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEjD,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAExD,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,UAAmC,EAAE,EAAE;QACtC,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE;YACjC,MAAM,EAAE,UAAU;SACnB,CAAC,CAAC;IACL,CAAC,EACD,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CACrC,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE;YACjC,MAAM,EAAE,EAAC,GAAG,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,cAAc,EAAC;SACzD,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAEvE,OAAO,CACL,eAAK,SAAS,EAAC,2BAA2B,aACxC,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,uCAAuC,EACjD,KAAK,EAAC,cAAc,EACpB,OAAO,EAAE,oBAAoB,gBACjB,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,YAElD,KAAC,YAAY,IAAC,SAAS,EAAC,aAAa,GAAG,GACjC,GACM,EACjB,KAAC,cAAc,+BAA8B,IACrC,EACV,KAAC,0BAA0B,IACzB,KAAK,EAAE,KAAK,CAAC,MAAM,EACnB,OAAO,EAAE,iBAAiB,GAC1B,EACF,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,SAAS,EACnB,KAAK,EACH,UAAU;oBACR,CAAC,CAAC,sBAAsB;oBACxB,CAAC,CAAC,mCAAmC,EAEzC,QAAQ,EAAE,CAAC,UAAU,EACrB,OAAO,EAAE,GAAG,EAAE,CAAC,8BAA8B,CAAC,KAAK,CAAC,EAAE,CAAC,YAEvD,KAAC,SAAS,IAAC,SAAS,EAAC,aAAa,GAAG,GAC9B,IACL,CACP,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,EAChC,SAAS,EACT,WAAW,EACX,KAAK,EACL,aAAa,GACqB;IAClC,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,2BAA2B,CAC9C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CACrC,CAAC;IACF,MAAM,WAAW,GAAG,2BAA2B,CAC7C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,WAAW,CAC7C,CAAC;IACF,MAAM,KAAK,GAAG,2BAA2B,CAAC,CAAC,KAAK,EAAE,EAAE,CAClD,KAAK,CAAC,eAAe,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAC3D,CAAC;IACF,MAAM,gBAAgB,GAAG,2BAA2B,CAClD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,gBAAgB,CAClD,CAAC;IACF,MAAM,eAAe,GAAG,2BAA2B,CACjD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,eAAe,CACjD,CAAC;IACF,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAEtE,MAAM,cAAc,GAAG,OAAO,CAC3B,KAAK,CAAC,MAAsC,CAAC,YAAY,CAC3D,CAAC;IAEF,MAAM,wBAAwB,GAAG,WAAW,CAC1C,CAAC,MAAe,EAAE,EAAE;QAClB,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE;YACjC,MAAM,EAAE,EAAC,GAAG,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAC;SAChD,CAAC,CAAC;IACL,CAAC,EACD,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CACnD,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,aAAa,CAAC,EAChD,CAAC,YAAY,EAAE,aAAa,CAAC,CAC9B,CAAC;IACF,MAAM,YAAY,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACzD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAEhD,EAAE,CAAC,CAAC;IACN,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,EAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAC,CAAC,CAAC;IAE1E,MAAM,kBAAkB,GAAG,WAAW,CACpC,CACE,SAAiB,EACjB,KAAqD,EACrD,EAAE;QACF,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,IAAI,GAAG,EAAC,GAAG,OAAO,EAAC,CAAC;YAC1B,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,UAAU,GAAG,OAAO,CACxB,GAAG,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,EACrC,CAAC,SAAS,CAAC,CACZ,CAAC;IACF,MAAM,mBAAmB,GAAG,OAAO,CACjC,GAAG,EAAE,CAAC,CAAC;QACL,OAAO,EAAE,KAAK,CAAC,EAAE;QACjB,SAAS,EAAE,6BAA6B;KACzC,CAAC,EACF,CAAC,KAAK,CAAC,EAAE,CAAC,CACX,CAAC;IACF,MAAM,oBAAoB,GAAG,OAAO,CAClC,GAAG,EAAE,CAAC,CAAC;QACL,WAAW,EAAE,CAAC,aAAa,EAAE,EAAE;YAC7B,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACzD,CAAC;QACD,UAAU,EAAE,GAAG,EAAE;YACf,eAAe,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;KACF,CAAC,EACF,CAAC,eAAe,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAC3D,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,gBAAgB,CAAC;gBACf,KAAK,EAAE,SAAS,CAAC,WAAW;gBAC5B,MAAM,EAAE,SAAS,CAAC,YAAY;aAC/B,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,UAAU,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,UAAU,CAAC,CAAC;QAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE5B,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC;IAC/C,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CACH,SAAS;QACP,CAAC,CAAC,oCAAoC,CAAC;YACnC,SAAS;YACT,KAAK;YACL,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;SAChD,CAAC;QACJ,CAAC,CAAC,SAAS,EACf,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,CACnD,CAAC;IACF,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CACH,SAAS,IAAI,eAAe;QAC1B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YACb,MAAM,EAAE,eAAe;YACvB,SAAS;SACV,CAAC;QACJ,CAAC,CAAC,IAAI,EACV,CAAC,SAAS,EAAE,eAAe,CAAC,CAC7B,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,YAAY,EAAC,CAAC,EACvD,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,CACzB,CAAC;IACF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAA2B,GAAG,EAAE,CACtE,qCAAqC,CAAC,WAAW,CAAC,CACnD,CAAC;IACF,MAAM,cAAc,GAClB,QAAQ,CAAC,GAAG,KAAK,WAAW;QAC1B,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,EAAC,UAAU,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,SAAS,EAAC,GACxE,cAAc,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,gBAAgB,GAAG,CAAC,KAAY,EAAE,EAAE;YACxC,MAAM,MAAM,GAAI,KAAyC,CAAC,MAAM,CAAC;YACjE,IAAI,MAAM,EAAE,OAAO,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;gBACjC,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;oBACtB,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,KAAK,WAAW;wBACzB,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;oBACzD,OAAO;wBACL,GAAG,MAAM;wBACT,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,GAAG,CAAC;qBAChD,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QAEF,gCAAgC,CAAC,gBAAgB,CAC/C,UAAU,EACV,gBAAgB,CACjB,CAAC;QACF,OAAO,GAAG,EAAE;YACV,gCAAgC,CAAC,mBAAmB,CAClD,UAAU,EACV,gBAAgB,CACjB,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,wBAAwB,CAAC;QACzE,IACE,CAAC,SAAS;YACV,CAAC,eAAe;YAChB,aAAa,CAAC,KAAK,IAAI,CAAC;YACxB,aAAa,CAAC,MAAM,IAAI,CAAC;YACzB,CAAC,CAAC,mBAAmB,IAAI,UAAU,CAAC,EACpC,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;YACjC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAC7B,wBAAwB,CAAC;oBACvB,MAAM,EAAE,eAAe;oBACvB,SAAS;iBACV,CAAC,CACH,CAAC;gBACF,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC5C,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC3B,OAAO;gBACT,CAAC;gBAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;gBAClD,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;wBACtB,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,KAAK,WAAW;4BACzB,CAAC,CAAC,OAAO;4BACT,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;wBACzD,OAAO;4BACL,GAAG,MAAM;4BACT,UAAU,EAAE,IAAI;4BAChB,wBAAwB,EAAE,iBAAiB;yBAC5C,CAAC;oBACJ,CAAC,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GAAG,oBAAoB,CAAC;oBACzC,MAAM;oBACN,KAAK,EAAE,aAAa,CAAC,KAAK;oBAC1B,MAAM,EAAE,aAAa,CAAC,MAAM;oBAC5B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;iBAC3B,CAAC,CAAC;gBACH,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;oBACtB,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,KAAK,WAAW;wBACzB,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;oBACzD,OAAO;wBACL,GAAG,MAAM;wBACT,SAAS,EAAE,aAAa;wBACxB,UAAU,EAAE,IAAI;wBAChB,wBAAwB,EAAE,iBAAiB;qBAC5C,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;wBACtB,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,KAAK,WAAW;4BACzB,CAAC,CAAC,OAAO;4BACT,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;wBACzD,OAAO;4BACL,GAAG,MAAM;4BACT,UAAU,EAAE,IAAI;4BAChB,wBAAwB,EAAE,iBAAiB;yBAC5C,CAAC;oBACJ,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,eAAe,EAAE,CAAC;QAEvB,OAAO,GAAG,EAAE;YACV,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,aAAa,CAAC,MAAM;QACpB,aAAa,CAAC,KAAK;QACnB,UAAU;QACV,UAAU;QACV,iBAAiB;QACjB,WAAW;QACX,SAAS;QACT,eAAe;QACf,wBAAwB;KACzB,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,IAA6B,EAAE,EAAE;QAChC,MAAM,WAAW,GAAG,SAAS,EAAE,WAAW,CAAC;QAC3C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAGtC,CAAC;QACd,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,WAAW,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/D,SAAS,CAAC,KAAK,CACb,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAC/D,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,IAAI,GAAG,CAAC;QACrD,SAAS,CAAC,MAAM,CAAC;YACf,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YAC1B,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;YACnD,SAAS,EAAE,0BAA0B,CAAC,WAAW,EAAE,UAAU,CAAC;SAC/D,CAAC,CAAC;IACL,CAAC,EACD,CAAC,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC,CACnD,CAAC;IAEF,MAAM,qBAAqB,GAAG,WAAW,CACvC,CAAC,EACC,SAAS,EAAE,aAAa,EACxB,gBAAgB,GAIjB,EAAE,EAAE;QACH,MAAM,kBAAkB,GAAG,OAAO,CAChC,gBAAgB;YAChB,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAClE,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC/B,CACF,CAAC;QACF,IACE,SAAS;YACT,CAAC,UAAU;YACX,SAAS,KAAK,IAAI;YAClB,CAAC,kBAAkB,EACnB,CAAC;YACD,OAAO;QACT,CAAC;QAED,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE;YACtB,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,KAAK,WAAW;gBACzB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,qCAAqC,CAAC,WAAW,CAAC,CAAC;YACzD,OAAO;gBACL,GAAG,MAAM;gBACT,SAAS,EAAE,aAAa;gBACxB,UAAU,EAAE,kBAAkB,IAAI,MAAM,CAAC,UAAU,IAAI,CAAC,SAAS;aAClE,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAChD,CAAC;IAEF,MAAM,eAAe,GAAG,CACtB,KAAC,gBAAgB,IACf,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,GAAG,EAAE,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAC9C,CACH,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAC9B,cAAK,SAAS,EAAC,2EAA2E,0CAEpF,CACP,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CACV,KAAC,wBAAwB,IAAC,KAAK,EAAE,KAAK,GAAI,CAC3C,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACpD,cAAK,SAAS,EAAC,2EAA2E,yDAEpF,CACP,CAAC,CAAC,CAAC,CACF,eAAK,GAAG,EAAE,YAAY,EAAE,SAAS,EAAC,wBAAwB,aACvD,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAChE,KAAC,6BAA6B,IAE5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,kBAAkB,EAClC,mBAAmB,EAAE,mBAAmB,EACxC,oBAAoB,EAAE,oBAAoB,EAC1C,aAAa,EAAE,aAAa,IATvB,SAAS,CAUd,CACH,CAAC,EACD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;iBAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;iBAClC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAC3B,eAEE,SAAS,EAAC,sGAAsG,0CAElF,SAAS,SAAS,GAAG,EAClD,KAAK,CAAC,KAAK,EAAE,OAAO,KAJhB,SAAS,CAKV,CACP,CAAC,EACJ,KAAC,WAAW,IACV,SAAS,EAAC,eAAe,EACzB,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,QAAQ,EACN,SAAS;oBACP,CAAC,CAAC,8BAA8B,CAAC,SAAS,EAAE,aAAa,CAAC;oBAC1D,CAAC,CAAC,EAAE,EAER,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAC5B,WAAW,EAAE,SAAS,CAAC,WAAW,EAClC,SAAS,EAAE;oBACT,UAAU,EAAE,IAAI;oBAChB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAC,SAAS,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjC,iBAAiB,EAAE,qBAAqB;oBACxC,GAAG,CAAC,SAAS,CAAC,WAAW;wBACvB,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,OAAO;4BACpD,CAAC,CAAC,EAAC,OAAO,EAAE,gBAAgB,EAAC;4BAC7B,CAAC,CAAC,EAAC,OAAO,EAAE,gBAAgB,EAAC;wBAC/B,CAAC,CAAC,EAAE,CAAC;iBACR,GACD,IACE,CACP,CAAC;IAEF,OAAO,CACL,cAAK,SAAS,EAAC,gBAAgB,YAC7B,KAAC,0BAA0B,IACzB,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,wBAAwB,EACxC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,UAAU,GACnB,GACE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAiC;IACzE,SAAS,EAAE,wBAAwB;IACnC,aAAa,EAAE,6BAA6B;IAC5C,IAAI,EAAE,OAAO;CACd,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GACzC;IACE,IAAI,EAAE,6BAA6B;IACnC,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,OAAO;IACb,SAAS,EAAE,CAAC,EAAC,aAAa,EAAC,EAAE,EAAE,CAC7B,OAAO,CACL,4BAA4B,CAAC,aAAa,CAAC;QAC3C,kBAAkB,CAAC,aAAa,CAAC,CAClC;IACH,WAAW,EAAE,CAAC,EAAC,aAAa,EAAC,EAAE,EAAE,CAC/B,aAAa;QACX,CAAC,CAAC,yCAAyC,CAAC;YACxC,KAAK,EAAE,GAAG,aAAa,CAAC,SAAS,MAAM;YACvC,SAAS,EAAE,aAAa,CAAC,SAAS;YAClC,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,cAAc,EAAE,aAAa,CAAC,KAAK;SACpC,CAAC;QACJ,CAAC,CAAC,SAAS;CAChB,CAAC","sourcesContent":["import {WebMercatorViewport} from '@deck.gl/core';\nimport type {ComponentProps} from 'react';\nimport type DeckGLReact from '@deck.gl/react';\n\ntype DeckProps = ComponentProps<typeof DeckGLReact>;\nimport {\n escapeId,\n getColValAsNumber,\n useStoreWithDuckDb,\n} from '@sqlrooms/duckdb';\nimport {\n column,\n type MosaicDashboardEntryType,\n type MosaicDashboardPanelConfigType,\n type MosaicDashboardPanelRenderer,\n type MosaicDashboardPanelRendererProps,\n sql,\n type ChartDataPolicy,\n type ChartRuntimeIssue,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n useMosaicClient,\n useStoreWithMosaicDashboard,\n} from '@sqlrooms/mosaic';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport type {MosaicClient} from '@uwdata/mosaic-core';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport type {Table as ArrowTable} from 'apache-arrow';\nimport {FocusIcon, MapIcon, SettingsIcon} from 'lucide-react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {DeckMapConfigPopoverEditor} from './DeckMapConfigPopoverEditor';\nimport {DeckJsonMap} from './DeckJsonMap';\nimport {MapSettingsPanel} from './MapSettings';\nimport {MosaicDashboardPanelLayout} from '@sqlrooms/mosaic';\nimport {\n asDeckJsonMapConfig,\n createDeckMapDashboardDatasetQuery,\n createDeckMapDashboardDatasets,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n resolveDeckMapDashboardDatasetSource,\n type DeckMapDashboardFitToDataConfig,\n type DeckMapDashboardDatasetClientState,\n type DeckMapDashboardDatasetConfig,\n type DeckMapDashboardInteractionConfig,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {getDeckMapDataPolicy} from './mapDataPolicy';\nimport {\n createDeckMapDashboardPanelConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\n\nfunction DeckMapRuntimeIssuePanel({issue}: {issue: ChartRuntimeIssue}) {\n const title =\n issue.kind === 'too-much-data'\n ? 'Too much data'\n : issue.kind === 'sql-error'\n ? 'Map query failed'\n : 'Unable to display map';\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">{title}</div>\n <div className=\"text-center text-sm whitespace-pre-wrap\">\n {issue.message}\n </div>\n </div>\n );\n}\n\nfunction DeckMapDashboardDatasetClient({\n dashboard,\n dataset,\n datasetId,\n dataPolicy,\n panel,\n onDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n selectionName,\n}: {\n dashboard: MosaicDashboardEntryType;\n dataset: DeckMapDashboardDatasetConfig;\n datasetId: string;\n dataPolicy?: ChartDataPolicy | null;\n panel: MosaicDashboardPanelConfigType;\n onDatasetState: (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selectionName: string;\n}) {\n const source = useMemo(\n () =>\n resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset,\n }),\n [dashboard, dataset, panel],\n );\n const query = useCallback(\n (filter: unknown) =>\n source\n ? createDeckMapDashboardDatasetQuery(source, filter)\n : createDeckMapDashboardDatasetQuery(\n {tableName: '__missing_dashboard_map_dataset__'},\n filter,\n ),\n [source],\n );\n const {data, error, isLoading, client} = useMosaicClient({\n id: `${panel.id}:${datasetId}`,\n selectionName,\n query,\n dataPolicy,\n enabled: Boolean(source),\n runtimeIssueContext,\n runtimeIssueReporter,\n });\n\n useEffect(() => {\n onDatasetState(datasetId, {\n arrowTable: data ?? undefined,\n error,\n isLoading,\n client,\n });\n\n return () => {\n onDatasetState(datasetId, undefined);\n };\n }, [client, data, datasetId, error, isLoading, onDatasetState]);\n\n return null;\n}\n\nfunction createPointRadiusPredicate(\n interaction: DeckMapDashboardInteractionConfig,\n coordinate: [number, number],\n) {\n const [longitude, latitude] = coordinate;\n const radiusMeters = interaction.radiusMeters ?? 500;\n const metersPerDegree = 111_320;\n const cosLatitude = Math.cos(latitude * (Math.PI / 180));\n const radiusSquared = radiusMeters * radiusMeters;\n\n return sql`(\n pow((${column(interaction.longitudeColumn)} - ${longitude}) * ${\n cosLatitude * metersPerDegree\n }, 2) +\n pow((${column(interaction.latitudeColumn)} - ${latitude}) * ${\n metersPerDegree\n }, 2)\n ) < ${radiusSquared}`;\n}\n\ntype DeckMapInteractionEvent = {\n coordinate?: number[] | null;\n object?: unknown;\n index?: number;\n picked?: boolean;\n};\n\nfunction getCoordinate(\n info: DeckMapInteractionEvent,\n): [number, number] | undefined {\n return info.coordinate && info.coordinate.length >= 2\n ? [info.coordinate[0]!, info.coordinate[1]!]\n : undefined;\n}\n\nfunction isPickedMapFeature(info: DeckMapInteractionEvent) {\n return Boolean(info.picked || info.object || (info.index ?? -1) >= 0);\n}\n\nfunction createDeckMapBoundsQuery(options: {\n source: {tableName?: string; sqlQuery?: string};\n fitToData: DeckMapDashboardFitToDataConfig;\n}) {\n const {source, fitToData} = options;\n const baseSourceSql = source.sqlQuery\n ? `SELECT * FROM (${source.sqlQuery}) AS \"__sqlrooms_dashboard_map_source\"`\n : `SELECT * FROM ${(source.tableName ?? '')\n .split('.')\n .map(escapeId)\n .join('.')}`;\n const longitudeColumn = escapeId(fitToData.longitudeColumn);\n const latitudeColumn = escapeId(fitToData.latitudeColumn);\n\n return `\n SELECT\n ST_XMin(extent) AS min_longitude,\n ST_YMin(extent) AS min_latitude,\n ST_XMax(extent) AS max_longitude,\n ST_YMax(extent) AS max_latitude\n FROM (\n SELECT ST_Extent_Agg(ST_Point(${longitudeColumn}, ${latitudeColumn})) AS extent\n FROM (${baseSourceSql}) AS \"__sqlrooms_dashboard_map_points\"\n WHERE ${longitudeColumn} IS NOT NULL AND ${latitudeColumn} IS NOT NULL\n ) AS \"__sqlrooms_dashboard_map_extent\"\n WHERE extent IS NOT NULL\n `;\n}\n\nfunction readBoundsFromExtentResult(result: ArrowTable) {\n const minLongitude = getColValAsNumber(result, 'min_longitude');\n const minLatitude = getColValAsNumber(result, 'min_latitude');\n const maxLongitude = getColValAsNumber(result, 'max_longitude');\n const maxLatitude = getColValAsNumber(result, 'max_latitude');\n if (\n !Number.isFinite(minLongitude) ||\n !Number.isFinite(minLatitude) ||\n !Number.isFinite(maxLongitude) ||\n !Number.isFinite(maxLatitude)\n ) {\n return null;\n }\n\n return [\n [\n minLongitude === maxLongitude ? minLongitude - 0.01 : minLongitude,\n minLatitude === maxLatitude ? minLatitude - 0.01 : minLatitude,\n ],\n [\n minLongitude === maxLongitude ? maxLongitude + 0.01 : maxLongitude,\n minLatitude === maxLatitude ? maxLatitude + 0.01 : maxLatitude,\n ],\n ] as const;\n}\n\nfunction fitViewStateToBounds(options: {\n bounds: readonly [readonly [number, number], readonly [number, number]];\n width: number;\n height: number;\n padding?: number;\n maxZoom?: number;\n}) {\n const {bounds, width, height, padding = 40, maxZoom = 12} = options;\n const viewport = new WebMercatorViewport({\n width: Math.max(width, 1),\n height: Math.max(height, 1),\n });\n const fitted = viewport.fitBounds(\n [\n [bounds[0][0], bounds[0][1]],\n [bounds[1][0], bounds[1][1]],\n ],\n {padding},\n ) as WebMercatorViewport & {\n longitude: number;\n latitude: number;\n zoom: number;\n };\n\n return {\n longitude: fitted.longitude,\n latitude: fitted.latitude,\n zoom: Math.min(fitted.zoom, maxZoom),\n };\n}\n\nconst deckMapDashboardFitRequestTarget = new EventTarget();\n\nfunction emitDeckMapDashboardFitRequest(panelId: string) {\n deckMapDashboardFitRequestTarget.dispatchEvent(\n new CustomEvent('fit-view', {detail: {panelId}}),\n );\n}\n\ntype DeckMapDashboardFitState = {\n key: string;\n viewState: DeckProps['viewState'];\n didAutoFit: boolean;\n fitRequestVersion: number;\n handledFitRequestVersion: number;\n};\n\nfunction createInitialDeckMapDashboardFitState(\n key: string,\n): DeckMapDashboardFitState {\n return {\n key,\n viewState: undefined,\n didAutoFit: false,\n fitRequestVersion: 0,\n handledFitRequestVersion: 0,\n };\n}\n\nfunction DeckMapDashboardHeaderActions({\n dashboardId,\n panel,\n}: MosaicDashboardPanelRendererProps) {\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const canFitView = Boolean(mapConfig?.fitToData);\n\n const isSettingsOpen = Boolean(mapConfig?.settingsOpen);\n\n const handleConfigApply = useCallback(\n (nextConfig: Record<string, unknown>) => {\n updatePanel(dashboardId, panel.id, {\n config: nextConfig,\n });\n },\n [dashboardId, panel.id, updatePanel],\n );\n\n const handleToggleSettings = useCallback(() => {\n updatePanel(dashboardId, panel.id, {\n config: {...panel.config, settingsOpen: !isSettingsOpen},\n });\n }, [dashboardId, isSettingsOpen, panel.config, panel.id, updatePanel]);\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"data-[state=active]:bg-accent h-6 w-6\"\n title=\"Map settings\"\n onClick={handleToggleSettings}\n data-state={isSettingsOpen ? 'active' : 'inactive'}\n >\n <SettingsIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Map settings</TooltipContent>\n </Tooltip>\n <DeckMapConfigPopoverEditor\n value={panel.config}\n onApply={handleConfigApply}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n title={\n canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map'\n }\n disabled={!canFitView}\n onClick={() => emitDeckMapDashboardFitRequest(panel.id)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n}\n\nfunction DeckMapDashboardRenderer({\n dashboard,\n dashboardId,\n panel,\n selectionName,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n const issue = useStoreWithMosaicDashboard((state) =>\n state.mosaicDashboard.getPanelIssue(dashboardId, panel.id),\n );\n const reportPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.reportPanelIssue,\n );\n const clearPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.clearPanelIssue,\n );\n const executeSql = useStoreWithDuckDb((state) => state.db.executeSql);\n\n const isSettingsOpen = Boolean(\n (panel.config as DeckMapDashboardPanelConfig).settingsOpen,\n );\n\n const handleSettingsOpenChange = useCallback(\n (isOpen: boolean) => {\n updatePanel(dashboardId, panel.id, {\n config: {...panel.config, settingsOpen: isOpen},\n });\n },\n [dashboardId, panel.config, panel.id, updatePanel],\n );\n const selection = useMemo<Selection>(\n () => getSelection(selectionName, 'crossfilter'),\n [getSelection, selectionName],\n );\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [datasetStates, setDatasetStates] = useState<\n Record<string, DeckMapDashboardDatasetClientState>\n >({});\n const [containerSize, setContainerSize] = useState({width: 0, height: 0});\n\n const handleDatasetState = useCallback(\n (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => {\n setDatasetStates((current) => {\n const next = {...current};\n if (state) {\n next[datasetId] = state;\n } else {\n delete next[datasetId];\n }\n return next;\n });\n },\n [],\n );\n\n const dataPolicy = useMemo<ChartDataPolicy>(\n () => getDeckMapDataPolicy(mapConfig),\n [mapConfig],\n );\n const runtimeIssueContext = useMemo(\n () => ({\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n }),\n [panel.id],\n );\n const runtimeIssueReporter = useMemo<ChartRuntimeIssueReporter>(\n () => ({\n reportIssue: (issueToReport) => {\n reportPanelIssue(dashboardId, panel.id, issueToReport);\n },\n clearIssue: () => {\n clearPanelIssue(dashboardId, panel.id);\n },\n }),\n [clearPanelIssue, dashboardId, panel.id, reportPanelIssue],\n );\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const updateSize = () => {\n setContainerSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n };\n\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const fitToData = mapConfig?.fitToData ?? null;\n const fitToDataSource = useMemo(\n () =>\n fitToData\n ? resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset: mapConfig?.datasets[fitToData.dataset],\n })\n : undefined,\n [dashboard, fitToData, mapConfig?.datasets, panel],\n );\n const fitToDataKey = useMemo(\n () =>\n fitToData && fitToDataSource\n ? JSON.stringify({\n source: fitToDataSource,\n fitToData,\n })\n : null,\n [fitToData, fitToDataSource],\n );\n const fitStateKey = useMemo(\n () => JSON.stringify({panelId: panel.id, fitToDataKey}),\n [fitToDataKey, panel.id],\n );\n const [fitState, setFitState] = useState<DeckMapDashboardFitState>(() =>\n createInitialDeckMapDashboardFitState(fitStateKey),\n );\n const activeFitState =\n fitState.key === fitStateKey\n ? fitState\n : createInitialDeckMapDashboardFitState(fitStateKey);\n const {didAutoFit, fitRequestVersion, handledFitRequestVersion, viewState} =\n activeFitState;\n\n useEffect(() => {\n const handleFitRequest = (event: Event) => {\n const detail = (event as CustomEvent<{panelId?: string}>).detail;\n if (detail?.panelId === panel.id) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n fitRequestVersion: scoped.fitRequestVersion + 1,\n };\n });\n }\n };\n\n deckMapDashboardFitRequestTarget.addEventListener(\n 'fit-view',\n handleFitRequest,\n );\n return () => {\n deckMapDashboardFitRequestTarget.removeEventListener(\n 'fit-view',\n handleFitRequest,\n );\n };\n }, [fitStateKey, panel.id]);\n\n useEffect(() => {\n const hasManualFitRequest = fitRequestVersion > handledFitRequestVersion;\n if (\n !fitToData ||\n !fitToDataSource ||\n containerSize.width <= 0 ||\n containerSize.height <= 0 ||\n (!hasManualFitRequest && didAutoFit)\n ) {\n return;\n }\n\n let isCancelled = false;\n\n const fitToDataBounds = async () => {\n try {\n const handle = await executeSql(\n createDeckMapBoundsQuery({\n source: fitToDataSource,\n fitToData,\n }),\n );\n const result = handle ? await handle : null;\n if (isCancelled || !result) {\n return;\n }\n\n const bounds = readBoundsFromExtentResult(result);\n if (!bounds) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n return;\n }\n\n const nextViewState = fitViewStateToBounds({\n bounds,\n width: containerSize.width,\n height: containerSize.height,\n padding: fitToData.padding,\n maxZoom: fitToData.maxZoom,\n });\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n viewState: nextViewState,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n } catch {\n if (!isCancelled) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n }\n }\n };\n\n void fitToDataBounds();\n\n return () => {\n isCancelled = true;\n };\n }, [\n containerSize.height,\n containerSize.width,\n didAutoFit,\n executeSql,\n fitRequestVersion,\n fitStateKey,\n fitToData,\n fitToDataSource,\n handledFitRequestVersion,\n ]);\n\n const handleBrushEvent = useCallback(\n (info: DeckMapInteractionEvent) => {\n const interaction = mapConfig?.interaction;\n if (!interaction) {\n return;\n }\n\n const client = datasetStates[interaction.dataset]?.client as\n | MosaicClient\n | null\n | undefined;\n if (!client) {\n return;\n }\n const coordinate = getCoordinate(info);\n if (!coordinate) {\n return;\n }\n if (interaction.event !== 'click' && !isPickedMapFeature(info)) {\n selection.reset(\n selection.clauses.filter((clause) => clause.source === client),\n );\n return;\n }\n\n const radiusMeters = interaction.radiusMeters ?? 500;\n selection.update({\n source: client,\n clients: new Set([client]),\n value: [coordinate[0], coordinate[1], radiusMeters],\n predicate: createPointRadiusPredicate(interaction, coordinate),\n });\n },\n [datasetStates, mapConfig?.interaction, selection],\n );\n\n const handleViewStateChange = useCallback(\n ({\n viewState: nextViewState,\n interactionState,\n }: {\n viewState: any;\n interactionState?: any;\n }) => {\n const hasUserInteraction = Boolean(\n interactionState &&\n ['isDragging', 'isPanning', 'isRotating', 'isZooming'].some((key) =>\n Boolean(interactionState[key]),\n ),\n );\n if (\n fitToData &&\n !didAutoFit &&\n viewState === null &&\n !hasUserInteraction\n ) {\n return;\n }\n\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n viewState: nextViewState,\n didAutoFit: hasUserInteraction || scoped.didAutoFit || !fitToData,\n };\n });\n },\n [didAutoFit, fitStateKey, fitToData, viewState],\n );\n\n const settingsContent = (\n <MapSettingsPanel\n dashboardId={dashboardId}\n panel={panel}\n onClose={() => handleSettingsOpenChange(false)}\n />\n );\n\n const mapContent = !mapConfig ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Invalid map panel config.\n </div>\n ) : issue ? (\n <DeckMapRuntimeIssuePanel issue={issue} />\n ) : Object.entries(mapConfig.datasets).length === 0 ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Map panels require at least one dataset.\n </div>\n ) : (\n <div ref={containerRef} className=\"relative h-full w-full\">\n {Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => (\n <DeckMapDashboardDatasetClient\n key={datasetId}\n dashboard={dashboard}\n dataset={dataset}\n datasetId={datasetId}\n dataPolicy={dataPolicy}\n panel={panel}\n onDatasetState={handleDatasetState}\n runtimeIssueContext={runtimeIssueContext}\n runtimeIssueReporter={runtimeIssueReporter}\n selectionName={selectionName}\n />\n ))}\n {Object.entries(datasetStates)\n .filter(([, state]) => state.error)\n .map(([datasetId, state]) => (\n <div\n key={datasetId}\n className=\"bg-background/90 text-destructive absolute inset-x-4 top-4 z-10 rounded-md border p-3 text-sm shadow\"\n >\n Failed to load dataset "{datasetId}":{' '}\n {state.error?.message}\n </div>\n ))}\n <DeckJsonMap\n className=\"h-full w-full\"\n spec={mapConfig.spec}\n datasets={\n mapConfig\n ? createDeckMapDashboardDatasets(mapConfig, datasetStates)\n : {}\n }\n mapStyle={mapConfig.mapStyle}\n mapProps={mapConfig.mapProps}\n showLegends={mapConfig.showLegends}\n deckProps={{\n controller: true,\n ...(viewState ? {viewState} : {}),\n onViewStateChange: handleViewStateChange,\n ...(mapConfig.interaction\n ? (mapConfig.interaction.event ?? 'hover') === 'click'\n ? {onClick: handleBrushEvent}\n : {onHover: handleBrushEvent}\n : {}),\n }}\n />\n </div>\n );\n\n return (\n <div className=\"h-full min-h-0\">\n <MosaicDashboardPanelLayout\n isOpen={isSettingsOpen}\n onIsOpenChange={handleSettingsOpenChange}\n settings={settingsContent}\n content={mapContent}\n />\n </div>\n );\n}\n\nexport const deckMapDashboardPanelRenderer: MosaicDashboardPanelRenderer = {\n component: DeckMapDashboardRenderer,\n headerActions: DeckMapDashboardHeaderActions,\n icon: MapIcon,\n};\n\nexport const deckMapDashboardAddPanelAction: import('@sqlrooms/mosaic').MosaicDashboardAddPanelAction =\n {\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n label: 'Map',\n icon: MapIcon,\n isEnabled: ({selectedTable}) =>\n Boolean(\n findLongitudeLatitudeColumns(selectedTable) ??\n findGeometryColumn(selectedTable),\n ),\n createPanel: ({selectedTable}) =>\n selectedTable\n ? createDeckMapDashboardPanelConfigForTable({\n title: `${selectedTable.tableName} map`,\n tableName: selectedTable.tableName,\n columns: selectedTable.columns,\n tableReference: selectedTable.table,\n })\n : undefined,\n };\n"]}
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"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","sourcesContent":["import {WebMercatorViewport} from '@deck.gl/core';\nimport type {ComponentProps} from 'react';\nimport type DeckGLReact from '@deck.gl/react';\n\ntype DeckProps = ComponentProps<typeof DeckGLReact>;\nimport {\n escapeId,\n getColValAsNumber,\n quoteTableReference,\n useStoreWithDuckDb,\n} from '@sqlrooms/duckdb';\nimport {\n column,\n type MosaicDashboardEntryType,\n type MosaicDashboardPanelConfigType,\n type MosaicDashboardPanelRenderer,\n type MosaicDashboardPanelRendererProps,\n sql,\n type ChartDataPolicy,\n type ChartRuntimeIssue,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n useMosaicClient,\n useStoreWithMosaicDashboard,\n usePanelClientRegistration,\n usePanelClients,\n usePanelResetFilters,\n ResetFiltersButton,\n} from '@sqlrooms/mosaic';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport type {MosaicClient} from '@uwdata/mosaic-core';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport type {Table as ArrowTable} from 'apache-arrow';\nimport {FocusIcon, MapIcon, SettingsIcon} from 'lucide-react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {DeckMapConfigPopoverEditor} from './DeckMapConfigPopoverEditor';\nimport {DeckJsonMap} from './DeckJsonMap';\nimport {MapSettingsPanel} from './MapSettings';\nimport {MosaicDashboardPanelLayout} from '@sqlrooms/mosaic';\nimport {\n asDeckJsonMapConfig,\n createDeckMapDashboardDatasetQuery,\n createDeckMapDashboardDatasets,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n resolveDeckMapDashboardDatasetSource,\n type DeckMapDashboardFitToDataConfig,\n type DeckMapDashboardDatasetClientState,\n type DeckMapDashboardDatasetConfig,\n type DeckMapDashboardInteractionConfig,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {getDeckMapDataPolicy} from './mapDataPolicy';\nimport {\n createDeckMapDashboardPanelConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\n\nfunction DeckMapRuntimeIssuePanel({issue}: {issue: ChartRuntimeIssue}) {\n const title =\n issue.kind === 'too-much-data'\n ? 'Too much data'\n : issue.kind === 'sql-error'\n ? 'Map query failed'\n : 'Unable to display map';\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">{title}</div>\n <div className=\"text-center text-sm whitespace-pre-wrap\">\n {issue.message}\n </div>\n </div>\n );\n}\n\nfunction DeckMapDashboardDatasetClient({\n dashboard,\n dataset,\n datasetId,\n dataPolicy,\n panel,\n onDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n selectionName,\n}: {\n dashboard: MosaicDashboardEntryType;\n dataset: DeckMapDashboardDatasetConfig;\n datasetId: string;\n dataPolicy?: ChartDataPolicy | null;\n panel: MosaicDashboardPanelConfigType;\n onDatasetState: (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selectionName: string;\n}) {\n const source = useMemo(\n () =>\n resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset,\n }),\n [dashboard, dataset, panel],\n );\n const query = useCallback(\n (filter: unknown) =>\n source\n ? createDeckMapDashboardDatasetQuery(source, filter)\n : createDeckMapDashboardDatasetQuery(\n {tableName: '__missing_dashboard_map_dataset__'},\n filter,\n ),\n [source],\n );\n const {data, error, isLoading, client} = useMosaicClient({\n id: `${panel.id}:${datasetId}`,\n selectionName,\n query,\n dataPolicy,\n enabled: Boolean(source),\n runtimeIssueContext,\n runtimeIssueReporter,\n });\n\n // Register client for panel reset button\n usePanelClientRegistration(dashboard.id, panel.id, client ? [client] : []);\n\n useEffect(() => {\n onDatasetState(datasetId, {\n arrowTable: data ?? undefined,\n error,\n isLoading,\n client,\n });\n\n return () => {\n onDatasetState(datasetId, undefined);\n };\n }, [client, data, datasetId, error, isLoading, onDatasetState]);\n\n return null;\n}\n\nfunction createPointRadiusPredicate(\n interaction: DeckMapDashboardInteractionConfig,\n coordinate: [number, number],\n) {\n const [longitude, latitude] = coordinate;\n const radiusMeters = interaction.radiusMeters ?? 500;\n const metersPerDegree = 111_320;\n const cosLatitude = Math.cos(latitude * (Math.PI / 180));\n const radiusSquared = radiusMeters * radiusMeters;\n\n return sql`(\n pow((${column(interaction.longitudeColumn)} - ${longitude}) * ${\n cosLatitude * metersPerDegree\n }, 2) +\n pow((${column(interaction.latitudeColumn)} - ${latitude}) * ${\n metersPerDegree\n }, 2)\n ) < ${radiusSquared}`;\n}\n\ntype DeckMapInteractionEvent = {\n coordinate?: number[] | null;\n object?: unknown;\n index?: number;\n picked?: boolean;\n};\n\nfunction getCoordinate(\n info: DeckMapInteractionEvent,\n): [number, number] | undefined {\n return info.coordinate && info.coordinate.length >= 2\n ? [info.coordinate[0]!, info.coordinate[1]!]\n : undefined;\n}\n\nfunction isPickedMapFeature(info: DeckMapInteractionEvent) {\n return Boolean(info.picked || info.object || (info.index ?? -1) >= 0);\n}\n\nexport function createDeckMapBoundsQuery(options: {\n source: {tableName?: string; sqlQuery?: string};\n fitToData: DeckMapDashboardFitToDataConfig;\n}) {\n const {source, fitToData} = options;\n const baseSourceSql = source.sqlQuery\n ? `SELECT * FROM (${source.sqlQuery}) AS \"__sqlrooms_dashboard_map_source\"`\n : `SELECT * FROM ${quoteTableReference(source.tableName ?? '')}`;\n const longitudeColumn = escapeId(fitToData.longitudeColumn);\n const latitudeColumn = escapeId(fitToData.latitudeColumn);\n\n return `\n SELECT\n ST_XMin(extent) AS min_longitude,\n ST_YMin(extent) AS min_latitude,\n ST_XMax(extent) AS max_longitude,\n ST_YMax(extent) AS max_latitude\n FROM (\n SELECT ST_Extent_Agg(ST_Point(${longitudeColumn}, ${latitudeColumn})) AS extent\n FROM (${baseSourceSql}) AS \"__sqlrooms_dashboard_map_points\"\n WHERE ${longitudeColumn} IS NOT NULL AND ${latitudeColumn} IS NOT NULL\n ) AS \"__sqlrooms_dashboard_map_extent\"\n WHERE extent IS NOT NULL\n `;\n}\n\nfunction readBoundsFromExtentResult(result: ArrowTable) {\n const minLongitude = getColValAsNumber(result, 'min_longitude');\n const minLatitude = getColValAsNumber(result, 'min_latitude');\n const maxLongitude = getColValAsNumber(result, 'max_longitude');\n const maxLatitude = getColValAsNumber(result, 'max_latitude');\n if (\n !Number.isFinite(minLongitude) ||\n !Number.isFinite(minLatitude) ||\n !Number.isFinite(maxLongitude) ||\n !Number.isFinite(maxLatitude)\n ) {\n return null;\n }\n\n return [\n [\n minLongitude === maxLongitude ? minLongitude - 0.01 : minLongitude,\n minLatitude === maxLatitude ? minLatitude - 0.01 : minLatitude,\n ],\n [\n minLongitude === maxLongitude ? maxLongitude + 0.01 : maxLongitude,\n minLatitude === maxLatitude ? maxLatitude + 0.01 : maxLatitude,\n ],\n ] as const;\n}\n\nfunction fitViewStateToBounds(options: {\n bounds: readonly [readonly [number, number], readonly [number, number]];\n width: number;\n height: number;\n padding?: number;\n maxZoom?: number;\n}) {\n const {bounds, width, height, padding = 40, maxZoom = 12} = options;\n const viewport = new WebMercatorViewport({\n width: Math.max(width, 1),\n height: Math.max(height, 1),\n });\n const fitted = viewport.fitBounds(\n [\n [bounds[0][0], bounds[0][1]],\n [bounds[1][0], bounds[1][1]],\n ],\n {padding},\n ) as WebMercatorViewport & {\n longitude: number;\n latitude: number;\n zoom: number;\n };\n\n return {\n longitude: fitted.longitude,\n latitude: fitted.latitude,\n zoom: Math.min(fitted.zoom, maxZoom),\n };\n}\n\nconst deckMapDashboardFitRequestTarget = new EventTarget();\n\nfunction emitDeckMapDashboardFitRequest(panelId: string) {\n deckMapDashboardFitRequestTarget.dispatchEvent(\n new CustomEvent('fit-view', {detail: {panelId}}),\n );\n}\n\ntype DeckMapDashboardFitState = {\n key: string;\n viewState: DeckProps['viewState'];\n didAutoFit: boolean;\n fitRequestVersion: number;\n handledFitRequestVersion: number;\n};\n\nfunction createInitialDeckMapDashboardFitState(\n key: string,\n): DeckMapDashboardFitState {\n return {\n key,\n viewState: undefined,\n didAutoFit: false,\n fitRequestVersion: 0,\n handledFitRequestVersion: 0,\n };\n}\n\nfunction DeckMapDashboardHeaderActions({\n dashboardId,\n panel,\n selectionName,\n}: MosaicDashboardPanelRendererProps) {\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n const panelClients = usePanelClients(dashboardId, panel.id);\n const {hasActiveFilters, reset} = usePanelResetFilters({\n panelClients,\n selectionName,\n });\n\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const canFitView = Boolean(mapConfig?.fitToData);\n\n const isSettingsOpen = Boolean(mapConfig?.settingsOpen);\n\n const handleConfigApply = useCallback(\n (nextConfig: Record<string, unknown>) => {\n updatePanel(dashboardId, panel.id, {\n config: nextConfig,\n });\n },\n [dashboardId, panel.id, updatePanel],\n );\n\n const handleToggleSettings = useCallback(() => {\n updatePanel(dashboardId, panel.id, {\n config: {...panel.config, settingsOpen: !isSettingsOpen},\n });\n }, [dashboardId, isSettingsOpen, panel.config, panel.id, updatePanel]);\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <ResetFiltersButton\n disabled={!hasActiveFilters}\n onClick={reset}\n tooltip=\"Reset panel filters\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"data-[state=active]:bg-accent h-6 w-6\"\n title=\"Map settings\"\n onClick={handleToggleSettings}\n data-state={isSettingsOpen ? 'active' : 'inactive'}\n >\n <SettingsIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Map settings</TooltipContent>\n </Tooltip>\n <DeckMapConfigPopoverEditor\n value={panel.config}\n onApply={handleConfigApply}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n title={\n canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map'\n }\n disabled={!canFitView}\n onClick={() => emitDeckMapDashboardFitRequest(panel.id)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n}\n\nfunction DeckMapDashboardRenderer({\n dashboard,\n dashboardId,\n panel,\n selectionName,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n const issue = useStoreWithMosaicDashboard((state) =>\n state.mosaicDashboard.getPanelIssue(dashboardId, panel.id),\n );\n const reportPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.reportPanelIssue,\n );\n const clearPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.clearPanelIssue,\n );\n const executeSql = useStoreWithDuckDb((state) => state.db.executeSql);\n\n const isSettingsOpen = Boolean(\n (panel.config as DeckMapDashboardPanelConfig).settingsOpen,\n );\n\n const handleSettingsOpenChange = useCallback(\n (isOpen: boolean) => {\n updatePanel(dashboardId, panel.id, {\n config: {...panel.config, settingsOpen: isOpen},\n });\n },\n [dashboardId, panel.config, panel.id, updatePanel],\n );\n const selection = useMemo<Selection>(\n () => getSelection(selectionName, 'crossfilter'),\n [getSelection, selectionName],\n );\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [datasetStates, setDatasetStates] = useState<\n Record<string, DeckMapDashboardDatasetClientState>\n >({});\n const [containerSize, setContainerSize] = useState({width: 0, height: 0});\n\n const handleDatasetState = useCallback(\n (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => {\n setDatasetStates((current) => {\n const next = {...current};\n if (state) {\n next[datasetId] = state;\n } else {\n delete next[datasetId];\n }\n return next;\n });\n },\n [],\n );\n\n const dataPolicy = useMemo<ChartDataPolicy>(\n () => getDeckMapDataPolicy(mapConfig),\n [mapConfig],\n );\n const runtimeIssueContext = useMemo(\n () => ({\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n }),\n [panel.id],\n );\n const runtimeIssueReporter = useMemo<ChartRuntimeIssueReporter>(\n () => ({\n reportIssue: (issueToReport) => {\n reportPanelIssue(dashboardId, panel.id, issueToReport);\n },\n clearIssue: () => {\n clearPanelIssue(dashboardId, panel.id);\n },\n }),\n [clearPanelIssue, dashboardId, panel.id, reportPanelIssue],\n );\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const updateSize = () => {\n setContainerSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n };\n\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const fitToData = mapConfig?.fitToData ?? null;\n const fitToDataSource = useMemo(\n () =>\n fitToData\n ? resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset: mapConfig?.datasets[fitToData.dataset],\n })\n : undefined,\n [dashboard, fitToData, mapConfig?.datasets, panel],\n );\n const fitToDataKey = useMemo(\n () =>\n fitToData && fitToDataSource\n ? JSON.stringify({\n source: fitToDataSource,\n fitToData,\n })\n : null,\n [fitToData, fitToDataSource],\n );\n const fitStateKey = useMemo(\n () => JSON.stringify({panelId: panel.id, fitToDataKey}),\n [fitToDataKey, panel.id],\n );\n const [fitState, setFitState] = useState<DeckMapDashboardFitState>(() =>\n createInitialDeckMapDashboardFitState(fitStateKey),\n );\n const activeFitState =\n fitState.key === fitStateKey\n ? fitState\n : createInitialDeckMapDashboardFitState(fitStateKey);\n const {didAutoFit, fitRequestVersion, handledFitRequestVersion, viewState} =\n activeFitState;\n\n useEffect(() => {\n const handleFitRequest = (event: Event) => {\n const detail = (event as CustomEvent<{panelId?: string}>).detail;\n if (detail?.panelId === panel.id) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n fitRequestVersion: scoped.fitRequestVersion + 1,\n };\n });\n }\n };\n\n deckMapDashboardFitRequestTarget.addEventListener(\n 'fit-view',\n handleFitRequest,\n );\n return () => {\n deckMapDashboardFitRequestTarget.removeEventListener(\n 'fit-view',\n handleFitRequest,\n );\n };\n }, [fitStateKey, panel.id]);\n\n useEffect(() => {\n const hasManualFitRequest = fitRequestVersion > handledFitRequestVersion;\n if (\n !fitToData ||\n !fitToDataSource ||\n containerSize.width <= 0 ||\n containerSize.height <= 0 ||\n (!hasManualFitRequest && didAutoFit)\n ) {\n return;\n }\n\n let isCancelled = false;\n\n const fitToDataBounds = async () => {\n try {\n const handle = await executeSql(\n createDeckMapBoundsQuery({\n source: fitToDataSource,\n fitToData,\n }),\n );\n const result = handle ? await handle : null;\n if (isCancelled || !result) {\n return;\n }\n\n const bounds = readBoundsFromExtentResult(result);\n if (!bounds) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n return;\n }\n\n const nextViewState = fitViewStateToBounds({\n bounds,\n width: containerSize.width,\n height: containerSize.height,\n padding: fitToData.padding,\n maxZoom: fitToData.maxZoom,\n });\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n viewState: nextViewState,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n } catch {\n if (!isCancelled) {\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n didAutoFit: true,\n handledFitRequestVersion: fitRequestVersion,\n };\n });\n }\n }\n };\n\n void fitToDataBounds();\n\n return () => {\n isCancelled = true;\n };\n }, [\n containerSize.height,\n containerSize.width,\n didAutoFit,\n executeSql,\n fitRequestVersion,\n fitStateKey,\n fitToData,\n fitToDataSource,\n handledFitRequestVersion,\n ]);\n\n const handleBrushEvent = useCallback(\n (info: DeckMapInteractionEvent) => {\n const interaction = mapConfig?.interaction;\n if (!interaction) {\n return;\n }\n\n const client = datasetStates[interaction.dataset]?.client as\n | MosaicClient\n | null\n | undefined;\n if (!client) {\n return;\n }\n const coordinate = getCoordinate(info);\n if (!coordinate) {\n return;\n }\n if (interaction.event !== 'click' && !isPickedMapFeature(info)) {\n selection.reset(\n selection.clauses.filter((clause) => clause.source === client),\n );\n return;\n }\n\n const radiusMeters = interaction.radiusMeters ?? 500;\n selection.update({\n source: client,\n clients: new Set([client]),\n value: [coordinate[0], coordinate[1], radiusMeters],\n predicate: createPointRadiusPredicate(interaction, coordinate),\n });\n },\n [datasetStates, mapConfig?.interaction, selection],\n );\n\n const handleViewStateChange = useCallback(\n ({\n viewState: nextViewState,\n interactionState,\n }: {\n viewState: any;\n interactionState?: any;\n }) => {\n const hasUserInteraction = Boolean(\n interactionState &&\n ['isDragging', 'isPanning', 'isRotating', 'isZooming'].some((key) =>\n Boolean(interactionState[key]),\n ),\n );\n if (\n fitToData &&\n !didAutoFit &&\n viewState === null &&\n !hasUserInteraction\n ) {\n return;\n }\n\n setFitState((current) => {\n const scoped =\n current.key === fitStateKey\n ? current\n : createInitialDeckMapDashboardFitState(fitStateKey);\n return {\n ...scoped,\n viewState: nextViewState,\n didAutoFit: hasUserInteraction || scoped.didAutoFit || !fitToData,\n };\n });\n },\n [didAutoFit, fitStateKey, fitToData, viewState],\n );\n\n const settingsContent = (\n <MapSettingsPanel\n dashboardId={dashboardId}\n panel={panel}\n onClose={() => handleSettingsOpenChange(false)}\n />\n );\n\n const mapContent = !mapConfig ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Invalid map panel config.\n </div>\n ) : issue ? (\n <DeckMapRuntimeIssuePanel issue={issue} />\n ) : Object.entries(mapConfig.datasets).length === 0 ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Map panels require at least one dataset.\n </div>\n ) : (\n <div ref={containerRef} className=\"relative h-full w-full\">\n {Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => (\n <DeckMapDashboardDatasetClient\n key={datasetId}\n dashboard={dashboard}\n dataset={dataset}\n datasetId={datasetId}\n dataPolicy={dataPolicy}\n panel={panel}\n onDatasetState={handleDatasetState}\n runtimeIssueContext={runtimeIssueContext}\n runtimeIssueReporter={runtimeIssueReporter}\n selectionName={selectionName}\n />\n ))}\n {Object.entries(datasetStates)\n .filter(([, state]) => state.error)\n .map(([datasetId, state]) => (\n <div\n key={datasetId}\n className=\"bg-background/90 text-destructive absolute inset-x-4 top-4 z-10 rounded-md border p-3 text-sm shadow\"\n >\n Failed to load dataset "{datasetId}":{' '}\n {state.error?.message}\n </div>\n ))}\n <DeckJsonMap\n className=\"h-full w-full\"\n spec={mapConfig.spec}\n datasets={\n mapConfig\n ? createDeckMapDashboardDatasets(mapConfig, datasetStates)\n : {}\n }\n mapStyle={mapConfig.mapStyle}\n mapProps={mapConfig.mapProps}\n showLegends={mapConfig.showLegends}\n deckProps={{\n controller: true,\n ...(viewState ? {viewState} : {}),\n onViewStateChange: handleViewStateChange,\n ...(mapConfig.interaction\n ? (mapConfig.interaction.event ?? 'hover') === 'click'\n ? {onClick: handleBrushEvent}\n : {onHover: handleBrushEvent}\n : {}),\n }}\n />\n </div>\n );\n\n return (\n <div className=\"h-full min-h-0\">\n <MosaicDashboardPanelLayout\n isOpen={isSettingsOpen}\n onIsOpenChange={handleSettingsOpenChange}\n settings={settingsContent}\n content={mapContent}\n />\n </div>\n );\n}\n\nexport const deckMapDashboardPanelRenderer: MosaicDashboardPanelRenderer = {\n component: DeckMapDashboardRenderer,\n headerActions: DeckMapDashboardHeaderActions,\n icon: MapIcon,\n};\n\nexport const deckMapDashboardAddPanelAction: import('@sqlrooms/mosaic').MosaicDashboardAddPanelAction =\n {\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n label: 'Map',\n icon: MapIcon,\n isEnabled: ({selectedTable}) =>\n Boolean(\n findLongitudeLatitudeColumns(selectedTable) ??\n findGeometryColumn(selectedTable),\n ),\n createPanel: ({selectedTable}) =>\n selectedTable\n ? createDeckMapDashboardPanelConfigForTable({\n title: `${selectedTable.tableName} map`,\n tableName: selectedTable.tableName,\n columns: selectedTable.columns,\n tableReference: selectedTable.table,\n })\n : undefined,\n };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/deck",
|
|
3
|
-
"version": "0.29.0-rc.
|
|
3
|
+
"version": "0.29.0-rc.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/sqlrooms/sqlrooms.git"
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@loaders.gl/gis": "^4.4.1",
|
|
38
38
|
"@loaders.gl/wkt": "^4.4.1",
|
|
39
39
|
"@paralleldrive/cuid2": "^3.0.0",
|
|
40
|
-
"@sqlrooms/color-scales": "0.29.0-rc.
|
|
41
|
-
"@sqlrooms/duckdb": "0.29.0-rc.
|
|
42
|
-
"@sqlrooms/mosaic": "0.29.0-rc.
|
|
43
|
-
"@sqlrooms/ui": "0.29.0-rc.
|
|
40
|
+
"@sqlrooms/color-scales": "0.29.0-rc.8",
|
|
41
|
+
"@sqlrooms/duckdb": "0.29.0-rc.8",
|
|
42
|
+
"@sqlrooms/mosaic": "0.29.0-rc.8",
|
|
43
|
+
"@sqlrooms/ui": "0.29.0-rc.8",
|
|
44
44
|
"@uwdata/mosaic-core": "^0.21.0",
|
|
45
45
|
"@uwdata/mosaic-sql": "^0.21.0",
|
|
46
46
|
"ai": "^6.0.159",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "dcb1a51631c5fa87b49d3e78ae6c0023eccd4189"
|
|
69
69
|
}
|