bolt-table 0.1.36 → 0.1.38
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.mts +106 -2
- package/dist/index.d.ts +106 -2
- package/dist/index.js +1109 -137
- package/dist/index.mjs +1107 -136
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -102,6 +102,18 @@ var XIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase,
|
|
|
102
102
|
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
103
103
|
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
104
104
|
] });
|
|
105
|
+
var SparklesIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
|
|
106
|
+
/* @__PURE__ */ jsx("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }),
|
|
107
|
+
/* @__PURE__ */ jsx("path", { d: "M5 3v4" }),
|
|
108
|
+
/* @__PURE__ */ jsx("path", { d: "M19 17v4" }),
|
|
109
|
+
/* @__PURE__ */ jsx("path", { d: "M3 5h4" }),
|
|
110
|
+
/* @__PURE__ */ jsx("path", { d: "M17 19h4" })
|
|
111
|
+
] });
|
|
112
|
+
var SendIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
|
|
113
|
+
/* @__PURE__ */ jsx("path", { d: "m22 2-7 20-4-9-9-4Z" }),
|
|
114
|
+
/* @__PURE__ */ jsx("path", { d: "M22 2 11 13" })
|
|
115
|
+
] });
|
|
116
|
+
var LoaderIcon = ({ style, className }) => /* @__PURE__ */ jsx("svg", { ...svgBase, style, className, children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
|
|
105
117
|
|
|
106
118
|
// src/DraggableHeader.tsx
|
|
107
119
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -643,6 +655,298 @@ var DraggableHeader = React.memo(
|
|
|
643
655
|
DraggableHeader.displayName = "DraggableHeader";
|
|
644
656
|
var DraggableHeader_default = DraggableHeader;
|
|
645
657
|
|
|
658
|
+
// src/ai.ts
|
|
659
|
+
function detectColumnType(key, data) {
|
|
660
|
+
const values = [];
|
|
661
|
+
for (let i = 0; i < Math.min(data.length, 20); i++) {
|
|
662
|
+
const v = data[i]?.[key];
|
|
663
|
+
if (v != null) values.push(v);
|
|
664
|
+
}
|
|
665
|
+
if (values.length === 0) return { type: "unknown", sample: "" };
|
|
666
|
+
const allNumbers = values.every((v) => typeof v === "number");
|
|
667
|
+
const allBooleans = values.every((v) => typeof v === "boolean");
|
|
668
|
+
const uniqueVals = [...new Set(values.map(String))];
|
|
669
|
+
const sampleStr = uniqueVals.length <= 8 ? uniqueVals.join(", ") : uniqueVals.slice(0, 6).join(", ") + "...";
|
|
670
|
+
if (allBooleans) return { type: "boolean", sample: sampleStr };
|
|
671
|
+
if (allNumbers) {
|
|
672
|
+
const nums = values;
|
|
673
|
+
const min = Math.min(...nums);
|
|
674
|
+
const max = Math.max(...nums);
|
|
675
|
+
return { type: "number", sample: `range ${min}\u2013${max}` };
|
|
676
|
+
}
|
|
677
|
+
return { type: "string", sample: sampleStr };
|
|
678
|
+
}
|
|
679
|
+
var cachedSchema = null;
|
|
680
|
+
function buildSchemaFingerprint(columns, dataLen) {
|
|
681
|
+
return columns.filter((c) => c.key !== "__select__" && c.key !== "__expand__").map((c) => c.key).join(",") + `:${dataLen}`;
|
|
682
|
+
}
|
|
683
|
+
function buildSystemPrompt(columns, data) {
|
|
684
|
+
const fingerprint = buildSchemaFingerprint(columns, data.length);
|
|
685
|
+
if (cachedSchema?.fingerprint === fingerprint) {
|
|
686
|
+
return cachedSchema.prompt;
|
|
687
|
+
}
|
|
688
|
+
const cols = columns.filter((c) => c.key !== "__select__" && c.key !== "__expand__");
|
|
689
|
+
const schema = cols.map((c) => {
|
|
690
|
+
const key = c.dataIndex ?? c.key;
|
|
691
|
+
const title = typeof c.title === "string" ? c.title : c.key;
|
|
692
|
+
const info = detectColumnType(key, data);
|
|
693
|
+
const w = c.width ?? 150;
|
|
694
|
+
const pin = c.pinned ? `, pinned: "${c.pinned}"` : "";
|
|
695
|
+
const hidden = c.hidden ? ", hidden: true" : "";
|
|
696
|
+
const vals = info.sample ? "|vals: " + info.sample : "";
|
|
697
|
+
return ` ${c.key}|${key}|"${title}"|${info.type}|w:${w}${pin}${hidden}${vals}`;
|
|
698
|
+
}).join("\n");
|
|
699
|
+
const sample = data.slice(0, 3).map((row) => {
|
|
700
|
+
const obj = {};
|
|
701
|
+
for (const col of cols) {
|
|
702
|
+
const di = col.dataIndex ?? col.key;
|
|
703
|
+
obj[di] = row[di];
|
|
704
|
+
}
|
|
705
|
+
return obj;
|
|
706
|
+
});
|
|
707
|
+
const prompt = `Data table AI. Respond ONLY with valid JSON, no markdown/explanation.
|
|
708
|
+
|
|
709
|
+
SCHEMA (key|dataIndex|title|type|width|flags|sample):
|
|
710
|
+
${schema}
|
|
711
|
+
|
|
712
|
+
SAMPLE (${sample.length}/${data.length} rows):
|
|
713
|
+
${JSON.stringify(sample)}
|
|
714
|
+
|
|
715
|
+
COLUMN ORDER: [${cols.map((c) => `"${c.key}"`).join(",")}]
|
|
716
|
+
|
|
717
|
+
OPS (combine any):
|
|
718
|
+
filter: {type:"filter",conditions:[{column:"<dataIndex>",op:"<op>",value:<v>}],logic:"and"|"or"}
|
|
719
|
+
sort: {type:"sort",column:"<dataIndex>",direction:"asc"|"desc"}
|
|
720
|
+
rowStyle: {type:"rowStyle",conditions:[...],logic:"and"|"or",style:{cssProp:"val"}}
|
|
721
|
+
cellStyle: {type:"cellStyle",column:"<dataIndex>",conditions:[...],logic:"and"|"or",style:{cssProp:"val"}}
|
|
722
|
+
hideColumns: {type:"hideColumns",columns:["key",...]}
|
|
723
|
+
showColumns: {type:"showColumns",columns:["key",...]}
|
|
724
|
+
resizeColumn: {type:"resizeColumn",column:"<key>",width:<px>}
|
|
725
|
+
reorderColumns: {type:"reorderColumns",order:["key1","key2",...]} (full column order)
|
|
726
|
+
pinColumn: {type:"pinColumn",column:"<key>",pinned:"left"|"right"|false}
|
|
727
|
+
setPage: {type:"setPage",page:<number>}
|
|
728
|
+
|
|
729
|
+
OPS: eq,neq,gt,gte,lt,lte,contains,notContains,startsWith,endsWith,in,notIn
|
|
730
|
+
|
|
731
|
+
FORMAT: {"operations":[...],"message":"brief description"}
|
|
732
|
+
|
|
733
|
+
RULES:
|
|
734
|
+
- Use dataIndex for data ops, key for column ops (hide/show/resize/reorder/pin).
|
|
735
|
+
- Colors: semi-transparent rgba. CSS props: camelCase.
|
|
736
|
+
- reorderColumns: provide FULL ordered array of ALL visible column keys.
|
|
737
|
+
- resizeColumn width: integer pixels (min 40, max 800).
|
|
738
|
+
- Combine multiple ops freely. Message: concise plain English.`;
|
|
739
|
+
cachedSchema = { fingerprint, prompt };
|
|
740
|
+
return prompt;
|
|
741
|
+
}
|
|
742
|
+
async function callAI(config, systemPrompt, userQuery) {
|
|
743
|
+
const { provider, apiKey, model, baseUrl, maxTokens = 1024, temperature = 0.1 } = config;
|
|
744
|
+
if (provider === "openai" || provider === "custom") {
|
|
745
|
+
const url = baseUrl ? `${baseUrl.replace(/\/$/, "")}/chat/completions` : "https://api.openai.com/v1/chat/completions";
|
|
746
|
+
const res = await fetch(url, {
|
|
747
|
+
method: "POST",
|
|
748
|
+
headers: {
|
|
749
|
+
"Content-Type": "application/json",
|
|
750
|
+
Authorization: `Bearer ${apiKey}`
|
|
751
|
+
},
|
|
752
|
+
body: JSON.stringify({
|
|
753
|
+
model: model ?? "gpt-4o-mini",
|
|
754
|
+
messages: [
|
|
755
|
+
{ role: "system", content: systemPrompt },
|
|
756
|
+
{ role: "user", content: userQuery }
|
|
757
|
+
],
|
|
758
|
+
max_tokens: maxTokens,
|
|
759
|
+
temperature
|
|
760
|
+
})
|
|
761
|
+
});
|
|
762
|
+
if (!res.ok) {
|
|
763
|
+
const body = await res.text().catch(() => "");
|
|
764
|
+
throw new Error(`AI request failed (${res.status}): ${body}`);
|
|
765
|
+
}
|
|
766
|
+
const json = await res.json();
|
|
767
|
+
return json.choices?.[0]?.message?.content ?? "";
|
|
768
|
+
}
|
|
769
|
+
if (provider === "anthropic") {
|
|
770
|
+
const url = baseUrl ? `${baseUrl.replace(/\/$/, "")}/messages` : "https://api.anthropic.com/v1/messages";
|
|
771
|
+
const res = await fetch(url, {
|
|
772
|
+
method: "POST",
|
|
773
|
+
headers: {
|
|
774
|
+
"Content-Type": "application/json",
|
|
775
|
+
"x-api-key": apiKey,
|
|
776
|
+
"anthropic-version": "2023-06-01",
|
|
777
|
+
"anthropic-dangerous-direct-browser-access": "true"
|
|
778
|
+
},
|
|
779
|
+
body: JSON.stringify({
|
|
780
|
+
model: model ?? "claude-sonnet-4-20250514",
|
|
781
|
+
system: systemPrompt,
|
|
782
|
+
messages: [{ role: "user", content: userQuery }],
|
|
783
|
+
max_tokens: maxTokens,
|
|
784
|
+
temperature
|
|
785
|
+
})
|
|
786
|
+
});
|
|
787
|
+
if (!res.ok) {
|
|
788
|
+
const body = await res.text().catch(() => "");
|
|
789
|
+
throw new Error(`AI request failed (${res.status}): ${body}`);
|
|
790
|
+
}
|
|
791
|
+
const json = await res.json();
|
|
792
|
+
const textBlock = json.content?.find(
|
|
793
|
+
(b) => b.type === "text"
|
|
794
|
+
);
|
|
795
|
+
return textBlock?.text ?? "";
|
|
796
|
+
}
|
|
797
|
+
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
798
|
+
}
|
|
799
|
+
function parseAIResponse(raw) {
|
|
800
|
+
let text = raw.trim();
|
|
801
|
+
const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
802
|
+
if (fenceMatch) text = fenceMatch[1].trim();
|
|
803
|
+
const start = text.indexOf("{");
|
|
804
|
+
const end = text.lastIndexOf("}");
|
|
805
|
+
if (start !== -1 && end > start) {
|
|
806
|
+
text = text.slice(start, end + 1);
|
|
807
|
+
}
|
|
808
|
+
const parsed = JSON.parse(text);
|
|
809
|
+
if (!parsed.operations || !Array.isArray(parsed.operations)) {
|
|
810
|
+
throw new Error("Invalid AI response: missing operations array");
|
|
811
|
+
}
|
|
812
|
+
return {
|
|
813
|
+
operations: parsed.operations,
|
|
814
|
+
message: parsed.message ?? "AI operations applied."
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function evaluateCondition(condition, row) {
|
|
818
|
+
const rawVal = row[condition.column];
|
|
819
|
+
const target = condition.value;
|
|
820
|
+
switch (condition.op) {
|
|
821
|
+
case "eq":
|
|
822
|
+
return rawVal == target;
|
|
823
|
+
case "neq":
|
|
824
|
+
return rawVal != target;
|
|
825
|
+
case "gt":
|
|
826
|
+
return Number(rawVal) > Number(target);
|
|
827
|
+
case "gte":
|
|
828
|
+
return Number(rawVal) >= Number(target);
|
|
829
|
+
case "lt":
|
|
830
|
+
return Number(rawVal) < Number(target);
|
|
831
|
+
case "lte":
|
|
832
|
+
return Number(rawVal) <= Number(target);
|
|
833
|
+
case "contains":
|
|
834
|
+
return String(rawVal ?? "").toLowerCase().includes(String(target).toLowerCase());
|
|
835
|
+
case "notContains":
|
|
836
|
+
return !String(rawVal ?? "").toLowerCase().includes(String(target).toLowerCase());
|
|
837
|
+
case "startsWith":
|
|
838
|
+
return String(rawVal ?? "").toLowerCase().startsWith(String(target).toLowerCase());
|
|
839
|
+
case "endsWith":
|
|
840
|
+
return String(rawVal ?? "").toLowerCase().endsWith(String(target).toLowerCase());
|
|
841
|
+
case "in":
|
|
842
|
+
if (Array.isArray(target)) {
|
|
843
|
+
return target.some((t) => rawVal == t);
|
|
844
|
+
}
|
|
845
|
+
return false;
|
|
846
|
+
case "notIn":
|
|
847
|
+
if (Array.isArray(target)) {
|
|
848
|
+
return !target.some((t) => rawVal == t);
|
|
849
|
+
}
|
|
850
|
+
return true;
|
|
851
|
+
default:
|
|
852
|
+
return true;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
function matchesConditions(conditions, logic, row) {
|
|
856
|
+
if (!conditions || conditions.length === 0) return true;
|
|
857
|
+
if (logic === "or") {
|
|
858
|
+
return conditions.some((c) => evaluateCondition(c, row));
|
|
859
|
+
}
|
|
860
|
+
return conditions.every((c) => evaluateCondition(c, row));
|
|
861
|
+
}
|
|
862
|
+
function applyAIFilter(data, op) {
|
|
863
|
+
return data.filter((row) => matchesConditions(op.conditions, op.logic, row));
|
|
864
|
+
}
|
|
865
|
+
function applyAISort(data, op) {
|
|
866
|
+
const dir = op.direction === "asc" ? 1 : -1;
|
|
867
|
+
const col = op.column;
|
|
868
|
+
return [...data].sort((a, b) => {
|
|
869
|
+
const aVal = a[col];
|
|
870
|
+
const bVal = b[col];
|
|
871
|
+
if (aVal == null && bVal == null) return 0;
|
|
872
|
+
if (aVal == null) return 1;
|
|
873
|
+
if (bVal == null) return -1;
|
|
874
|
+
if (typeof aVal === "number" && typeof bVal === "number")
|
|
875
|
+
return (aVal - bVal) * dir;
|
|
876
|
+
return String(aVal).localeCompare(String(bVal)) * dir;
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
function getAIRowStyle(row, ops) {
|
|
880
|
+
let merged;
|
|
881
|
+
for (const op of ops) {
|
|
882
|
+
if (matchesConditions(op.conditions, op.logic, row)) {
|
|
883
|
+
if (!merged) merged = {};
|
|
884
|
+
Object.assign(merged, op.style);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return merged;
|
|
888
|
+
}
|
|
889
|
+
function getAICellStyle(row, columnKey, ops) {
|
|
890
|
+
let merged;
|
|
891
|
+
for (const op of ops) {
|
|
892
|
+
if (op.column === columnKey && matchesConditions(op.conditions, op.logic, row)) {
|
|
893
|
+
if (!merged) merged = {};
|
|
894
|
+
Object.assign(merged, op.style);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return merged;
|
|
898
|
+
}
|
|
899
|
+
function applyAIOperations(data, operations) {
|
|
900
|
+
let filteredData = data;
|
|
901
|
+
let sortOp = null;
|
|
902
|
+
const styleOps = [];
|
|
903
|
+
const cellStyleOps = [];
|
|
904
|
+
const hideColumns = [];
|
|
905
|
+
const showColumns = [];
|
|
906
|
+
const resizeOps = [];
|
|
907
|
+
let reorderOp = null;
|
|
908
|
+
const pinOps = [];
|
|
909
|
+
let setPageOp = null;
|
|
910
|
+
for (const op of operations) {
|
|
911
|
+
switch (op.type) {
|
|
912
|
+
case "filter":
|
|
913
|
+
filteredData = applyAIFilter(filteredData, op);
|
|
914
|
+
break;
|
|
915
|
+
case "sort":
|
|
916
|
+
sortOp = op;
|
|
917
|
+
break;
|
|
918
|
+
case "rowStyle":
|
|
919
|
+
styleOps.push(op);
|
|
920
|
+
break;
|
|
921
|
+
case "cellStyle":
|
|
922
|
+
cellStyleOps.push(op);
|
|
923
|
+
break;
|
|
924
|
+
case "hideColumns":
|
|
925
|
+
hideColumns.push(...op.columns);
|
|
926
|
+
break;
|
|
927
|
+
case "showColumns":
|
|
928
|
+
showColumns.push(...op.columns);
|
|
929
|
+
break;
|
|
930
|
+
case "resizeColumn":
|
|
931
|
+
resizeOps.push(op);
|
|
932
|
+
break;
|
|
933
|
+
case "reorderColumns":
|
|
934
|
+
reorderOp = op;
|
|
935
|
+
break;
|
|
936
|
+
case "pinColumn":
|
|
937
|
+
pinOps.push(op);
|
|
938
|
+
break;
|
|
939
|
+
case "setPage":
|
|
940
|
+
setPageOp = op;
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (sortOp) {
|
|
945
|
+
filteredData = applyAISort(filteredData, sortOp);
|
|
946
|
+
}
|
|
947
|
+
return { filteredData, sortOp, styleOps, cellStyleOps, hideColumns, showColumns, resizeOps, reorderOp, pinOps, setPageOp };
|
|
948
|
+
}
|
|
949
|
+
|
|
646
950
|
// src/ResizeOverlay.tsx
|
|
647
951
|
import { forwardRef, useImperativeHandle, useRef as useRef2 } from "react";
|
|
648
952
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -870,9 +1174,11 @@ var Cell = React3.memo(
|
|
|
870
1174
|
isLoading,
|
|
871
1175
|
onEdit,
|
|
872
1176
|
isEditing,
|
|
873
|
-
onEditComplete
|
|
1177
|
+
onEditComplete,
|
|
1178
|
+
cellStyleFn
|
|
874
1179
|
}) => {
|
|
875
1180
|
const isPinned = Boolean(column.pinned);
|
|
1181
|
+
const extraCellStyle = cellStyleFn?.(record, column.dataIndex ?? column.key);
|
|
876
1182
|
if (isLoading && column.key !== "__select__" && column.key !== "__expand__") {
|
|
877
1183
|
const shimmerContent = column.shimmerRender ? column.shimmerRender() : /* @__PURE__ */ jsx4(
|
|
878
1184
|
"div",
|
|
@@ -1024,7 +1330,8 @@ var Cell = React3.memo(
|
|
|
1024
1330
|
minWidth: 0,
|
|
1025
1331
|
...column.style,
|
|
1026
1332
|
...isPinned ? styles?.pinnedCell : void 0,
|
|
1027
|
-
...styles?.cell
|
|
1333
|
+
...styles?.cell,
|
|
1334
|
+
...extraCellStyle
|
|
1028
1335
|
},
|
|
1029
1336
|
children: isSystem ? content : showEditor ? content : /* @__PURE__ */ jsx4(
|
|
1030
1337
|
"div",
|
|
@@ -1051,6 +1358,7 @@ var Cell = React3.memo(
|
|
|
1051
1358
|
if (prev.onEdit !== next.onEdit) return false;
|
|
1052
1359
|
if (prev.isEditing !== next.isEditing) return false;
|
|
1053
1360
|
if (prev.onEditComplete !== next.onEditComplete) return false;
|
|
1361
|
+
if (prev.cellStyleFn !== next.cellStyleFn) return false;
|
|
1054
1362
|
if (prev.column.key === "__select__") {
|
|
1055
1363
|
return prev.isSelected === next.isSelected && prev.normalizedSelectedKeys === next.normalizedSelectedKeys;
|
|
1056
1364
|
}
|
|
@@ -1152,7 +1460,8 @@ var TableBody = ({
|
|
|
1152
1460
|
onEditComplete,
|
|
1153
1461
|
enableDynamicRowHeight = false,
|
|
1154
1462
|
onRowHeightChange,
|
|
1155
|
-
columnGridIndexMap
|
|
1463
|
+
columnGridIndexMap,
|
|
1464
|
+
cellStyleFn
|
|
1156
1465
|
}) => {
|
|
1157
1466
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1158
1467
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
@@ -1281,7 +1590,8 @@ var TableBody = ({
|
|
|
1281
1590
|
recordFingerprint,
|
|
1282
1591
|
onEdit,
|
|
1283
1592
|
isEditing: editingCell?.rowKey === rowKey && editingCell?.columnKey === col.key,
|
|
1284
|
-
onEditComplete
|
|
1593
|
+
onEditComplete,
|
|
1594
|
+
cellStyleFn
|
|
1285
1595
|
}
|
|
1286
1596
|
)
|
|
1287
1597
|
}
|
|
@@ -1318,7 +1628,8 @@ var TableBody = ({
|
|
|
1318
1628
|
recordFingerprint,
|
|
1319
1629
|
onEdit,
|
|
1320
1630
|
isEditing: editingCell?.rowKey === rowKey && editingCell?.columnKey === col.key,
|
|
1321
|
-
onEditComplete
|
|
1631
|
+
onEditComplete,
|
|
1632
|
+
cellStyleFn
|
|
1322
1633
|
}
|
|
1323
1634
|
)
|
|
1324
1635
|
}
|
|
@@ -1508,7 +1819,8 @@ var TableBody = ({
|
|
|
1508
1819
|
recordFingerprint,
|
|
1509
1820
|
onEdit,
|
|
1510
1821
|
isEditing: editingCell?.rowKey === rk && editingCell?.columnKey === col.key,
|
|
1511
|
-
onEditComplete
|
|
1822
|
+
onEditComplete,
|
|
1823
|
+
cellStyleFn
|
|
1512
1824
|
}
|
|
1513
1825
|
)
|
|
1514
1826
|
}
|
|
@@ -1636,7 +1948,8 @@ var TableBody = ({
|
|
|
1636
1948
|
recordFingerprint,
|
|
1637
1949
|
onEdit,
|
|
1638
1950
|
isEditing: editingCell?.rowKey === rk && editingCell?.columnKey === col.key,
|
|
1639
|
-
onEditComplete
|
|
1951
|
+
onEditComplete,
|
|
1952
|
+
cellStyleFn
|
|
1640
1953
|
}
|
|
1641
1954
|
)
|
|
1642
1955
|
}
|
|
@@ -1731,7 +2044,13 @@ function BoltTable({
|
|
|
1731
2044
|
globalSearchValue,
|
|
1732
2045
|
onGlobalSearchChange,
|
|
1733
2046
|
toolbarContent,
|
|
1734
|
-
columnSettingsLabel
|
|
2047
|
+
columnSettingsLabel,
|
|
2048
|
+
aiMode = false,
|
|
2049
|
+
aiConfig,
|
|
2050
|
+
onAIQuery,
|
|
2051
|
+
onAIResponse,
|
|
2052
|
+
aiPlaceholder = "Ask AI anything about your data...",
|
|
2053
|
+
aiButtonLabel
|
|
1735
2054
|
}) {
|
|
1736
2055
|
const data = useMemo2(() => {
|
|
1737
2056
|
if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
|
|
@@ -1905,6 +2224,213 @@ function BoltTable({
|
|
|
1905
2224
|
document.removeEventListener("keydown", onKey);
|
|
1906
2225
|
};
|
|
1907
2226
|
}, [showColumnPicker]);
|
|
2227
|
+
const [aiBarOpen, setAiBarOpen] = useState3(false);
|
|
2228
|
+
const [aiQuery, setAiQuery] = useState3("");
|
|
2229
|
+
const [aiLoading, setAiLoading] = useState3(false);
|
|
2230
|
+
const [aiResult, setAiResult] = useState3(null);
|
|
2231
|
+
const [aiError, setAiError] = useState3(null);
|
|
2232
|
+
const aiInputRef = useRef4(null);
|
|
2233
|
+
const [aiStyleOps, setAiStyleOps] = useState3([]);
|
|
2234
|
+
const [aiCellStyleOps, setAiCellStyleOps] = useState3(
|
|
2235
|
+
[]
|
|
2236
|
+
);
|
|
2237
|
+
const [aiFilteredDataKeys, setAiFilteredDataKeys] = useState3(null);
|
|
2238
|
+
const [aiSortKey, setAiSortKey] = useState3(null);
|
|
2239
|
+
const [aiSortDir, setAiSortDir] = useState3(null);
|
|
2240
|
+
const aiFiltersStorageKey = columnPersistence && typeof columnPersistence === "object" ? `bt-ai-filters-${columnPersistence.storageKey}` : "bt-ai-filters";
|
|
2241
|
+
const [savedAIFilters, setSavedAIFilters] = useState3(() => {
|
|
2242
|
+
try {
|
|
2243
|
+
const raw = localStorage.getItem(aiFiltersStorageKey);
|
|
2244
|
+
return raw ? JSON.parse(raw) : [];
|
|
2245
|
+
} catch {
|
|
2246
|
+
return [];
|
|
2247
|
+
}
|
|
2248
|
+
});
|
|
2249
|
+
const [showSavedFilters, setShowSavedFilters] = useState3(false);
|
|
2250
|
+
const savedFiltersRef = useRef4(null);
|
|
2251
|
+
React4.useEffect(() => {
|
|
2252
|
+
if (!showSavedFilters) return;
|
|
2253
|
+
const close = (e) => {
|
|
2254
|
+
if (savedFiltersRef.current && !savedFiltersRef.current.contains(e.target)) {
|
|
2255
|
+
setShowSavedFilters(false);
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
document.addEventListener("mousedown", close);
|
|
2259
|
+
return () => document.removeEventListener("mousedown", close);
|
|
2260
|
+
}, [showSavedFilters]);
|
|
2261
|
+
const saveCurrentAIFilter = useCallback2(() => {
|
|
2262
|
+
if (!aiResult) return;
|
|
2263
|
+
const label = aiQuery || aiResult.message;
|
|
2264
|
+
const entry = { label, operations: aiResult.operations, query: aiQuery };
|
|
2265
|
+
const next = [...savedAIFilters, entry];
|
|
2266
|
+
setSavedAIFilters(next);
|
|
2267
|
+
try {
|
|
2268
|
+
localStorage.setItem(aiFiltersStorageKey, JSON.stringify(next));
|
|
2269
|
+
} catch {
|
|
2270
|
+
}
|
|
2271
|
+
}, [aiResult, aiQuery, savedAIFilters, aiFiltersStorageKey]);
|
|
2272
|
+
const removeSavedFilter = useCallback2((index) => {
|
|
2273
|
+
const next = savedAIFilters.filter((_, i) => i !== index);
|
|
2274
|
+
setSavedAIFilters(next);
|
|
2275
|
+
try {
|
|
2276
|
+
localStorage.setItem(aiFiltersStorageKey, JSON.stringify(next));
|
|
2277
|
+
} catch {
|
|
2278
|
+
}
|
|
2279
|
+
}, [savedAIFilters, aiFiltersStorageKey]);
|
|
2280
|
+
const applySavedFilter = useCallback2((filter) => {
|
|
2281
|
+
const { filteredData, sortOp, styleOps: sOps, cellStyleOps: csOps, hideColumns: hideCols, showColumns: showCols, resizeOps, reorderOp, pinOps, setPageOp } = applyAIOperations(data, filter.operations);
|
|
2282
|
+
setAiStyleOps(sOps);
|
|
2283
|
+
setAiCellStyleOps(csOps);
|
|
2284
|
+
if (filter.operations.some((op) => op.type === "filter")) {
|
|
2285
|
+
const keySet = /* @__PURE__ */ new Set();
|
|
2286
|
+
filteredData.forEach((row, idx) => {
|
|
2287
|
+
const k = typeof rowKey === "function" ? rowKey(row) : String(row[typeof rowKey === "string" ? rowKey : "id"] ?? idx);
|
|
2288
|
+
keySet.add(k);
|
|
2289
|
+
});
|
|
2290
|
+
setAiFilteredDataKeys(keySet);
|
|
2291
|
+
} else {
|
|
2292
|
+
setAiFilteredDataKeys(null);
|
|
2293
|
+
}
|
|
2294
|
+
if (sortOp) {
|
|
2295
|
+
setAiSortKey(sortOp.column);
|
|
2296
|
+
setAiSortDir(sortOp.direction);
|
|
2297
|
+
} else {
|
|
2298
|
+
setAiSortKey(null);
|
|
2299
|
+
setAiSortDir(null);
|
|
2300
|
+
}
|
|
2301
|
+
if (hideCols.length > 0 || showCols.length > 0) {
|
|
2302
|
+
setColumns(
|
|
2303
|
+
(prev) => prev.map((col) => {
|
|
2304
|
+
if (hideCols.includes(col.key)) return { ...col, hidden: true };
|
|
2305
|
+
if (showCols.includes(col.key)) return { ...col, hidden: false };
|
|
2306
|
+
return col;
|
|
2307
|
+
})
|
|
2308
|
+
);
|
|
2309
|
+
}
|
|
2310
|
+
for (const rOp of resizeOps) {
|
|
2311
|
+
const w = Math.max(40, Math.min(800, rOp.width));
|
|
2312
|
+
setColumnWidths((prev) => {
|
|
2313
|
+
const n = new Map(prev);
|
|
2314
|
+
n.set(rOp.column, w);
|
|
2315
|
+
return n;
|
|
2316
|
+
});
|
|
2317
|
+
onColumnResize?.(rOp.column, w);
|
|
2318
|
+
}
|
|
2319
|
+
if (reorderOp) {
|
|
2320
|
+
setColumnOrder(reorderOp.order);
|
|
2321
|
+
onColumnOrderChange?.(reorderOp.order);
|
|
2322
|
+
}
|
|
2323
|
+
for (const pOp of pinOps) {
|
|
2324
|
+
setColumns(
|
|
2325
|
+
(prev) => prev.map((col) => col.key === pOp.column ? { ...col, pinned: pOp.pinned } : col)
|
|
2326
|
+
);
|
|
2327
|
+
onColumnPin?.(pOp.column, pOp.pinned);
|
|
2328
|
+
}
|
|
2329
|
+
if (setPageOp) {
|
|
2330
|
+
setInternalPage(setPageOp.page);
|
|
2331
|
+
}
|
|
2332
|
+
setAiResult({ operations: filter.operations, message: `Applied saved filter: ${filter.label}` });
|
|
2333
|
+
setShowSavedFilters(false);
|
|
2334
|
+
}, [data, rowKey, onColumnResize, onColumnOrderChange, onColumnPin]);
|
|
2335
|
+
const onAIResponseRef = useRef4(onAIResponse);
|
|
2336
|
+
onAIResponseRef.current = onAIResponse;
|
|
2337
|
+
const handleAISubmit = useCallback2(async () => {
|
|
2338
|
+
const query = aiQuery.trim();
|
|
2339
|
+
if (!query) return;
|
|
2340
|
+
setAiLoading(true);
|
|
2341
|
+
setAiError(null);
|
|
2342
|
+
try {
|
|
2343
|
+
let response;
|
|
2344
|
+
if (onAIQuery) {
|
|
2345
|
+
response = await onAIQuery(query, {
|
|
2346
|
+
data,
|
|
2347
|
+
columns: initialColumns
|
|
2348
|
+
});
|
|
2349
|
+
} else if (aiConfig) {
|
|
2350
|
+
const sysPrompt = buildSystemPrompt(initialColumns, data);
|
|
2351
|
+
const raw = await callAI(aiConfig, sysPrompt, query);
|
|
2352
|
+
response = parseAIResponse(raw);
|
|
2353
|
+
} else {
|
|
2354
|
+
throw new Error("AI mode requires either aiConfig or onAIQuery prop");
|
|
2355
|
+
}
|
|
2356
|
+
const { filteredData, sortOp, styleOps: sOps, cellStyleOps: csOps, hideColumns: hideCols, showColumns: showCols, resizeOps, reorderOp, pinOps, setPageOp } = applyAIOperations(data, response.operations);
|
|
2357
|
+
setAiStyleOps(sOps);
|
|
2358
|
+
setAiCellStyleOps(csOps);
|
|
2359
|
+
if (response.operations.some((op) => op.type === "filter")) {
|
|
2360
|
+
const keySet = /* @__PURE__ */ new Set();
|
|
2361
|
+
filteredData.forEach((row, idx) => {
|
|
2362
|
+
const k = typeof rowKey === "function" ? rowKey(row) : String(row[typeof rowKey === "string" ? rowKey : "id"] ?? idx);
|
|
2363
|
+
keySet.add(k);
|
|
2364
|
+
});
|
|
2365
|
+
setAiFilteredDataKeys(keySet);
|
|
2366
|
+
} else {
|
|
2367
|
+
setAiFilteredDataKeys(null);
|
|
2368
|
+
}
|
|
2369
|
+
if (sortOp) {
|
|
2370
|
+
setAiSortKey(sortOp.column);
|
|
2371
|
+
setAiSortDir(sortOp.direction);
|
|
2372
|
+
} else {
|
|
2373
|
+
setAiSortKey(null);
|
|
2374
|
+
setAiSortDir(null);
|
|
2375
|
+
}
|
|
2376
|
+
if (hideCols.length > 0 || showCols.length > 0) {
|
|
2377
|
+
setColumns(
|
|
2378
|
+
(prev) => prev.map((col) => {
|
|
2379
|
+
if (hideCols.includes(col.key)) return { ...col, hidden: true };
|
|
2380
|
+
if (showCols.includes(col.key)) return { ...col, hidden: false };
|
|
2381
|
+
return col;
|
|
2382
|
+
})
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2385
|
+
for (const rOp of resizeOps) {
|
|
2386
|
+
const w = Math.max(40, Math.min(800, rOp.width));
|
|
2387
|
+
setColumnWidths((prev) => {
|
|
2388
|
+
const n = new Map(prev);
|
|
2389
|
+
n.set(rOp.column, w);
|
|
2390
|
+
return n;
|
|
2391
|
+
});
|
|
2392
|
+
onColumnResize?.(rOp.column, w);
|
|
2393
|
+
}
|
|
2394
|
+
if (reorderOp) {
|
|
2395
|
+
setColumnOrder(reorderOp.order);
|
|
2396
|
+
onColumnOrderChange?.(reorderOp.order);
|
|
2397
|
+
}
|
|
2398
|
+
for (const pOp of pinOps) {
|
|
2399
|
+
setColumns(
|
|
2400
|
+
(prev) => prev.map((col) => col.key === pOp.column ? { ...col, pinned: pOp.pinned } : col)
|
|
2401
|
+
);
|
|
2402
|
+
onColumnPin?.(pOp.column, pOp.pinned);
|
|
2403
|
+
}
|
|
2404
|
+
if (setPageOp) {
|
|
2405
|
+
setInternalPage(setPageOp.page);
|
|
2406
|
+
}
|
|
2407
|
+
setAiResult(response);
|
|
2408
|
+
onAIResponseRef.current?.(response);
|
|
2409
|
+
} catch (err) {
|
|
2410
|
+
setAiError(err instanceof Error ? err.message : "AI query failed");
|
|
2411
|
+
} finally {
|
|
2412
|
+
setAiLoading(false);
|
|
2413
|
+
}
|
|
2414
|
+
}, [aiQuery, aiConfig, onAIQuery, data, initialColumns, rowKey]);
|
|
2415
|
+
const handleAIClear = useCallback2(() => {
|
|
2416
|
+
setAiResult(null);
|
|
2417
|
+
setAiError(null);
|
|
2418
|
+
setAiStyleOps([]);
|
|
2419
|
+
setAiCellStyleOps([]);
|
|
2420
|
+
setAiFilteredDataKeys(null);
|
|
2421
|
+
setAiSortKey(null);
|
|
2422
|
+
setAiSortDir(null);
|
|
2423
|
+
setAiQuery("");
|
|
2424
|
+
}, []);
|
|
2425
|
+
const handleAIBarClose = useCallback2(() => {
|
|
2426
|
+
setAiBarOpen(false);
|
|
2427
|
+
handleAIClear();
|
|
2428
|
+
}, [handleAIClear]);
|
|
2429
|
+
React4.useEffect(() => {
|
|
2430
|
+
if (aiBarOpen && aiInputRef.current) {
|
|
2431
|
+
setTimeout(() => aiInputRef.current?.focus(), 300);
|
|
2432
|
+
}
|
|
2433
|
+
}, [aiBarOpen]);
|
|
1908
2434
|
const columnsWithPersistedWidths = useMemo2(
|
|
1909
2435
|
() => columns.map((col) => ({
|
|
1910
2436
|
...col,
|
|
@@ -2546,6 +3072,47 @@ function BoltTable({
|
|
|
2546
3072
|
}
|
|
2547
3073
|
return result;
|
|
2548
3074
|
}, [data, sortState, columnFilters, globalSearchValue, internalGlobalSearch]);
|
|
3075
|
+
const aiProcessedData = useMemo2(() => {
|
|
3076
|
+
let result = processedData;
|
|
3077
|
+
if (aiFilteredDataKeys) {
|
|
3078
|
+
result = result.filter((row, idx) => {
|
|
3079
|
+
if (row == null) return false;
|
|
3080
|
+
const k = typeof rowKey === "function" ? rowKey(row) : String(
|
|
3081
|
+
row[typeof rowKey === "string" ? rowKey : "id"] ?? idx
|
|
3082
|
+
);
|
|
3083
|
+
return aiFilteredDataKeys.has(k);
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
if (aiSortKey && aiSortDir) {
|
|
3087
|
+
const dir = aiSortDir === "asc" ? 1 : -1;
|
|
3088
|
+
const col = aiSortKey;
|
|
3089
|
+
result = [...result].sort((a, b) => {
|
|
3090
|
+
const aVal = a[col];
|
|
3091
|
+
const bVal = b[col];
|
|
3092
|
+
if (aVal == null && bVal == null) return 0;
|
|
3093
|
+
if (aVal == null) return 1;
|
|
3094
|
+
if (bVal == null) return -1;
|
|
3095
|
+
if (typeof aVal === "number" && typeof bVal === "number")
|
|
3096
|
+
return (aVal - bVal) * dir;
|
|
3097
|
+
return String(aVal).localeCompare(String(bVal)) * dir;
|
|
3098
|
+
});
|
|
3099
|
+
}
|
|
3100
|
+
return result;
|
|
3101
|
+
}, [processedData, aiFilteredDataKeys, aiSortKey, aiSortDir, rowKey]);
|
|
3102
|
+
const getAIRowStyleForRecord = useCallback2(
|
|
3103
|
+
(record) => {
|
|
3104
|
+
if (aiStyleOps.length === 0) return void 0;
|
|
3105
|
+
return getAIRowStyle(record, aiStyleOps);
|
|
3106
|
+
},
|
|
3107
|
+
[aiStyleOps]
|
|
3108
|
+
);
|
|
3109
|
+
const getAICellStyleForRecord = useCallback2(
|
|
3110
|
+
(record, columnKey) => {
|
|
3111
|
+
if (aiCellStyleOps.length === 0) return void 0;
|
|
3112
|
+
return getAICellStyle(record, columnKey, aiCellStyleOps);
|
|
3113
|
+
},
|
|
3114
|
+
[aiCellStyleOps]
|
|
3115
|
+
);
|
|
2549
3116
|
const pinnedRowCacheRef = useRef4(/* @__PURE__ */ new Map());
|
|
2550
3117
|
const { pinnedTopRows, pinnedBottomRows, unpinnedProcessedData } = useMemo2(() => {
|
|
2551
3118
|
if (!resolvedRowPinning || !resolvedRowPinning.top?.length && !resolvedRowPinning.bottom?.length) {
|
|
@@ -2553,7 +3120,7 @@ function BoltTable({
|
|
|
2553
3120
|
return {
|
|
2554
3121
|
pinnedTopRows: [],
|
|
2555
3122
|
pinnedBottomRows: [],
|
|
2556
|
-
unpinnedProcessedData:
|
|
3123
|
+
unpinnedProcessedData: aiProcessedData
|
|
2557
3124
|
};
|
|
2558
3125
|
}
|
|
2559
3126
|
const topKeySet = new Set((resolvedRowPinning.top ?? []).map(String));
|
|
@@ -2563,7 +3130,7 @@ function BoltTable({
|
|
|
2563
3130
|
const topMap = /* @__PURE__ */ new Map();
|
|
2564
3131
|
const bottomMap = /* @__PURE__ */ new Map();
|
|
2565
3132
|
const rest = [];
|
|
2566
|
-
|
|
3133
|
+
aiProcessedData.forEach((row, idx) => {
|
|
2567
3134
|
if (row == null) return;
|
|
2568
3135
|
const key = getSafeRowKey(row, idx);
|
|
2569
3136
|
if (topKeySet.has(key)) {
|
|
@@ -2603,7 +3170,7 @@ function BoltTable({
|
|
|
2603
3170
|
unpinnedProcessedData: rest
|
|
2604
3171
|
};
|
|
2605
3172
|
}, [
|
|
2606
|
-
|
|
3173
|
+
aiProcessedData,
|
|
2607
3174
|
resolvedRowPinning,
|
|
2608
3175
|
getSafeRowKey,
|
|
2609
3176
|
keepPinnedRowsAcrossPages
|
|
@@ -2672,7 +3239,7 @@ function BoltTable({
|
|
|
2672
3239
|
return unpinnedProcessedData.slice(start, start + pgSize);
|
|
2673
3240
|
}, [unpinnedProcessedData, needsClientPagination, pgCurrent, pgSize]);
|
|
2674
3241
|
const shimmerCount = pgEnabled ? pgSize : 15;
|
|
2675
|
-
const showShimmer = isLoading &&
|
|
3242
|
+
const showShimmer = isLoading && aiProcessedData.length === 0;
|
|
2676
3243
|
const shimmerRowKeyField = typeof rowKey === "string" ? rowKey : "id";
|
|
2677
3244
|
const shimmerData = useMemo2(() => {
|
|
2678
3245
|
if (!showShimmer) return null;
|
|
@@ -2956,49 +3523,395 @@ function BoltTable({
|
|
|
2956
3523
|
border: 1px dashed ${accentColor} !important;
|
|
2957
3524
|
}
|
|
2958
3525
|
${onRowClick ? "[data-bt-cell] { cursor: pointer; }" : ""}
|
|
3526
|
+
@keyframes bt-spin { to { transform: rotate(360deg); } }
|
|
3527
|
+
@keyframes bt-ai-shimmer {
|
|
3528
|
+
0% { background-position: -200% 0; }
|
|
3529
|
+
100% { background-position: 200% 0; }
|
|
3530
|
+
}
|
|
2959
3531
|
` }),
|
|
2960
|
-
(!hideGlobalSearch || showColumnSettings) && /* @__PURE__ */ jsxs5(
|
|
3532
|
+
(!hideGlobalSearch || showColumnSettings || aiMode) && /* @__PURE__ */ jsxs5(
|
|
2961
3533
|
"div",
|
|
2962
3534
|
{
|
|
2963
3535
|
style: {
|
|
3536
|
+
position: "relative",
|
|
2964
3537
|
display: "flex",
|
|
2965
3538
|
alignItems: "center",
|
|
2966
3539
|
gap: 8,
|
|
2967
3540
|
padding: "6px 8px",
|
|
2968
3541
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2969
3542
|
fontSize: 12,
|
|
2970
|
-
flexShrink: 0
|
|
3543
|
+
flexShrink: 0,
|
|
3544
|
+
zIndex: 20
|
|
2971
3545
|
},
|
|
2972
3546
|
children: [
|
|
2973
|
-
|
|
3547
|
+
/* @__PURE__ */ jsxs5(
|
|
2974
3548
|
"div",
|
|
2975
3549
|
{
|
|
2976
3550
|
style: {
|
|
2977
3551
|
display: "flex",
|
|
2978
3552
|
alignItems: "center",
|
|
2979
|
-
gap:
|
|
3553
|
+
gap: 8,
|
|
2980
3554
|
flex: "1 1 0%",
|
|
2981
|
-
|
|
3555
|
+
opacity: aiBarOpen ? 0 : 1,
|
|
3556
|
+
transform: aiBarOpen ? "scale(0.97)" : "scale(1)",
|
|
3557
|
+
transition: "opacity 0.25s ease, transform 0.25s ease",
|
|
3558
|
+
pointerEvents: aiBarOpen ? "none" : "auto",
|
|
3559
|
+
minWidth: 0
|
|
3560
|
+
},
|
|
3561
|
+
children: [
|
|
3562
|
+
!hideGlobalSearch && /* @__PURE__ */ jsxs5(
|
|
3563
|
+
"div",
|
|
3564
|
+
{
|
|
3565
|
+
style: {
|
|
3566
|
+
display: "flex",
|
|
3567
|
+
alignItems: "center",
|
|
3568
|
+
gap: 4,
|
|
3569
|
+
flex: "1 1 0%",
|
|
3570
|
+
position: "relative"
|
|
3571
|
+
},
|
|
3572
|
+
children: [
|
|
3573
|
+
/* @__PURE__ */ jsx5(
|
|
3574
|
+
"span",
|
|
3575
|
+
{
|
|
3576
|
+
style: {
|
|
3577
|
+
display: "flex",
|
|
3578
|
+
color: "GrayText",
|
|
3579
|
+
flexShrink: 0
|
|
3580
|
+
},
|
|
3581
|
+
children: icons?.search ?? /* @__PURE__ */ jsx5(SearchIcon, { style: { width: 14, height: 14 } })
|
|
3582
|
+
}
|
|
3583
|
+
),
|
|
3584
|
+
/* @__PURE__ */ jsx5(
|
|
3585
|
+
"input",
|
|
3586
|
+
{
|
|
3587
|
+
type: "text",
|
|
3588
|
+
placeholder: "Search all columns...",
|
|
3589
|
+
value: globalSearchValue ?? internalGlobalSearch,
|
|
3590
|
+
onChange: (e) => {
|
|
3591
|
+
const v = e.target.value;
|
|
3592
|
+
if (onGlobalSearchChange) onGlobalSearchChange(v);
|
|
3593
|
+
else setInternalGlobalSearch(v);
|
|
3594
|
+
},
|
|
3595
|
+
style: {
|
|
3596
|
+
flex: "1 1 0%",
|
|
3597
|
+
border: "none",
|
|
3598
|
+
outline: "none",
|
|
3599
|
+
background: "transparent",
|
|
3600
|
+
font: "inherit",
|
|
3601
|
+
color: "inherit",
|
|
3602
|
+
padding: "4px 6px",
|
|
3603
|
+
minWidth: 0
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
),
|
|
3607
|
+
(globalSearchValue ?? internalGlobalSearch) && /* @__PURE__ */ jsx5(
|
|
3608
|
+
"button",
|
|
3609
|
+
{
|
|
3610
|
+
type: "button",
|
|
3611
|
+
onClick: () => {
|
|
3612
|
+
if (onGlobalSearchChange) onGlobalSearchChange("");
|
|
3613
|
+
else setInternalGlobalSearch("");
|
|
3614
|
+
},
|
|
3615
|
+
style: {
|
|
3616
|
+
display: "flex",
|
|
3617
|
+
alignItems: "center",
|
|
3618
|
+
justifyContent: "center",
|
|
3619
|
+
background: "none",
|
|
3620
|
+
border: "none",
|
|
3621
|
+
cursor: "pointer",
|
|
3622
|
+
padding: 2,
|
|
3623
|
+
color: "GrayText",
|
|
3624
|
+
flexShrink: 0
|
|
3625
|
+
},
|
|
3626
|
+
children: icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 12, height: 12 } })
|
|
3627
|
+
}
|
|
3628
|
+
)
|
|
3629
|
+
]
|
|
3630
|
+
}
|
|
3631
|
+
),
|
|
3632
|
+
toolbarContent,
|
|
3633
|
+
showColumnSettings && /* @__PURE__ */ jsxs5("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
3634
|
+
/* @__PURE__ */ jsxs5(
|
|
3635
|
+
"button",
|
|
3636
|
+
{
|
|
3637
|
+
type: "button",
|
|
3638
|
+
onClick: () => setShowColumnPicker((p) => !p),
|
|
3639
|
+
style: {
|
|
3640
|
+
display: "flex",
|
|
3641
|
+
alignItems: "center",
|
|
3642
|
+
justifyContent: "center",
|
|
3643
|
+
background: "none",
|
|
3644
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3645
|
+
borderRadius: 4,
|
|
3646
|
+
cursor: "pointer",
|
|
3647
|
+
padding: "4px 6px",
|
|
3648
|
+
color: "inherit",
|
|
3649
|
+
gap: 4,
|
|
3650
|
+
fontSize: 12
|
|
3651
|
+
},
|
|
3652
|
+
title: "Column settings",
|
|
3653
|
+
children: [
|
|
3654
|
+
icons?.columns ?? /* @__PURE__ */ jsx5(ColumnsIcon, { style: { width: 14, height: 14 } }),
|
|
3655
|
+
/* @__PURE__ */ jsx5("span", { children: columnSettingsLabel ?? "Columns" })
|
|
3656
|
+
]
|
|
3657
|
+
}
|
|
3658
|
+
),
|
|
3659
|
+
showColumnPicker && /* @__PURE__ */ jsx5(
|
|
3660
|
+
"div",
|
|
3661
|
+
{
|
|
3662
|
+
ref: columnPickerRef,
|
|
3663
|
+
style: {
|
|
3664
|
+
position: "absolute",
|
|
3665
|
+
top: "100%",
|
|
3666
|
+
right: 0,
|
|
3667
|
+
zIndex: 99999,
|
|
3668
|
+
minWidth: 200,
|
|
3669
|
+
maxHeight: 320,
|
|
3670
|
+
overflowY: "auto",
|
|
3671
|
+
borderRadius: 8,
|
|
3672
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3673
|
+
boxShadow: "0 4px 24px rgba(0,0,0,0.12)",
|
|
3674
|
+
backdropFilter: "blur(16px)",
|
|
3675
|
+
WebkitBackdropFilter: "blur(16px)",
|
|
3676
|
+
backgroundColor: "rgba(128,128,128,0.08)",
|
|
3677
|
+
padding: "4px 0",
|
|
3678
|
+
marginTop: 4
|
|
3679
|
+
},
|
|
3680
|
+
children: initialColumns.filter(
|
|
3681
|
+
(c) => c.key !== "__select__" && c.key !== "__expand__"
|
|
3682
|
+
).map((col) => {
|
|
3683
|
+
const current = columns.find(
|
|
3684
|
+
(c) => c.key === col.key
|
|
3685
|
+
);
|
|
3686
|
+
const isHidden = current?.hidden ?? false;
|
|
3687
|
+
const isPinned = !!current?.pinned;
|
|
3688
|
+
return /* @__PURE__ */ jsxs5(
|
|
3689
|
+
"label",
|
|
3690
|
+
{
|
|
3691
|
+
style: {
|
|
3692
|
+
display: "flex",
|
|
3693
|
+
alignItems: "center",
|
|
3694
|
+
gap: 8,
|
|
3695
|
+
padding: "6px 12px",
|
|
3696
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3697
|
+
opacity: isPinned ? 0.5 : 1,
|
|
3698
|
+
fontSize: 12
|
|
3699
|
+
},
|
|
3700
|
+
children: [
|
|
3701
|
+
/* @__PURE__ */ jsx5(
|
|
3702
|
+
"input",
|
|
3703
|
+
{
|
|
3704
|
+
type: "checkbox",
|
|
3705
|
+
checked: !isHidden,
|
|
3706
|
+
disabled: isPinned,
|
|
3707
|
+
onChange: () => {
|
|
3708
|
+
if (isPinned) return;
|
|
3709
|
+
handleToggleHide(col.key);
|
|
3710
|
+
},
|
|
3711
|
+
style: {
|
|
3712
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3713
|
+
accentColor
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
),
|
|
3717
|
+
/* @__PURE__ */ jsx5(
|
|
3718
|
+
"span",
|
|
3719
|
+
{
|
|
3720
|
+
style: {
|
|
3721
|
+
overflow: "hidden",
|
|
3722
|
+
textOverflow: "ellipsis",
|
|
3723
|
+
whiteSpace: "nowrap"
|
|
3724
|
+
},
|
|
3725
|
+
children: typeof col.title === "string" ? col.title : col.key
|
|
3726
|
+
}
|
|
3727
|
+
)
|
|
3728
|
+
]
|
|
3729
|
+
},
|
|
3730
|
+
col.key
|
|
3731
|
+
);
|
|
3732
|
+
})
|
|
3733
|
+
}
|
|
3734
|
+
)
|
|
3735
|
+
] }),
|
|
3736
|
+
aiMode && savedAIFilters.length > 0 && /* @__PURE__ */ jsxs5("div", { ref: savedFiltersRef, style: { position: "relative", flexShrink: 0 }, children: [
|
|
3737
|
+
/* @__PURE__ */ jsxs5(
|
|
3738
|
+
"button",
|
|
3739
|
+
{
|
|
3740
|
+
type: "button",
|
|
3741
|
+
onClick: () => setShowSavedFilters((p) => !p),
|
|
3742
|
+
style: {
|
|
3743
|
+
display: "flex",
|
|
3744
|
+
alignItems: "center",
|
|
3745
|
+
gap: 4,
|
|
3746
|
+
background: "none",
|
|
3747
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3748
|
+
borderRadius: 4,
|
|
3749
|
+
cursor: "pointer",
|
|
3750
|
+
padding: "4px 6px",
|
|
3751
|
+
color: "inherit",
|
|
3752
|
+
fontSize: 12
|
|
3753
|
+
},
|
|
3754
|
+
title: "Saved AI filters",
|
|
3755
|
+
children: [
|
|
3756
|
+
/* @__PURE__ */ jsx5("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("polygon", { points: "22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" }) }),
|
|
3757
|
+
/* @__PURE__ */ jsx5("span", { children: savedAIFilters.length })
|
|
3758
|
+
]
|
|
3759
|
+
}
|
|
3760
|
+
),
|
|
3761
|
+
showSavedFilters && /* @__PURE__ */ jsxs5(
|
|
3762
|
+
"div",
|
|
3763
|
+
{
|
|
3764
|
+
style: {
|
|
3765
|
+
position: "absolute",
|
|
3766
|
+
top: "100%",
|
|
3767
|
+
right: 0,
|
|
3768
|
+
zIndex: 99999,
|
|
3769
|
+
minWidth: 240,
|
|
3770
|
+
maxWidth: 360,
|
|
3771
|
+
maxHeight: 320,
|
|
3772
|
+
overflowY: "auto",
|
|
3773
|
+
borderRadius: 8,
|
|
3774
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3775
|
+
boxShadow: "0 4px 24px rgba(0,0,0,0.12)",
|
|
3776
|
+
backdropFilter: "blur(16px)",
|
|
3777
|
+
WebkitBackdropFilter: "blur(16px)",
|
|
3778
|
+
backgroundColor: "rgba(128,128,128,0.08)",
|
|
3779
|
+
padding: "4px 0",
|
|
3780
|
+
marginTop: 4
|
|
3781
|
+
},
|
|
3782
|
+
children: [
|
|
3783
|
+
/* @__PURE__ */ jsx5("div", { style: { padding: "6px 12px", fontSize: 11, opacity: 0.5, fontWeight: 600 }, children: "Saved Filters" }),
|
|
3784
|
+
savedAIFilters.map((f, i) => /* @__PURE__ */ jsxs5(
|
|
3785
|
+
"div",
|
|
3786
|
+
{
|
|
3787
|
+
style: {
|
|
3788
|
+
display: "flex",
|
|
3789
|
+
alignItems: "center",
|
|
3790
|
+
gap: 6,
|
|
3791
|
+
padding: "6px 12px",
|
|
3792
|
+
cursor: "pointer",
|
|
3793
|
+
fontSize: 12
|
|
3794
|
+
},
|
|
3795
|
+
onMouseEnter: (e) => {
|
|
3796
|
+
e.currentTarget.style.backgroundColor = "rgba(128,128,128,0.15)";
|
|
3797
|
+
},
|
|
3798
|
+
onMouseLeave: (e) => {
|
|
3799
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
3800
|
+
},
|
|
3801
|
+
children: [
|
|
3802
|
+
/* @__PURE__ */ jsx5(
|
|
3803
|
+
"span",
|
|
3804
|
+
{
|
|
3805
|
+
style: { flex: "1 1 0%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
3806
|
+
onClick: () => applySavedFilter(f),
|
|
3807
|
+
children: f.label
|
|
3808
|
+
}
|
|
3809
|
+
),
|
|
3810
|
+
/* @__PURE__ */ jsx5(
|
|
3811
|
+
"button",
|
|
3812
|
+
{
|
|
3813
|
+
type: "button",
|
|
3814
|
+
onClick: (e) => {
|
|
3815
|
+
e.stopPropagation();
|
|
3816
|
+
removeSavedFilter(i);
|
|
3817
|
+
},
|
|
3818
|
+
style: {
|
|
3819
|
+
display: "flex",
|
|
3820
|
+
alignItems: "center",
|
|
3821
|
+
background: "none",
|
|
3822
|
+
border: "none",
|
|
3823
|
+
cursor: "pointer",
|
|
3824
|
+
padding: 2,
|
|
3825
|
+
color: "GrayText",
|
|
3826
|
+
flexShrink: 0
|
|
3827
|
+
},
|
|
3828
|
+
title: "Remove",
|
|
3829
|
+
children: icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 10, height: 10 } })
|
|
3830
|
+
}
|
|
3831
|
+
)
|
|
3832
|
+
]
|
|
3833
|
+
},
|
|
3834
|
+
i
|
|
3835
|
+
))
|
|
3836
|
+
]
|
|
3837
|
+
}
|
|
3838
|
+
)
|
|
3839
|
+
] }),
|
|
3840
|
+
aiMode && /* @__PURE__ */ jsxs5(
|
|
3841
|
+
"button",
|
|
3842
|
+
{
|
|
3843
|
+
type: "button",
|
|
3844
|
+
onClick: () => setAiBarOpen(true),
|
|
3845
|
+
style: {
|
|
3846
|
+
display: "flex",
|
|
3847
|
+
alignItems: "center",
|
|
3848
|
+
justifyContent: "center",
|
|
3849
|
+
gap: 4,
|
|
3850
|
+
background: `linear-gradient(135deg, ${accentColor}18, ${accentColor}08)`,
|
|
3851
|
+
border: `1px solid ${accentColor}40`,
|
|
3852
|
+
borderRadius: 4,
|
|
3853
|
+
cursor: "pointer",
|
|
3854
|
+
padding: "4px 8px",
|
|
3855
|
+
color: accentColor,
|
|
3856
|
+
fontSize: 12,
|
|
3857
|
+
fontWeight: 500,
|
|
3858
|
+
flexShrink: 0,
|
|
3859
|
+
transition: "all 0.2s ease"
|
|
3860
|
+
},
|
|
3861
|
+
title: "Ask AI",
|
|
3862
|
+
children: [
|
|
3863
|
+
icons?.sparkles ?? /* @__PURE__ */ jsx5(SparklesIcon, { style: { width: 14, height: 14 } }),
|
|
3864
|
+
/* @__PURE__ */ jsx5("span", { children: aiButtonLabel ?? "Ask AI" })
|
|
3865
|
+
]
|
|
3866
|
+
}
|
|
3867
|
+
)
|
|
3868
|
+
]
|
|
3869
|
+
}
|
|
3870
|
+
),
|
|
3871
|
+
aiMode && /* @__PURE__ */ jsxs5(
|
|
3872
|
+
"div",
|
|
3873
|
+
{
|
|
3874
|
+
style: {
|
|
3875
|
+
position: "absolute",
|
|
3876
|
+
inset: 0,
|
|
3877
|
+
display: "flex",
|
|
3878
|
+
alignItems: "center",
|
|
3879
|
+
gap: 8,
|
|
3880
|
+
padding: "4px 8px",
|
|
3881
|
+
opacity: aiBarOpen ? 1 : 0,
|
|
3882
|
+
transform: aiBarOpen ? "translateX(0)" : "translateX(40px)",
|
|
3883
|
+
transition: "opacity 0.3s cubic-bezier(0.4,0,0.2,1), transform 0.3s cubic-bezier(0.4,0,0.2,1)",
|
|
3884
|
+
pointerEvents: aiBarOpen ? "auto" : "none",
|
|
3885
|
+
zIndex: 2,
|
|
3886
|
+
background: "inherit",
|
|
3887
|
+
backdropFilter: "blur(12px)",
|
|
3888
|
+
WebkitBackdropFilter: "blur(12px)"
|
|
2982
3889
|
},
|
|
2983
3890
|
children: [
|
|
2984
3891
|
/* @__PURE__ */ jsx5(
|
|
2985
3892
|
"span",
|
|
2986
3893
|
{
|
|
2987
|
-
style: {
|
|
2988
|
-
|
|
3894
|
+
style: {
|
|
3895
|
+
display: "flex",
|
|
3896
|
+
color: accentColor,
|
|
3897
|
+
flexShrink: 0
|
|
3898
|
+
},
|
|
3899
|
+
children: icons?.sparkles ?? /* @__PURE__ */ jsx5(SparklesIcon, { style: { width: 16, height: 16 } })
|
|
2989
3900
|
}
|
|
2990
3901
|
),
|
|
2991
3902
|
/* @__PURE__ */ jsx5(
|
|
2992
3903
|
"input",
|
|
2993
3904
|
{
|
|
3905
|
+
ref: aiInputRef,
|
|
2994
3906
|
type: "text",
|
|
2995
|
-
placeholder:
|
|
2996
|
-
value:
|
|
2997
|
-
onChange: (e) =>
|
|
2998
|
-
|
|
2999
|
-
if (
|
|
3000
|
-
|
|
3907
|
+
placeholder: aiPlaceholder,
|
|
3908
|
+
value: aiQuery,
|
|
3909
|
+
onChange: (e) => setAiQuery(e.target.value),
|
|
3910
|
+
onKeyDown: (e) => {
|
|
3911
|
+
if (e.key === "Enter" && !aiLoading) handleAISubmit();
|
|
3912
|
+
if (e.key === "Escape") handleAIBarClose();
|
|
3001
3913
|
},
|
|
3914
|
+
disabled: aiLoading,
|
|
3002
3915
|
style: {
|
|
3003
3916
|
flex: "1 1 0%",
|
|
3004
3917
|
border: "none",
|
|
@@ -3007,18 +3920,51 @@ function BoltTable({
|
|
|
3007
3920
|
font: "inherit",
|
|
3008
3921
|
color: "inherit",
|
|
3009
3922
|
padding: "4px 6px",
|
|
3010
|
-
minWidth: 0
|
|
3923
|
+
minWidth: 0,
|
|
3924
|
+
fontSize: 12
|
|
3011
3925
|
}
|
|
3012
3926
|
}
|
|
3013
3927
|
),
|
|
3014
|
-
|
|
3928
|
+
/* @__PURE__ */ jsx5(
|
|
3015
3929
|
"button",
|
|
3016
3930
|
{
|
|
3017
3931
|
type: "button",
|
|
3018
|
-
onClick:
|
|
3019
|
-
|
|
3020
|
-
|
|
3932
|
+
onClick: handleAISubmit,
|
|
3933
|
+
disabled: aiLoading || !aiQuery.trim(),
|
|
3934
|
+
style: {
|
|
3935
|
+
display: "flex",
|
|
3936
|
+
alignItems: "center",
|
|
3937
|
+
justifyContent: "center",
|
|
3938
|
+
background: aiQuery.trim() ? accentColor : "rgba(128,128,128,0.15)",
|
|
3939
|
+
border: "none",
|
|
3940
|
+
borderRadius: 4,
|
|
3941
|
+
cursor: aiLoading || !aiQuery.trim() ? "not-allowed" : "pointer",
|
|
3942
|
+
padding: "4px 8px",
|
|
3943
|
+
color: aiQuery.trim() ? "#fff" : "GrayText",
|
|
3944
|
+
transition: "all 0.2s ease",
|
|
3945
|
+
flexShrink: 0,
|
|
3946
|
+
gap: 4,
|
|
3947
|
+
fontSize: 12,
|
|
3948
|
+
opacity: aiLoading ? 0.7 : 1
|
|
3021
3949
|
},
|
|
3950
|
+
title: "Send",
|
|
3951
|
+
children: aiLoading ? /* @__PURE__ */ jsx5(Fragment4, { children: icons?.loader ?? /* @__PURE__ */ jsx5(
|
|
3952
|
+
LoaderIcon,
|
|
3953
|
+
{
|
|
3954
|
+
style: {
|
|
3955
|
+
width: 14,
|
|
3956
|
+
height: 14,
|
|
3957
|
+
animation: "bt-spin 1s linear infinite"
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
) }) : /* @__PURE__ */ jsx5(Fragment4, { children: icons?.send ?? /* @__PURE__ */ jsx5(SendIcon, { style: { width: 14, height: 14 } }) })
|
|
3961
|
+
}
|
|
3962
|
+
),
|
|
3963
|
+
/* @__PURE__ */ jsx5(
|
|
3964
|
+
"button",
|
|
3965
|
+
{
|
|
3966
|
+
type: "button",
|
|
3967
|
+
onClick: handleAIBarClose,
|
|
3022
3968
|
style: {
|
|
3023
3969
|
display: "flex",
|
|
3024
3970
|
alignItems: "center",
|
|
@@ -3030,114 +3976,127 @@ function BoltTable({
|
|
|
3030
3976
|
color: "GrayText",
|
|
3031
3977
|
flexShrink: 0
|
|
3032
3978
|
},
|
|
3033
|
-
|
|
3979
|
+
title: "Close AI",
|
|
3980
|
+
children: icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 14, height: 14 } })
|
|
3034
3981
|
}
|
|
3035
3982
|
)
|
|
3036
3983
|
]
|
|
3037
3984
|
}
|
|
3985
|
+
)
|
|
3986
|
+
]
|
|
3987
|
+
}
|
|
3988
|
+
),
|
|
3989
|
+
aiResult && /* @__PURE__ */ jsxs5(
|
|
3990
|
+
"div",
|
|
3991
|
+
{
|
|
3992
|
+
style: {
|
|
3993
|
+
display: "flex",
|
|
3994
|
+
alignItems: "center",
|
|
3995
|
+
gap: 8,
|
|
3996
|
+
padding: "6px 12px",
|
|
3997
|
+
fontSize: 12,
|
|
3998
|
+
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
3999
|
+
background: `linear-gradient(90deg, ${accentColor}08, transparent)`,
|
|
4000
|
+
flexShrink: 0
|
|
4001
|
+
},
|
|
4002
|
+
children: [
|
|
4003
|
+
/* @__PURE__ */ jsx5("span", { style: { color: accentColor, display: "flex", flexShrink: 0 }, children: icons?.sparkles ?? /* @__PURE__ */ jsx5(SparklesIcon, { style: { width: 14, height: 14 } }) }),
|
|
4004
|
+
/* @__PURE__ */ jsx5("span", { style: { flex: "1 1 0%", opacity: 0.85 }, children: aiResult.message }),
|
|
4005
|
+
/* @__PURE__ */ jsxs5(
|
|
4006
|
+
"button",
|
|
4007
|
+
{
|
|
4008
|
+
type: "button",
|
|
4009
|
+
onClick: saveCurrentAIFilter,
|
|
4010
|
+
style: {
|
|
4011
|
+
display: "flex",
|
|
4012
|
+
alignItems: "center",
|
|
4013
|
+
gap: 4,
|
|
4014
|
+
background: `${accentColor}12`,
|
|
4015
|
+
border: `1px solid ${accentColor}30`,
|
|
4016
|
+
borderRadius: 4,
|
|
4017
|
+
cursor: "pointer",
|
|
4018
|
+
padding: "2px 8px",
|
|
4019
|
+
color: accentColor,
|
|
4020
|
+
fontSize: 11,
|
|
4021
|
+
flexShrink: 0,
|
|
4022
|
+
fontWeight: 500,
|
|
4023
|
+
transition: "all 0.2s ease"
|
|
4024
|
+
},
|
|
4025
|
+
title: "Save this filter for quick access later",
|
|
4026
|
+
children: [
|
|
4027
|
+
/* @__PURE__ */ jsxs5("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4028
|
+
/* @__PURE__ */ jsx5("path", { d: "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" }),
|
|
4029
|
+
/* @__PURE__ */ jsx5("polyline", { points: "17 21 17 13 7 13 7 21" }),
|
|
4030
|
+
/* @__PURE__ */ jsx5("polyline", { points: "7 3 7 8 15 8" })
|
|
4031
|
+
] }),
|
|
4032
|
+
/* @__PURE__ */ jsx5("span", { children: "Save Filter" })
|
|
4033
|
+
]
|
|
4034
|
+
}
|
|
3038
4035
|
),
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
"button",
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
fontSize: 12
|
|
3104
|
-
},
|
|
3105
|
-
children: [
|
|
3106
|
-
/* @__PURE__ */ jsx5(
|
|
3107
|
-
"input",
|
|
3108
|
-
{
|
|
3109
|
-
type: "checkbox",
|
|
3110
|
-
checked: !isHidden,
|
|
3111
|
-
disabled: isPinned,
|
|
3112
|
-
onChange: () => {
|
|
3113
|
-
if (isPinned) return;
|
|
3114
|
-
handleToggleHide(col.key);
|
|
3115
|
-
},
|
|
3116
|
-
style: {
|
|
3117
|
-
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3118
|
-
accentColor
|
|
3119
|
-
}
|
|
3120
|
-
}
|
|
3121
|
-
),
|
|
3122
|
-
/* @__PURE__ */ jsx5(
|
|
3123
|
-
"span",
|
|
3124
|
-
{
|
|
3125
|
-
style: {
|
|
3126
|
-
overflow: "hidden",
|
|
3127
|
-
textOverflow: "ellipsis",
|
|
3128
|
-
whiteSpace: "nowrap"
|
|
3129
|
-
},
|
|
3130
|
-
children: typeof col.title === "string" ? col.title : col.key
|
|
3131
|
-
}
|
|
3132
|
-
)
|
|
3133
|
-
]
|
|
3134
|
-
},
|
|
3135
|
-
col.key
|
|
3136
|
-
);
|
|
3137
|
-
})
|
|
3138
|
-
}
|
|
3139
|
-
)
|
|
3140
|
-
] })
|
|
4036
|
+
/* @__PURE__ */ jsxs5(
|
|
4037
|
+
"button",
|
|
4038
|
+
{
|
|
4039
|
+
type: "button",
|
|
4040
|
+
onClick: handleAIClear,
|
|
4041
|
+
style: {
|
|
4042
|
+
display: "flex",
|
|
4043
|
+
alignItems: "center",
|
|
4044
|
+
gap: 4,
|
|
4045
|
+
background: "none",
|
|
4046
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
4047
|
+
borderRadius: 4,
|
|
4048
|
+
cursor: "pointer",
|
|
4049
|
+
padding: "2px 8px",
|
|
4050
|
+
color: "inherit",
|
|
4051
|
+
fontSize: 11,
|
|
4052
|
+
flexShrink: 0,
|
|
4053
|
+
opacity: 0.7
|
|
4054
|
+
},
|
|
4055
|
+
title: "Clear AI results",
|
|
4056
|
+
children: [
|
|
4057
|
+
icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 10, height: 10 } }),
|
|
4058
|
+
/* @__PURE__ */ jsx5("span", { children: "Clear" })
|
|
4059
|
+
]
|
|
4060
|
+
}
|
|
4061
|
+
)
|
|
4062
|
+
]
|
|
4063
|
+
}
|
|
4064
|
+
),
|
|
4065
|
+
aiError && !aiResult && /* @__PURE__ */ jsxs5(
|
|
4066
|
+
"div",
|
|
4067
|
+
{
|
|
4068
|
+
style: {
|
|
4069
|
+
display: "flex",
|
|
4070
|
+
alignItems: "center",
|
|
4071
|
+
gap: 8,
|
|
4072
|
+
padding: "6px 12px",
|
|
4073
|
+
fontSize: 12,
|
|
4074
|
+
borderBottom: "1px solid rgba(239,68,68,0.2)",
|
|
4075
|
+
background: "rgba(239,68,68,0.06)",
|
|
4076
|
+
color: "#ef4444",
|
|
4077
|
+
flexShrink: 0
|
|
4078
|
+
},
|
|
4079
|
+
children: [
|
|
4080
|
+
/* @__PURE__ */ jsx5("span", { style: { flex: "1 1 0%" }, children: aiError }),
|
|
4081
|
+
/* @__PURE__ */ jsx5(
|
|
4082
|
+
"button",
|
|
4083
|
+
{
|
|
4084
|
+
type: "button",
|
|
4085
|
+
onClick: () => setAiError(null),
|
|
4086
|
+
style: {
|
|
4087
|
+
display: "flex",
|
|
4088
|
+
alignItems: "center",
|
|
4089
|
+
justifyContent: "center",
|
|
4090
|
+
background: "none",
|
|
4091
|
+
border: "none",
|
|
4092
|
+
cursor: "pointer",
|
|
4093
|
+
padding: 2,
|
|
4094
|
+
color: "#ef4444",
|
|
4095
|
+
flexShrink: 0
|
|
4096
|
+
},
|
|
4097
|
+
children: icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 12, height: 12 } })
|
|
4098
|
+
}
|
|
4099
|
+
)
|
|
3141
4100
|
]
|
|
3142
4101
|
}
|
|
3143
4102
|
),
|
|
@@ -3639,14 +4598,20 @@ function BoltTable({
|
|
|
3639
4598
|
gridTemplateColumns,
|
|
3640
4599
|
headerHeight: HEADER_HEIGHT,
|
|
3641
4600
|
rowClassName,
|
|
3642
|
-
rowStyle,
|
|
4601
|
+
rowStyle: aiStyleOps.length > 0 ? (record, index) => {
|
|
4602
|
+
const base = rowStyle ? rowStyle(record, index) : void 0;
|
|
4603
|
+
const ai = getAIRowStyleForRecord(record);
|
|
4604
|
+
if (!base && !ai) return {};
|
|
4605
|
+
return { ...base, ...ai };
|
|
4606
|
+
} : rowStyle,
|
|
3643
4607
|
bodyGridRow: hasColumnGroups ? 3 : 2,
|
|
3644
4608
|
onEdit,
|
|
3645
4609
|
editingCell,
|
|
3646
4610
|
onEditComplete: handleEditComplete,
|
|
3647
4611
|
enableDynamicRowHeight,
|
|
3648
4612
|
onRowHeightChange: handleRowHeightChange,
|
|
3649
|
-
columnGridIndexMap
|
|
4613
|
+
columnGridIndexMap,
|
|
4614
|
+
cellStyleFn: aiCellStyleOps.length > 0 ? (record, columnKey) => getAICellStyleForRecord(record, columnKey) : void 0
|
|
3650
4615
|
}
|
|
3651
4616
|
)
|
|
3652
4617
|
]
|
|
@@ -4264,9 +5229,15 @@ function BoltTable({
|
|
|
4264
5229
|
})()
|
|
4265
5230
|
] });
|
|
4266
5231
|
}
|
|
5232
|
+
|
|
5233
|
+
// src/types.ts
|
|
5234
|
+
function defineConfig(config) {
|
|
5235
|
+
return config;
|
|
5236
|
+
}
|
|
4267
5237
|
export {
|
|
4268
5238
|
BoltTable,
|
|
4269
5239
|
DraggableHeader_default as DraggableHeader,
|
|
4270
5240
|
ResizeOverlay_default as ResizeOverlay,
|
|
4271
|
-
TableBody_default as TableBody
|
|
5241
|
+
TableBody_default as TableBody,
|
|
5242
|
+
defineConfig
|
|
4272
5243
|
};
|