@quantumwake/terminal-ux-dashboard-components 0.1.5 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +317 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +320 -16
- package/dist/index.js.map +1 -1
- package/package.json +16 -11
package/dist/index.js
CHANGED
|
@@ -8,6 +8,9 @@ import { ResponsiveHeatMap } from '@nivo/heatmap';
|
|
|
8
8
|
import PivotTableUI from 'react-pivottable/PivotTableUI';
|
|
9
9
|
import 'react-pivottable/pivottable.css';
|
|
10
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
|
+
import CodeMirror, { EditorView, Prec, keymap } from '@uiw/react-codemirror';
|
|
12
|
+
import { sql, PostgreSQL, schemaCompletionSource, keywordCompletionSource } from '@codemirror/lang-sql';
|
|
13
|
+
import { snippetCompletion, completeFromList, autocompletion, acceptCompletion } from '@codemirror/autocomplete';
|
|
11
14
|
|
|
12
15
|
// src/context/DashboardContext.tsx
|
|
13
16
|
var DashboardContext = createContext(null);
|
|
@@ -636,6 +639,280 @@ function ChartStyleControls({ style, onChange }) {
|
|
|
636
639
|
] })
|
|
637
640
|
] });
|
|
638
641
|
}
|
|
642
|
+
var AGGREGATES = [
|
|
643
|
+
"count",
|
|
644
|
+
"count_if",
|
|
645
|
+
"sum",
|
|
646
|
+
"avg",
|
|
647
|
+
"min",
|
|
648
|
+
"max",
|
|
649
|
+
"median",
|
|
650
|
+
"mode",
|
|
651
|
+
"stddev",
|
|
652
|
+
"stddev_pop",
|
|
653
|
+
"stddev_samp",
|
|
654
|
+
"var_pop",
|
|
655
|
+
"var_samp",
|
|
656
|
+
"variance",
|
|
657
|
+
"quantile",
|
|
658
|
+
"quantile_cont",
|
|
659
|
+
"quantile_disc",
|
|
660
|
+
"approx_count_distinct",
|
|
661
|
+
"approx_quantile",
|
|
662
|
+
"arg_max",
|
|
663
|
+
"arg_min",
|
|
664
|
+
"first",
|
|
665
|
+
"last",
|
|
666
|
+
"product",
|
|
667
|
+
"bool_and",
|
|
668
|
+
"bool_or",
|
|
669
|
+
"bit_and",
|
|
670
|
+
"bit_or",
|
|
671
|
+
"bit_xor",
|
|
672
|
+
"string_agg",
|
|
673
|
+
"list",
|
|
674
|
+
"array_agg",
|
|
675
|
+
"histogram",
|
|
676
|
+
"corr",
|
|
677
|
+
"covar_pop",
|
|
678
|
+
"covar_samp",
|
|
679
|
+
"kurtosis",
|
|
680
|
+
"skewness",
|
|
681
|
+
"entropy",
|
|
682
|
+
"row_number",
|
|
683
|
+
"rank",
|
|
684
|
+
"dense_rank",
|
|
685
|
+
"percent_rank",
|
|
686
|
+
"cume_dist",
|
|
687
|
+
"ntile",
|
|
688
|
+
"lag",
|
|
689
|
+
"lead",
|
|
690
|
+
"first_value",
|
|
691
|
+
"last_value",
|
|
692
|
+
"nth_value"
|
|
693
|
+
];
|
|
694
|
+
var SCALARS = [
|
|
695
|
+
// string
|
|
696
|
+
"length",
|
|
697
|
+
"len",
|
|
698
|
+
"lower",
|
|
699
|
+
"upper",
|
|
700
|
+
"trim",
|
|
701
|
+
"ltrim",
|
|
702
|
+
"rtrim",
|
|
703
|
+
"substring",
|
|
704
|
+
"substr",
|
|
705
|
+
"concat",
|
|
706
|
+
"concat_ws",
|
|
707
|
+
"replace",
|
|
708
|
+
"reverse",
|
|
709
|
+
"repeat",
|
|
710
|
+
"lpad",
|
|
711
|
+
"rpad",
|
|
712
|
+
"left",
|
|
713
|
+
"right",
|
|
714
|
+
"contains",
|
|
715
|
+
"starts_with",
|
|
716
|
+
"ends_with",
|
|
717
|
+
"position",
|
|
718
|
+
"split_part",
|
|
719
|
+
"string_split",
|
|
720
|
+
"regexp_matches",
|
|
721
|
+
"regexp_replace",
|
|
722
|
+
"regexp_extract",
|
|
723
|
+
"regexp_full_match",
|
|
724
|
+
"regexp_split_to_array",
|
|
725
|
+
"format",
|
|
726
|
+
"printf",
|
|
727
|
+
"md5",
|
|
728
|
+
"sha256",
|
|
729
|
+
"levenshtein",
|
|
730
|
+
"jaccard",
|
|
731
|
+
"ascii",
|
|
732
|
+
"chr",
|
|
733
|
+
// date / time
|
|
734
|
+
"now",
|
|
735
|
+
"current_date",
|
|
736
|
+
"current_timestamp",
|
|
737
|
+
"today",
|
|
738
|
+
"date_trunc",
|
|
739
|
+
"date_part",
|
|
740
|
+
"date_diff",
|
|
741
|
+
"date_add",
|
|
742
|
+
"date_sub",
|
|
743
|
+
"age",
|
|
744
|
+
"strftime",
|
|
745
|
+
"strptime",
|
|
746
|
+
"epoch",
|
|
747
|
+
"epoch_ms",
|
|
748
|
+
"extract",
|
|
749
|
+
"make_date",
|
|
750
|
+
"make_time",
|
|
751
|
+
"make_timestamp",
|
|
752
|
+
"last_day",
|
|
753
|
+
"dayname",
|
|
754
|
+
"monthname",
|
|
755
|
+
"year",
|
|
756
|
+
"month",
|
|
757
|
+
"day",
|
|
758
|
+
"hour",
|
|
759
|
+
"minute",
|
|
760
|
+
"second",
|
|
761
|
+
"dayofweek",
|
|
762
|
+
"dayofyear",
|
|
763
|
+
"week",
|
|
764
|
+
"quarter",
|
|
765
|
+
"time_bucket",
|
|
766
|
+
// math
|
|
767
|
+
"abs",
|
|
768
|
+
"ceil",
|
|
769
|
+
"ceiling",
|
|
770
|
+
"floor",
|
|
771
|
+
"round",
|
|
772
|
+
"trunc",
|
|
773
|
+
"sign",
|
|
774
|
+
"mod",
|
|
775
|
+
"pow",
|
|
776
|
+
"power",
|
|
777
|
+
"sqrt",
|
|
778
|
+
"cbrt",
|
|
779
|
+
"exp",
|
|
780
|
+
"ln",
|
|
781
|
+
"log",
|
|
782
|
+
"log2",
|
|
783
|
+
"log10",
|
|
784
|
+
"greatest",
|
|
785
|
+
"least",
|
|
786
|
+
"gcd",
|
|
787
|
+
"lcm",
|
|
788
|
+
"factorial",
|
|
789
|
+
"random",
|
|
790
|
+
"pi",
|
|
791
|
+
"degrees",
|
|
792
|
+
"radians",
|
|
793
|
+
"sin",
|
|
794
|
+
"cos",
|
|
795
|
+
"tan",
|
|
796
|
+
"asin",
|
|
797
|
+
"acos",
|
|
798
|
+
"atan",
|
|
799
|
+
"atan2",
|
|
800
|
+
// conditional / null / cast
|
|
801
|
+
"coalesce",
|
|
802
|
+
"ifnull",
|
|
803
|
+
"nullif",
|
|
804
|
+
"nvl",
|
|
805
|
+
"if",
|
|
806
|
+
"try_cast",
|
|
807
|
+
"cast",
|
|
808
|
+
"typeof",
|
|
809
|
+
// list / struct / map / json
|
|
810
|
+
"list_value",
|
|
811
|
+
"list_aggregate",
|
|
812
|
+
"list_distinct",
|
|
813
|
+
"list_sort",
|
|
814
|
+
"list_reverse",
|
|
815
|
+
"list_slice",
|
|
816
|
+
"list_concat",
|
|
817
|
+
"list_contains",
|
|
818
|
+
"list_position",
|
|
819
|
+
"list_extract",
|
|
820
|
+
"list_transform",
|
|
821
|
+
"list_filter",
|
|
822
|
+
"unnest",
|
|
823
|
+
"array_length",
|
|
824
|
+
"array_to_string",
|
|
825
|
+
"struct_pack",
|
|
826
|
+
"struct_extract",
|
|
827
|
+
"map",
|
|
828
|
+
"map_keys",
|
|
829
|
+
"map_values",
|
|
830
|
+
"json_extract",
|
|
831
|
+
"json_extract_string",
|
|
832
|
+
"to_json",
|
|
833
|
+
"from_json",
|
|
834
|
+
"json_array_length",
|
|
835
|
+
"json_keys",
|
|
836
|
+
"generate_series",
|
|
837
|
+
"range"
|
|
838
|
+
];
|
|
839
|
+
var TYPES = [
|
|
840
|
+
"BOOLEAN",
|
|
841
|
+
"TINYINT",
|
|
842
|
+
"SMALLINT",
|
|
843
|
+
"INTEGER",
|
|
844
|
+
"BIGINT",
|
|
845
|
+
"HUGEINT",
|
|
846
|
+
"UTINYINT",
|
|
847
|
+
"USMALLINT",
|
|
848
|
+
"UINTEGER",
|
|
849
|
+
"UBIGINT",
|
|
850
|
+
"FLOAT",
|
|
851
|
+
"REAL",
|
|
852
|
+
"DOUBLE",
|
|
853
|
+
"DECIMAL",
|
|
854
|
+
"NUMERIC",
|
|
855
|
+
"VARCHAR",
|
|
856
|
+
"CHAR",
|
|
857
|
+
"TEXT",
|
|
858
|
+
"BLOB",
|
|
859
|
+
"BIT",
|
|
860
|
+
"DATE",
|
|
861
|
+
"TIME",
|
|
862
|
+
"TIMESTAMP",
|
|
863
|
+
"TIMESTAMPTZ",
|
|
864
|
+
"INTERVAL",
|
|
865
|
+
"UUID",
|
|
866
|
+
"JSON",
|
|
867
|
+
"LIST",
|
|
868
|
+
"ARRAY",
|
|
869
|
+
"STRUCT",
|
|
870
|
+
"MAP",
|
|
871
|
+
"UNION",
|
|
872
|
+
"ENUM"
|
|
873
|
+
];
|
|
874
|
+
var EXTRA_KEYWORDS = [
|
|
875
|
+
"QUALIFY",
|
|
876
|
+
"EXCLUDE",
|
|
877
|
+
"PIVOT",
|
|
878
|
+
"UNPIVOT",
|
|
879
|
+
"ASOF",
|
|
880
|
+
"POSITIONAL",
|
|
881
|
+
"SEMI",
|
|
882
|
+
"ANTI",
|
|
883
|
+
"SUMMARIZE",
|
|
884
|
+
"DISTINCT ON",
|
|
885
|
+
"GROUP BY ALL",
|
|
886
|
+
"ORDER BY ALL",
|
|
887
|
+
"USING SAMPLE"
|
|
888
|
+
];
|
|
889
|
+
function opts(labels, type, boost = 0) {
|
|
890
|
+
return labels.map((label) => ({ label, type, boost }));
|
|
891
|
+
}
|
|
892
|
+
var SNIPPETS = [
|
|
893
|
+
snippetCompletion("SELECT ${col}, count(*) AS n\nFROM data\nGROUP BY ${col}\nORDER BY n DESC", {
|
|
894
|
+
label: "group by count",
|
|
895
|
+
type: "snippet",
|
|
896
|
+
detail: "aggregate by column"
|
|
897
|
+
}),
|
|
898
|
+
snippetCompletion("SELECT *\nFROM data\nORDER BY ${col} DESC\nLIMIT 10", {
|
|
899
|
+
label: "top N",
|
|
900
|
+
type: "snippet",
|
|
901
|
+
detail: "order + limit"
|
|
902
|
+
}),
|
|
903
|
+
snippetCompletion("SELECT DISTINCT ${col}\nFROM data", {
|
|
904
|
+
label: "select distinct",
|
|
905
|
+
type: "snippet"
|
|
906
|
+
})
|
|
907
|
+
];
|
|
908
|
+
var duckdbCompletionSource = completeFromList([
|
|
909
|
+
...opts(AGGREGATES, "function", 1),
|
|
910
|
+
// boost aggregates slightly — common in analysis
|
|
911
|
+
...opts(SCALARS, "function"),
|
|
912
|
+
...opts(TYPES, "type"),
|
|
913
|
+
...opts(EXTRA_KEYWORDS, "keyword"),
|
|
914
|
+
...SNIPPETS
|
|
915
|
+
]);
|
|
639
916
|
var DEFAULT_SQL = "SELECT *\nFROM data\nLIMIT 100";
|
|
640
917
|
var renderCell = (v) => {
|
|
641
918
|
if (v == null) return "";
|
|
@@ -645,12 +922,12 @@ var renderCell = (v) => {
|
|
|
645
922
|
};
|
|
646
923
|
function SqlConsole({ columns = [], stateId, defaultColumnsOpen = false, defaultSql = DEFAULT_SQL, autoRun = false }) {
|
|
647
924
|
const { theme, runQuery } = useDashboard();
|
|
648
|
-
const [sql, setSql] = useState(defaultSql);
|
|
925
|
+
const [sql$1, setSql] = useState(defaultSql);
|
|
649
926
|
const [result, setResult] = useState(null);
|
|
650
927
|
const [error, setError] = useState(null);
|
|
651
928
|
const [running, setRunning] = useState(false);
|
|
652
929
|
const [columnsOpen, setColumnsOpen] = useState(defaultColumnsOpen);
|
|
653
|
-
const run = async (text = sql) => {
|
|
930
|
+
const run = async (text = sql$1) => {
|
|
654
931
|
if (running || !text.trim()) return;
|
|
655
932
|
setRunning(true);
|
|
656
933
|
setError(null);
|
|
@@ -669,12 +946,38 @@ function SqlConsole({ columns = [], stateId, defaultColumnsOpen = false, default
|
|
|
669
946
|
setSql(defaultSql);
|
|
670
947
|
void run(defaultSql);
|
|
671
948
|
}, [stateId, autoRun, defaultSql]);
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
}
|
|
949
|
+
const runRef = useRef(() => {
|
|
950
|
+
});
|
|
951
|
+
runRef.current = () => {
|
|
952
|
+
void run();
|
|
677
953
|
};
|
|
954
|
+
const schemaKey = columns.map((c) => c.name).join(",");
|
|
955
|
+
const extensions = useMemo(() => {
|
|
956
|
+
const sqlConfig = {
|
|
957
|
+
dialect: PostgreSQL,
|
|
958
|
+
schema: { data: columns.map((c) => c.name) },
|
|
959
|
+
defaultTable: "data",
|
|
960
|
+
upperCaseKeywords: true
|
|
961
|
+
};
|
|
962
|
+
return [
|
|
963
|
+
sql(sqlConfig),
|
|
964
|
+
autocompletion({
|
|
965
|
+
override: [
|
|
966
|
+
schemaCompletionSource(sqlConfig),
|
|
967
|
+
keywordCompletionSource(PostgreSQL, true),
|
|
968
|
+
duckdbCompletionSource
|
|
969
|
+
]
|
|
970
|
+
}),
|
|
971
|
+
EditorView.lineWrapping,
|
|
972
|
+
Prec.highest(keymap.of([
|
|
973
|
+
{ key: "Mod-Enter", run: () => {
|
|
974
|
+
runRef.current();
|
|
975
|
+
return true;
|
|
976
|
+
} },
|
|
977
|
+
{ key: "Tab", run: acceptCompletion }
|
|
978
|
+
]))
|
|
979
|
+
];
|
|
980
|
+
}, [schemaKey]);
|
|
678
981
|
const resultColumns = result?.columns || [];
|
|
679
982
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
680
983
|
/* @__PURE__ */ jsxs("div", { className: `border-b ${theme.border} bg-midnight-elevated p-3 shrink-0`, children: [
|
|
@@ -687,7 +990,7 @@ function SqlConsole({ columns = [], stateId, defaultColumnsOpen = false, default
|
|
|
687
990
|
"button",
|
|
688
991
|
{
|
|
689
992
|
onClick: () => void run(),
|
|
690
|
-
disabled: running || !sql.trim(),
|
|
993
|
+
disabled: running || !sql$1.trim(),
|
|
691
994
|
className: `flex items-center gap-1.5 px-3 py-1 border text-xs font-mono transition-colors ${running ? "border-midnight-border opacity-50" : "border-midnight-accent text-midnight-accent hover:bg-midnight-accent/10"}`,
|
|
692
995
|
children: [
|
|
693
996
|
running ? /* @__PURE__ */ jsx(Loader2, { className: "w-3.5 h-3.5 animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "w-3.5 h-3.5" }),
|
|
@@ -698,15 +1001,16 @@ function SqlConsole({ columns = [], stateId, defaultColumnsOpen = false, default
|
|
|
698
1001
|
)
|
|
699
1002
|
] }),
|
|
700
1003
|
/* @__PURE__ */ jsx(
|
|
701
|
-
|
|
1004
|
+
CodeMirror,
|
|
702
1005
|
{
|
|
703
|
-
value: sql,
|
|
704
|
-
onChange:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
placeholder: "SELECT ... FROM data"
|
|
1006
|
+
value: sql$1,
|
|
1007
|
+
onChange: setSql,
|
|
1008
|
+
extensions,
|
|
1009
|
+
theme: "dark",
|
|
1010
|
+
basicSetup: { lineNumbers: false, foldGutter: false, highlightActiveLine: false, autocompletion: false },
|
|
1011
|
+
height: "120px",
|
|
1012
|
+
placeholder: "SELECT ... FROM data",
|
|
1013
|
+
className: "border border-midnight-border text-sm overflow-hidden focus-within:border-midnight-accent"
|
|
710
1014
|
}
|
|
711
1015
|
),
|
|
712
1016
|
columns.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
|