@quantumwake/terminal-ux-dashboard-components 0.1.3 → 0.1.5

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/dist/index.d.cts CHANGED
@@ -326,6 +326,9 @@ interface SqlConsoleColumn {
326
326
  interface SqlConsoleProps {
327
327
  columns?: SqlConsoleColumn[];
328
328
  stateId?: string;
329
+ defaultColumnsOpen?: boolean;
330
+ defaultSql?: string;
331
+ autoRun?: boolean;
329
332
  }
330
333
  /**
331
334
  * SqlConsole — a HuggingFace-style read-only SQL editor over a state's full
@@ -333,7 +336,7 @@ interface SqlConsoleProps {
333
336
  * in the viewer) as a view named `data`; queries run against the entire dataset,
334
337
  * not a client sample.
335
338
  */
336
- declare function SqlConsole({ columns, stateId }: SqlConsoleProps): react.JSX.Element;
339
+ declare function SqlConsole({ columns, stateId, defaultColumnsOpen, defaultSql, autoRun }: SqlConsoleProps): react.JSX.Element;
337
340
 
338
341
  interface PanelConfig {
339
342
  sql?: string;
@@ -457,6 +460,7 @@ interface Dashboard {
457
460
  panels?: DashboardPanel[];
458
461
  [key: string]: unknown;
459
462
  }
463
+ type Mode = 'dashboard' | 'builder' | 'sql';
460
464
  interface DataExplorerProps {
461
465
  /** All records for the active state (viz/builder source). Empty when not loaded. */
462
466
  records: Row[];
@@ -478,11 +482,17 @@ interface DataExplorerProps {
478
482
  loading?: boolean;
479
483
  /** True while the AI is generating/refining the dashboard. */
480
484
  analyzing?: boolean;
485
+ /** Initial mode tab. Defaults to 'dashboard'; the published viewer uses 'sql'
486
+ * so the SQL console is the primary surface. Clamped to `tabs`. */
487
+ defaultMode?: Mode;
488
+ /** Which mode tabs to show, in order. Defaults to all three. Pass a subset to
489
+ * turn tabs off (e.g. ['sql'] for a SQL-only explorer). */
490
+ tabs?: Mode[];
481
491
  /** Select a state (host fetches its profile/records). */
482
492
  onSelectState: (id: string) => void;
483
493
  /** Refresh the states catalog. */
484
494
  onRefreshStates?: () => void;
485
495
  }
486
- declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
496
+ declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, defaultMode, tabs, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
487
497
 
488
498
  export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, DEFAULT_CHART_STYLE, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, type PanelInput, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, compileWhere, groupBy, legendConfig, qIdent, qLit, shapeChartData, useCapabilities, useDashboard, withStyleDefaults };
package/dist/index.d.ts CHANGED
@@ -326,6 +326,9 @@ interface SqlConsoleColumn {
326
326
  interface SqlConsoleProps {
327
327
  columns?: SqlConsoleColumn[];
328
328
  stateId?: string;
329
+ defaultColumnsOpen?: boolean;
330
+ defaultSql?: string;
331
+ autoRun?: boolean;
329
332
  }
330
333
  /**
331
334
  * SqlConsole — a HuggingFace-style read-only SQL editor over a state's full
@@ -333,7 +336,7 @@ interface SqlConsoleProps {
333
336
  * in the viewer) as a view named `data`; queries run against the entire dataset,
334
337
  * not a client sample.
335
338
  */
336
- declare function SqlConsole({ columns, stateId }: SqlConsoleProps): react.JSX.Element;
339
+ declare function SqlConsole({ columns, stateId, defaultColumnsOpen, defaultSql, autoRun }: SqlConsoleProps): react.JSX.Element;
337
340
 
338
341
  interface PanelConfig {
339
342
  sql?: string;
@@ -457,6 +460,7 @@ interface Dashboard {
457
460
  panels?: DashboardPanel[];
458
461
  [key: string]: unknown;
459
462
  }
463
+ type Mode = 'dashboard' | 'builder' | 'sql';
460
464
  interface DataExplorerProps {
461
465
  /** All records for the active state (viz/builder source). Empty when not loaded. */
462
466
  records: Row[];
@@ -478,11 +482,17 @@ interface DataExplorerProps {
478
482
  loading?: boolean;
479
483
  /** True while the AI is generating/refining the dashboard. */
480
484
  analyzing?: boolean;
485
+ /** Initial mode tab. Defaults to 'dashboard'; the published viewer uses 'sql'
486
+ * so the SQL console is the primary surface. Clamped to `tabs`. */
487
+ defaultMode?: Mode;
488
+ /** Which mode tabs to show, in order. Defaults to all three. Pass a subset to
489
+ * turn tabs off (e.g. ['sql'] for a SQL-only explorer). */
490
+ tabs?: Mode[];
481
491
  /** Select a state (host fetches its profile/records). */
482
492
  onSelectState: (id: string) => void;
483
493
  /** Refresh the states catalog. */
484
494
  onRefreshStates?: () => void;
485
495
  }
486
- declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
496
+ declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, defaultMode, tabs, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
487
497
 
488
498
  export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, DEFAULT_CHART_STYLE, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, type PanelInput, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, compileWhere, groupBy, legendConfig, qIdent, qLit, shapeChartData, useCapabilities, useDashboard, withStyleDefaults };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useContext, useMemo, useState, useRef, useEffect, Suspense } from 'react';
1
+ import { createContext, useContext, useMemo, useState, useEffect, useRef, Suspense } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { ResponsiveBar } from '@nivo/bar';
4
4
  import { ResponsivePie } from '@nivo/pie';
@@ -7,7 +7,7 @@ import { ResponsiveScatterPlot } from '@nivo/scatterplot';
7
7
  import { ResponsiveHeatMap } from '@nivo/heatmap';
8
8
  import PivotTableUI from 'react-pivottable/PivotTableUI';
9
9
  import 'react-pivottable/pivottable.css';
10
- import { Loader2, Play, AlertCircle, Rows3, BarChart3, PieChart, TrendingUp, ScatterChart, LayoutGrid, Code, ChevronDown, Sparkles, X, RefreshCw, Minimize2, Maximize2, Terminal, Plus, Save, FolderOpen, Trash2, Filter, Database, Send, GripVertical } from 'lucide-react';
10
+ import { Loader2, Play, ChevronDown, AlertCircle, Rows3, BarChart3, PieChart, TrendingUp, ScatterChart, LayoutGrid, Code, Sparkles, X, Terminal, RefreshCw, Minimize2, Maximize2, Plus, Save, FolderOpen, Trash2, Filter, Database, Send, GripVertical } from 'lucide-react';
11
11
 
12
12
  // src/context/DashboardContext.tsx
13
13
  var DashboardContext = createContext(null);
@@ -643,18 +643,19 @@ var renderCell = (v) => {
643
643
  if (typeof v === "boolean") return v ? "true" : "false";
644
644
  return String(v);
645
645
  };
646
- function SqlConsole({ columns = [], stateId }) {
646
+ function SqlConsole({ columns = [], stateId, defaultColumnsOpen = false, defaultSql = DEFAULT_SQL, autoRun = false }) {
647
647
  const { theme, runQuery } = useDashboard();
648
- const [sql, setSql] = useState(DEFAULT_SQL);
648
+ const [sql, setSql] = useState(defaultSql);
649
649
  const [result, setResult] = useState(null);
650
650
  const [error, setError] = useState(null);
651
651
  const [running, setRunning] = useState(false);
652
- const run = async () => {
653
- if (running || !sql.trim()) return;
652
+ const [columnsOpen, setColumnsOpen] = useState(defaultColumnsOpen);
653
+ const run = async (text = sql) => {
654
+ if (running || !text.trim()) return;
654
655
  setRunning(true);
655
656
  setError(null);
656
657
  try {
657
- const data = await runQuery(sql, stateId);
658
+ const data = await runQuery(text, stateId);
658
659
  setResult({ columns: data.columns || [], rows: data.rows || [] });
659
660
  } catch (err) {
660
661
  setResult(null);
@@ -663,6 +664,11 @@ function SqlConsole({ columns = [], stateId }) {
663
664
  setRunning(false);
664
665
  }
665
666
  };
667
+ useEffect(() => {
668
+ if (!autoRun || !stateId) return;
669
+ setSql(defaultSql);
670
+ void run(defaultSql);
671
+ }, [stateId, autoRun, defaultSql]);
666
672
  const onKeyDown = (e) => {
667
673
  if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
668
674
  e.preventDefault();
@@ -703,19 +709,34 @@ function SqlConsole({ columns = [], stateId }) {
703
709
  placeholder: "SELECT ... FROM data"
704
710
  }
705
711
  ),
706
- columns.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1", children: columns.map((c) => /* @__PURE__ */ jsxs(
707
- "button",
708
- {
709
- title: `Insert ${c.name}`,
710
- onClick: () => setSql((s) => `${s}${s.endsWith(" ") || s.endsWith("\n") || !s ? "" : " "}${c.name}`),
711
- className: "px-1.5 py-0.5 border border-midnight-border text-[11px] font-mono text-midnight-text-muted hover:bg-midnight-raised transition-colors",
712
- children: [
713
- c.name,
714
- /* @__PURE__ */ jsx("span", { className: "opacity-50 ml-1", children: c.type })
715
- ]
716
- },
717
- c.name
718
- )) })
712
+ columns.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
713
+ /* @__PURE__ */ jsxs(
714
+ "button",
715
+ {
716
+ onClick: () => setColumnsOpen((o) => !o),
717
+ className: "flex items-center gap-1 text-[11px] font-mono text-midnight-text-muted hover:text-midnight-text-body transition-colors",
718
+ children: [
719
+ /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 transition-transform ${columnsOpen ? "" : "-rotate-90"}` }),
720
+ "Columns (",
721
+ columns.length,
722
+ ")"
723
+ ]
724
+ }
725
+ ),
726
+ columnsOpen && /* @__PURE__ */ jsx("div", { className: "mt-1.5 flex flex-wrap gap-1", children: columns.map((c) => /* @__PURE__ */ jsxs(
727
+ "button",
728
+ {
729
+ title: `Insert ${c.name}`,
730
+ onClick: () => setSql((s) => `${s}${s.endsWith(" ") || s.endsWith("\n") || !s ? "" : " "}${c.name}`),
731
+ className: "px-1.5 py-0.5 border border-midnight-border text-[11px] font-mono text-midnight-text-muted hover:bg-midnight-raised transition-colors",
732
+ children: [
733
+ c.name,
734
+ /* @__PURE__ */ jsx("span", { className: "opacity-50 ml-1", children: c.type })
735
+ ]
736
+ },
737
+ c.name
738
+ )) })
739
+ ] })
719
740
  ] }),
720
741
  (result || error) && /* @__PURE__ */ jsx("div", { className: `flex items-center gap-4 px-3 py-1.5 border-b ${theme.border} text-xs font-mono shrink-0 ${error ? "text-red-400" : "text-midnight-text-muted"}`, children: error ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
721
742
  /* @__PURE__ */ jsx(AlertCircle, { className: "w-3.5 h-3.5" }),
@@ -1606,6 +1627,11 @@ function ModeTab({ active, onClick, icon: Icon, label }) {
1606
1627
  }
1607
1628
  );
1608
1629
  }
1630
+ var MODE_TABS = [
1631
+ { mode: "dashboard", icon: Sparkles, label: "Dashboard" },
1632
+ { mode: "builder", icon: BarChart3, label: "Chart Builder" },
1633
+ { mode: "sql", icon: Terminal, label: "SQL" }
1634
+ ];
1609
1635
  function DataExplorer({
1610
1636
  records,
1611
1637
  columns,
@@ -1617,12 +1643,15 @@ function DataExplorer({
1617
1643
  savedDashboards = [],
1618
1644
  loading = false,
1619
1645
  analyzing = false,
1646
+ defaultMode = "dashboard",
1647
+ tabs = ["dashboard", "builder", "sql"],
1620
1648
  onSelectState,
1621
1649
  onRefreshStates
1622
1650
  }) {
1623
1651
  const { theme, newDashboard, addPanel, saveDashboard, listDashboards, searchDashboards, loadDashboard, deleteDashboard, analyzeDataset, refineDashboard } = useDashboard();
1624
1652
  const caps = useCapabilities();
1625
- const [mode, setMode] = useState("dashboard");
1653
+ const visibleTabs = MODE_TABS.filter((t) => tabs.includes(t.mode));
1654
+ const [mode, setMode] = useState(tabs.includes(defaultMode) ? defaultMode : tabs[0] ?? "sql");
1626
1655
  const [fullscreen, setFullscreen] = useState(false);
1627
1656
  const [showSaved, setShowSaved] = useState(false);
1628
1657
  const [saveName, setSaveName] = useState("");
@@ -1687,9 +1716,7 @@ function DataExplorer({
1687
1716
  )
1688
1717
  ] }),
1689
1718
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 mb-3 shrink-0", children: [
1690
- /* @__PURE__ */ jsx(ModeTab, { active: mode === "dashboard", onClick: () => setMode("dashboard"), icon: Sparkles, label: "Dashboard" }),
1691
- /* @__PURE__ */ jsx(ModeTab, { active: mode === "builder", onClick: () => setMode("builder"), icon: BarChart3, label: "Chart Builder" }),
1692
- /* @__PURE__ */ jsx(ModeTab, { active: mode === "sql", onClick: () => setMode("sql"), icon: Terminal, label: "SQL" }),
1719
+ visibleTabs.map((t) => /* @__PURE__ */ jsx(ModeTab, { active: mode === t.mode, onClick: () => setMode(t.mode), icon: t.icon, label: t.label }, t.mode)),
1693
1720
  caps.canNew && /* @__PURE__ */ jsxs(
1694
1721
  "button",
1695
1722
  {