@databricks/appkit-ui 0.17.0 → 0.19.0
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/CLAUDE.md +9 -1
- package/dist/cli/commands/plugin/create/scaffold.js +2 -8
- package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
- package/dist/react/charts/base.js +3 -2
- package/dist/react/charts/base.js.map +1 -1
- package/dist/react/charts/normalize.d.ts.map +1 -1
- package/dist/react/charts/normalize.js +3 -1
- package/dist/react/charts/normalize.js.map +1 -1
- package/dist/react/charts/options.d.ts +1 -0
- package/dist/react/charts/options.d.ts.map +1 -1
- package/dist/react/charts/options.js +13 -8
- package/dist/react/charts/options.js.map +1 -1
- package/dist/react/charts/utils.d.ts.map +1 -1
- package/dist/react/charts/utils.js +23 -1
- package/dist/react/charts/utils.js.map +1 -1
- package/dist/react/file-browser/directory-list.d.ts +54 -0
- package/dist/react/file-browser/directory-list.d.ts.map +1 -0
- package/dist/react/file-browser/directory-list.js +74 -0
- package/dist/react/file-browser/directory-list.js.map +1 -0
- package/dist/react/file-browser/file-breadcrumb.d.ts +25 -0
- package/dist/react/file-browser/file-breadcrumb.d.ts.map +1 -0
- package/dist/react/file-browser/file-breadcrumb.js +27 -0
- package/dist/react/file-browser/file-breadcrumb.js.map +1 -0
- package/dist/react/file-browser/file-entry.d.ts +27 -0
- package/dist/react/file-browser/file-entry.d.ts.map +1 -0
- package/dist/react/file-browser/file-entry.js +31 -0
- package/dist/react/file-browser/file-entry.js.map +1 -0
- package/dist/react/file-browser/file-preview-panel.d.ts +42 -0
- package/dist/react/file-browser/file-preview-panel.d.ts.map +1 -0
- package/dist/react/file-browser/file-preview-panel.js +135 -0
- package/dist/react/file-browser/file-preview-panel.js.map +1 -0
- package/dist/react/file-browser/index.d.ts +7 -0
- package/dist/react/file-browser/index.js +6 -0
- package/dist/react/file-browser/new-folder-input.d.ts +36 -0
- package/dist/react/file-browser/new-folder-input.d.ts.map +1 -0
- package/dist/react/file-browser/new-folder-input.js +52 -0
- package/dist/react/file-browser/new-folder-input.js.map +1 -0
- package/dist/react/file-browser/types.d.ts +52 -0
- package/dist/react/file-browser/types.d.ts.map +1 -0
- package/dist/react/genie/genie-chart-inference.d.ts +17 -0
- package/dist/react/genie/genie-chart-inference.d.ts.map +1 -0
- package/dist/react/genie/genie-chart-inference.js +75 -0
- package/dist/react/genie/genie-chart-inference.js.map +1 -0
- package/dist/react/genie/genie-chat-message-list.js +1 -1
- package/dist/react/genie/genie-chat-message.d.ts.map +1 -1
- package/dist/react/genie/genie-chat-message.js +27 -16
- package/dist/react/genie/genie-chat-message.js.map +1 -1
- package/dist/react/genie/genie-query-transform.d.ts +31 -0
- package/dist/react/genie/genie-query-transform.d.ts.map +1 -0
- package/dist/react/genie/genie-query-transform.js +79 -0
- package/dist/react/genie/genie-query-transform.js.map +1 -0
- package/dist/react/genie/genie-query-visualization.d.ts +25 -0
- package/dist/react/genie/genie-query-visualization.d.ts.map +1 -0
- package/dist/react/genie/genie-query-visualization.js +79 -0
- package/dist/react/genie/genie-query-visualization.js.map +1 -0
- package/dist/react/genie/index.d.ts +4 -1
- package/dist/react/genie/index.js +3 -0
- package/dist/react/genie/types.d.ts +2 -2
- package/dist/react/genie/types.d.ts.map +1 -1
- package/dist/react/index.d.ts +13 -2
- package/dist/react/index.js +16 -6
- package/dist/react/lib/format.d.ts +14 -0
- package/dist/react/lib/format.d.ts.map +1 -0
- package/dist/react/lib/format.js +17 -1
- package/dist/react/lib/format.js.map +1 -1
- package/dist/react/table/data-table.js +2 -2
- package/dist/react/table/table-wrapper.js +1 -1
- package/dist/react/ui/breadcrumb.js +1 -1
- package/dist/react/ui/index.js +5 -5
- package/dist/react/ui/navigation-menu.js +1 -1
- package/dist/react/ui/sidebar.js +1 -1
- package/dist/shared/src/genie.d.ts +16 -2
- package/dist/shared/src/genie.d.ts.map +1 -1
- package/dist/shared/src/index.d.ts +1 -1
- package/docs/api/appkit/Class.Plugin.md +60 -12
- package/docs/api/appkit/Class.ResourceRegistry.md +3 -3
- package/docs/api/appkit/Function.createApp.md +3 -3
- package/docs/api/appkit/Interface.PluginManifest.md +9 -3
- package/docs/api/appkit/TypeAlias.PluginData.md +45 -0
- package/docs/api/appkit/TypeAlias.ToPlugin.md +1 -1
- package/docs/api/appkit-ui/files/DirectoryList.md +36 -0
- package/docs/api/appkit-ui/files/FileBreadcrumb.md +27 -0
- package/docs/api/appkit-ui/files/FileEntry.md +27 -0
- package/docs/api/appkit-ui/files/FilePreviewPanel.md +32 -0
- package/docs/api/appkit-ui/files/NewFolderInput.md +30 -0
- package/docs/api/appkit-ui/genie/GenieQueryVisualization.md +29 -0
- package/docs/api/appkit.md +1 -0
- package/docs/configuration.md +15 -0
- package/docs/plugins/custom-plugins.md +4 -13
- package/docs/plugins/files.md +350 -0
- package/docs/plugins.md +2 -1
- package/llms.txt +9 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//#region src/react/genie/genie-chart-inference.ts
|
|
2
|
+
const INFERENCE_CONFIG = {
|
|
3
|
+
minRows: 2,
|
|
4
|
+
pieMaxCategories: 7,
|
|
5
|
+
barMaxCategories: 100,
|
|
6
|
+
groupedBarMaxCategories: 50
|
|
7
|
+
};
|
|
8
|
+
function countUnique(rows, key) {
|
|
9
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10
|
+
for (const row of rows) seen.add(row[key]);
|
|
11
|
+
return seen.size;
|
|
12
|
+
}
|
|
13
|
+
function hasNegativeValues(rows, key) {
|
|
14
|
+
for (const row of rows) if (Number(row[key]) < 0) return true;
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Infer the best chart type for the given Genie query result.
|
|
19
|
+
* Returns `null` when the data is not suitable for charting.
|
|
20
|
+
*/
|
|
21
|
+
function inferChartType(rows, columns) {
|
|
22
|
+
if (rows.length < INFERENCE_CONFIG.minRows || columns.length < 2) return null;
|
|
23
|
+
const dateCols = columns.filter((c) => c.category === "date");
|
|
24
|
+
const numericCols = columns.filter((c) => c.category === "numeric");
|
|
25
|
+
const stringCols = columns.filter((c) => c.category === "string");
|
|
26
|
+
if (numericCols.length === 0) return null;
|
|
27
|
+
if (dateCols.length > 0 && numericCols.length >= 1) return {
|
|
28
|
+
chartType: "line",
|
|
29
|
+
xKey: dateCols[0].name,
|
|
30
|
+
yKey: numericCols.length === 1 ? numericCols[0].name : numericCols.map((c) => c.name)
|
|
31
|
+
};
|
|
32
|
+
if (stringCols.length > 0 && numericCols.length >= 1) {
|
|
33
|
+
const xKey = stringCols[0].name;
|
|
34
|
+
const uniqueCategories = countUnique(rows, xKey);
|
|
35
|
+
if (numericCols.length === 1) {
|
|
36
|
+
const yKey = numericCols[0].name;
|
|
37
|
+
if (uniqueCategories <= INFERENCE_CONFIG.pieMaxCategories && !hasNegativeValues(rows, yKey)) return {
|
|
38
|
+
chartType: "pie",
|
|
39
|
+
xKey,
|
|
40
|
+
yKey
|
|
41
|
+
};
|
|
42
|
+
if (uniqueCategories <= INFERENCE_CONFIG.barMaxCategories) return {
|
|
43
|
+
chartType: "bar",
|
|
44
|
+
xKey,
|
|
45
|
+
yKey
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
chartType: "line",
|
|
49
|
+
xKey,
|
|
50
|
+
yKey
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const yKey = numericCols.map((c) => c.name);
|
|
54
|
+
if (uniqueCategories <= INFERENCE_CONFIG.groupedBarMaxCategories) return {
|
|
55
|
+
chartType: "bar",
|
|
56
|
+
xKey,
|
|
57
|
+
yKey
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
chartType: "line",
|
|
61
|
+
xKey,
|
|
62
|
+
yKey
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (numericCols.length >= 2 && stringCols.length === 0 && dateCols.length === 0) return {
|
|
66
|
+
chartType: "scatter",
|
|
67
|
+
xKey: numericCols[0].name,
|
|
68
|
+
yKey: numericCols[1].name
|
|
69
|
+
};
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
export { inferChartType };
|
|
75
|
+
//# sourceMappingURL=genie-chart-inference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie-chart-inference.js","names":[],"sources":["../../../src/react/genie/genie-chart-inference.ts"],"sourcesContent":["/**\n * ┌─────────────────────────────────────────────────────────────────────┐\n * │ CHART INFERENCE RULES │\n * │ │\n * │ These rules determine what chart type is shown for Genie query │\n * │ results. Modify thresholds and chart type mappings here. │\n * │ │\n * │ Column types are classified from SQL type_name: │\n * │ DATE: DATE, TIMESTAMP, TIMESTAMP_NTZ │\n * │ NUMERIC: DECIMAL, INT, DOUBLE, FLOAT, LONG, etc. │\n * │ STRING: STRING, VARCHAR, CHAR │\n * │ │\n * │ Rules (applied in priority order): │\n * │ │\n * │ SKIP (return null): │\n * │ - < 2 rows │\n * │ - < 2 columns │\n * │ - No numeric columns │\n * │ │\n * │ MATCH: │\n * │ 1. DATE + numeric(s) → line (timeseries) │\n * │ 2. STRING + 1 numeric, ≤7 cats → pie │\n * │ 3. STRING + 1 numeric, ≤100 cats → bar │\n * │ 4. STRING + 1 numeric, >100 cats → line │\n * │ 5. STRING + N numerics, ≤50 cats → bar (grouped) │\n * │ 6. STRING + N numerics, >50 cats → line (multi-series) │\n * │ 7. 2+ numerics only → scatter │\n * │ 8. Otherwise → null (skip) │\n * │ │\n * │ KNOWN LIMITATIONS: │\n * │ - First-column heuristic: picks first string col as category │\n * │ - No semantic understanding (can't tell ID from meaningful val) │\n * └─────────────────────────────────────────────────────────────────────┘\n */\n\nimport type { ChartType } from \"../charts/types\";\nimport type { GenieColumnMeta } from \"./genie-query-transform\";\n\n// ---------------------------------------------------------------------------\n// Configuration — edit thresholds here\n// ---------------------------------------------------------------------------\n\nconst INFERENCE_CONFIG = {\n /** Min rows required to show any chart */\n minRows: 2,\n /** Max unique categories for pie chart */\n pieMaxCategories: 7,\n /** Max unique categories for bar chart (single series) */\n barMaxCategories: 100,\n /** Max unique categories for grouped bar chart (multi series) */\n groupedBarMaxCategories: 50,\n} as const;\n\nexport interface ChartInference {\n chartType: ChartType;\n xKey: string;\n yKey: string | string[];\n}\n\nfunction countUnique(rows: Record<string, unknown>[], key: string): number {\n const seen = new Set<unknown>();\n for (const row of rows) {\n seen.add(row[key]);\n }\n return seen.size;\n}\n\nfunction hasNegativeValues(\n rows: Record<string, unknown>[],\n key: string,\n): boolean {\n for (const row of rows) {\n if (Number(row[key]) < 0) return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Main inference function\n// ---------------------------------------------------------------------------\n\n/**\n * Infer the best chart type for the given Genie query result.\n * Returns `null` when the data is not suitable for charting.\n */\nexport function inferChartType(\n rows: Record<string, unknown>[],\n columns: GenieColumnMeta[],\n): ChartInference | null {\n // Guard: need at least minRows and 2 columns\n if (rows.length < INFERENCE_CONFIG.minRows || columns.length < 2) {\n return null;\n }\n\n const dateCols = columns.filter((c) => c.category === \"date\");\n const numericCols = columns.filter((c) => c.category === \"numeric\");\n const stringCols = columns.filter((c) => c.category === \"string\");\n\n // Guard: must have at least one numeric column\n if (numericCols.length === 0) return null;\n\n // Rule 1: DATE + numeric(s) → line (timeseries)\n if (dateCols.length > 0 && numericCols.length >= 1) {\n return {\n chartType: \"line\",\n xKey: dateCols[0].name,\n yKey:\n numericCols.length === 1\n ? numericCols[0].name\n : numericCols.map((c) => c.name),\n };\n }\n\n // Rules 2–6: STRING + numeric(s)\n if (stringCols.length > 0 && numericCols.length >= 1) {\n const xKey = stringCols[0].name;\n const uniqueCategories = countUnique(rows, xKey);\n\n if (numericCols.length === 1) {\n const yKey = numericCols[0].name;\n\n // Rule 2: few categories → pie (skip if negative values)\n if (\n uniqueCategories <= INFERENCE_CONFIG.pieMaxCategories &&\n !hasNegativeValues(rows, yKey)\n ) {\n return { chartType: \"pie\", xKey, yKey };\n }\n // Rule 3: moderate categories → bar\n if (uniqueCategories <= INFERENCE_CONFIG.barMaxCategories) {\n return { chartType: \"bar\", xKey, yKey };\n }\n // Rule 4: many categories → line\n return { chartType: \"line\", xKey, yKey };\n }\n\n // Multiple numerics\n const yKey = numericCols.map((c) => c.name);\n\n // Rule 5: moderate categories → bar (grouped)\n if (uniqueCategories <= INFERENCE_CONFIG.groupedBarMaxCategories) {\n return { chartType: \"bar\", xKey, yKey };\n }\n // Rule 6: many categories → line (multi-series)\n return { chartType: \"line\", xKey, yKey };\n }\n\n // Rule 7: 2+ numerics only (no string, no date) → scatter\n if (\n numericCols.length >= 2 &&\n stringCols.length === 0 &&\n dateCols.length === 0\n ) {\n return {\n chartType: \"scatter\",\n xKey: numericCols[0].name,\n yKey: numericCols[1].name,\n };\n }\n\n // Rule 8: fallback — no chart\n return null;\n}\n"],"mappings":";AA0CA,MAAM,mBAAmB;CAEvB,SAAS;CAET,kBAAkB;CAElB,kBAAkB;CAElB,yBAAyB;CAC1B;AAQD,SAAS,YAAY,MAAiC,KAAqB;CACzE,MAAM,uBAAO,IAAI,KAAc;AAC/B,MAAK,MAAM,OAAO,KAChB,MAAK,IAAI,IAAI,KAAK;AAEpB,QAAO,KAAK;;AAGd,SAAS,kBACP,MACA,KACS;AACT,MAAK,MAAM,OAAO,KAChB,KAAI,OAAO,IAAI,KAAK,GAAG,EAAG,QAAO;AAEnC,QAAO;;;;;;AAWT,SAAgB,eACd,MACA,SACuB;AAEvB,KAAI,KAAK,SAAS,iBAAiB,WAAW,QAAQ,SAAS,EAC7D,QAAO;CAGT,MAAM,WAAW,QAAQ,QAAQ,MAAM,EAAE,aAAa,OAAO;CAC7D,MAAM,cAAc,QAAQ,QAAQ,MAAM,EAAE,aAAa,UAAU;CACnE,MAAM,aAAa,QAAQ,QAAQ,MAAM,EAAE,aAAa,SAAS;AAGjE,KAAI,YAAY,WAAW,EAAG,QAAO;AAGrC,KAAI,SAAS,SAAS,KAAK,YAAY,UAAU,EAC/C,QAAO;EACL,WAAW;EACX,MAAM,SAAS,GAAG;EAClB,MACE,YAAY,WAAW,IACnB,YAAY,GAAG,OACf,YAAY,KAAK,MAAM,EAAE,KAAK;EACrC;AAIH,KAAI,WAAW,SAAS,KAAK,YAAY,UAAU,GAAG;EACpD,MAAM,OAAO,WAAW,GAAG;EAC3B,MAAM,mBAAmB,YAAY,MAAM,KAAK;AAEhD,MAAI,YAAY,WAAW,GAAG;GAC5B,MAAM,OAAO,YAAY,GAAG;AAG5B,OACE,oBAAoB,iBAAiB,oBACrC,CAAC,kBAAkB,MAAM,KAAK,CAE9B,QAAO;IAAE,WAAW;IAAO;IAAM;IAAM;AAGzC,OAAI,oBAAoB,iBAAiB,iBACvC,QAAO;IAAE,WAAW;IAAO;IAAM;IAAM;AAGzC,UAAO;IAAE,WAAW;IAAQ;IAAM;IAAM;;EAI1C,MAAM,OAAO,YAAY,KAAK,MAAM,EAAE,KAAK;AAG3C,MAAI,oBAAoB,iBAAiB,wBACvC,QAAO;GAAE,WAAW;GAAO;GAAM;GAAM;AAGzC,SAAO;GAAE,WAAW;GAAQ;GAAM;GAAM;;AAI1C,KACE,YAAY,UAAU,KACtB,WAAW,WAAW,KACtB,SAAS,WAAW,EAEpB,QAAO;EACL,WAAW;EACX,MAAM,YAAY,GAAG;EACrB,MAAM,YAAY,GAAG;EACtB;AAIH,QAAO"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
-
import { ScrollArea } from "../ui/scroll-area.js";
|
|
3
2
|
import { Skeleton } from "../ui/skeleton.js";
|
|
3
|
+
import { ScrollArea } from "../ui/scroll-area.js";
|
|
4
4
|
import { Spinner } from "../ui/spinner.js";
|
|
5
5
|
import { GenieChatMessage } from "./genie-chat-message.js";
|
|
6
6
|
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genie-chat-message.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"genie-chat-message.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"mappings":";;;;UA0BiB,qBAAA;;EAEf,OAAA,EAAS,gBAAA;EAFM;EAIf,SAAA;AAAA;;iBAQc,gBAAA,CAAA;EACd,OAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
|
-
import { Avatar, AvatarFallback } from "../ui/avatar.js";
|
|
3
2
|
import { Card } from "../ui/card.js";
|
|
3
|
+
import { Avatar, AvatarFallback } from "../ui/avatar.js";
|
|
4
|
+
import { GenieQueryVisualization } from "./genie-query-visualization.js";
|
|
4
5
|
import { useMemo } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { marked } from "marked";
|
|
@@ -45,22 +46,32 @@ function GenieChatMessage({ message, className }) {
|
|
|
45
46
|
})]
|
|
46
47
|
}), queryAttachments.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
47
48
|
className: "flex flex-col gap-2 w-full min-w-0",
|
|
48
|
-
children: queryAttachments.map((att) =>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
children: queryAttachments.map((att) => {
|
|
50
|
+
const key = att.attachmentId ?? "query";
|
|
51
|
+
const queryResult = att.attachmentId ? message.queryResults.get(att.attachmentId) : void 0;
|
|
52
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
53
|
+
className: "flex flex-col gap-2",
|
|
54
|
+
children: [/* @__PURE__ */ jsx(Card, {
|
|
55
|
+
className: "px-4 py-3 text-xs overflow-hidden shadow-none",
|
|
56
|
+
children: /* @__PURE__ */ jsxs("details", { children: [/* @__PURE__ */ jsx("summary", {
|
|
57
|
+
className: "cursor-pointer select-none font-medium",
|
|
58
|
+
children: att.query?.title ?? "SQL Query"
|
|
59
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
60
|
+
className: "mt-2 flex flex-col gap-1",
|
|
61
|
+
children: [att.query?.description && /* @__PURE__ */ jsx("span", {
|
|
62
|
+
className: "text-muted-foreground",
|
|
63
|
+
children: att.query.description
|
|
64
|
+
}), att.query?.query && /* @__PURE__ */ jsx("pre", {
|
|
65
|
+
className: "mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all",
|
|
66
|
+
children: att.query.query
|
|
67
|
+
})]
|
|
68
|
+
})] })
|
|
69
|
+
}), queryResult != null && /* @__PURE__ */ jsx(Card, {
|
|
70
|
+
className: "px-4 py-3 overflow-hidden",
|
|
71
|
+
children: /* @__PURE__ */ jsx(GenieQueryVisualization, { data: queryResult })
|
|
61
72
|
})]
|
|
62
|
-
}
|
|
63
|
-
}
|
|
73
|
+
}, key);
|
|
74
|
+
})
|
|
64
75
|
})]
|
|
65
76
|
})]
|
|
66
77
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genie-chat-message.js","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":["import { marked } from \"marked\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Avatar, AvatarFallback } from \"../ui/avatar\";\nimport { Card } from \"../ui/card\";\nimport type { GenieAttachmentResponse, GenieMessageItem } from \"./types\";\n\n/**\n * Using `marked` instead of `react-markdown` because `react-markdown` depends on\n * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.\n * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.\n */\nmarked.setOptions({ breaks: true, gfm: true });\n\nconst markdownStyles = cn(\n \"text-sm\",\n \"[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0\",\n \"[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto\",\n \"[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded\",\n \"[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1\",\n \"[&_table]:border-collapse [&_th]:border [&_td]:border\",\n \"[&_th]:border-border [&_td]:border-border\",\n \"[&_a]:underline\",\n);\n\nexport interface GenieChatMessageProps {\n /** The message object to render */\n message: GenieMessageItem;\n /** Additional CSS class */\n className?: string;\n}\n\nfunction isQueryAttachment(att: GenieAttachmentResponse): boolean {\n return !!(att.query?.title || att.query?.query);\n}\n\n/** Renders a single Genie message bubble with optional expandable SQL query attachments. */\nexport function GenieChatMessage({\n message,\n className,\n}: GenieChatMessageProps) {\n const isUser = message.role === \"user\";\n const queryAttachments = message.attachments.filter(isQueryAttachment);\n const html = useMemo(\n () => (message.content ? (marked.parse(message.content) as string) : \"\"),\n [message.content],\n );\n\n return (\n <div\n className={cn(\n \"flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Avatar className=\"h-8 w-8 shrink-0 mt-1\">\n <AvatarFallback\n className={cn(\n \"text-xs font-medium\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {isUser ? \"You\" : \"AI\"}\n </AvatarFallback>\n </Avatar>\n\n <div\n className={cn(\n \"flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden\",\n isUser ? \"items-end\" : \"items-start\",\n )}\n >\n <Card\n className={cn(\n \"px-4 py-3 max-w-full overflow-hidden\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {html && (\n <div\n className={markdownStyles}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n\n {message.error && (\n <p className=\"text-sm text-destructive mt-1\">{message.error}</p>\n )}\n </Card>\n\n {queryAttachments.length > 0 && (\n <div className=\"flex flex-col gap-2 w-full min-w-0\">\n {queryAttachments.map((att) =>
|
|
1
|
+
{"version":3,"file":"genie-chat-message.js","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":["import { marked } from \"marked\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Avatar, AvatarFallback } from \"../ui/avatar\";\nimport { Card } from \"../ui/card\";\nimport { GenieQueryVisualization } from \"./genie-query-visualization\";\nimport type { GenieAttachmentResponse, GenieMessageItem } from \"./types\";\n\n/**\n * Using `marked` instead of `react-markdown` because `react-markdown` depends on\n * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.\n * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.\n */\nmarked.setOptions({ breaks: true, gfm: true });\n\nconst markdownStyles = cn(\n \"text-sm\",\n \"[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0\",\n \"[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto\",\n \"[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded\",\n \"[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1\",\n \"[&_table]:border-collapse [&_th]:border [&_td]:border\",\n \"[&_th]:border-border [&_td]:border-border\",\n \"[&_a]:underline\",\n);\n\nexport interface GenieChatMessageProps {\n /** The message object to render */\n message: GenieMessageItem;\n /** Additional CSS class */\n className?: string;\n}\n\nfunction isQueryAttachment(att: GenieAttachmentResponse): boolean {\n return !!(att.query?.title || att.query?.query);\n}\n\n/** Renders a single Genie message bubble with optional expandable SQL query attachments. */\nexport function GenieChatMessage({\n message,\n className,\n}: GenieChatMessageProps) {\n const isUser = message.role === \"user\";\n const queryAttachments = message.attachments.filter(isQueryAttachment);\n const html = useMemo(\n () => (message.content ? (marked.parse(message.content) as string) : \"\"),\n [message.content],\n );\n\n return (\n <div\n className={cn(\n \"flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Avatar className=\"h-8 w-8 shrink-0 mt-1\">\n <AvatarFallback\n className={cn(\n \"text-xs font-medium\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {isUser ? \"You\" : \"AI\"}\n </AvatarFallback>\n </Avatar>\n\n <div\n className={cn(\n \"flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden\",\n isUser ? \"items-end\" : \"items-start\",\n )}\n >\n <Card\n className={cn(\n \"px-4 py-3 max-w-full overflow-hidden\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {html && (\n <div\n className={markdownStyles}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n\n {message.error && (\n <p className=\"text-sm text-destructive mt-1\">{message.error}</p>\n )}\n </Card>\n\n {queryAttachments.length > 0 && (\n <div className=\"flex flex-col gap-2 w-full min-w-0\">\n {queryAttachments.map((att) => {\n const key = att.attachmentId ?? \"query\";\n const queryResult = att.attachmentId\n ? message.queryResults.get(att.attachmentId)\n : undefined;\n\n return (\n <div key={key} className=\"flex flex-col gap-2\">\n <Card className=\"px-4 py-3 text-xs overflow-hidden shadow-none\">\n <details>\n <summary className=\"cursor-pointer select-none font-medium\">\n {att.query?.title ?? \"SQL Query\"}\n </summary>\n <div className=\"mt-2 flex flex-col gap-1\">\n {att.query?.description && (\n <span className=\"text-muted-foreground\">\n {att.query.description}\n </span>\n )}\n {att.query?.query && (\n <pre className=\"mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all\">\n {att.query.query}\n </pre>\n )}\n </div>\n </details>\n </Card>\n {queryResult != null && (\n <Card className=\"px-4 py-3 overflow-hidden\">\n <GenieQueryVisualization data={queryResult} />\n </Card>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,OAAO,WAAW;CAAE,QAAQ;CAAM,KAAK;CAAM,CAAC;AAE9C,MAAM,iBAAiB,GACrB,WACA,kDACA,gGACA,6EACA,qEACA,yDACA,6CACA,kBACD;AASD,SAAS,kBAAkB,KAAuC;AAChE,QAAO,CAAC,EAAE,IAAI,OAAO,SAAS,IAAI,OAAO;;;AAI3C,SAAgB,iBAAiB,EAC/B,SACA,aACwB;CACxB,MAAM,SAAS,QAAQ,SAAS;CAChC,MAAM,mBAAmB,QAAQ,YAAY,OAAO,kBAAkB;CACtE,MAAM,OAAO,cACJ,QAAQ,UAAW,OAAO,MAAM,QAAQ,QAAQ,GAAc,IACrE,CAAC,QAAQ,QAAQ,CAClB;AAED,QACE,qBAAC;EACC,WAAW,GACT,cACA,SAAS,qBAAqB,YAC9B,UACD;aAED,oBAAC;GAAO,WAAU;aAChB,oBAAC;IACC,WAAW,GACT,uBACA,SAAS,uCAAuC,WACjD;cAEA,SAAS,QAAQ;KACH;IACV,EAET,qBAAC;GACC,WAAW,GACT,2DACA,SAAS,cAAc,cACxB;cAED,qBAAC;IACC,WAAW,GACT,wCACA,SAAS,uCAAuC,WACjD;eAEA,QACC,oBAAC;KACC,WAAW;KACX,yBAAyB,EAAE,QAAQ,MAAM;MACzC,EAGH,QAAQ,SACP,oBAAC;KAAE,WAAU;eAAiC,QAAQ;MAAU;KAE7D,EAEN,iBAAiB,SAAS,KACzB,oBAAC;IAAI,WAAU;cACZ,iBAAiB,KAAK,QAAQ;KAC7B,MAAM,MAAM,IAAI,gBAAgB;KAChC,MAAM,cAAc,IAAI,eACpB,QAAQ,aAAa,IAAI,IAAI,aAAa,GAC1C;AAEJ,YACE,qBAAC;MAAc,WAAU;iBACvB,oBAAC;OAAK,WAAU;iBACd,qBAAC,wBACC,oBAAC;QAAQ,WAAU;kBAChB,IAAI,OAAO,SAAS;SACb,EACV,qBAAC;QAAI,WAAU;mBACZ,IAAI,OAAO,eACV,oBAAC;SAAK,WAAU;mBACb,IAAI,MAAM;UACN,EAER,IAAI,OAAO,SACV,oBAAC;SAAI,WAAU;mBACZ,IAAI,MAAM;UACP;SAEJ,IACE;QACL,EACN,eAAe,QACd,oBAAC;OAAK,WAAU;iBACd,oBAAC,2BAAwB,MAAM,cAAe;QACzC;QAvBD,IAyBJ;MAER;KACE;IAEJ;GACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { GenieStatementResponse } from "../../shared/src/genie.js";
|
|
2
|
+
import "../../shared/src/index.js";
|
|
3
|
+
|
|
4
|
+
//#region src/react/genie/genie-query-transform.d.ts
|
|
5
|
+
type ColumnCategory = "numeric" | "date" | "string";
|
|
6
|
+
interface GenieColumnMeta {
|
|
7
|
+
name: string;
|
|
8
|
+
typeName: string;
|
|
9
|
+
category: ColumnCategory;
|
|
10
|
+
}
|
|
11
|
+
interface TransformedGenieData {
|
|
12
|
+
rows: Record<string, unknown>[];
|
|
13
|
+
columns: GenieColumnMeta[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Transform a Genie statement_response into chart-ready rows + column metadata.
|
|
17
|
+
*
|
|
18
|
+
* Expects `data` to have the shape:
|
|
19
|
+
* ```
|
|
20
|
+
* {
|
|
21
|
+
* manifest: { schema: { columns: [{ name, type_name }, ...] } },
|
|
22
|
+
* result: { data_array: [["val", ...], ...] }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* Returns `null` when the data is empty or malformed.
|
|
27
|
+
*/
|
|
28
|
+
declare function transformGenieData(data: GenieStatementResponse | null | undefined): TransformedGenieData | null;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData };
|
|
31
|
+
//# sourceMappingURL=genie-query-transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie-query-transform.d.ts","names":[],"sources":["../../../src/react/genie/genie-query-transform.ts"],"mappings":";;;;KA8BY,cAAA;AAAA,UAEK,eAAA;EACf,IAAA;EACA,QAAA;EACA,QAAA,EAAU,cAAA;AAAA;AAAA,UAGK,oBAAA;EACf,IAAA,EAAM,MAAA;EACN,OAAA,EAAS,eAAA;AAAA;;;;;;AAuCX;;;;;;;;iBAAgB,kBAAA,CACd,IAAA,EAAM,sBAAA,sBACL,oBAAA"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/react/genie/genie-query-transform.ts
|
|
2
|
+
const NUMERIC_SQL_TYPES = new Set([
|
|
3
|
+
"DECIMAL",
|
|
4
|
+
"INT",
|
|
5
|
+
"INTEGER",
|
|
6
|
+
"BIGINT",
|
|
7
|
+
"LONG",
|
|
8
|
+
"SMALLINT",
|
|
9
|
+
"TINYINT",
|
|
10
|
+
"FLOAT",
|
|
11
|
+
"DOUBLE",
|
|
12
|
+
"SHORT",
|
|
13
|
+
"BYTE"
|
|
14
|
+
]);
|
|
15
|
+
const DATE_SQL_TYPES = new Set([
|
|
16
|
+
"DATE",
|
|
17
|
+
"TIMESTAMP",
|
|
18
|
+
"TIMESTAMP_NTZ"
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* Classify a SQL type_name into a high-level category.
|
|
22
|
+
*/
|
|
23
|
+
function classifySqlType(typeName) {
|
|
24
|
+
const upper = typeName.toUpperCase();
|
|
25
|
+
if (NUMERIC_SQL_TYPES.has(upper)) return "numeric";
|
|
26
|
+
if (DATE_SQL_TYPES.has(upper)) return "date";
|
|
27
|
+
return "string";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse a single cell value based on its column category.
|
|
31
|
+
*/
|
|
32
|
+
function parseValue(raw, category) {
|
|
33
|
+
if (raw == null) return null;
|
|
34
|
+
if (category === "numeric") {
|
|
35
|
+
const n = Number(raw);
|
|
36
|
+
return Number.isNaN(n) ? null : n;
|
|
37
|
+
}
|
|
38
|
+
return raw;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Transform a Genie statement_response into chart-ready rows + column metadata.
|
|
42
|
+
*
|
|
43
|
+
* Expects `data` to have the shape:
|
|
44
|
+
* ```
|
|
45
|
+
* {
|
|
46
|
+
* manifest: { schema: { columns: [{ name, type_name }, ...] } },
|
|
47
|
+
* result: { data_array: [["val", ...], ...] }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Returns `null` when the data is empty or malformed.
|
|
52
|
+
*/
|
|
53
|
+
function transformGenieData(data) {
|
|
54
|
+
if (!data) return null;
|
|
55
|
+
const rawColumns = data.manifest?.schema?.columns;
|
|
56
|
+
if (!rawColumns || rawColumns.length === 0) return null;
|
|
57
|
+
const dataArray = data.result?.data_array;
|
|
58
|
+
if (!dataArray || dataArray.length === 0) return null;
|
|
59
|
+
const columns = rawColumns.map((col) => ({
|
|
60
|
+
name: col.name,
|
|
61
|
+
typeName: col.type_name,
|
|
62
|
+
category: classifySqlType(col.type_name)
|
|
63
|
+
}));
|
|
64
|
+
return {
|
|
65
|
+
rows: dataArray.map((row) => {
|
|
66
|
+
const record = {};
|
|
67
|
+
for (let i = 0; i < columns.length; i++) {
|
|
68
|
+
const col = columns[i];
|
|
69
|
+
record[col.name] = parseValue(row[i] ?? null, col.category);
|
|
70
|
+
}
|
|
71
|
+
return record;
|
|
72
|
+
}),
|
|
73
|
+
columns
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { transformGenieData };
|
|
79
|
+
//# sourceMappingURL=genie-query-transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie-query-transform.js","names":[],"sources":["../../../src/react/genie/genie-query-transform.ts"],"sourcesContent":["/**\n * Converts Genie's statement_response data into a flat record array\n * suitable for charting.\n *\n * The Genie API returns `{ manifest.schema.columns, result.data_array }`\n * where each column carries a SQL `type_name`. This module parses values\n * according to those types so downstream chart code receives proper\n * numbers and strings.\n */\n\nimport type { GenieStatementResponse } from \"shared\";\n\n// SQL type_name values that map to numeric JS values\nconst NUMERIC_SQL_TYPES = new Set([\n \"DECIMAL\",\n \"INT\",\n \"INTEGER\",\n \"BIGINT\",\n \"LONG\",\n \"SMALLINT\",\n \"TINYINT\",\n \"FLOAT\",\n \"DOUBLE\",\n \"SHORT\",\n \"BYTE\",\n]);\n\n// SQL type_name values that map to date/timestamp strings\nconst DATE_SQL_TYPES = new Set([\"DATE\", \"TIMESTAMP\", \"TIMESTAMP_NTZ\"]);\n\nexport type ColumnCategory = \"numeric\" | \"date\" | \"string\";\n\nexport interface GenieColumnMeta {\n name: string;\n typeName: string;\n category: ColumnCategory;\n}\n\nexport interface TransformedGenieData {\n rows: Record<string, unknown>[];\n columns: GenieColumnMeta[];\n}\n\n/**\n * Classify a SQL type_name into a high-level category.\n */\nexport function classifySqlType(typeName: string): ColumnCategory {\n const upper = typeName.toUpperCase();\n if (NUMERIC_SQL_TYPES.has(upper)) return \"numeric\";\n if (DATE_SQL_TYPES.has(upper)) return \"date\";\n return \"string\";\n}\n\n/**\n * Parse a single cell value based on its column category.\n */\nfunction parseValue(raw: string | null, category: ColumnCategory): unknown {\n if (raw == null) return null;\n if (category === \"numeric\") {\n const n = Number(raw);\n return Number.isNaN(n) ? null : n;\n }\n // Dates and strings stay as strings — normalizeChartData detects ISO dates\n return raw;\n}\n\n/**\n * Transform a Genie statement_response into chart-ready rows + column metadata.\n *\n * Expects `data` to have the shape:\n * ```\n * {\n * manifest: { schema: { columns: [{ name, type_name }, ...] } },\n * result: { data_array: [[\"val\", ...], ...] }\n * }\n * ```\n *\n * Returns `null` when the data is empty or malformed.\n */\nexport function transformGenieData(\n data: GenieStatementResponse | null | undefined,\n): TransformedGenieData | null {\n if (!data) return null;\n\n const rawColumns = data.manifest?.schema?.columns;\n if (!rawColumns || rawColumns.length === 0) {\n return null;\n }\n\n const dataArray = data.result?.data_array;\n if (!dataArray || dataArray.length === 0) {\n return null;\n }\n\n const columns: GenieColumnMeta[] = rawColumns.map((col) => ({\n name: col.name,\n typeName: col.type_name,\n category: classifySqlType(col.type_name),\n }));\n\n const rows: Record<string, unknown>[] = dataArray.map((row) => {\n const record: Record<string, unknown> = {};\n for (let i = 0; i < columns.length; i++) {\n const col = columns[i];\n record[col.name] = parseValue(row[i] ?? null, col.category);\n }\n return record;\n });\n\n return { rows, columns };\n}\n"],"mappings":";AAaA,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAGF,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAQ;CAAa;CAAgB,CAAC;;;;AAkBtE,SAAgB,gBAAgB,UAAkC;CAChE,MAAM,QAAQ,SAAS,aAAa;AACpC,KAAI,kBAAkB,IAAI,MAAM,CAAE,QAAO;AACzC,KAAI,eAAe,IAAI,MAAM,CAAE,QAAO;AACtC,QAAO;;;;;AAMT,SAAS,WAAW,KAAoB,UAAmC;AACzE,KAAI,OAAO,KAAM,QAAO;AACxB,KAAI,aAAa,WAAW;EAC1B,MAAM,IAAI,OAAO,IAAI;AACrB,SAAO,OAAO,MAAM,EAAE,GAAG,OAAO;;AAGlC,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,mBACd,MAC6B;AAC7B,KAAI,CAAC,KAAM,QAAO;CAElB,MAAM,aAAa,KAAK,UAAU,QAAQ;AAC1C,KAAI,CAAC,cAAc,WAAW,WAAW,EACvC,QAAO;CAGT,MAAM,YAAY,KAAK,QAAQ;AAC/B,KAAI,CAAC,aAAa,UAAU,WAAW,EACrC,QAAO;CAGT,MAAM,UAA6B,WAAW,KAAK,SAAS;EAC1D,MAAM,IAAI;EACV,UAAU,IAAI;EACd,UAAU,gBAAgB,IAAI,UAAU;EACzC,EAAE;AAWH,QAAO;EAAE,MAT+B,UAAU,KAAK,QAAQ;GAC7D,MAAM,SAAkC,EAAE;AAC1C,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,MAAM,QAAQ;AACpB,WAAO,IAAI,QAAQ,WAAW,IAAI,MAAM,MAAM,IAAI,SAAS;;AAE7D,UAAO;IACP;EAEa;EAAS"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { GenieStatementResponse } from "../../shared/src/genie.js";
|
|
2
|
+
import "../../shared/src/index.js";
|
|
3
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/react/genie/genie-query-visualization.d.ts
|
|
6
|
+
interface GenieQueryVisualizationProps {
|
|
7
|
+
/** Raw statement_response from the Genie API */
|
|
8
|
+
data: GenieStatementResponse;
|
|
9
|
+
/** Additional CSS classes */
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Renders a chart + data table for a Genie query result.
|
|
14
|
+
*
|
|
15
|
+
* - When a chart type can be inferred: shows Tabs with "Chart" (default) and "Table"
|
|
16
|
+
* - When no chart fits: shows only the data table
|
|
17
|
+
* - When data is empty/malformed: renders nothing
|
|
18
|
+
*/
|
|
19
|
+
declare function GenieQueryVisualization({
|
|
20
|
+
data,
|
|
21
|
+
className
|
|
22
|
+
}: GenieQueryVisualizationProps): react_jsx_runtime0.JSX.Element | null;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { GenieQueryVisualization };
|
|
25
|
+
//# sourceMappingURL=genie-query-visualization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie-query-visualization.d.ts","names":[],"sources":["../../../src/react/genie/genie-query-visualization.tsx"],"mappings":";;;;;UAmBiB,4BAAA;;EAEf,IAAA,EAAM,sBAAA;;EAEN,SAAA;AAAA;;;;;;;;iBAUc,uBAAA,CAAA;EACd,IAAA;EACA;AAAA,GACC,4BAAA,GAA4B,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { BaseChart } from "../charts/base.js";
|
|
2
|
+
import { ChartErrorBoundary } from "../charts/chart-error-boundary.js";
|
|
3
|
+
import { inferChartType } from "./genie-chart-inference.js";
|
|
4
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table.js";
|
|
5
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs.js";
|
|
6
|
+
import { transformGenieData } from "./genie-query-transform.js";
|
|
7
|
+
import { useMemo } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
|
|
10
|
+
//#region src/react/genie/genie-query-visualization.tsx
|
|
11
|
+
const TABLE_ROW_LIMIT = 50;
|
|
12
|
+
const CHART_HEIGHT = 250;
|
|
13
|
+
/**
|
|
14
|
+
* Renders a chart + data table for a Genie query result.
|
|
15
|
+
*
|
|
16
|
+
* - When a chart type can be inferred: shows Tabs with "Chart" (default) and "Table"
|
|
17
|
+
* - When no chart fits: shows only the data table
|
|
18
|
+
* - When data is empty/malformed: renders nothing
|
|
19
|
+
*/
|
|
20
|
+
function GenieQueryVisualization({ data, className }) {
|
|
21
|
+
const transformed = useMemo(() => transformGenieData(data), [data]);
|
|
22
|
+
const inference = useMemo(() => transformed ? inferChartType(transformed.rows, transformed.columns) : null, [transformed]);
|
|
23
|
+
if (!transformed || transformed.rows.length === 0) return null;
|
|
24
|
+
const { rows, columns } = transformed;
|
|
25
|
+
const truncated = rows.length > TABLE_ROW_LIMIT;
|
|
26
|
+
const displayRows = truncated ? rows.slice(0, TABLE_ROW_LIMIT) : rows;
|
|
27
|
+
const dataTable = /* @__PURE__ */ jsxs("div", {
|
|
28
|
+
className: "overflow-auto max-h-[300px]",
|
|
29
|
+
children: [/* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => /* @__PURE__ */ jsx(TableHead, { children: col.name }, col.name)) }) }), /* @__PURE__ */ jsx(TableBody, { children: displayRows.map((row, i) => /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => /* @__PURE__ */ jsx(TableCell, { children: row[col.name] != null ? String(row[col.name]) : "" }, col.name)) }, i)) })] }), truncated && /* @__PURE__ */ jsxs("p", {
|
|
30
|
+
className: "text-xs text-muted-foreground px-2 py-1",
|
|
31
|
+
children: [
|
|
32
|
+
"Showing ",
|
|
33
|
+
TABLE_ROW_LIMIT,
|
|
34
|
+
" of ",
|
|
35
|
+
rows.length,
|
|
36
|
+
" rows"
|
|
37
|
+
]
|
|
38
|
+
})]
|
|
39
|
+
});
|
|
40
|
+
if (!inference) return /* @__PURE__ */ jsx("div", {
|
|
41
|
+
className,
|
|
42
|
+
children: dataTable
|
|
43
|
+
});
|
|
44
|
+
return /* @__PURE__ */ jsxs(Tabs, {
|
|
45
|
+
defaultValue: "chart",
|
|
46
|
+
className,
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsxs(TabsList, { children: [/* @__PURE__ */ jsx(TabsTrigger, {
|
|
49
|
+
value: "chart",
|
|
50
|
+
children: "Chart"
|
|
51
|
+
}), /* @__PURE__ */ jsx(TabsTrigger, {
|
|
52
|
+
value: "table",
|
|
53
|
+
children: "Table"
|
|
54
|
+
})] }),
|
|
55
|
+
/* @__PURE__ */ jsx(TabsContent, {
|
|
56
|
+
value: "chart",
|
|
57
|
+
children: /* @__PURE__ */ jsx(ChartErrorBoundary, {
|
|
58
|
+
fallback: dataTable,
|
|
59
|
+
children: /* @__PURE__ */ jsx(BaseChart, {
|
|
60
|
+
data: rows,
|
|
61
|
+
chartType: inference.chartType,
|
|
62
|
+
xKey: inference.xKey,
|
|
63
|
+
yKey: inference.yKey,
|
|
64
|
+
height: CHART_HEIGHT,
|
|
65
|
+
showLegend: Array.isArray(inference.yKey)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ jsx(TabsContent, {
|
|
70
|
+
value: "table",
|
|
71
|
+
children: dataTable
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { GenieQueryVisualization };
|
|
79
|
+
//# sourceMappingURL=genie-query-visualization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie-query-visualization.js","names":[],"sources":["../../../src/react/genie/genie-query-visualization.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { GenieStatementResponse } from \"shared\";\nimport { BaseChart } from \"../charts/base\";\nimport { ChartErrorBoundary } from \"../charts/chart-error-boundary\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../ui/tabs\";\nimport { inferChartType } from \"./genie-chart-inference\";\nimport { transformGenieData } from \"./genie-query-transform\";\n\nconst TABLE_ROW_LIMIT = 50;\nconst CHART_HEIGHT = 250;\n\nexport interface GenieQueryVisualizationProps {\n /** Raw statement_response from the Genie API */\n data: GenieStatementResponse;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Renders a chart + data table for a Genie query result.\n *\n * - When a chart type can be inferred: shows Tabs with \"Chart\" (default) and \"Table\"\n * - When no chart fits: shows only the data table\n * - When data is empty/malformed: renders nothing\n */\nexport function GenieQueryVisualization({\n data,\n className,\n}: GenieQueryVisualizationProps) {\n const transformed = useMemo(() => transformGenieData(data), [data]);\n const inference = useMemo(\n () =>\n transformed\n ? inferChartType(transformed.rows, transformed.columns)\n : null,\n [transformed],\n );\n\n if (!transformed || transformed.rows.length === 0) return null;\n\n const { rows, columns } = transformed;\n const truncated = rows.length > TABLE_ROW_LIMIT;\n const displayRows = truncated ? rows.slice(0, TABLE_ROW_LIMIT) : rows;\n\n const dataTable = (\n <div className=\"overflow-auto max-h-[300px]\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead key={col.name}>{col.name}</TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {displayRows.map((row, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: tabular data rows have no unique identifier\n <TableRow key={i}>\n {columns.map((col) => (\n <TableCell key={col.name}>\n {row[col.name] != null ? String(row[col.name]) : \"\"}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n {truncated && (\n <p className=\"text-xs text-muted-foreground px-2 py-1\">\n Showing {TABLE_ROW_LIMIT} of {rows.length} rows\n </p>\n )}\n </div>\n );\n\n if (!inference) {\n return <div className={className}>{dataTable}</div>;\n }\n\n return (\n <Tabs defaultValue=\"chart\" className={className}>\n <TabsList>\n <TabsTrigger value=\"chart\">Chart</TabsTrigger>\n <TabsTrigger value=\"table\">Table</TabsTrigger>\n </TabsList>\n <TabsContent value=\"chart\">\n <ChartErrorBoundary fallback={dataTable}>\n <BaseChart\n data={rows}\n chartType={inference.chartType}\n xKey={inference.xKey}\n yKey={inference.yKey}\n height={CHART_HEIGHT}\n showLegend={Array.isArray(inference.yKey)}\n />\n </ChartErrorBoundary>\n </TabsContent>\n <TabsContent value=\"table\">{dataTable}</TabsContent>\n </Tabs>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,MAAM,kBAAkB;AACxB,MAAM,eAAe;;;;;;;;AAgBrB,SAAgB,wBAAwB,EACtC,MACA,aAC+B;CAC/B,MAAM,cAAc,cAAc,mBAAmB,KAAK,EAAE,CAAC,KAAK,CAAC;CACnE,MAAM,YAAY,cAEd,cACI,eAAe,YAAY,MAAM,YAAY,QAAQ,GACrD,MACN,CAAC,YAAY,CACd;AAED,KAAI,CAAC,eAAe,YAAY,KAAK,WAAW,EAAG,QAAO;CAE1D,MAAM,EAAE,MAAM,YAAY;CAC1B,MAAM,YAAY,KAAK,SAAS;CAChC,MAAM,cAAc,YAAY,KAAK,MAAM,GAAG,gBAAgB,GAAG;CAEjE,MAAM,YACJ,qBAAC;EAAI,WAAU;aACb,qBAAC,oBACC,oBAAC,yBACC,oBAAC,sBACE,QAAQ,KAAK,QACZ,oBAAC,uBAA0B,IAAI,QAAf,IAAI,KAA4B,CAChD,GACO,GACC,EACd,oBAAC,uBACE,YAAY,KAAK,KAAK,MAErB,oBAAC,sBACE,QAAQ,KAAK,QACZ,oBAAC,uBACE,IAAI,IAAI,SAAS,OAAO,OAAO,IAAI,IAAI,MAAM,GAAG,MADnC,IAAI,KAER,CACZ,IALW,EAMJ,CACX,GACQ,IACN,EACP,aACC,qBAAC;GAAE,WAAU;;IAA0C;IAC5C;IAAgB;IAAK,KAAK;IAAO;;IACxC;GAEF;AAGR,KAAI,CAAC,UACH,QAAO,oBAAC;EAAe;YAAY;GAAgB;AAGrD,QACE,qBAAC;EAAK,cAAa;EAAmB;;GACpC,qBAAC,uBACC,oBAAC;IAAY,OAAM;cAAQ;KAAmB,EAC9C,oBAAC;IAAY,OAAM;cAAQ;KAAmB,IACrC;GACX,oBAAC;IAAY,OAAM;cACjB,oBAAC;KAAmB,UAAU;eAC5B,oBAAC;MACC,MAAM;MACN,WAAW,UAAU;MACrB,MAAM,UAAU;MAChB,MAAM,UAAU;MAChB,QAAQ;MACR,YAAY,MAAM,QAAQ,UAAU,KAAK;OACzC;MACiB;KACT;GACd,oBAAC;IAAY,OAAM;cAAS;KAAwB;;GAC/C"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
2
|
+
import { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData } from "./genie-query-transform.js";
|
|
3
|
+
import { ChartInference, inferChartType } from "./genie-chart-inference.js";
|
|
2
4
|
import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./types.js";
|
|
3
5
|
import { GenieChat } from "./genie-chat.js";
|
|
4
6
|
import { GenieChatInput } from "./genie-chat-input.js";
|
|
5
7
|
import { GenieChatMessage } from "./genie-chat-message.js";
|
|
6
8
|
import { GenieChatMessageList } from "./genie-chat-message-list.js";
|
|
9
|
+
import { GenieQueryVisualization } from "./genie-query-visualization.js";
|
|
7
10
|
import { useGenieChat } from "./use-genie-chat.js";
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { inferChartType } from "./genie-chart-inference.js";
|
|
1
2
|
import { GenieChatInput } from "./genie-chat-input.js";
|
|
3
|
+
import { transformGenieData } from "./genie-query-transform.js";
|
|
4
|
+
import { GenieQueryVisualization } from "./genie-query-visualization.js";
|
|
2
5
|
import { GenieChatMessage } from "./genie-chat-message.js";
|
|
3
6
|
import { GenieChatMessageList } from "./genie-chat-message-list.js";
|
|
4
7
|
import { useGenieChat } from "./use-genie-chat.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
2
2
|
import "../../shared/src/index.js";
|
|
3
3
|
|
|
4
4
|
//#region src/react/genie/types.d.ts
|
|
@@ -9,7 +9,7 @@ interface GenieMessageItem {
|
|
|
9
9
|
content: string;
|
|
10
10
|
status: string;
|
|
11
11
|
attachments: GenieAttachmentResponse[];
|
|
12
|
-
queryResults: Map<string,
|
|
12
|
+
queryResults: Map<string, GenieStatementResponse>;
|
|
13
13
|
error?: string;
|
|
14
14
|
}
|
|
15
15
|
interface UseGenieChatOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"mappings":";;;;KASY,eAAA;AAAA,UAOK,gBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA,EAAa,uBAAA;EACb,YAAA,EAAc,GAAA,SAAY,sBAAA;EAC1B,KAAA;AAAA;AAAA,UAGe,mBAAA;EAJW;EAM1B,KAAA;EANiB;EAQjB,QAAA;EAbA;EAeA,YAAA;EAbA;EAeA,YAAA;AAAA;AAAA,UAGe,kBAAA;EACf,QAAA,EAAU,gBAAA;EACV,MAAA,EAAQ,eAAA;EACR,cAAA;EACA,KAAA;EACA,WAAA,GAAc,OAAA;EACd,KAAA;EAjBe;EAmBf,eAAA;;EAEA,sBAAA;EAnBA;EAqBA,iBAAA;AAAA;AAAA,UAGe,cAAA;EAlBH;EAoBZ,KAAA;EAjBe;EAmBf,QAAA;;EAEA,WAAA;EApBA;EAsBA,SAAA;AAAA"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../shared/src/genie.js";
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../shared/src/genie.js";
|
|
2
2
|
import { DATE_FIELD_PATTERNS, METADATA_DATE_PATTERNS, NAME_FIELD_PATTERNS } from "../js/constants.js";
|
|
3
3
|
import { AreaChartProps, AreaChartSpecificProps, BarChartProps, BarChartSpecificProps, ChartBaseProps, ChartColorPalette, ChartData, ChartType, DataFormat, DataProps, DonutChartProps, HeatmapChartProps, HeatmapChartSpecificProps, LineChartProps, LineChartSpecificProps, NormalizedChartData, NormalizedChartDataBase, Orientation, PieChartProps, PieChartSpecificProps, QueryProps, RadarChartProps, RadarChartSpecificProps, ScatterChartProps, ScatterChartSpecificProps, UnifiedChartProps, isArrowTable, isDataProps, isQueryProps } from "./charts/types.js";
|
|
4
4
|
import { AreaChart } from "./charts/area/index.js";
|
|
@@ -18,11 +18,22 @@ import { useAllThemeColors, useThemeColors } from "./charts/theme.js";
|
|
|
18
18
|
import { createTimeSeriesData, formatLabel, sortTimeSeriesAscending, toChartArray, toChartValue, truncateLabel } from "./charts/utils.js";
|
|
19
19
|
import { CartesianContext, HeatmapContext, OptionBuilderContext, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./charts/options.js";
|
|
20
20
|
import "./charts/index.js";
|
|
21
|
+
import { formatFileSize } from "./lib/format.js";
|
|
22
|
+
import { DirectoryEntry, FileBrowserLabels, FilePreview } from "./file-browser/types.js";
|
|
23
|
+
import { DirectoryList, DirectoryListProps } from "./file-browser/directory-list.js";
|
|
24
|
+
import { FileBreadcrumb, FileBreadcrumbProps } from "./file-browser/file-breadcrumb.js";
|
|
25
|
+
import { FileEntry, FileEntryProps } from "./file-browser/file-entry.js";
|
|
26
|
+
import { FilePreviewPanel, FilePreviewPanelProps } from "./file-browser/file-preview-panel.js";
|
|
27
|
+
import { NewFolderInput, NewFolderInputProps } from "./file-browser/new-folder-input.js";
|
|
28
|
+
import "./file-browser/index.js";
|
|
29
|
+
import { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData } from "./genie/genie-query-transform.js";
|
|
30
|
+
import { ChartInference, inferChartType } from "./genie/genie-chart-inference.js";
|
|
21
31
|
import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./genie/types.js";
|
|
22
32
|
import { GenieChat } from "./genie/genie-chat.js";
|
|
23
33
|
import { GenieChatInput } from "./genie/genie-chat-input.js";
|
|
24
34
|
import { GenieChatMessage } from "./genie/genie-chat-message.js";
|
|
25
35
|
import { GenieChatMessageList } from "./genie/genie-chat-message-list.js";
|
|
36
|
+
import { GenieQueryVisualization } from "./genie/genie-query-visualization.js";
|
|
26
37
|
import { useGenieChat } from "./genie/use-genie-chat.js";
|
|
27
38
|
import "./genie/index.js";
|
|
28
39
|
import { AnalyticsFormat, InferResultByFormat, InferRowType, PluginRegistry, QueryRegistry, TypedArrowTable, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./hooks/types.js";
|
|
@@ -86,4 +97,4 @@ import { Textarea } from "./ui/textarea.js";
|
|
|
86
97
|
import { Toggle, toggleVariants } from "./ui/toggle.js";
|
|
87
98
|
import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group.js";
|
|
88
99
|
import "./ui/index.js";
|
|
89
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnalyticsFormat, AreaChart, AreaChartProps, AreaChartSpecificProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BarChartProps, BarChartSpecificProps, BaseChart, BaseChartProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianContext, ChartBaseProps, ChartColorPalette, ChartConfig, ChartContainer, ChartData, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DATE_FIELD_PATTERNS, DataFormat, DataProps, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, DonutChartProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FALLBACK_COLORS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GenieAttachmentResponse, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, GenieChatProps, GenieChatStatus, GenieMessageItem, GenieMessageResponse, GenieStreamEvent, HeatmapChart, HeatmapChartProps, HeatmapChartSpecificProps, HeatmapContext, HoverCard, HoverCardContent, HoverCardTrigger, InferResultByFormat, InferRowType, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, LineChart, LineChartProps, LineChartSpecificProps, METADATA_DATE_PATTERNS, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NAME_FIELD_PATTERNS, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NormalizedChartData, NormalizedChartDataBase, NormalizedHeatmapData, OptionBuilderContext, Orientation, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, PieChartProps, PieChartSpecificProps, PluginRegistry, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, QueryProps, QueryRegistry, RadarChart, RadarChartProps, RadarChartSpecificProps, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, ScatterChartProps, ScatterChartSpecificProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, UseGenieChatOptions, UseGenieChatReturn, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
|
|
100
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnalyticsFormat, AreaChart, AreaChartProps, AreaChartSpecificProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BarChartProps, BarChartSpecificProps, BaseChart, BaseChartProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianContext, ChartBaseProps, ChartColorPalette, ChartConfig, ChartContainer, ChartData, ChartInference, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, ColumnCategory, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DATE_FIELD_PATTERNS, DataFormat, DataProps, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DirectoryEntry, DirectoryList, DirectoryListProps, DonutChart, DonutChartProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FALLBACK_COLORS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, FileBreadcrumb, FileBreadcrumbProps, FileBrowserLabels, FileEntry, FileEntryProps, FilePreview, FilePreviewPanel, FilePreviewPanelProps, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GenieAttachmentResponse, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, GenieChatProps, GenieChatStatus, GenieColumnMeta, GenieMessageItem, GenieMessageResponse, GenieQueryVisualization, GenieStatementResponse, GenieStreamEvent, HeatmapChart, HeatmapChartProps, HeatmapChartSpecificProps, HeatmapContext, HoverCard, HoverCardContent, HoverCardTrigger, InferResultByFormat, InferRowType, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, LineChart, LineChartProps, LineChartSpecificProps, METADATA_DATE_PATTERNS, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NAME_FIELD_PATTERNS, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NewFolderInput, NewFolderInputProps, NormalizedChartData, NormalizedChartDataBase, NormalizedHeatmapData, OptionBuilderContext, Orientation, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, PieChartProps, PieChartSpecificProps, PluginRegistry, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, QueryProps, QueryRegistry, RadarChart, RadarChartProps, RadarChartSpecificProps, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, ScatterChartProps, ScatterChartSpecificProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TransformedGenieData, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, UseGenieChatOptions, UseGenieChatReturn, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatFileSize, formatLabel, inferChartType, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, transformGenieData, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
|