@sqlrooms/mosaic 0.29.0-rc.0 → 0.29.0-rc.2
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/README.md +41 -2
- package/dist/MosaicChart.d.ts +20 -0
- package/dist/MosaicChart.d.ts.map +1 -0
- package/dist/MosaicChart.js +25 -0
- package/dist/MosaicChart.js.map +1 -0
- package/dist/MosaicChartBuilder.d.ts +32 -0
- package/dist/MosaicChartBuilder.d.ts.map +1 -0
- package/dist/MosaicChartBuilder.js +35 -0
- package/dist/MosaicChartBuilder.js.map +1 -0
- package/dist/MosaicColorLegend.d.ts +18 -0
- package/dist/MosaicColorLegend.d.ts.map +1 -0
- package/dist/MosaicColorLegend.js +117 -0
- package/dist/MosaicColorLegend.js.map +1 -0
- package/dist/MosaicSlice.d.ts +16 -13
- package/dist/MosaicSlice.d.ts.map +1 -1
- package/dist/MosaicSlice.js +67 -32
- package/dist/MosaicSlice.js.map +1 -1
- package/dist/VgPlotChart.d.ts +8 -0
- package/dist/VgPlotChart.d.ts.map +1 -1
- package/dist/VgPlotChart.js +26 -6
- package/dist/VgPlotChart.js.map +1 -1
- package/dist/chart-builders/ChartBuilderContent.d.ts +26 -0
- package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContent.js +59 -0
- package/dist/chart-builders/ChartBuilderContent.js.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts +11 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.js +10 -0
- package/dist/chart-builders/ChartBuilderContext.js.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts +23 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.js +15 -0
- package/dist/chart-builders/ChartBuilderDialog.js.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts +13 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.js +19 -0
- package/dist/chart-builders/FieldSelectorInput.js.map +1 -0
- package/dist/chart-builders/builders.d.ts +7 -0
- package/dist/chart-builders/builders.d.ts.map +1 -0
- package/dist/chart-builders/builders.js +280 -0
- package/dist/chart-builders/builders.js.map +1 -0
- package/dist/chart-builders/chartSpecTitle.d.ts +7 -0
- package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -0
- package/dist/chart-builders/chartSpecTitle.js +10 -0
- package/dist/chart-builders/chartSpecTitle.js.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts +45 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.js +109 -0
- package/dist/chart-builders/createMosaicChartTool.js.map +1 -0
- package/dist/chart-builders/describeChartSpecs.d.ts +7 -0
- package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -0
- package/dist/chart-builders/describeChartSpecs.js +38 -0
- package/dist/chart-builders/describeChartSpecs.js.map +1 -0
- package/dist/chart-builders/types.d.ts +40 -0
- package/dist/chart-builders/types.d.ts.map +1 -0
- package/dist/chart-builders/types.js +2 -0
- package/dist/chart-builders/types.js.map +1 -0
- package/dist/dashboard/MosaicDashboard.d.ts +20 -0
- package/dist/dashboard/MosaicDashboard.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboard.js +68 -0
- package/dist/dashboard/MosaicDashboard.js.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js +49 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.js +45 -0
- package/dist/dashboard/MosaicDashboardCharts.js.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts +11 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.js +10 -0
- package/dist/dashboard/MosaicDashboardContext.js.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.js +21 -0
- package/dist/dashboard/MosaicDashboardProfiler.js.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts +68 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.js +230 -0
- package/dist/dashboard/MosaicDashboardSlice.js.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.js +19 -0
- package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts +8 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js +40 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -0
- package/dist/editor/MosaicChartContainer.d.ts +51 -0
- package/dist/editor/MosaicChartContainer.d.ts.map +1 -0
- package/dist/editor/MosaicChartContainer.js +39 -0
- package/dist/editor/MosaicChartContainer.js.map +1 -0
- package/dist/editor/MosaicChartDisplay.d.ts +18 -0
- package/dist/editor/MosaicChartDisplay.d.ts.map +1 -0
- package/dist/editor/MosaicChartDisplay.js +21 -0
- package/dist/editor/MosaicChartDisplay.js.map +1 -0
- package/dist/editor/MosaicChartEditorActions.d.ts +20 -0
- package/dist/editor/MosaicChartEditorActions.d.ts.map +1 -0
- package/dist/editor/MosaicChartEditorActions.js +18 -0
- package/dist/editor/MosaicChartEditorActions.js.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts +15 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.js +26 -0
- package/dist/editor/MosaicCodeMirrorEditor.js.map +1 -0
- package/dist/editor/MosaicEditorContext.d.ts +8 -0
- package/dist/editor/MosaicEditorContext.d.ts.map +1 -0
- package/dist/editor/MosaicEditorContext.js +14 -0
- package/dist/editor/MosaicEditorContext.js.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts +20 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.js +25 -0
- package/dist/editor/MosaicSpecEditorPanel.js.map +1 -0
- package/dist/editor/mosaicSchema.d.ts +20 -0
- package/dist/editor/mosaicSchema.d.ts.map +1 -0
- package/dist/editor/mosaicSchema.js +57 -0
- package/dist/editor/mosaicSchema.js.map +1 -0
- package/dist/editor/types.d.ts +72 -0
- package/dist/editor/types.d.ts.map +1 -0
- package/dist/editor/types.js +2 -0
- package/dist/editor/types.js.map +1 -0
- package/dist/editor/useMosaicChartEditor.d.ts +9 -0
- package/dist/editor/useMosaicChartEditor.d.ts.map +1 -0
- package/dist/editor/useMosaicChartEditor.js +199 -0
- package/dist/editor/useMosaicChartEditor.js.map +1 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/profiler/MosaicProfiler.d.ts +32 -0
- package/dist/profiler/MosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/MosaicProfiler.js +57 -0
- package/dist/profiler/MosaicProfiler.js.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts +7 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.js +196 -0
- package/dist/profiler/MosaicProfilerHeader.js.map +1 -0
- package/dist/profiler/MosaicProfilerRows.d.ts +9 -0
- package/dist/profiler/MosaicProfilerRows.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerRows.js +65 -0
- package/dist/profiler/MosaicProfilerRows.js.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts +9 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.js +28 -0
- package/dist/profiler/MosaicProfilerStatusBar.js.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts +50 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.js +121 -0
- package/dist/profiler/ProfilerCategoryClient.js.map +1 -0
- package/dist/profiler/ProfilerCountClient.d.ts +28 -0
- package/dist/profiler/ProfilerCountClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCountClient.js +51 -0
- package/dist/profiler/ProfilerCountClient.js.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts +69 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.js +179 -0
- package/dist/profiler/ProfilerHistogramClient.js.map +1 -0
- package/dist/profiler/ProfilerPageClient.d.ts +37 -0
- package/dist/profiler/ProfilerPageClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerPageClient.js +65 -0
- package/dist/profiler/ProfilerPageClient.js.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts +24 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js +51 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js.map +1 -0
- package/dist/profiler/createProfilerStore.d.ts +45 -0
- package/dist/profiler/createProfilerStore.d.ts.map +1 -0
- package/dist/profiler/createProfilerStore.js +120 -0
- package/dist/profiler/createProfilerStore.js.map +1 -0
- package/dist/profiler/layout.d.ts +7 -0
- package/dist/profiler/layout.d.ts.map +1 -0
- package/dist/profiler/layout.js +13 -0
- package/dist/profiler/layout.js.map +1 -0
- package/dist/profiler/profilerController.d.ts +64 -0
- package/dist/profiler/profilerController.d.ts.map +1 -0
- package/dist/profiler/profilerController.js +123 -0
- package/dist/profiler/profilerController.js.map +1 -0
- package/dist/profiler/types.d.ts +86 -0
- package/dist/profiler/types.d.ts.map +1 -0
- package/dist/profiler/types.js +2 -0
- package/dist/profiler/types.js.map +1 -0
- package/dist/profiler/useMosaicProfiler.d.ts +7 -0
- package/dist/profiler/useMosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/useMosaicProfiler.js +339 -0
- package/dist/profiler/useMosaicProfiler.js.map +1 -0
- package/dist/profiler/utils.d.ts +61 -0
- package/dist/profiler/utils.d.ts.map +1 -0
- package/dist/profiler/utils.js +347 -0
- package/dist/profiler/utils.js.map +1 -0
- package/dist/tableInterop.d.ts +30 -0
- package/dist/tableInterop.d.ts.map +1 -0
- package/dist/tableInterop.js +85 -0
- package/dist/tableInterop.js.map +1 -0
- package/dist/use-mosaic.d.ts +11 -0
- package/dist/use-mosaic.d.ts.map +1 -0
- package/dist/use-mosaic.js +42 -0
- package/dist/use-mosaic.js.map +1 -0
- package/dist/useMosaicClient.d.ts +5 -4
- package/dist/useMosaicClient.d.ts.map +1 -1
- package/dist/useMosaicClient.js +13 -3
- package/dist/useMosaicClient.js.map +1 -1
- package/package.json +24 -6
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,KAAK,EACL,SAAS,GACV,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,KAAK,EACL,SAAS,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAC,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAKlB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,cAAc,GAOf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oBAAoB,GAErB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,GAEnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,uBAAuB,GAExB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAC,iBAAiB,EAAC,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAC,eAAe,EAA8B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,sBAAsB;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAExD,2BAA2B;AAC3B,OAAO,EAAC,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,oBAAoB,EAAC,MAAM,+BAA+B,CAAC;AAgBnE,OAAO,EACL,qBAAqB,EACrB,gCAAgC,EAChC,mCAAmC,EACnC,oCAAoC,GACrC,MAAM,mBAAmB,CAAC;AAc3B,oCAAoC;AACpC,OAAO,EAAC,0BAA0B,EAAC,MAAM,2BAA2B,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\nexport {\n isParam,\n isSelection,\n makeClient,\n Param,\n Selection,\n} from '@uwdata/mosaic-core';\nexport {astToDOM, astToESM, parseSpec} from '@uwdata/mosaic-spec';\nexport type {Spec} from '@uwdata/mosaic-spec';\nexport {asc, column, desc, Query, sql} from '@uwdata/mosaic-sql';\nexport * as vg from '@uwdata/vgplot';\nexport {\n createDefaultMosaicConfig,\n createMosaicSlice,\n MosaicSliceConfig,\n type CreateMosaicSliceProps,\n type MosaicClientOptions,\n type MosaicSliceState,\n type TrackedClient,\n} from './MosaicSlice';\nexport {\n MosaicProfiler,\n type MosaicProfilerCompoundHeaderProps,\n type MosaicProfilerCompoundRowsProps,\n type MosaicProfilerCompoundStatusBarProps,\n type MosaicProfilerCompoundTableProps,\n type MosaicProfilerProps,\n type MosaicProfilerRootProps,\n} from './profiler/MosaicProfiler';\nexport {\n MosaicProfilerHeader,\n type MosaicProfilerHeaderProps,\n} from './profiler/MosaicProfilerHeader';\nexport {\n MosaicProfilerRows,\n type MosaicProfilerRowsProps,\n} from './profiler/MosaicProfilerRows';\nexport {\n MosaicProfilerStatusBar,\n type MosaicProfilerStatusBarProps,\n} from './profiler/MosaicProfilerStatusBar';\nexport {useMosaicProfiler} from './profiler/useMosaicProfiler';\nexport {useMosaicClient, type UseMosaicClientOptions} from './useMosaicClient';\nexport {\n createMosaicColorLegendPlot,\n MosaicColorLegend,\n type MosaicColorLegendProps,\n} from './MosaicColorLegend';\nexport {VgPlotChart} from './VgPlotChart';\n\n// Compound components\nexport {MosaicChart} from './MosaicChart';\nexport {MosaicChartBuilder} from './MosaicChartBuilder';\n\n// Editor hooks and context\nexport {useMosaicEditorContext} from './editor/MosaicEditorContext';\nexport {\n getCachedMosaicSchema,\n loadMosaicSchema,\n preloadMosaicSchema,\n} from './editor/mosaicSchema';\nexport {useMosaicChartEditor} from './editor/useMosaicChartEditor';\n\n// Editor types\nexport type {MosaicChartContainerProps} from './editor/MosaicChartContainer';\nexport type {MosaicChartDisplayProps} from './editor/MosaicChartDisplay';\nexport type {MosaicChartEditorActionsProps} from './editor/MosaicChartEditorActions';\nexport type {MosaicCodeMirrorEditorProps} from './editor/MosaicCodeMirrorEditor';\nexport type {MosaicSpecEditorPanelProps} from './editor/MosaicSpecEditorPanel';\nexport type {\n MosaicEditorActions,\n MosaicEditorContextValue,\n MosaicEditorState,\n OnMosaicSpecChange,\n UseMosaicChartEditorOptions,\n UseMosaicChartEditorReturn,\n} from './editor/types';\nexport {\n getProfilerTableWidth,\n PROFILER_DEFAULT_COLUMN_WIDTH_PX,\n PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX,\n PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX,\n} from './profiler/layout';\nexport type {\n MosaicProfilerCategoryBucket,\n MosaicProfilerCategorySummary,\n MosaicProfilerColumnKind,\n MosaicProfilerColumnState,\n MosaicProfilerHistogramSummary,\n MosaicProfilerOptions,\n MosaicProfilerPaginationState,\n MosaicProfilerSorting,\n MosaicProfilerSummaryState,\n UseMosaicProfilerReturn,\n} from './profiler/types';\n\n// Chart builder types and utilities\nexport {createDefaultChartBuilders} from './chart-builders/builders';\nexport type {ChartBuilderContentProps} from './chart-builders/ChartBuilderContent';\nexport type {ChartBuilderDialogProps} from './chart-builders/ChartBuilderDialog';\nexport type {FieldSelectorInputProps} from './chart-builders/FieldSelectorInput';\nexport type {\n ChartBuilderColumn,\n ChartBuilderField,\n ChartBuilderTemplate,\n} from './chart-builders/types';\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ComponentProps, type PropsWithChildren, type ReactElement } from 'react';
|
|
2
|
+
import { Table } from '@sqlrooms/ui';
|
|
3
|
+
import { type MosaicProfilerHeaderProps } from './MosaicProfilerHeader';
|
|
4
|
+
import { type MosaicProfilerRowsProps } from './MosaicProfilerRows';
|
|
5
|
+
import { type MosaicProfilerStatusBarProps } from './MosaicProfilerStatusBar';
|
|
6
|
+
import type { MosaicProfilerOptions, UseMosaicProfilerReturn } from './types';
|
|
7
|
+
export type MosaicProfilerRootProps = PropsWithChildren<{
|
|
8
|
+
profiler: UseMosaicProfilerReturn;
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Provides an existing profiler instance to compound profiler subcomponents.
|
|
12
|
+
*/
|
|
13
|
+
export declare function MosaicProfilerRoot({ children, profiler, }: MosaicProfilerRootProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export type MosaicProfilerProps = PropsWithChildren<MosaicProfilerOptions>;
|
|
15
|
+
export type MosaicProfilerCompoundHeaderProps = Omit<MosaicProfilerHeaderProps, 'profiler'>;
|
|
16
|
+
declare function MosaicProfilerCompoundHeader(props: MosaicProfilerCompoundHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export type MosaicProfilerCompoundRowsProps = Omit<MosaicProfilerRowsProps, 'profiler'>;
|
|
18
|
+
declare function MosaicProfilerCompoundRows(props: MosaicProfilerCompoundRowsProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export type MosaicProfilerCompoundStatusBarProps = Omit<MosaicProfilerStatusBarProps, 'profiler'>;
|
|
20
|
+
declare function MosaicProfilerCompoundStatusBar(props: MosaicProfilerCompoundStatusBarProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export type MosaicProfilerCompoundTableProps = ComponentProps<typeof Table>;
|
|
22
|
+
declare function MosaicProfilerCompoundTable({ className, disableWrapper, style, ...props }: MosaicProfilerCompoundTableProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
type MosaicProfilerCompoundComponent = ((props: MosaicProfilerProps) => ReactElement) & {
|
|
24
|
+
Header: typeof MosaicProfilerCompoundHeader;
|
|
25
|
+
Root: typeof MosaicProfilerRoot;
|
|
26
|
+
Rows: typeof MosaicProfilerCompoundRows;
|
|
27
|
+
StatusBar: typeof MosaicProfilerCompoundStatusBar;
|
|
28
|
+
Table: typeof MosaicProfilerCompoundTable;
|
|
29
|
+
};
|
|
30
|
+
export declare const MosaicProfiler: MosaicProfilerCompoundComponent;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=MosaicProfiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfiler.d.ts","sourceRoot":"","sources":["../../src/profiler/MosaicProfiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AACf,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAC,qBAAqB,EAAE,uBAAuB,EAAC,MAAM,SAAS,CAAC;AAiB5E,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACtD,QAAQ,EAAE,uBAAuB,CAAC;CACnC,CAAC,CAAC;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,GACT,EAAE,uBAAuB,2CAMzB;AAED,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;AAgB3E,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,yBAAyB,EACzB,UAAU,CACX,CAAC;AAEF,iBAAS,4BAA4B,CACnC,KAAK,EAAE,iCAAiC,2CAIzC;AAED,MAAM,MAAM,+BAA+B,GAAG,IAAI,CAChD,uBAAuB,EACvB,UAAU,CACX,CAAC;AAEF,iBAAS,0BAA0B,CAAC,KAAK,EAAE,+BAA+B,2CAGzE;AAED,MAAM,MAAM,oCAAoC,GAAG,IAAI,CACrD,4BAA4B,EAC5B,UAAU,CACX,CAAC;AAEF,iBAAS,+BAA+B,CACtC,KAAK,EAAE,oCAAoC,2CAI5C;AAED,MAAM,MAAM,gCAAgC,GAAG,cAAc,CAAC,OAAO,KAAK,CAAC,CAAC;AAE5E,iBAAS,2BAA2B,CAAC,EACnC,SAAS,EACT,cAAqB,EACrB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,gCAAgC,2CAclC;AAED,KAAK,+BAA+B,GAAG,CAAC,CACtC,KAAK,EAAE,mBAAmB,KACvB,YAAY,CAAC,GAAG;IACnB,MAAM,EAAE,OAAO,4BAA4B,CAAC;IAC5C,IAAI,EAAE,OAAO,kBAAkB,CAAC;IAChC,IAAI,EAAE,OAAO,0BAA0B,CAAC;IACxC,SAAS,EAAE,OAAO,+BAA+B,CAAC;IAClD,KAAK,EAAE,OAAO,2BAA2B,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,+BAS5B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, } from 'react';
|
|
3
|
+
import { Table } from '@sqlrooms/ui';
|
|
4
|
+
import { getProfilerTableWidth } from './layout';
|
|
5
|
+
import { MosaicProfilerHeader, } from './MosaicProfilerHeader';
|
|
6
|
+
import { MosaicProfilerRows, } from './MosaicProfilerRows';
|
|
7
|
+
import { MosaicProfilerStatusBar, } from './MosaicProfilerStatusBar';
|
|
8
|
+
import { useMosaicProfiler } from './useMosaicProfiler';
|
|
9
|
+
const profilerContext = createContext(null);
|
|
10
|
+
function useProfilerCompoundContext() {
|
|
11
|
+
const profiler = useContext(profilerContext);
|
|
12
|
+
if (!profiler) {
|
|
13
|
+
throw new Error('MosaicProfiler compound components must be rendered inside <MosaicProfiler> or <MosaicProfiler.Root>.');
|
|
14
|
+
}
|
|
15
|
+
return profiler;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Provides an existing profiler instance to compound profiler subcomponents.
|
|
19
|
+
*/
|
|
20
|
+
export function MosaicProfilerRoot({ children, profiler, }) {
|
|
21
|
+
return (_jsx(profilerContext.Provider, { value: profiler, children: children }));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a profiler instance and exposes it to compound profiler
|
|
25
|
+
* subcomponents through context.
|
|
26
|
+
*/
|
|
27
|
+
function MosaicProfilerComponent({ children, ...options }) {
|
|
28
|
+
const profiler = useMosaicProfiler(options);
|
|
29
|
+
return (_jsx(MosaicProfilerRoot, { profiler: profiler, children: children }));
|
|
30
|
+
}
|
|
31
|
+
function MosaicProfilerCompoundHeader(props) {
|
|
32
|
+
const profiler = useProfilerCompoundContext();
|
|
33
|
+
return _jsx(MosaicProfilerHeader, { ...props, profiler: profiler });
|
|
34
|
+
}
|
|
35
|
+
function MosaicProfilerCompoundRows(props) {
|
|
36
|
+
const profiler = useProfilerCompoundContext();
|
|
37
|
+
return _jsx(MosaicProfilerRows, { ...props, profiler: profiler });
|
|
38
|
+
}
|
|
39
|
+
function MosaicProfilerCompoundStatusBar(props) {
|
|
40
|
+
const profiler = useProfilerCompoundContext();
|
|
41
|
+
return _jsx(MosaicProfilerStatusBar, { ...props, profiler: profiler });
|
|
42
|
+
}
|
|
43
|
+
function MosaicProfilerCompoundTable({ className, disableWrapper = true, style, ...props }) {
|
|
44
|
+
const profiler = useProfilerCompoundContext();
|
|
45
|
+
const tableWidth = getProfilerTableWidth(profiler.columns);
|
|
46
|
+
return (_jsx(Table, { disableWrapper: disableWrapper, className: ['min-w-full table-fixed', className]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(' '), style: { width: `${tableWidth}px`, ...style }, ...props }));
|
|
49
|
+
}
|
|
50
|
+
export const MosaicProfiler = Object.assign(MosaicProfilerComponent, {
|
|
51
|
+
Header: MosaicProfilerCompoundHeader,
|
|
52
|
+
Root: MosaicProfilerRoot,
|
|
53
|
+
Rows: MosaicProfilerCompoundRows,
|
|
54
|
+
StatusBar: MosaicProfilerCompoundStatusBar,
|
|
55
|
+
Table: MosaicProfilerCompoundTable,
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=MosaicProfiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfiler.js","sourceRoot":"","sources":["../../src/profiler/MosaicProfiler.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,aAAa,EACb,UAAU,GAIX,MAAM,OAAO,CAAC;AACf,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AACnC,OAAO,EAAC,qBAAqB,EAAC,MAAM,UAAU,CAAC;AAC/C,OAAO,EACL,oBAAoB,GAErB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,uBAAuB,GAExB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAEtD,MAAM,eAAe,GAAG,aAAa,CAAiC,IAAI,CAAC,CAAC;AAE5E,SAAS,0BAA0B;IACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAMD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,GACgB;IACxB,OAAO,CACL,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ,YACtC,QAAQ,GACgB,CAC5B,CAAC;AACJ,CAAC;AAID;;;GAGG;AACH,SAAS,uBAAuB,CAAC,EAC/B,QAAQ,EACR,GAAG,OAAO,EACU;IACpB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CACL,KAAC,kBAAkB,IAAC,QAAQ,EAAE,QAAQ,YAAG,QAAQ,GAAsB,CACxE,CAAC;AACJ,CAAC;AAOD,SAAS,4BAA4B,CACnC,KAAwC;IAExC,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,OAAO,KAAC,oBAAoB,OAAK,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;AACjE,CAAC;AAOD,SAAS,0BAA0B,CAAC,KAAsC;IACxE,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,OAAO,KAAC,kBAAkB,OAAK,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;AAC/D,CAAC;AAOD,SAAS,+BAA+B,CACtC,KAA2C;IAE3C,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,OAAO,KAAC,uBAAuB,OAAK,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;AACpE,CAAC;AAID,SAAS,2BAA2B,CAAC,EACnC,SAAS,EACT,cAAc,GAAG,IAAI,EACrB,KAAK,EACL,GAAG,KAAK,EACyB;IACjC,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,qBAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE3D,OAAO,CACL,KAAC,KAAK,IACJ,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,CAAC,wBAAwB,EAAE,SAAS,CAAC;aAC7C,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,EACZ,KAAK,EAAE,EAAC,KAAK,EAAE,GAAG,UAAU,IAAI,EAAE,GAAG,KAAK,EAAC,KACvC,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAYD,MAAM,CAAC,MAAM,cAAc,GAAoC,MAAM,CAAC,MAAM,CAC1E,uBAAuB,EACvB;IACE,MAAM,EAAE,4BAA4B;IACpC,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,0BAA0B;IAChC,SAAS,EAAE,+BAA+B;IAC1C,KAAK,EAAE,2BAA2B;CACnC,CACF,CAAC","sourcesContent":["import {\n createContext,\n useContext,\n type ComponentProps,\n type PropsWithChildren,\n type ReactElement,\n} from 'react';\nimport {Table} from '@sqlrooms/ui';\nimport {getProfilerTableWidth} from './layout';\nimport {\n MosaicProfilerHeader,\n type MosaicProfilerHeaderProps,\n} from './MosaicProfilerHeader';\nimport {\n MosaicProfilerRows,\n type MosaicProfilerRowsProps,\n} from './MosaicProfilerRows';\nimport {\n MosaicProfilerStatusBar,\n type MosaicProfilerStatusBarProps,\n} from './MosaicProfilerStatusBar';\nimport type {MosaicProfilerOptions, UseMosaicProfilerReturn} from './types';\nimport {useMosaicProfiler} from './useMosaicProfiler';\n\nconst profilerContext = createContext<UseMosaicProfilerReturn | null>(null);\n\nfunction useProfilerCompoundContext() {\n const profiler = useContext(profilerContext);\n\n if (!profiler) {\n throw new Error(\n 'MosaicProfiler compound components must be rendered inside <MosaicProfiler> or <MosaicProfiler.Root>.',\n );\n }\n\n return profiler;\n}\n\nexport type MosaicProfilerRootProps = PropsWithChildren<{\n profiler: UseMosaicProfilerReturn;\n}>;\n\n/**\n * Provides an existing profiler instance to compound profiler subcomponents.\n */\nexport function MosaicProfilerRoot({\n children,\n profiler,\n}: MosaicProfilerRootProps) {\n return (\n <profilerContext.Provider value={profiler}>\n {children}\n </profilerContext.Provider>\n );\n}\n\nexport type MosaicProfilerProps = PropsWithChildren<MosaicProfilerOptions>;\n\n/**\n * Creates a profiler instance and exposes it to compound profiler\n * subcomponents through context.\n */\nfunction MosaicProfilerComponent({\n children,\n ...options\n}: MosaicProfilerProps): ReactElement {\n const profiler = useMosaicProfiler(options);\n return (\n <MosaicProfilerRoot profiler={profiler}>{children}</MosaicProfilerRoot>\n );\n}\n\nexport type MosaicProfilerCompoundHeaderProps = Omit<\n MosaicProfilerHeaderProps,\n 'profiler'\n>;\n\nfunction MosaicProfilerCompoundHeader(\n props: MosaicProfilerCompoundHeaderProps,\n) {\n const profiler = useProfilerCompoundContext();\n return <MosaicProfilerHeader {...props} profiler={profiler} />;\n}\n\nexport type MosaicProfilerCompoundRowsProps = Omit<\n MosaicProfilerRowsProps,\n 'profiler'\n>;\n\nfunction MosaicProfilerCompoundRows(props: MosaicProfilerCompoundRowsProps) {\n const profiler = useProfilerCompoundContext();\n return <MosaicProfilerRows {...props} profiler={profiler} />;\n}\n\nexport type MosaicProfilerCompoundStatusBarProps = Omit<\n MosaicProfilerStatusBarProps,\n 'profiler'\n>;\n\nfunction MosaicProfilerCompoundStatusBar(\n props: MosaicProfilerCompoundStatusBarProps,\n) {\n const profiler = useProfilerCompoundContext();\n return <MosaicProfilerStatusBar {...props} profiler={profiler} />;\n}\n\nexport type MosaicProfilerCompoundTableProps = ComponentProps<typeof Table>;\n\nfunction MosaicProfilerCompoundTable({\n className,\n disableWrapper = true,\n style,\n ...props\n}: MosaicProfilerCompoundTableProps) {\n const profiler = useProfilerCompoundContext();\n const tableWidth = getProfilerTableWidth(profiler.columns);\n\n return (\n <Table\n disableWrapper={disableWrapper}\n className={['min-w-full table-fixed', className]\n .filter(Boolean)\n .join(' ')}\n style={{width: `${tableWidth}px`, ...style}}\n {...props}\n />\n );\n}\n\ntype MosaicProfilerCompoundComponent = ((\n props: MosaicProfilerProps,\n) => ReactElement) & {\n Header: typeof MosaicProfilerCompoundHeader;\n Root: typeof MosaicProfilerRoot;\n Rows: typeof MosaicProfilerCompoundRows;\n StatusBar: typeof MosaicProfilerCompoundStatusBar;\n Table: typeof MosaicProfilerCompoundTable;\n};\n\nexport const MosaicProfiler: MosaicProfilerCompoundComponent = Object.assign(\n MosaicProfilerComponent,\n {\n Header: MosaicProfilerCompoundHeader,\n Root: MosaicProfilerRoot,\n Rows: MosaicProfilerCompoundRows,\n StatusBar: MosaicProfilerCompoundStatusBar,\n Table: MosaicProfilerCompoundTable,\n },\n);\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UseMosaicProfilerReturn } from './types';
|
|
2
|
+
export type MosaicProfilerHeaderProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
profiler: Pick<UseMosaicProfilerReturn, 'columns' | 'setSorting' | 'sorting'>;
|
|
5
|
+
};
|
|
6
|
+
export declare function MosaicProfilerHeader({ className, profiler, }: MosaicProfilerHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=MosaicProfilerHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerHeader.d.ts","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerHeader.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAKV,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC,CAAC;CAC/E,CAAC;AAgYF,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,QAAQ,GACT,EAAE,yBAAyB,2CA0E3B"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Badge, cn, TableHead, TableHeader, TableRow } from '@sqlrooms/ui';
|
|
3
|
+
import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { getProfilerColumnWidthPx, PROFILER_DEFAULT_COLUMN_WIDTH_PX, PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX, PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX, } from './layout';
|
|
6
|
+
import { isProfilerUnsupportedSummaryType } from './utils';
|
|
7
|
+
const COLUMN_WIDTH_CLASS = `min-w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px] w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px]`;
|
|
8
|
+
const STICKY_ROW_NUMBER_CLASS = `bg-background sticky left-0 top-0 z-40 min-w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] border-r px-1 text-center`;
|
|
9
|
+
const STICKY_COLUMN_HEADER_CLASS = 'bg-background sticky top-0 z-30 align-top whitespace-nowrap shadow-[inset_0_-1px_0_hsl(var(--border))]';
|
|
10
|
+
function getColumnWidthClass(column) {
|
|
11
|
+
return isProfilerUnsupportedSummaryType(column.field.type)
|
|
12
|
+
? `min-w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px] w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px]`
|
|
13
|
+
: COLUMN_WIDTH_CLASS;
|
|
14
|
+
}
|
|
15
|
+
function setNextSortState(currentSorting, columnId, setSorting) {
|
|
16
|
+
const current = currentSorting.find((entry) => entry.id === columnId);
|
|
17
|
+
if (!current) {
|
|
18
|
+
setSorting([{ desc: false, id: columnId }]);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!current.desc) {
|
|
22
|
+
setSorting([{ desc: true, id: columnId }]);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setSorting([]);
|
|
26
|
+
}
|
|
27
|
+
function formatPercentOfTotal(value) {
|
|
28
|
+
const maximumFractionDigits = value >= 0.1 ? 0 : value >= 0.01 ? 1 : 2;
|
|
29
|
+
return Intl.NumberFormat(undefined, {
|
|
30
|
+
maximumFractionDigits,
|
|
31
|
+
style: 'percent',
|
|
32
|
+
}).format(value);
|
|
33
|
+
}
|
|
34
|
+
function CategorySummaryCell({ summary, }) {
|
|
35
|
+
const [hoveredKey, setHoveredKey] = useState();
|
|
36
|
+
const totalCount = summary.buckets.reduce((acc, bucket) => acc + bucket.totalCount, 0);
|
|
37
|
+
const activeBucket = summary.buckets.find((bucket) => bucket.key === hoveredKey || bucket.key === summary.selectedKey);
|
|
38
|
+
const footerLabel = activeBucket
|
|
39
|
+
? `${activeBucket.label} (${activeBucket.totalCount.toLocaleString()} ${activeBucket.totalCount === 1 ? 'row' : 'rows'}, ${formatPercentOfTotal(totalCount > 0 ? activeBucket.totalCount / totalCount : 0)})`
|
|
40
|
+
: `${summary.bucketCount.toLocaleString()} categories`;
|
|
41
|
+
return (_jsxs("div", { className: "space-y-0.5 pt-1.5", children: [_jsx("div", { className: "flex h-10 overflow-hidden rounded-sm border", children: summary.buckets.map((bucket) => {
|
|
42
|
+
const width = totalCount > 0
|
|
43
|
+
? `${(bucket.totalCount / totalCount) * 100}%`
|
|
44
|
+
: '0%';
|
|
45
|
+
const fillPct = bucket.totalCount > 0
|
|
46
|
+
? (bucket.filteredCount / bucket.totalCount) * 100
|
|
47
|
+
: 0;
|
|
48
|
+
const isSelected = summary.selectedKey === bucket.key;
|
|
49
|
+
const background = bucket.kind === 'overflow'
|
|
50
|
+
? `repeating-linear-gradient(to right, hsl(var(--border)) 0px, hsl(var(--border)) 2px, transparent 2px, transparent 4px)`
|
|
51
|
+
: `linear-gradient(to top, hsl(var(--chart-1)) ${fillPct}%, hsl(var(--muted-foreground) / 0.22) ${fillPct}%, hsl(var(--muted-foreground) / 0.22) 100%)`;
|
|
52
|
+
return (_jsx("button", { type: "button", disabled: !bucket.selectable, className: cn('relative flex h-full items-center justify-center overflow-hidden border-r px-0.5 text-[10px] font-normal text-white transition-opacity disabled:cursor-default', isSelected && 'ring-ring ring-1 ring-inset', !bucket.selectable && 'text-muted-foreground'), style: {
|
|
53
|
+
background,
|
|
54
|
+
flexBasis: width,
|
|
55
|
+
flexGrow: bucket.totalCount,
|
|
56
|
+
}, onClick: () => summary.toggleValue(bucket.key), onMouseEnter: () => setHoveredKey(bucket.key), onMouseLeave: () => setHoveredKey(undefined), children: _jsx("span", { className: "max-w-full truncate px-1", children: bucket.label }) }, bucket.key));
|
|
57
|
+
}) }), _jsx("div", { className: "text-muted-foreground truncate text-[10px] font-normal", children: footerLabel })] }));
|
|
58
|
+
}
|
|
59
|
+
const histogramInteractorIds = new WeakMap();
|
|
60
|
+
let nextHistogramInteractorId = 0;
|
|
61
|
+
function getHistogramInteractorId(interactor) {
|
|
62
|
+
const cachedId = histogramInteractorIds.get(interactor);
|
|
63
|
+
if (cachedId !== undefined) {
|
|
64
|
+
return cachedId;
|
|
65
|
+
}
|
|
66
|
+
const id = ++nextHistogramInteractorId;
|
|
67
|
+
histogramInteractorIds.set(interactor, id);
|
|
68
|
+
return id;
|
|
69
|
+
}
|
|
70
|
+
function createScale(type, domain, range) {
|
|
71
|
+
const [d0, d1] = domain.map((value) => value instanceof Date ? value.getTime() : value);
|
|
72
|
+
const [r0, r1] = range;
|
|
73
|
+
const span = d1 - d0 || 1;
|
|
74
|
+
const rspan = r1 - r0;
|
|
75
|
+
return {
|
|
76
|
+
apply(value) {
|
|
77
|
+
const numeric = value instanceof Date ? value.getTime() : value;
|
|
78
|
+
return r0 + ((numeric - d0) / span) * rspan;
|
|
79
|
+
},
|
|
80
|
+
domain,
|
|
81
|
+
invert(value) {
|
|
82
|
+
const numeric = d0 + ((value - r0) / (rspan || 1)) * span;
|
|
83
|
+
return type === 'utc' ? new Date(numeric) : numeric;
|
|
84
|
+
},
|
|
85
|
+
range,
|
|
86
|
+
type,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function formatDomainValue(value, valueType) {
|
|
90
|
+
if (valueType === 'date') {
|
|
91
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
92
|
+
return date.toISOString().slice(0, 10);
|
|
93
|
+
}
|
|
94
|
+
return Intl.NumberFormat(undefined, {
|
|
95
|
+
maximumFractionDigits: 2,
|
|
96
|
+
}).format(typeof value === 'number' ? value : value.getTime());
|
|
97
|
+
}
|
|
98
|
+
function HistogramSummaryCell({ summary, }) {
|
|
99
|
+
const svgRef = useRef(null);
|
|
100
|
+
const brushRootRef = useRef(null);
|
|
101
|
+
const initializedBrushRef = useRef(undefined);
|
|
102
|
+
const layout = useMemo(() => {
|
|
103
|
+
const width = 122;
|
|
104
|
+
const height = 40;
|
|
105
|
+
const margin = { bottom: 4, left: 4, right: 4, top: 2 };
|
|
106
|
+
const nullBarWidth = summary.totalNullCount > 0 ? 5 : 0;
|
|
107
|
+
const nullBarGap = nullBarWidth > 0 ? 3 : 0;
|
|
108
|
+
const totalBins = summary.totalBins.length
|
|
109
|
+
? summary.totalBins
|
|
110
|
+
: summary.filteredBins;
|
|
111
|
+
const domain = totalBins.length > 0
|
|
112
|
+
? [totalBins[0].x0, totalBins[totalBins.length - 1].x1]
|
|
113
|
+
: null;
|
|
114
|
+
const totalMax = Math.max(summary.totalNullCount, ...totalBins.map((bin) => bin.length), 1);
|
|
115
|
+
const xScale = domain
|
|
116
|
+
? createScale(summary.valueType === 'date' ? 'utc' : 'linear', domain, [
|
|
117
|
+
margin.left + nullBarWidth + nullBarGap,
|
|
118
|
+
width - margin.right,
|
|
119
|
+
])
|
|
120
|
+
: null;
|
|
121
|
+
const yScale = createScale('linear', [0, totalMax], [height - margin.bottom, margin.top]);
|
|
122
|
+
return {
|
|
123
|
+
height,
|
|
124
|
+
margin,
|
|
125
|
+
nullBarGap,
|
|
126
|
+
nullBarWidth,
|
|
127
|
+
width,
|
|
128
|
+
xScale,
|
|
129
|
+
yScale,
|
|
130
|
+
};
|
|
131
|
+
}, [summary]);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
const svg = svgRef.current;
|
|
134
|
+
const brushRoot = brushRootRef.current;
|
|
135
|
+
const interactor = summary.interactor;
|
|
136
|
+
if (!svg || !brushRoot || !interactor || !layout.xScale)
|
|
137
|
+
return;
|
|
138
|
+
const brushKey = [
|
|
139
|
+
getHistogramInteractorId(interactor),
|
|
140
|
+
summary.valueType,
|
|
141
|
+
layout.xScale.domain
|
|
142
|
+
.map((value) => (value instanceof Date ? value.getTime() : value))
|
|
143
|
+
.join(':'),
|
|
144
|
+
layout.xScale.range.join(':'),
|
|
145
|
+
].join('|');
|
|
146
|
+
if (initializedBrushRef.current === brushKey)
|
|
147
|
+
return;
|
|
148
|
+
svg.scale = (channel) => {
|
|
149
|
+
if (channel === 'x')
|
|
150
|
+
return layout.xScale;
|
|
151
|
+
if (channel === 'y')
|
|
152
|
+
return layout.yScale;
|
|
153
|
+
return undefined;
|
|
154
|
+
};
|
|
155
|
+
brushRoot.replaceChildren();
|
|
156
|
+
interactor.init(svg, brushRoot);
|
|
157
|
+
initializedBrushRef.current = brushKey;
|
|
158
|
+
}, [layout.xScale, layout.yScale, summary.interactor, summary.valueType]);
|
|
159
|
+
const axisY = layout.height - layout.margin.bottom;
|
|
160
|
+
const nullBarCenter = layout.margin.left + layout.nullBarWidth / 2;
|
|
161
|
+
const xAxisStart = layout.xScale?.range[0] ?? layout.margin.left;
|
|
162
|
+
const xAxisEnd = layout.xScale?.range[1] ?? layout.width - layout.margin.right;
|
|
163
|
+
return (_jsxs("div", { className: "space-y-0 pt-1.5", children: [_jsxs("svg", { ref: svgRef, width: layout.width, height: layout.height, viewBox: `0 0 ${layout.width} ${layout.height}`, className: "max-w-full overflow-visible", children: [summary.totalNullCount > 0 ? (_jsx("rect", { x: layout.margin.left, y: layout.yScale.apply(summary.totalNullCount), width: layout.nullBarWidth, height: layout.yScale.apply(0) -
|
|
164
|
+
layout.yScale.apply(summary.totalNullCount), fill: "hsl(var(--muted-foreground) / 0.22)" })) : null, summary.totalNullCount > 0 ? (_jsx("rect", { x: layout.margin.left, y: layout.yScale.apply(summary.filteredNullCount), width: layout.nullBarWidth, height: layout.yScale.apply(0) -
|
|
165
|
+
layout.yScale.apply(summary.filteredNullCount), fill: "hsl(var(--chart-1))", opacity: 0.95 })) : null, summary.totalBins.map((bin, index) => {
|
|
166
|
+
const x0 = layout.xScale?.apply(bin.x0) ?? 0;
|
|
167
|
+
const x1 = layout.xScale?.apply(bin.x1) ?? 0;
|
|
168
|
+
const y = layout.yScale.apply(bin.length);
|
|
169
|
+
return (_jsx("rect", { x: x0 + 1, y: y, width: Math.max(x1 - x0 - 1, 1), height: layout.yScale.apply(0) - y, fill: "hsl(var(--muted-foreground) / 0.22)" }, `bg-${index}`));
|
|
170
|
+
}), summary.filteredBins.map((bin, index) => {
|
|
171
|
+
const x0 = layout.xScale?.apply(bin.x0) ?? 0;
|
|
172
|
+
const x1 = layout.xScale?.apply(bin.x1) ?? 0;
|
|
173
|
+
const y = layout.yScale.apply(bin.length);
|
|
174
|
+
return (_jsx("rect", { x: x0 + 1, y: y, width: Math.max(x1 - x0 - 1, 1), height: layout.yScale.apply(0) - y, fill: "hsl(var(--chart-1))", opacity: 0.95 }, `fg-${index}`));
|
|
175
|
+
}), _jsx("line", { x1: xAxisStart, x2: xAxisEnd, y1: axisY, y2: axisY, stroke: "hsl(var(--border))" }), _jsx("line", { x1: xAxisStart, x2: xAxisStart, y1: axisY, y2: axisY + 2.5, stroke: "hsl(var(--border))" }), _jsx("line", { x1: xAxisEnd, x2: xAxisEnd, y1: axisY, y2: axisY + 2.5, stroke: "hsl(var(--border))" }), summary.totalNullCount > 0 ? (_jsx("line", { x1: nullBarCenter, x2: nullBarCenter, y1: axisY, y2: axisY + 2.5, stroke: "hsl(var(--chart-1))" })) : null, _jsx("g", { ref: brushRootRef })] }), _jsxs("div", { className: "text-muted-foreground relative h-3.5 text-[10px] font-normal", children: [summary.totalNullCount > 0 ? (_jsx("span", { className: "absolute -translate-x-1/2", style: { left: nullBarCenter }, children: "\u2205" })) : null, _jsx("span", { className: "absolute", style: { left: xAxisStart }, children: summary.totalBins[0]
|
|
176
|
+
? formatDomainValue(summary.totalBins[0].x0, summary.valueType)
|
|
177
|
+
: '0' }), _jsx("span", { className: "absolute -translate-x-full", style: { left: xAxisEnd }, children: summary.totalBins.at(-1)
|
|
178
|
+
? formatDomainValue(summary.totalBins.at(-1).x1, summary.valueType)
|
|
179
|
+
: '0' })] })] }));
|
|
180
|
+
}
|
|
181
|
+
function SummaryCell({ column }) {
|
|
182
|
+
if (column.summary.kind === 'histogram') {
|
|
183
|
+
return _jsx(HistogramSummaryCell, { summary: column.summary });
|
|
184
|
+
}
|
|
185
|
+
if (column.summary.kind === 'category') {
|
|
186
|
+
return _jsx(CategorySummaryCell, { summary: column.summary });
|
|
187
|
+
}
|
|
188
|
+
return (_jsx("div", { className: "text-muted-foreground pt-1.5 text-[10px] font-normal", children: column.summary.label }));
|
|
189
|
+
}
|
|
190
|
+
export function MosaicProfilerHeader({ className, profiler, }) {
|
|
191
|
+
return (_jsxs(_Fragment, { children: [_jsxs("colgroup", { children: [_jsx("col", { style: { width: PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX } }), profiler.columns.map((column) => (_jsx("col", { style: { width: getProfilerColumnWidthPx(column) } }, column.name)))] }), _jsx(TableHeader, { className: cn('sticky top-0 z-30', className), children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: STICKY_ROW_NUMBER_CLASS, children: "#" }), profiler.columns.map((column) => {
|
|
192
|
+
const sortState = profiler.sorting.find((entry) => entry.id === column.name);
|
|
193
|
+
return (_jsx(TableHead, { className: cn(getColumnWidthClass(column), STICKY_COLUMN_HEADER_CLASS), children: _jsxs("div", { className: "min-w-0", children: [_jsxs("button", { type: "button", className: "group relative flex w-full items-start gap-1.5 pr-4 text-left", onClick: () => setNextSortState(profiler.sorting, column.name, profiler.setSorting), children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-[13px] leading-tight font-semibold", children: column.name }), _jsx(Badge, { variant: "outline", className: "mt-0.5 max-w-full truncate px-2 py-0 text-[9px] opacity-60", children: String(column.field.type) })] }), _jsx("span", { className: "text-muted-foreground pointer-events-none absolute top-1 right-0 flex h-4 w-4 items-center justify-center", children: sortState ? (sortState.desc ? (_jsx(ChevronDownIcon, { className: "h-4 w-4" })) : (_jsx(ChevronUpIcon, { className: "h-4 w-4" }))) : (_jsxs("span", { className: "flex h-4 w-4 flex-col items-center justify-center opacity-0 transition-opacity group-hover:opacity-60", children: [_jsx(ChevronUpIcon, { className: "-mb-1 h-3 w-3" }), _jsx(ChevronDownIcon, { className: "-mt-1 h-3 w-3" })] })) })] }), _jsx(SummaryCell, { column: column })] }) }, column.name));
|
|
194
|
+
})] }) })] }));
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=MosaicProfilerHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerHeader.js","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerHeader.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Badge, cn, TableHead, TableHeader, TableRow} from '@sqlrooms/ui';\nimport {ChevronDownIcon, ChevronUpIcon} from 'lucide-react';\nimport {useEffect, useMemo, useRef, useState} from 'react';\nimport {\n getProfilerColumnWidthPx,\n PROFILER_DEFAULT_COLUMN_WIDTH_PX,\n PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX,\n PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX,\n} from './layout';\nimport type {\n MosaicProfilerCategorySummary,\n MosaicProfilerColumnState,\n MosaicProfilerHistogramSummary,\n MosaicProfilerSorting,\n UseMosaicProfilerReturn,\n} from './types';\nimport {isProfilerUnsupportedSummaryType} from './utils';\n\nexport type MosaicProfilerHeaderProps = {\n className?: string;\n profiler: Pick<UseMosaicProfilerReturn, 'columns' | 'setSorting' | 'sorting'>;\n};\n\nconst COLUMN_WIDTH_CLASS = `min-w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px] w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_DEFAULT_COLUMN_WIDTH_PX}px]`;\nconst STICKY_ROW_NUMBER_CLASS = `bg-background sticky left-0 top-0 z-40 min-w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}px] border-r px-1 text-center`;\nconst STICKY_COLUMN_HEADER_CLASS =\n 'bg-background sticky top-0 z-30 align-top whitespace-nowrap shadow-[inset_0_-1px_0_hsl(var(--border))]';\n\nfunction getColumnWidthClass(column: MosaicProfilerColumnState) {\n return isProfilerUnsupportedSummaryType(column.field.type)\n ? `min-w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px] w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px] max-w-[${PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX}px]`\n : COLUMN_WIDTH_CLASS;\n}\n\nfunction setNextSortState(\n currentSorting: MosaicProfilerSorting,\n columnId: string,\n setSorting: UseMosaicProfilerReturn['setSorting'],\n) {\n const current = currentSorting.find((entry) => entry.id === columnId);\n if (!current) {\n setSorting([{desc: false, id: columnId}]);\n return;\n }\n if (!current.desc) {\n setSorting([{desc: true, id: columnId}]);\n return;\n }\n setSorting([]);\n}\n\nfunction formatPercentOfTotal(value: number) {\n const maximumFractionDigits = value >= 0.1 ? 0 : value >= 0.01 ? 1 : 2;\n return Intl.NumberFormat(undefined, {\n maximumFractionDigits,\n style: 'percent',\n }).format(value);\n}\n\nfunction CategorySummaryCell({\n summary,\n}: {\n summary: MosaicProfilerCategorySummary;\n}) {\n const [hoveredKey, setHoveredKey] = useState<string>();\n const totalCount = summary.buckets.reduce(\n (acc, bucket) => acc + bucket.totalCount,\n 0,\n );\n const activeBucket = summary.buckets.find(\n (bucket) => bucket.key === hoveredKey || bucket.key === summary.selectedKey,\n );\n const footerLabel = activeBucket\n ? `${activeBucket.label} (${activeBucket.totalCount.toLocaleString()} ${activeBucket.totalCount === 1 ? 'row' : 'rows'}, ${formatPercentOfTotal(totalCount > 0 ? activeBucket.totalCount / totalCount : 0)})`\n : `${summary.bucketCount.toLocaleString()} categories`;\n\n return (\n <div className=\"space-y-0.5 pt-1.5\">\n <div className=\"flex h-10 overflow-hidden rounded-sm border\">\n {summary.buckets.map((bucket) => {\n const width =\n totalCount > 0\n ? `${(bucket.totalCount / totalCount) * 100}%`\n : '0%';\n const fillPct =\n bucket.totalCount > 0\n ? (bucket.filteredCount / bucket.totalCount) * 100\n : 0;\n const isSelected = summary.selectedKey === bucket.key;\n const background =\n bucket.kind === 'overflow'\n ? `repeating-linear-gradient(to right, hsl(var(--border)) 0px, hsl(var(--border)) 2px, transparent 2px, transparent 4px)`\n : `linear-gradient(to top, hsl(var(--chart-1)) ${fillPct}%, hsl(var(--muted-foreground) / 0.22) ${fillPct}%, hsl(var(--muted-foreground) / 0.22) 100%)`;\n\n return (\n <button\n key={bucket.key}\n type=\"button\"\n disabled={!bucket.selectable}\n className={cn(\n 'relative flex h-full items-center justify-center overflow-hidden border-r px-0.5 text-[10px] font-normal text-white transition-opacity disabled:cursor-default',\n isSelected && 'ring-ring ring-1 ring-inset',\n !bucket.selectable && 'text-muted-foreground',\n )}\n style={{\n background,\n flexBasis: width,\n flexGrow: bucket.totalCount,\n }}\n onClick={() => summary.toggleValue(bucket.key)}\n onMouseEnter={() => setHoveredKey(bucket.key)}\n onMouseLeave={() => setHoveredKey(undefined)}\n >\n <span className=\"max-w-full truncate px-1\">{bucket.label}</span>\n </button>\n );\n })}\n </div>\n <div className=\"text-muted-foreground truncate text-[10px] font-normal\">\n {footerLabel}\n </div>\n </div>\n );\n}\n\ntype ScaleLike = {\n apply: (value: number | Date) => number;\n domain: [number | Date, number | Date];\n invert: (value: number) => number | Date;\n range: [number, number];\n type: 'linear' | 'utc';\n};\n\nconst histogramInteractorIds = new WeakMap<object, number>();\nlet nextHistogramInteractorId = 0;\n\nfunction getHistogramInteractorId(interactor: object) {\n const cachedId = histogramInteractorIds.get(interactor);\n if (cachedId !== undefined) {\n return cachedId;\n }\n\n const id = ++nextHistogramInteractorId;\n histogramInteractorIds.set(interactor, id);\n return id;\n}\n\nfunction createScale(\n type: ScaleLike['type'],\n domain: [number | Date, number | Date],\n range: [number, number],\n): ScaleLike {\n const [d0, d1] = domain.map((value) =>\n value instanceof Date ? value.getTime() : value,\n ) as [number, number];\n const [r0, r1] = range;\n const span = d1 - d0 || 1;\n const rspan = r1 - r0;\n\n return {\n apply(value: number | Date) {\n const numeric = value instanceof Date ? value.getTime() : value;\n return r0 + ((numeric - d0) / span) * rspan;\n },\n domain,\n invert(value: number) {\n const numeric = d0 + ((value - r0) / (rspan || 1)) * span;\n return type === 'utc' ? new Date(numeric) : numeric;\n },\n range,\n type,\n };\n}\n\nfunction formatDomainValue(value: number | Date, valueType: 'date' | 'number') {\n if (valueType === 'date') {\n const date = value instanceof Date ? value : new Date(value);\n return date.toISOString().slice(0, 10);\n }\n return Intl.NumberFormat(undefined, {\n maximumFractionDigits: 2,\n }).format(typeof value === 'number' ? value : value.getTime());\n}\n\nfunction HistogramSummaryCell({\n summary,\n}: {\n summary: MosaicProfilerHistogramSummary;\n}) {\n const svgRef = useRef<SVGSVGElement>(null);\n const brushRootRef = useRef<SVGGElement>(null);\n const initializedBrushRef = useRef<string | undefined>(undefined);\n\n const layout = useMemo(() => {\n const width = 122;\n const height = 40;\n const margin = {bottom: 4, left: 4, right: 4, top: 2};\n const nullBarWidth = summary.totalNullCount > 0 ? 5 : 0;\n const nullBarGap = nullBarWidth > 0 ? 3 : 0;\n const totalBins = summary.totalBins.length\n ? summary.totalBins\n : summary.filteredBins;\n const domain: [number | Date, number | Date] | null =\n totalBins.length > 0\n ? [totalBins[0]!.x0, totalBins[totalBins.length - 1]!.x1]\n : null;\n const totalMax = Math.max(\n summary.totalNullCount,\n ...totalBins.map((bin) => bin.length),\n 1,\n );\n const xScale = domain\n ? createScale(summary.valueType === 'date' ? 'utc' : 'linear', domain, [\n margin.left + nullBarWidth + nullBarGap,\n width - margin.right,\n ])\n : null;\n const yScale = createScale(\n 'linear',\n [0, totalMax],\n [height - margin.bottom, margin.top],\n );\n return {\n height,\n margin,\n nullBarGap,\n nullBarWidth,\n width,\n xScale,\n yScale,\n };\n }, [summary]);\n\n useEffect(() => {\n const svg = svgRef.current;\n const brushRoot = brushRootRef.current;\n const interactor = summary.interactor;\n if (!svg || !brushRoot || !interactor || !layout.xScale) return;\n\n const brushKey = [\n getHistogramInteractorId(interactor),\n summary.valueType,\n layout.xScale.domain\n .map((value) => (value instanceof Date ? value.getTime() : value))\n .join(':'),\n layout.xScale.range.join(':'),\n ].join('|');\n if (initializedBrushRef.current === brushKey) return;\n\n (\n svg as SVGSVGElement & {\n scale: (channel: string) => ScaleLike | undefined;\n }\n ).scale = (channel: string) => {\n if (channel === 'x') return layout.xScale!;\n if (channel === 'y') return layout.yScale;\n return undefined;\n };\n\n brushRoot.replaceChildren();\n interactor.init(svg as any, brushRoot);\n initializedBrushRef.current = brushKey;\n }, [layout.xScale, layout.yScale, summary.interactor, summary.valueType]);\n\n const axisY = layout.height - layout.margin.bottom;\n const nullBarCenter = layout.margin.left + layout.nullBarWidth / 2;\n const xAxisStart = layout.xScale?.range[0] ?? layout.margin.left;\n const xAxisEnd =\n layout.xScale?.range[1] ?? layout.width - layout.margin.right;\n\n return (\n <div className=\"space-y-0 pt-1.5\">\n <svg\n ref={svgRef}\n width={layout.width}\n height={layout.height}\n viewBox={`0 0 ${layout.width} ${layout.height}`}\n className=\"max-w-full overflow-visible\"\n >\n {summary.totalNullCount > 0 ? (\n <rect\n x={layout.margin.left}\n y={layout.yScale.apply(summary.totalNullCount)}\n width={layout.nullBarWidth}\n height={\n layout.yScale.apply(0) -\n layout.yScale.apply(summary.totalNullCount)\n }\n fill=\"hsl(var(--muted-foreground) / 0.22)\"\n />\n ) : null}\n {summary.totalNullCount > 0 ? (\n <rect\n x={layout.margin.left}\n y={layout.yScale.apply(summary.filteredNullCount)}\n width={layout.nullBarWidth}\n height={\n layout.yScale.apply(0) -\n layout.yScale.apply(summary.filteredNullCount)\n }\n fill=\"hsl(var(--chart-1))\"\n opacity={0.95}\n />\n ) : null}\n {summary.totalBins.map((bin, index) => {\n const x0 = layout.xScale?.apply(bin.x0) ?? 0;\n const x1 = layout.xScale?.apply(bin.x1) ?? 0;\n const y = layout.yScale.apply(bin.length);\n return (\n <rect\n key={`bg-${index}`}\n x={x0 + 1}\n y={y}\n width={Math.max(x1 - x0 - 1, 1)}\n height={layout.yScale.apply(0) - y}\n fill=\"hsl(var(--muted-foreground) / 0.22)\"\n />\n );\n })}\n {summary.filteredBins.map((bin, index) => {\n const x0 = layout.xScale?.apply(bin.x0) ?? 0;\n const x1 = layout.xScale?.apply(bin.x1) ?? 0;\n const y = layout.yScale.apply(bin.length);\n return (\n <rect\n key={`fg-${index}`}\n x={x0 + 1}\n y={y}\n width={Math.max(x1 - x0 - 1, 1)}\n height={layout.yScale.apply(0) - y}\n fill=\"hsl(var(--chart-1))\"\n opacity={0.95}\n />\n );\n })}\n <line\n x1={xAxisStart}\n x2={xAxisEnd}\n y1={axisY}\n y2={axisY}\n stroke=\"hsl(var(--border))\"\n />\n <line\n x1={xAxisStart}\n x2={xAxisStart}\n y1={axisY}\n y2={axisY + 2.5}\n stroke=\"hsl(var(--border))\"\n />\n <line\n x1={xAxisEnd}\n x2={xAxisEnd}\n y1={axisY}\n y2={axisY + 2.5}\n stroke=\"hsl(var(--border))\"\n />\n {summary.totalNullCount > 0 ? (\n <line\n x1={nullBarCenter}\n x2={nullBarCenter}\n y1={axisY}\n y2={axisY + 2.5}\n stroke=\"hsl(var(--chart-1))\"\n />\n ) : null}\n <g ref={brushRootRef} />\n </svg>\n <div className=\"text-muted-foreground relative h-3.5 text-[10px] font-normal\">\n {summary.totalNullCount > 0 ? (\n <span\n className=\"absolute -translate-x-1/2\"\n style={{left: nullBarCenter}}\n >\n ∅\n </span>\n ) : null}\n <span className=\"absolute\" style={{left: xAxisStart}}>\n {summary.totalBins[0]\n ? formatDomainValue(summary.totalBins[0].x0, summary.valueType)\n : '0'}\n </span>\n <span className=\"absolute -translate-x-full\" style={{left: xAxisEnd}}>\n {summary.totalBins.at(-1)\n ? formatDomainValue(summary.totalBins.at(-1)!.x1, summary.valueType)\n : '0'}\n </span>\n </div>\n </div>\n );\n}\n\nfunction SummaryCell({column}: {column: MosaicProfilerColumnState}) {\n if (column.summary.kind === 'histogram') {\n return <HistogramSummaryCell summary={column.summary} />;\n }\n if (column.summary.kind === 'category') {\n return <CategorySummaryCell summary={column.summary} />;\n }\n return (\n <div className=\"text-muted-foreground pt-1.5 text-[10px] font-normal\">\n {column.summary.label}\n </div>\n );\n}\n\nexport function MosaicProfilerHeader({\n className,\n profiler,\n}: MosaicProfilerHeaderProps) {\n return (\n <>\n <colgroup>\n <col style={{width: PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX}} />\n {profiler.columns.map((column) => (\n <col\n key={column.name}\n style={{width: getProfilerColumnWidthPx(column)}}\n />\n ))}\n </colgroup>\n <TableHeader className={cn('sticky top-0 z-30', className)}>\n <TableRow>\n <TableHead className={STICKY_ROW_NUMBER_CLASS}>#</TableHead>\n {profiler.columns.map((column) => {\n const sortState = profiler.sorting.find(\n (entry) => entry.id === column.name,\n );\n return (\n <TableHead\n key={column.name}\n className={cn(\n getColumnWidthClass(column),\n STICKY_COLUMN_HEADER_CLASS,\n )}\n >\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"group relative flex w-full items-start gap-1.5 pr-4 text-left\"\n onClick={() =>\n setNextSortState(\n profiler.sorting,\n column.name,\n profiler.setSorting,\n )\n }\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-[13px] leading-tight font-semibold\">\n {column.name}\n </div>\n <Badge\n variant=\"outline\"\n className=\"mt-0.5 max-w-full truncate px-2 py-0 text-[9px] opacity-60\"\n >\n {String(column.field.type)}\n </Badge>\n </div>\n <span className=\"text-muted-foreground pointer-events-none absolute top-1 right-0 flex h-4 w-4 items-center justify-center\">\n {sortState ? (\n sortState.desc ? (\n <ChevronDownIcon className=\"h-4 w-4\" />\n ) : (\n <ChevronUpIcon className=\"h-4 w-4\" />\n )\n ) : (\n <span className=\"flex h-4 w-4 flex-col items-center justify-center opacity-0 transition-opacity group-hover:opacity-60\">\n <ChevronUpIcon className=\"-mb-1 h-3 w-3\" />\n <ChevronDownIcon className=\"-mt-1 h-3 w-3\" />\n </span>\n )}\n </span>\n </button>\n <SummaryCell column={column} />\n </div>\n </TableHead>\n );\n })}\n </TableRow>\n </TableHeader>\n </>\n );\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UseMosaicProfilerReturn } from './types';
|
|
2
|
+
export type MosaicProfilerRowsProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
profiler: Pick<UseMosaicProfilerReturn, 'columns' | 'pageTable' | 'pagination' | 'tableError'>;
|
|
5
|
+
};
|
|
6
|
+
declare function MosaicProfilerRowsImpl({ className, profiler, }: MosaicProfilerRowsProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const MosaicProfilerRows: import("react").MemoExoticComponent<typeof MosaicProfilerRowsImpl>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=MosaicProfilerRows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerRows.d.ts","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerRows.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,SAAS,CAAC;AAGrD,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,IAAI,CACZ,uBAAuB,EACvB,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,CACtD,CAAC;CACH,CAAC;AA+GF,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,QAAQ,GACT,EAAE,uBAAuB,2CA2CzB;AAoBD,eAAO,MAAM,kBAAkB,oEAW9B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowCellValue, isNumericArrowType } from '@sqlrooms/data-table';
|
|
3
|
+
import { cn, TableBody, TableCell, TableRow } from '@sqlrooms/ui';
|
|
4
|
+
import * as arrow from 'apache-arrow';
|
|
5
|
+
import { memo } from 'react';
|
|
6
|
+
import { isProfilerUnsupportedSummaryType } from './utils';
|
|
7
|
+
const COLUMN_WIDTH_CLASS = 'min-w-[140px] w-[140px] max-w-[140px]';
|
|
8
|
+
const ROW_NUMBER_CLASS = 'bg-background text-muted-foreground sticky left-0 z-10 w-[40px] max-w-[40px] min-w-[40px] border-r px-1 text-center';
|
|
9
|
+
function getColumnWidthClass(field) {
|
|
10
|
+
return isProfilerUnsupportedSummaryType(field.type)
|
|
11
|
+
? 'min-w-[104px] w-[104px] max-w-[104px]'
|
|
12
|
+
: COLUMN_WIDTH_CLASS;
|
|
13
|
+
}
|
|
14
|
+
function formatProfilerValue(type, value) {
|
|
15
|
+
if (arrow.DataType.isBinary(type) && value instanceof Uint8Array) {
|
|
16
|
+
return `${value.byteLength} bytes`;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function SizingRow({ columns }) {
|
|
21
|
+
return (_jsxs(TableRow, { "aria-hidden": "true", className: "pointer-events-none h-0 border-0 opacity-0 hover:bg-transparent", children: [_jsx(TableCell, { className: "w-[40px] max-w-[40px] min-w-[40px] border-r p-0" }), columns.map((column) => (_jsx(TableCell, { className: cn(getColumnWidthClass(column.field), 'border-r p-0') }, column.name)))] }));
|
|
22
|
+
}
|
|
23
|
+
function EmptyStateRow({ columns, message, tone = 'muted', }) {
|
|
24
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: ROW_NUMBER_CLASS }), _jsx(TableCell, { colSpan: Math.max(columns.length, 1), className: cn('max-w-[240px] border-r p-4 align-top font-mono text-xs', tone === 'error'
|
|
25
|
+
? 'text-sm text-red-500'
|
|
26
|
+
: 'text-muted-foreground text-sm'), children: message })] }));
|
|
27
|
+
}
|
|
28
|
+
const DataRow = memo(function DataRow({ columns, pageIndex, pageSize, pageTable, rowIndex, }) {
|
|
29
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: ROW_NUMBER_CLASS, children: pageIndex * pageSize + rowIndex + 1 }), columns.map((column) => {
|
|
30
|
+
const vector = pageTable.getChild(column.name);
|
|
31
|
+
const value = vector?.get(rowIndex);
|
|
32
|
+
return (_jsx(TableCell, { className: cn(getColumnWidthClass(column.field), 'max-w-[240px] overflow-hidden border-r align-top font-mono text-xs', isNumericArrowType(column.field.type) && 'text-right'), children: _jsx("span", { className: "block min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: _jsx(ArrowCellValue, { fieldName: column.name, fontSizeClass: "text-xs", formatValue: formatProfilerValue, type: column.field.type, value: value }) }) }, column.name));
|
|
33
|
+
})] }));
|
|
34
|
+
});
|
|
35
|
+
function MosaicProfilerRowsImpl({ className, profiler, }) {
|
|
36
|
+
if (profiler.tableError) {
|
|
37
|
+
return (_jsxs(TableBody, { className: className, children: [_jsx(SizingRow, { columns: profiler.columns }), _jsx(EmptyStateRow, { columns: profiler.columns, message: profiler.tableError.message, tone: "error" })] }));
|
|
38
|
+
}
|
|
39
|
+
if (!profiler.pageTable || profiler.pageTable.numRows === 0) {
|
|
40
|
+
return (_jsxs(TableBody, { className: className, children: [_jsx(SizingRow, { columns: profiler.columns }), _jsx(EmptyStateRow, { columns: profiler.columns, message: "No rows" })] }));
|
|
41
|
+
}
|
|
42
|
+
const rows = Array.from({ length: profiler.pageTable.numRows }, (_, index) => index);
|
|
43
|
+
const pageTable = profiler.pageTable;
|
|
44
|
+
return (_jsx(TableBody, { className: className, children: rows.map((rowIndex) => (_jsx(DataRow, { columns: profiler.columns, pageIndex: profiler.pagination.pageIndex, pageSize: profiler.pagination.pageSize, pageTable: pageTable, rowIndex: rowIndex }, rowIndex))) }));
|
|
45
|
+
}
|
|
46
|
+
function areRowColumnsEqual(left, right) {
|
|
47
|
+
if (left.length !== right.length) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return left.every((column, index) => {
|
|
51
|
+
const other = right[index];
|
|
52
|
+
return (column.name === other?.name &&
|
|
53
|
+
column.kind === other.kind &&
|
|
54
|
+
column.field === other.field);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export const MosaicProfilerRows = memo(MosaicProfilerRowsImpl, (previous, next) => previous.className === next.className &&
|
|
58
|
+
previous.profiler.pageTable === next.profiler.pageTable &&
|
|
59
|
+
previous.profiler.tableError === next.profiler.tableError &&
|
|
60
|
+
previous.profiler.pagination.pageIndex ===
|
|
61
|
+
next.profiler.pagination.pageIndex &&
|
|
62
|
+
previous.profiler.pagination.pageSize ===
|
|
63
|
+
next.profiler.pagination.pageSize &&
|
|
64
|
+
areRowColumnsEqual(previous.profiler.columns, next.profiler.columns));
|
|
65
|
+
//# sourceMappingURL=MosaicProfilerRows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerRows.js","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerRows.tsx"],"names":[],"mappings":"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","sourcesContent":["import {ArrowCellValue, isNumericArrowType} from '@sqlrooms/data-table';\nimport {cn, TableBody, TableCell, TableRow} from '@sqlrooms/ui';\nimport * as arrow from 'apache-arrow';\nimport {memo} from 'react';\nimport type {UseMosaicProfilerReturn} from './types';\nimport {isProfilerUnsupportedSummaryType} from './utils';\n\nexport type MosaicProfilerRowsProps = {\n className?: string;\n profiler: Pick<\n UseMosaicProfilerReturn,\n 'columns' | 'pageTable' | 'pagination' | 'tableError'\n >;\n};\n\nconst COLUMN_WIDTH_CLASS = 'min-w-[140px] w-[140px] max-w-[140px]';\nconst ROW_NUMBER_CLASS =\n 'bg-background text-muted-foreground sticky left-0 z-10 w-[40px] max-w-[40px] min-w-[40px] border-r px-1 text-center';\n\nfunction getColumnWidthClass(field: arrow.Field) {\n return isProfilerUnsupportedSummaryType(field.type)\n ? 'min-w-[104px] w-[104px] max-w-[104px]'\n : COLUMN_WIDTH_CLASS;\n}\n\nfunction formatProfilerValue(type: arrow.DataType, value: unknown) {\n if (arrow.DataType.isBinary(type) && value instanceof Uint8Array) {\n return `${value.byteLength} bytes`;\n }\n return undefined;\n}\n\nfunction SizingRow({columns}: {columns: UseMosaicProfilerReturn['columns']}) {\n return (\n <TableRow\n aria-hidden=\"true\"\n className=\"pointer-events-none h-0 border-0 opacity-0 hover:bg-transparent\"\n >\n <TableCell className=\"w-[40px] max-w-[40px] min-w-[40px] border-r p-0\" />\n {columns.map((column) => (\n <TableCell\n key={column.name}\n className={cn(getColumnWidthClass(column.field), 'border-r p-0')}\n />\n ))}\n </TableRow>\n );\n}\n\nfunction EmptyStateRow({\n columns,\n message,\n tone = 'muted',\n}: {\n columns: UseMosaicProfilerReturn['columns'];\n message: string;\n tone?: 'error' | 'muted';\n}) {\n return (\n <TableRow>\n <TableCell className={ROW_NUMBER_CLASS} />\n <TableCell\n colSpan={Math.max(columns.length, 1)}\n className={cn(\n 'max-w-[240px] border-r p-4 align-top font-mono text-xs',\n tone === 'error'\n ? 'text-sm text-red-500'\n : 'text-muted-foreground text-sm',\n )}\n >\n {message}\n </TableCell>\n </TableRow>\n );\n}\n\ntype DataRowProps = {\n columns: UseMosaicProfilerReturn['columns'];\n pageIndex: number;\n pageSize: number;\n pageTable: NonNullable<UseMosaicProfilerReturn['pageTable']>;\n rowIndex: number;\n};\n\nconst DataRow = memo(function DataRow({\n columns,\n pageIndex,\n pageSize,\n pageTable,\n rowIndex,\n}: DataRowProps) {\n return (\n <TableRow>\n <TableCell className={ROW_NUMBER_CLASS}>\n {pageIndex * pageSize + rowIndex + 1}\n </TableCell>\n {columns.map((column) => {\n const vector = pageTable.getChild(column.name) as arrow.Vector | null;\n const value = vector?.get(rowIndex);\n return (\n <TableCell\n key={column.name}\n className={cn(\n getColumnWidthClass(column.field),\n 'max-w-[240px] overflow-hidden border-r align-top font-mono text-xs',\n isNumericArrowType(column.field.type) && 'text-right',\n )}\n >\n <span className=\"block min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\">\n <ArrowCellValue\n fieldName={column.name}\n fontSizeClass=\"text-xs\"\n formatValue={formatProfilerValue}\n type={column.field.type}\n value={value}\n />\n </span>\n </TableCell>\n );\n })}\n </TableRow>\n );\n});\n\nfunction MosaicProfilerRowsImpl({\n className,\n profiler,\n}: MosaicProfilerRowsProps) {\n if (profiler.tableError) {\n return (\n <TableBody className={className}>\n <SizingRow columns={profiler.columns} />\n <EmptyStateRow\n columns={profiler.columns}\n message={profiler.tableError.message}\n tone=\"error\"\n />\n </TableBody>\n );\n }\n\n if (!profiler.pageTable || profiler.pageTable.numRows === 0) {\n return (\n <TableBody className={className}>\n <SizingRow columns={profiler.columns} />\n <EmptyStateRow columns={profiler.columns} message=\"No rows\" />\n </TableBody>\n );\n }\n\n const rows = Array.from(\n {length: profiler.pageTable.numRows},\n (_, index) => index,\n );\n const pageTable = profiler.pageTable;\n\n return (\n <TableBody className={className}>\n {rows.map((rowIndex) => (\n <DataRow\n key={rowIndex}\n columns={profiler.columns}\n pageIndex={profiler.pagination.pageIndex}\n pageSize={profiler.pagination.pageSize}\n pageTable={pageTable}\n rowIndex={rowIndex}\n />\n ))}\n </TableBody>\n );\n}\n\nfunction areRowColumnsEqual(\n left: UseMosaicProfilerReturn['columns'],\n right: UseMosaicProfilerReturn['columns'],\n) {\n if (left.length !== right.length) {\n return false;\n }\n\n return left.every((column, index) => {\n const other = right[index];\n return (\n column.name === other?.name &&\n column.kind === other.kind &&\n column.field === other.field\n );\n });\n}\n\nexport const MosaicProfilerRows = memo(\n MosaicProfilerRowsImpl,\n (previous, next) =>\n previous.className === next.className &&\n previous.profiler.pageTable === next.profiler.pageTable &&\n previous.profiler.tableError === next.profiler.tableError &&\n previous.profiler.pagination.pageIndex ===\n next.profiler.pagination.pageIndex &&\n previous.profiler.pagination.pageSize ===\n next.profiler.pagination.pageSize &&\n areRowColumnsEqual(previous.profiler.columns, next.profiler.columns),\n);\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { UseMosaicProfilerReturn } from './types';
|
|
3
|
+
export type MosaicProfilerStatusBarProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
profiler: Pick<UseMosaicProfilerReturn, 'filteredRowCount' | 'hasFilters' | 'pagination' | 'reset' | 'setPagination' | 'sql' | 'totalRowCount'>;
|
|
6
|
+
renderActions?: (sql: string) => ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export declare function MosaicProfilerStatusBar({ className, profiler, renderActions, }: MosaicProfilerStatusBarProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=MosaicProfilerStatusBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerStatusBar.d.ts","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerStatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,SAAS,CAAC;AAErD,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,IAAI,CACZ,uBAAuB,EACrB,kBAAkB,GAClB,YAAY,GACZ,YAAY,GACZ,OAAO,GACP,eAAe,GACf,KAAK,GACL,eAAe,CAClB,CAAC;IACF,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;CAC5C,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,QAAQ,EACR,aAAa,GACd,EAAE,4BAA4B,2CAmF9B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, cn } from '@sqlrooms/ui';
|
|
3
|
+
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
|
|
4
|
+
export function MosaicProfilerStatusBar({ className, profiler, renderActions, }) {
|
|
5
|
+
const actions = renderActions?.(profiler.sql);
|
|
6
|
+
const totalPages = profiler.filteredRowCount !== undefined
|
|
7
|
+
? Math.max(1, Math.ceil(profiler.filteredRowCount / profiler.pagination.pageSize))
|
|
8
|
+
: undefined;
|
|
9
|
+
const canGoPrevious = profiler.pagination.pageIndex > 0;
|
|
10
|
+
const canGoNext = totalPages !== undefined && profiler.pagination.pageIndex < totalPages - 1;
|
|
11
|
+
const showPaginationLabel = totalPages !== undefined;
|
|
12
|
+
return (_jsxs("div", { className: cn('flex items-center justify-between gap-3 border-t px-3 py-2 text-sm', className), children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("div", { className: "flex items-center gap-1 whitespace-nowrap", children: [_jsx(Button, { variant: "ghost", size: "xs", className: "h-6 w-6 p-0", "aria-label": "Previous page", disabled: !canGoPrevious, onClick: () => {
|
|
13
|
+
profiler.setPagination((prev) => ({
|
|
14
|
+
...prev,
|
|
15
|
+
pageIndex: Math.max(0, prev.pageIndex - 1),
|
|
16
|
+
}));
|
|
17
|
+
}, children: _jsx(ChevronLeftIcon, { size: 14 }) }), showPaginationLabel ? (_jsxs("span", { className: "text-muted-foreground min-w-14 text-center text-[11px]", children: [profiler.pagination.pageIndex + 1, " / ", totalPages] })) : null, _jsx(Button, { variant: "ghost", size: "xs", className: "h-6 w-6 p-0", "aria-label": "Next page", disabled: !canGoNext, onClick: () => {
|
|
18
|
+
profiler.setPagination((prev) => ({
|
|
19
|
+
...prev,
|
|
20
|
+
pageIndex: totalPages === undefined
|
|
21
|
+
? prev.pageIndex
|
|
22
|
+
: Math.min(totalPages - 1, prev.pageIndex + 1),
|
|
23
|
+
}));
|
|
24
|
+
}, children: _jsx(ChevronRightIcon, { size: 14 }) })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "link", size: "sm", className: "h-auto px-0", disabled: !profiler.hasFilters, onClick: profiler.reset, children: "Reset" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [profiler.filteredRowCount?.toLocaleString() ?? '0', profiler.totalRowCount !== undefined
|
|
25
|
+
? ` of ${profiler.totalRowCount.toLocaleString()} rows`
|
|
26
|
+
: ' rows'] })] })] }), actions ? _jsx("div", { children: actions }) : null] }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=MosaicProfilerStatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicProfilerStatusBar.js","sourceRoot":"","sources":["../../src/profiler/MosaicProfilerStatusBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {ReactNode} from 'react';\nimport {Button, cn} from '@sqlrooms/ui';\nimport {ChevronLeftIcon, ChevronRightIcon} from 'lucide-react';\nimport type {UseMosaicProfilerReturn} from './types';\n\nexport type MosaicProfilerStatusBarProps = {\n className?: string;\n profiler: Pick<\n UseMosaicProfilerReturn,\n | 'filteredRowCount'\n | 'hasFilters'\n | 'pagination'\n | 'reset'\n | 'setPagination'\n | 'sql'\n | 'totalRowCount'\n >;\n renderActions?: (sql: string) => ReactNode;\n};\n\nexport function MosaicProfilerStatusBar({\n className,\n profiler,\n renderActions,\n}: MosaicProfilerStatusBarProps) {\n const actions = renderActions?.(profiler.sql);\n const totalPages =\n profiler.filteredRowCount !== undefined\n ? Math.max(\n 1,\n Math.ceil(profiler.filteredRowCount / profiler.pagination.pageSize),\n )\n : undefined;\n const canGoPrevious = profiler.pagination.pageIndex > 0;\n const canGoNext =\n totalPages !== undefined && profiler.pagination.pageIndex < totalPages - 1;\n const showPaginationLabel = totalPages !== undefined;\n\n return (\n <div\n className={cn(\n 'flex items-center justify-between gap-3 border-t px-3 py-2 text-sm',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-1 whitespace-nowrap\">\n <Button\n variant=\"ghost\"\n size=\"xs\"\n className=\"h-6 w-6 p-0\"\n aria-label=\"Previous page\"\n disabled={!canGoPrevious}\n onClick={() => {\n profiler.setPagination((prev) => ({\n ...prev,\n pageIndex: Math.max(0, prev.pageIndex - 1),\n }));\n }}\n >\n <ChevronLeftIcon size={14} />\n </Button>\n {showPaginationLabel ? (\n <span className=\"text-muted-foreground min-w-14 text-center text-[11px]\">\n {profiler.pagination.pageIndex + 1} / {totalPages}\n </span>\n ) : null}\n <Button\n variant=\"ghost\"\n size=\"xs\"\n className=\"h-6 w-6 p-0\"\n aria-label=\"Next page\"\n disabled={!canGoNext}\n onClick={() => {\n profiler.setPagination((prev) => ({\n ...prev,\n pageIndex:\n totalPages === undefined\n ? prev.pageIndex\n : Math.min(totalPages - 1, prev.pageIndex + 1),\n }));\n }}\n >\n <ChevronRightIcon size={14} />\n </Button>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"link\"\n size=\"sm\"\n className=\"h-auto px-0\"\n disabled={!profiler.hasFilters}\n onClick={profiler.reset}\n >\n Reset\n </Button>\n <span className=\"text-muted-foreground text-xs\">\n {profiler.filteredRowCount?.toLocaleString() ?? '0'}\n {profiler.totalRowCount !== undefined\n ? ` of ${profiler.totalRowCount.toLocaleString()} rows`\n : ' rows'}\n </span>\n </div>\n </div>\n {actions ? <div>{actions}</div> : null}\n </div>\n );\n}\n"]}
|