dp-widgets-framework 1.5.4 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +477 -477
- package/dist/index.esm.js +145 -13
- package/dist/index.js +145 -13
- package/package.json +138 -138
package/dist/index.esm.js
CHANGED
|
@@ -1841,14 +1841,14 @@ function WidgetSettingsPanel({ pageId, widget, onClose, onWidgetUpdate, widgetBa
|
|
|
1841
1841
|
const renderCodeSettings = () => {
|
|
1842
1842
|
var _a;
|
|
1843
1843
|
return (jsxRuntimeExports.jsx("div", { className: "space-y-4", children: jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [jsxRuntimeExports.jsx(Label$1, { className: "text-xs", children: "Custom Widget Code" }), jsxRuntimeExports.jsx(CodeEditor, { value: ((_a = localWidget.config) === null || _a === void 0 ? void 0 : _a.customCode) ||
|
|
1844
|
-
`// Custom search widget code
|
|
1845
|
-
// You can modify the widget behavior here
|
|
1846
|
-
function customSearch(query) {
|
|
1847
|
-
// Your custom search logic
|
|
1848
|
-
console.log('Searching for:', query);
|
|
1849
|
-
return {
|
|
1850
|
-
// Return your search results
|
|
1851
|
-
};
|
|
1844
|
+
`// Custom search widget code
|
|
1845
|
+
// You can modify the widget behavior here
|
|
1846
|
+
function customSearch(query) {
|
|
1847
|
+
// Your custom search logic
|
|
1848
|
+
console.log('Searching for:', query);
|
|
1849
|
+
return {
|
|
1850
|
+
// Return your search results
|
|
1851
|
+
};
|
|
1852
1852
|
}`, onChange: (value) => updateConfig({
|
|
1853
1853
|
customCode: value || "",
|
|
1854
1854
|
}) })] }) }));
|
|
@@ -39327,6 +39327,23 @@ const parseAndUpdateFilterState = (apiResponse, setFilterState) => {
|
|
|
39327
39327
|
if (filterData.agent_message) {
|
|
39328
39328
|
newFilterState.agent_message = filterData.agent_message;
|
|
39329
39329
|
}
|
|
39330
|
+
// Handle confirmation state
|
|
39331
|
+
if (filterData.status) {
|
|
39332
|
+
newFilterState.status = filterData.status;
|
|
39333
|
+
}
|
|
39334
|
+
if (filterData.ambiguous_columns) {
|
|
39335
|
+
newFilterState.ambiguous_columns = filterData.ambiguous_columns;
|
|
39336
|
+
}
|
|
39337
|
+
if (filterData.message) {
|
|
39338
|
+
newFilterState.message = filterData.message;
|
|
39339
|
+
}
|
|
39340
|
+
if (filterData.filter_columns) {
|
|
39341
|
+
newFilterState.filter_columns = filterData.filter_columns;
|
|
39342
|
+
}
|
|
39343
|
+
if (filterData.resolved_columns) {
|
|
39344
|
+
newFilterState.resolved_columns = filterData.resolved_columns;
|
|
39345
|
+
}
|
|
39346
|
+
console.log('[parseAndUpdateFilterState] Updated filter state:', newFilterState);
|
|
39330
39347
|
return newFilterState;
|
|
39331
39348
|
});
|
|
39332
39349
|
}
|
|
@@ -39350,6 +39367,25 @@ const convertFilterStateToGroups = (filterState) => {
|
|
|
39350
39367
|
})),
|
|
39351
39368
|
}));
|
|
39352
39369
|
};
|
|
39370
|
+
// Component for handling table selection confirmation
|
|
39371
|
+
function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message, onConfirm, onCancel, }) {
|
|
39372
|
+
const [selectedTables, setSelectedTables] = useState({});
|
|
39373
|
+
useEffect(() => {
|
|
39374
|
+
// Initialize with first option for each column
|
|
39375
|
+
const initial = {};
|
|
39376
|
+
ambiguousColumns.forEach((col) => {
|
|
39377
|
+
initial[col.column] = col.tables[0];
|
|
39378
|
+
});
|
|
39379
|
+
setSelectedTables(initial);
|
|
39380
|
+
}, [ambiguousColumns]);
|
|
39381
|
+
const handleSubmit = () => {
|
|
39382
|
+
onConfirm(selectedTables);
|
|
39383
|
+
};
|
|
39384
|
+
const allSelected = ambiguousColumns.every((col) => selectedTables[col.column]);
|
|
39385
|
+
return (jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full p-4 bg-white", children: [jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-800 mb-2", children: "Table Selection Required" }), message && (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 mb-4 whitespace-pre-line", children: message }))] }), resolvedColumns && resolvedColumns.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "mb-4 p-3 bg-green-50 border border-green-200 rounded-lg", children: [jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-green-800 mb-2", children: "Already Resolved Columns:" }), jsxRuntimeExports.jsx("div", { className: "space-y-1", children: resolvedColumns.map((col) => (jsxRuntimeExports.jsxs("div", { className: "text-sm text-green-700", children: [jsxRuntimeExports.jsx("span", { className: "font-medium", children: col.column }), " \u2192 ", jsxRuntimeExports.jsx("span", { className: "text-green-600", children: col.table_name })] }, col.column))) })] })), jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 mb-4", children: jsxRuntimeExports.jsx("div", { className: "space-y-4", children: ambiguousColumns.map((col) => (jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 rounded-lg p-3", children: [jsxRuntimeExports.jsx("label", { className: "block mb-2", children: jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-gray-700", children: ["Column: ", jsxRuntimeExports.jsx("span", { className: "text-primary-600", children: col.column })] }) }), jsxRuntimeExports.jsxs("select", { value: selectedTables[col.column] || '', onChange: (e) => {
|
|
39386
|
+
setSelectedTables((prev) => (Object.assign(Object.assign({}, prev), { [col.column]: e.target.value })));
|
|
39387
|
+
}, className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500", children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select a table..." }), col.tables.map((table) => (jsxRuntimeExports.jsx("option", { value: table, children: table }, table)))] })] }, col.column))) }) }), jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-3 border-t border-gray-200", children: [jsxRuntimeExports.jsx(Button, { onClick: onCancel, variant: "outline", className: "flex-1", children: "Cancel" }), jsxRuntimeExports.jsx(Button, { onClick: handleSubmit, disabled: !allSelected, className: "flex-1 bg-primary-600 hover:bg-primary-700 text-white disabled:bg-gray-400", children: "Confirm Selection" })] })] }));
|
|
39388
|
+
}
|
|
39353
39389
|
function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
|
|
39354
39390
|
const hasCalledRef = useRef(false);
|
|
39355
39391
|
const [expandedGroups, setExpandedGroups] = useState({});
|
|
@@ -39455,10 +39491,23 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
|
|
|
39455
39491
|
if (onFilterChange) {
|
|
39456
39492
|
onFilterChange({});
|
|
39457
39493
|
}
|
|
39458
|
-
}, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
|
|
39494
|
+
}, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
|
|
39495
|
+
// Convert option IDs back to original label values
|
|
39496
|
+
const filtersWithLabels = {};
|
|
39497
|
+
Object.entries(selectedFilters).forEach(([groupId, optionIds]) => {
|
|
39498
|
+
const group = filterGroups.find(g => g.id === groupId);
|
|
39499
|
+
if (group) {
|
|
39500
|
+
filtersWithLabels[groupId] = optionIds.map(optionId => {
|
|
39501
|
+
const option = group.options.find(opt => opt.id === optionId);
|
|
39502
|
+
return (option === null || option === void 0 ? void 0 : option.label) || optionId;
|
|
39503
|
+
});
|
|
39504
|
+
}
|
|
39505
|
+
});
|
|
39506
|
+
onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
|
|
39507
|
+
}, disabled: isEditing, className: `${isEditing ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: "Apply Filters" })] }) })] }));
|
|
39459
39508
|
}
|
|
39460
39509
|
function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, widgetBackendUrl, datasetId, onApplyFilters, isEditing = false, }) {
|
|
39461
|
-
var _a, _b, _c, _d, _e, _f;
|
|
39510
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
39462
39511
|
const isFirstLoad = (_a = widget.config) === null || _a === void 0 ? void 0 : _a.isFirstLoad;
|
|
39463
39512
|
const widget_data = (_b = widget.widget_data) === null || _b === void 0 ? void 0 : _b.column_values;
|
|
39464
39513
|
const { setThreadId } = useCopilotContext();
|
|
@@ -39562,11 +39611,94 @@ function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, w
|
|
|
39562
39611
|
window.removeEventListener('clearFilterState', handleClearFilterState);
|
|
39563
39612
|
};
|
|
39564
39613
|
}, [widget.id, appendMessage, setFilterState, startLoadingTimeout]);
|
|
39614
|
+
// Handle confirmation submission
|
|
39615
|
+
const handleConfirmation = useCallback(async (tableMapping) => {
|
|
39616
|
+
var _a, _b, _c;
|
|
39617
|
+
console.log('[FiltersWidget] handleConfirmation called with:', {
|
|
39618
|
+
tableMapping,
|
|
39619
|
+
currentFilterState: filterState,
|
|
39620
|
+
widgetQuery: (_a = widget.config) === null || _a === void 0 ? void 0 : _a.query
|
|
39621
|
+
});
|
|
39622
|
+
// Format table mapping as a JSON string for the agent
|
|
39623
|
+
const tableMappingJson = JSON.stringify(tableMapping);
|
|
39624
|
+
// Get filter columns - try multiple sources
|
|
39625
|
+
let filterColumns = filterState.filter_columns || '';
|
|
39626
|
+
// Fallback: extract from the original query if not in state
|
|
39627
|
+
if (!filterColumns && ((_b = widget.config) === null || _b === void 0 ? void 0 : _b.query)) {
|
|
39628
|
+
const filterColumnsMatch = widget.config.query.match(/(?:filter by|filter)\s+(.+)/i);
|
|
39629
|
+
filterColumns = filterColumnsMatch ? filterColumnsMatch[1].trim() : '';
|
|
39630
|
+
}
|
|
39631
|
+
// Fallback: extract from ambiguous_columns if available
|
|
39632
|
+
if (!filterColumns && filterState.ambiguous_columns) {
|
|
39633
|
+
filterColumns = filterState.ambiguous_columns.map(col => col.column).join(',');
|
|
39634
|
+
}
|
|
39635
|
+
if (!filterColumns) {
|
|
39636
|
+
console.error('[FiltersWidget] No filter_columns found in state, query, or ambiguous_columns', {
|
|
39637
|
+
filterState,
|
|
39638
|
+
query: (_c = widget.config) === null || _c === void 0 ? void 0 : _c.query
|
|
39639
|
+
});
|
|
39640
|
+
return;
|
|
39641
|
+
}
|
|
39642
|
+
console.log('[FiltersWidget] Using filter columns:', filterColumns);
|
|
39643
|
+
// Send a very explicit message for the agent to parse
|
|
39644
|
+
const message = `User confirmed table selection. Call get_tables_columns_values with filter_columns="${filterColumns}" and table_mapping='${tableMappingJson}'`;
|
|
39645
|
+
console.log('[FiltersWidget] Sending table mapping confirmation:', {
|
|
39646
|
+
message,
|
|
39647
|
+
tableMapping,
|
|
39648
|
+
filterColumns,
|
|
39649
|
+
tableMappingJson
|
|
39650
|
+
});
|
|
39651
|
+
// Clear the confirmation state completely, including agent_message
|
|
39652
|
+
const newState = {
|
|
39653
|
+
dashboard_id: datasetId || "",
|
|
39654
|
+
status: undefined, // Don't set to 'processing' as it might block polling
|
|
39655
|
+
ambiguous_columns: undefined,
|
|
39656
|
+
message: undefined,
|
|
39657
|
+
agent_message: undefined, // Clear agent_message to allow polling
|
|
39658
|
+
column_values: [], // Clear column values to show loading
|
|
39659
|
+
filter_columns: undefined, // Clear the stored filter columns
|
|
39660
|
+
};
|
|
39661
|
+
console.log('[FiltersWidget] Clearing confirmation state:', newState);
|
|
39662
|
+
setFilterState(newState);
|
|
39663
|
+
setAgentState(newState);
|
|
39664
|
+
// Send the confirmation message
|
|
39665
|
+
appendMessage(new TextMessage({
|
|
39666
|
+
content: message,
|
|
39667
|
+
role: Role.User,
|
|
39668
|
+
}));
|
|
39669
|
+
// Reset counters and start polling
|
|
39670
|
+
setApiCallCount(0);
|
|
39671
|
+
setHasTimeoutError(false);
|
|
39672
|
+
console.log('[FiltersWidget] Starting polling after confirmation');
|
|
39673
|
+
startLoadingTimeout();
|
|
39674
|
+
}, [filterState.filter_columns, filterState.ambiguous_columns, (_e = widget.config) === null || _e === void 0 ? void 0 : _e.query, datasetId, appendMessage, setFilterState, setAgentState, startLoadingTimeout, setApiCallCount, setHasTimeoutError]);
|
|
39675
|
+
const handleCancelConfirmation = useCallback(() => {
|
|
39676
|
+
// Clear the confirmation state
|
|
39677
|
+
setFilterState((prev) => (Object.assign(Object.assign({}, prev), { status: undefined, ambiguous_columns: undefined, message: undefined })));
|
|
39678
|
+
}, [setFilterState]);
|
|
39565
39679
|
// Convert filter state to filter groups
|
|
39566
39680
|
const filterGroups = convertFilterStateToGroups(filterState);
|
|
39567
|
-
|
|
39568
|
-
|
|
39569
|
-
|
|
39681
|
+
// Check if we're waiting for confirmation
|
|
39682
|
+
const isWaitingForConfirmation = filterState.status === 'waiting_for_confirmation' &&
|
|
39683
|
+
filterState.ambiguous_columns &&
|
|
39684
|
+
filterState.ambiguous_columns.length > 0;
|
|
39685
|
+
console.log('[CopilotKitFilters] Filter state check:', {
|
|
39686
|
+
status: filterState.status,
|
|
39687
|
+
hasAmbiguousColumns: !!filterState.ambiguous_columns,
|
|
39688
|
+
ambiguousColumnsLength: ((_f = filterState.ambiguous_columns) === null || _f === void 0 ? void 0 : _f.length) || 0,
|
|
39689
|
+
isWaitingForConfirmation,
|
|
39690
|
+
fullFilterState: filterState
|
|
39691
|
+
});
|
|
39692
|
+
return (jsxRuntimeExports.jsx("div", { className: cn("flex flex-col h-full"), children: isWaitingForConfirmation ? (
|
|
39693
|
+
// Show table selection UI when waiting for user to select tables
|
|
39694
|
+
jsxRuntimeExports.jsx(TableSelectionConfirmation, { ambiguousColumns: filterState.ambiguous_columns || [], resolvedColumns: filterState.resolved_columns, message: filterState.message || filterState.agent_message, onConfirm: handleConfirmation, onCancel: handleCancelConfirmation })) : (filterState === null || filterState === void 0 ? void 0 : filterState.agent_message) &&
|
|
39695
|
+
(!((_g = filterState.column_values) === null || _g === void 0 ? void 0 : _g.length)) &&
|
|
39696
|
+
filterState.status !== 'waiting_for_confirmation'
|
|
39697
|
+
? (
|
|
39698
|
+
// Show agent message (errors, warnings, etc.)
|
|
39699
|
+
jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full p-4", children: jsxRuntimeExports.jsx("div", { className: "text-center max-w-md", children: jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-700 whitespace-pre-line", children: filterState.agent_message }) }) })) : (
|
|
39700
|
+
// Show normal filter UI
|
|
39701
|
+
jsxRuntimeExports.jsx(FiltersContent, { filterGroups: filterGroups, showHeader: showHeader, onFilterChange: onFilterChange, widget: widget, appendMessage: appendMessage, query: (_h = widget.config) === null || _h === void 0 ? void 0 : _h.query, isFirstLoad: isFirstLoad, widgetBackendUrl: widgetBackendUrl, widgetId: widget.id, startLoadingTimeout: startLoadingTimeout, clearLoadingTimeout: clearLoadingTimeout, filterState: filterState, onApplyFilters: onApplyFilters, isEditing: isEditing })) }));
|
|
39570
39702
|
}
|
|
39571
39703
|
function FiltersWidget({ widget, showHeader = true, onConfigUpdate, onFilterChange, widgetBackendUrl, onResetReady, datasetId, onApplyFilters, isEditing = false, }) {
|
|
39572
39704
|
var _a;
|
package/dist/index.js
CHANGED
|
@@ -1868,14 +1868,14 @@ function WidgetSettingsPanel({ pageId, widget, onClose, onWidgetUpdate, widgetBa
|
|
|
1868
1868
|
const renderCodeSettings = () => {
|
|
1869
1869
|
var _a;
|
|
1870
1870
|
return (jsxRuntimeExports.jsx("div", { className: "space-y-4", children: jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [jsxRuntimeExports.jsx(Label$1, { className: "text-xs", children: "Custom Widget Code" }), jsxRuntimeExports.jsx(CodeEditor, { value: ((_a = localWidget.config) === null || _a === void 0 ? void 0 : _a.customCode) ||
|
|
1871
|
-
`// Custom search widget code
|
|
1872
|
-
// You can modify the widget behavior here
|
|
1873
|
-
function customSearch(query) {
|
|
1874
|
-
// Your custom search logic
|
|
1875
|
-
console.log('Searching for:', query);
|
|
1876
|
-
return {
|
|
1877
|
-
// Return your search results
|
|
1878
|
-
};
|
|
1871
|
+
`// Custom search widget code
|
|
1872
|
+
// You can modify the widget behavior here
|
|
1873
|
+
function customSearch(query) {
|
|
1874
|
+
// Your custom search logic
|
|
1875
|
+
console.log('Searching for:', query);
|
|
1876
|
+
return {
|
|
1877
|
+
// Return your search results
|
|
1878
|
+
};
|
|
1879
1879
|
}`, onChange: (value) => updateConfig({
|
|
1880
1880
|
customCode: value || "",
|
|
1881
1881
|
}) })] }) }));
|
|
@@ -39354,6 +39354,23 @@ const parseAndUpdateFilterState = (apiResponse, setFilterState) => {
|
|
|
39354
39354
|
if (filterData.agent_message) {
|
|
39355
39355
|
newFilterState.agent_message = filterData.agent_message;
|
|
39356
39356
|
}
|
|
39357
|
+
// Handle confirmation state
|
|
39358
|
+
if (filterData.status) {
|
|
39359
|
+
newFilterState.status = filterData.status;
|
|
39360
|
+
}
|
|
39361
|
+
if (filterData.ambiguous_columns) {
|
|
39362
|
+
newFilterState.ambiguous_columns = filterData.ambiguous_columns;
|
|
39363
|
+
}
|
|
39364
|
+
if (filterData.message) {
|
|
39365
|
+
newFilterState.message = filterData.message;
|
|
39366
|
+
}
|
|
39367
|
+
if (filterData.filter_columns) {
|
|
39368
|
+
newFilterState.filter_columns = filterData.filter_columns;
|
|
39369
|
+
}
|
|
39370
|
+
if (filterData.resolved_columns) {
|
|
39371
|
+
newFilterState.resolved_columns = filterData.resolved_columns;
|
|
39372
|
+
}
|
|
39373
|
+
console.log('[parseAndUpdateFilterState] Updated filter state:', newFilterState);
|
|
39357
39374
|
return newFilterState;
|
|
39358
39375
|
});
|
|
39359
39376
|
}
|
|
@@ -39377,6 +39394,25 @@ const convertFilterStateToGroups = (filterState) => {
|
|
|
39377
39394
|
})),
|
|
39378
39395
|
}));
|
|
39379
39396
|
};
|
|
39397
|
+
// Component for handling table selection confirmation
|
|
39398
|
+
function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message, onConfirm, onCancel, }) {
|
|
39399
|
+
const [selectedTables, setSelectedTables] = React.useState({});
|
|
39400
|
+
React.useEffect(() => {
|
|
39401
|
+
// Initialize with first option for each column
|
|
39402
|
+
const initial = {};
|
|
39403
|
+
ambiguousColumns.forEach((col) => {
|
|
39404
|
+
initial[col.column] = col.tables[0];
|
|
39405
|
+
});
|
|
39406
|
+
setSelectedTables(initial);
|
|
39407
|
+
}, [ambiguousColumns]);
|
|
39408
|
+
const handleSubmit = () => {
|
|
39409
|
+
onConfirm(selectedTables);
|
|
39410
|
+
};
|
|
39411
|
+
const allSelected = ambiguousColumns.every((col) => selectedTables[col.column]);
|
|
39412
|
+
return (jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full p-4 bg-white", children: [jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-800 mb-2", children: "Table Selection Required" }), message && (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 mb-4 whitespace-pre-line", children: message }))] }), resolvedColumns && resolvedColumns.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "mb-4 p-3 bg-green-50 border border-green-200 rounded-lg", children: [jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-green-800 mb-2", children: "Already Resolved Columns:" }), jsxRuntimeExports.jsx("div", { className: "space-y-1", children: resolvedColumns.map((col) => (jsxRuntimeExports.jsxs("div", { className: "text-sm text-green-700", children: [jsxRuntimeExports.jsx("span", { className: "font-medium", children: col.column }), " \u2192 ", jsxRuntimeExports.jsx("span", { className: "text-green-600", children: col.table_name })] }, col.column))) })] })), jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 mb-4", children: jsxRuntimeExports.jsx("div", { className: "space-y-4", children: ambiguousColumns.map((col) => (jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 rounded-lg p-3", children: [jsxRuntimeExports.jsx("label", { className: "block mb-2", children: jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-gray-700", children: ["Column: ", jsxRuntimeExports.jsx("span", { className: "text-primary-600", children: col.column })] }) }), jsxRuntimeExports.jsxs("select", { value: selectedTables[col.column] || '', onChange: (e) => {
|
|
39413
|
+
setSelectedTables((prev) => (Object.assign(Object.assign({}, prev), { [col.column]: e.target.value })));
|
|
39414
|
+
}, className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500", children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select a table..." }), col.tables.map((table) => (jsxRuntimeExports.jsx("option", { value: table, children: table }, table)))] })] }, col.column))) }) }), jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-3 border-t border-gray-200", children: [jsxRuntimeExports.jsx(Button, { onClick: onCancel, variant: "outline", className: "flex-1", children: "Cancel" }), jsxRuntimeExports.jsx(Button, { onClick: handleSubmit, disabled: !allSelected, className: "flex-1 bg-primary-600 hover:bg-primary-700 text-white disabled:bg-gray-400", children: "Confirm Selection" })] })] }));
|
|
39415
|
+
}
|
|
39380
39416
|
function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
|
|
39381
39417
|
const hasCalledRef = React.useRef(false);
|
|
39382
39418
|
const [expandedGroups, setExpandedGroups] = React.useState({});
|
|
@@ -39482,10 +39518,23 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
|
|
|
39482
39518
|
if (onFilterChange) {
|
|
39483
39519
|
onFilterChange({});
|
|
39484
39520
|
}
|
|
39485
|
-
}, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
|
|
39521
|
+
}, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
|
|
39522
|
+
// Convert option IDs back to original label values
|
|
39523
|
+
const filtersWithLabels = {};
|
|
39524
|
+
Object.entries(selectedFilters).forEach(([groupId, optionIds]) => {
|
|
39525
|
+
const group = filterGroups.find(g => g.id === groupId);
|
|
39526
|
+
if (group) {
|
|
39527
|
+
filtersWithLabels[groupId] = optionIds.map(optionId => {
|
|
39528
|
+
const option = group.options.find(opt => opt.id === optionId);
|
|
39529
|
+
return (option === null || option === void 0 ? void 0 : option.label) || optionId;
|
|
39530
|
+
});
|
|
39531
|
+
}
|
|
39532
|
+
});
|
|
39533
|
+
onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
|
|
39534
|
+
}, disabled: isEditing, className: `${isEditing ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: "Apply Filters" })] }) })] }));
|
|
39486
39535
|
}
|
|
39487
39536
|
function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, widgetBackendUrl, datasetId, onApplyFilters, isEditing = false, }) {
|
|
39488
|
-
var _a, _b, _c, _d, _e, _f;
|
|
39537
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
39489
39538
|
const isFirstLoad = (_a = widget.config) === null || _a === void 0 ? void 0 : _a.isFirstLoad;
|
|
39490
39539
|
const widget_data = (_b = widget.widget_data) === null || _b === void 0 ? void 0 : _b.column_values;
|
|
39491
39540
|
const { setThreadId } = reactCore.useCopilotContext();
|
|
@@ -39589,11 +39638,94 @@ function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, w
|
|
|
39589
39638
|
window.removeEventListener('clearFilterState', handleClearFilterState);
|
|
39590
39639
|
};
|
|
39591
39640
|
}, [widget.id, appendMessage, setFilterState, startLoadingTimeout]);
|
|
39641
|
+
// Handle confirmation submission
|
|
39642
|
+
const handleConfirmation = React.useCallback(async (tableMapping) => {
|
|
39643
|
+
var _a, _b, _c;
|
|
39644
|
+
console.log('[FiltersWidget] handleConfirmation called with:', {
|
|
39645
|
+
tableMapping,
|
|
39646
|
+
currentFilterState: filterState,
|
|
39647
|
+
widgetQuery: (_a = widget.config) === null || _a === void 0 ? void 0 : _a.query
|
|
39648
|
+
});
|
|
39649
|
+
// Format table mapping as a JSON string for the agent
|
|
39650
|
+
const tableMappingJson = JSON.stringify(tableMapping);
|
|
39651
|
+
// Get filter columns - try multiple sources
|
|
39652
|
+
let filterColumns = filterState.filter_columns || '';
|
|
39653
|
+
// Fallback: extract from the original query if not in state
|
|
39654
|
+
if (!filterColumns && ((_b = widget.config) === null || _b === void 0 ? void 0 : _b.query)) {
|
|
39655
|
+
const filterColumnsMatch = widget.config.query.match(/(?:filter by|filter)\s+(.+)/i);
|
|
39656
|
+
filterColumns = filterColumnsMatch ? filterColumnsMatch[1].trim() : '';
|
|
39657
|
+
}
|
|
39658
|
+
// Fallback: extract from ambiguous_columns if available
|
|
39659
|
+
if (!filterColumns && filterState.ambiguous_columns) {
|
|
39660
|
+
filterColumns = filterState.ambiguous_columns.map(col => col.column).join(',');
|
|
39661
|
+
}
|
|
39662
|
+
if (!filterColumns) {
|
|
39663
|
+
console.error('[FiltersWidget] No filter_columns found in state, query, or ambiguous_columns', {
|
|
39664
|
+
filterState,
|
|
39665
|
+
query: (_c = widget.config) === null || _c === void 0 ? void 0 : _c.query
|
|
39666
|
+
});
|
|
39667
|
+
return;
|
|
39668
|
+
}
|
|
39669
|
+
console.log('[FiltersWidget] Using filter columns:', filterColumns);
|
|
39670
|
+
// Send a very explicit message for the agent to parse
|
|
39671
|
+
const message = `User confirmed table selection. Call get_tables_columns_values with filter_columns="${filterColumns}" and table_mapping='${tableMappingJson}'`;
|
|
39672
|
+
console.log('[FiltersWidget] Sending table mapping confirmation:', {
|
|
39673
|
+
message,
|
|
39674
|
+
tableMapping,
|
|
39675
|
+
filterColumns,
|
|
39676
|
+
tableMappingJson
|
|
39677
|
+
});
|
|
39678
|
+
// Clear the confirmation state completely, including agent_message
|
|
39679
|
+
const newState = {
|
|
39680
|
+
dashboard_id: datasetId || "",
|
|
39681
|
+
status: undefined, // Don't set to 'processing' as it might block polling
|
|
39682
|
+
ambiguous_columns: undefined,
|
|
39683
|
+
message: undefined,
|
|
39684
|
+
agent_message: undefined, // Clear agent_message to allow polling
|
|
39685
|
+
column_values: [], // Clear column values to show loading
|
|
39686
|
+
filter_columns: undefined, // Clear the stored filter columns
|
|
39687
|
+
};
|
|
39688
|
+
console.log('[FiltersWidget] Clearing confirmation state:', newState);
|
|
39689
|
+
setFilterState(newState);
|
|
39690
|
+
setAgentState(newState);
|
|
39691
|
+
// Send the confirmation message
|
|
39692
|
+
appendMessage(new TextMessage({
|
|
39693
|
+
content: message,
|
|
39694
|
+
role: Role.User,
|
|
39695
|
+
}));
|
|
39696
|
+
// Reset counters and start polling
|
|
39697
|
+
setApiCallCount(0);
|
|
39698
|
+
setHasTimeoutError(false);
|
|
39699
|
+
console.log('[FiltersWidget] Starting polling after confirmation');
|
|
39700
|
+
startLoadingTimeout();
|
|
39701
|
+
}, [filterState.filter_columns, filterState.ambiguous_columns, (_e = widget.config) === null || _e === void 0 ? void 0 : _e.query, datasetId, appendMessage, setFilterState, setAgentState, startLoadingTimeout, setApiCallCount, setHasTimeoutError]);
|
|
39702
|
+
const handleCancelConfirmation = React.useCallback(() => {
|
|
39703
|
+
// Clear the confirmation state
|
|
39704
|
+
setFilterState((prev) => (Object.assign(Object.assign({}, prev), { status: undefined, ambiguous_columns: undefined, message: undefined })));
|
|
39705
|
+
}, [setFilterState]);
|
|
39592
39706
|
// Convert filter state to filter groups
|
|
39593
39707
|
const filterGroups = convertFilterStateToGroups(filterState);
|
|
39594
|
-
|
|
39595
|
-
|
|
39596
|
-
|
|
39708
|
+
// Check if we're waiting for confirmation
|
|
39709
|
+
const isWaitingForConfirmation = filterState.status === 'waiting_for_confirmation' &&
|
|
39710
|
+
filterState.ambiguous_columns &&
|
|
39711
|
+
filterState.ambiguous_columns.length > 0;
|
|
39712
|
+
console.log('[CopilotKitFilters] Filter state check:', {
|
|
39713
|
+
status: filterState.status,
|
|
39714
|
+
hasAmbiguousColumns: !!filterState.ambiguous_columns,
|
|
39715
|
+
ambiguousColumnsLength: ((_f = filterState.ambiguous_columns) === null || _f === void 0 ? void 0 : _f.length) || 0,
|
|
39716
|
+
isWaitingForConfirmation,
|
|
39717
|
+
fullFilterState: filterState
|
|
39718
|
+
});
|
|
39719
|
+
return (jsxRuntimeExports.jsx("div", { className: cn("flex flex-col h-full"), children: isWaitingForConfirmation ? (
|
|
39720
|
+
// Show table selection UI when waiting for user to select tables
|
|
39721
|
+
jsxRuntimeExports.jsx(TableSelectionConfirmation, { ambiguousColumns: filterState.ambiguous_columns || [], resolvedColumns: filterState.resolved_columns, message: filterState.message || filterState.agent_message, onConfirm: handleConfirmation, onCancel: handleCancelConfirmation })) : (filterState === null || filterState === void 0 ? void 0 : filterState.agent_message) &&
|
|
39722
|
+
(!((_g = filterState.column_values) === null || _g === void 0 ? void 0 : _g.length)) &&
|
|
39723
|
+
filterState.status !== 'waiting_for_confirmation'
|
|
39724
|
+
? (
|
|
39725
|
+
// Show agent message (errors, warnings, etc.)
|
|
39726
|
+
jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full p-4", children: jsxRuntimeExports.jsx("div", { className: "text-center max-w-md", children: jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-700 whitespace-pre-line", children: filterState.agent_message }) }) })) : (
|
|
39727
|
+
// Show normal filter UI
|
|
39728
|
+
jsxRuntimeExports.jsx(FiltersContent, { filterGroups: filterGroups, showHeader: showHeader, onFilterChange: onFilterChange, widget: widget, appendMessage: appendMessage, query: (_h = widget.config) === null || _h === void 0 ? void 0 : _h.query, isFirstLoad: isFirstLoad, widgetBackendUrl: widgetBackendUrl, widgetId: widget.id, startLoadingTimeout: startLoadingTimeout, clearLoadingTimeout: clearLoadingTimeout, filterState: filterState, onApplyFilters: onApplyFilters, isEditing: isEditing })) }));
|
|
39597
39729
|
}
|
|
39598
39730
|
function FiltersWidget({ widget, showHeader = true, onConfigUpdate, onFilterChange, widgetBackendUrl, onResetReady, datasetId, onApplyFilters, isEditing = false, }) {
|
|
39599
39731
|
var _a;
|