dp-widgets-framework 1.5.9 → 1.6.1
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.esm.js +127 -25
- package/dist/index.js +127 -25
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1986,6 +1986,29 @@ function WidgetPalette({ widgetBackendUrl } = {}) {
|
|
|
1986
1986
|
}, className: "cursor-move hover:bg-accent transition-colors", children: jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [React__default.createElement(widget.icon, {}), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h4", { className: "font-medium text-sm", children: widget.name }), jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: widget.description })] })] }) }) }, widget.type))) }) })] }));
|
|
1987
1987
|
}
|
|
1988
1988
|
|
|
1989
|
+
const badgeVariants = cva("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
1990
|
+
variants: {
|
|
1991
|
+
variant: {
|
|
1992
|
+
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
1993
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
1994
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
1995
|
+
outline: "text-foreground",
|
|
1996
|
+
// Filter status variants
|
|
1997
|
+
success: "border-transparent bg-green-100 text-green-800 hover:bg-green-200",
|
|
1998
|
+
warning: "border-transparent bg-amber-100 text-amber-800 hover:bg-amber-200",
|
|
1999
|
+
muted: "border-transparent bg-gray-100 text-gray-600 hover:bg-gray-200",
|
|
2000
|
+
error: "border-transparent bg-red-100 text-red-800 hover:bg-red-200",
|
|
2001
|
+
},
|
|
2002
|
+
},
|
|
2003
|
+
defaultVariants: {
|
|
2004
|
+
variant: "default",
|
|
2005
|
+
},
|
|
2006
|
+
});
|
|
2007
|
+
function Badge(_a) {
|
|
2008
|
+
var { className, variant } = _a, props = __rest(_a, ["className", "variant"]);
|
|
2009
|
+
return (jsxRuntimeExports.jsx("div", Object.assign({ className: cn(badgeVariants({ variant }), className) }, props)));
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1989
2012
|
const borderRadiusMap$2 = {
|
|
1990
2013
|
none: "0px",
|
|
1991
2014
|
rounded: "0.375rem",
|
|
@@ -39327,6 +39350,10 @@ const parseAndUpdateFilterState = (apiResponse, setFilterState) => {
|
|
|
39327
39350
|
if (filterData.agent_message) {
|
|
39328
39351
|
newFilterState.agent_message = filterData.agent_message;
|
|
39329
39352
|
}
|
|
39353
|
+
// Handle error key as a fallback for agent_message
|
|
39354
|
+
if (filterData.error && !newFilterState.agent_message) {
|
|
39355
|
+
newFilterState.agent_message = filterData.error;
|
|
39356
|
+
}
|
|
39330
39357
|
// Handle confirmation state
|
|
39331
39358
|
if (filterData.status) {
|
|
39332
39359
|
newFilterState.status = filterData.status;
|
|
@@ -39382,9 +39409,9 @@ function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message
|
|
|
39382
39409
|
onConfirm(selectedTables);
|
|
39383
39410
|
};
|
|
39384
39411
|
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(
|
|
39412
|
+
return (jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full p-4 bg-white overflow-hidden", children: [jsxRuntimeExports.jsxs("div", { className: "mb-4 flex-shrink-0", 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 flex-shrink-0", 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("div", { className: "flex-1 overflow-y-auto mb-4 min-h-0 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", 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
39413
|
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" })] })] }));
|
|
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 flex-shrink-0", 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
39415
|
}
|
|
39389
39416
|
function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
|
|
39390
39417
|
var _a;
|
|
@@ -39499,19 +39526,19 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
|
|
|
39499
39526
|
if (isEmpty) {
|
|
39500
39527
|
return createLoadingComponent$4();
|
|
39501
39528
|
}
|
|
39502
|
-
return (jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col bg-white rounded-lg", children: [showHeader && (jsxRuntimeExports.jsx("div", { className: "px-4 py-3 border-b border-gray-100", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntimeExports.jsx(Bot, { className: "h-4 w-4" }), jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-800", children: "Filters" })] }) })), jsxRuntimeExports.jsx(
|
|
39529
|
+
return (jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col bg-white rounded-lg overflow-hidden", children: [showHeader && (jsxRuntimeExports.jsx("div", { className: "px-4 py-3 border-b border-gray-100 flex-shrink-0", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntimeExports.jsx(Bot, { className: "h-4 w-4" }), jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-800", children: "Filters" })] }) })), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto min-h-0 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", children: jsxRuntimeExports.jsx("div", { className: "p-2", children: filterGroups.map((group) => {
|
|
39503
39530
|
const isExpanded = expandedGroups[group.id];
|
|
39504
39531
|
const selectedCount = getSelectedCount(group.id);
|
|
39505
39532
|
const filteredOptions = getFilteredOptions(group);
|
|
39506
39533
|
return (jsxRuntimeExports.jsxs("div", { className: "mb-2 border border-gray-100 rounded-lg overflow-hidden", children: [jsxRuntimeExports.jsxs("button", { onClick: () => toggleGroup(group.id), className: cn("w-full flex items-center justify-between px-3 py-2.5", "bg-gray-50 hover:bg-gray-100 transition-colors", "focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-inset"), children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [isExpanded ? (jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4 text-primary-600" })) : (jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4 text-gray-500" })), jsxRuntimeExports.jsx("span", { className: "font-medium text-sm text-gray-700", children: group.name }), selectedCount > 0 && (jsxRuntimeExports.jsx("span", { className: "ml-1 px-1.5 py-0.5 text-xs font-medium bg-primary-100 text-primary-700 rounded-full", children: selectedCount }))] }), selectedCount > 0 && (jsxRuntimeExports.jsx("button", { onClick: (e) => {
|
|
39507
39534
|
e.stopPropagation();
|
|
39508
39535
|
clearGroupFilters(group.id);
|
|
39509
|
-
}, className: "text-xs text-primary-600 hover:text-primary-800 hover:underline", children: "Clear" }))] }), jsxRuntimeExports.jsx("div", { className: cn("overflow-hidden transition-all duration-200 ease-in-out", isExpanded ? "max-h-[
|
|
39536
|
+
}, className: "text-xs text-primary-600 hover:text-primary-800 hover:underline", children: "Clear" }))] }), jsxRuntimeExports.jsx("div", { className: cn("overflow-hidden transition-all duration-200 ease-in-out", isExpanded ? "max-h-[500px]" : "max-h-0"), children: jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 bg-white", children: [group.options.length > 5 && (jsxRuntimeExports.jsxs("div", { className: "relative mb-2", children: [jsxRuntimeExports.jsx(Search, { className: "absolute left-2.5 top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 text-gray-400" }), jsxRuntimeExports.jsx(Input, { type: "text", placeholder: `Search ${group.name.toLowerCase()}...`, value: searchQueries[group.id] || "", onChange: (e) => handleSearchChange(group.id, e.target.value), className: "pl-8 h-8 text-sm border-gray-200 focus:border-primary-400 focus:ring-primary-400" })] })), jsxRuntimeExports.jsx("div", { className: "space-y-1 max-h-[350px] overflow-y-auto pr-1 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", children: filteredOptions.length === 0 ? (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 py-2 text-center", children: "No options found" })) : (filteredOptions.map((option) => {
|
|
39510
39537
|
var _a;
|
|
39511
39538
|
const isChecked = ((_a = selectedFilters[group.id]) === null || _a === void 0 ? void 0 : _a.includes(option.id)) || false;
|
|
39512
39539
|
return (jsxRuntimeExports.jsxs("label", { className: cn("flex items-center gap-2.5 px-2 py-1.5 rounded-md cursor-pointer", "hover:bg-gray-50 transition-colors", isChecked && "bg-primary-50"), children: [jsxRuntimeExports.jsx(Checkbox, { checked: isChecked, onCheckedChange: (checked) => handleCheckboxChange(group.id, option.id, checked), className: cn("h-4 w-4 rounded border-gray-300", "data-[state=checked]:bg-primary-600 data-[state=checked]:border-primary-600") }), jsxRuntimeExports.jsx("span", { className: cn("text-sm flex-1 truncate", isChecked ? "text-primary-700 font-medium" : "text-gray-600"), title: option.label, children: option.label }), option.count !== undefined && (jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400", children: ["(", option.count, ")"] }))] }, option.id));
|
|
39513
39540
|
})) })] }) })] }, group.id));
|
|
39514
|
-
}) }) }), jsxRuntimeExports.jsx("div", { className: "px-4 py-2 border-t border-gray-100 bg-gray-50", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [Object.values(selectedFilters).some((arr) => arr.length > 0) ? (jsxRuntimeExports.jsx("button", { onClick: () => {
|
|
39541
|
+
}) }) }), jsxRuntimeExports.jsx("div", { className: "px-4 py-2 border-t border-gray-100 bg-gray-50 flex-shrink-0", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [Object.values(selectedFilters).some((arr) => arr.length > 0) ? (jsxRuntimeExports.jsx("button", { onClick: () => {
|
|
39515
39542
|
setSelectedFilters({});
|
|
39516
39543
|
if (onFilterChange) {
|
|
39517
39544
|
onFilterChange({});
|
|
@@ -41410,7 +41437,7 @@ const IconMap = {
|
|
|
41410
41437
|
'pie-chart': PieChart$1,
|
|
41411
41438
|
'chatbot': Bot,
|
|
41412
41439
|
};
|
|
41413
|
-
function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters,
|
|
41440
|
+
function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters, filterResults, isApplyingFilters = false }) {
|
|
41414
41441
|
const [widgets, setWidgets] = useState([]);
|
|
41415
41442
|
const [datasetId, setDatasetId] = useState('');
|
|
41416
41443
|
const [availableWidgets, setAvailableWidgets] = useState([]);
|
|
@@ -41425,6 +41452,31 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41425
41452
|
const [editInitialQuery, setEditInitialQuery] = useState("");
|
|
41426
41453
|
const [editingWidget, setEditingWidget] = useState(null);
|
|
41427
41454
|
const [widgetResetFunctions, setWidgetResetFunctions] = useState(new Map());
|
|
41455
|
+
// Helper to get filter status for a widget
|
|
41456
|
+
const getWidgetFilterStatus = useCallback((widgetId) => {
|
|
41457
|
+
if (!filterResults)
|
|
41458
|
+
return null;
|
|
41459
|
+
// Only show status for agent widgets
|
|
41460
|
+
const result = filterResults.results.find(r => r.widgetId === widgetId);
|
|
41461
|
+
if (!result)
|
|
41462
|
+
return null;
|
|
41463
|
+
return result;
|
|
41464
|
+
}, [filterResults]);
|
|
41465
|
+
// Helper to get badge variant based on filter status
|
|
41466
|
+
const getFilterStatusBadge = (status) => {
|
|
41467
|
+
switch (status) {
|
|
41468
|
+
case "updated":
|
|
41469
|
+
return { variant: "success", label: "Filtered", icon: "✓" };
|
|
41470
|
+
case "no_data":
|
|
41471
|
+
return { variant: "warning", label: "No Data", icon: "⚠" };
|
|
41472
|
+
case "skipped":
|
|
41473
|
+
return { variant: "muted", label: "Skipped", icon: "−" };
|
|
41474
|
+
case "failed":
|
|
41475
|
+
return { variant: "error", label: "Failed", icon: "✕" };
|
|
41476
|
+
default:
|
|
41477
|
+
return { variant: "muted", label: status, icon: "?" };
|
|
41478
|
+
}
|
|
41479
|
+
};
|
|
41428
41480
|
// Use external selectedWidget if provided, otherwise use internal state
|
|
41429
41481
|
const currentSelectedWidget = selectedWidget !== undefined ? selectedWidget : internalSelectedWidget;
|
|
41430
41482
|
const setSelectedWidget = onWidgetSelect || setInternalSelectedWidget;
|
|
@@ -41489,6 +41541,19 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41489
41541
|
}
|
|
41490
41542
|
});
|
|
41491
41543
|
window.dispatchEvent(event);
|
|
41544
|
+
// If filters have been applied (filter widget exists), regenerate filtered_sql_query for this widget
|
|
41545
|
+
// This handles the case where a widget's query is changed after filters have been applied
|
|
41546
|
+
const hasFilterWidget = widgets.some(w => w.type === 'filters');
|
|
41547
|
+
if (hasFilterWidget && editingWidget.type === 'agent' && widgetBackendUrl) {
|
|
41548
|
+
// Dispatch event to notify that filtered query needs regeneration for this widget
|
|
41549
|
+
const regenerateEvent = new CustomEvent('regenerateFilteredQuery', {
|
|
41550
|
+
detail: {
|
|
41551
|
+
widgetId: editingWidget.id,
|
|
41552
|
+
dashboardId: pageId
|
|
41553
|
+
}
|
|
41554
|
+
});
|
|
41555
|
+
window.dispatchEvent(regenerateEvent);
|
|
41556
|
+
}
|
|
41492
41557
|
}
|
|
41493
41558
|
};
|
|
41494
41559
|
const handleResetReady = useCallback((widgetId, resetFn) => {
|
|
@@ -41580,6 +41645,15 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41580
41645
|
};
|
|
41581
41646
|
loadWidgetTypes();
|
|
41582
41647
|
}, []);
|
|
41648
|
+
// Track original widget IDs from initial load
|
|
41649
|
+
const originalWidgetIdsRef = useRef(new Set());
|
|
41650
|
+
// Update original widget IDs when widgets are loaded from server
|
|
41651
|
+
useEffect(() => {
|
|
41652
|
+
if (pageData === null || pageData === void 0 ? void 0 : pageData.widgets) {
|
|
41653
|
+
const ids = new Set(pageData.widgets.map((w) => w.id));
|
|
41654
|
+
originalWidgetIdsRef.current = ids;
|
|
41655
|
+
}
|
|
41656
|
+
}, [pageData]);
|
|
41583
41657
|
// Use ref to store the latest save function without causing re-renders
|
|
41584
41658
|
const saveLayoutRef = useRef();
|
|
41585
41659
|
// Update the ref whenever dependencies change
|
|
@@ -41587,6 +41661,13 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41587
41661
|
if (!pageData) {
|
|
41588
41662
|
throw new Error("No page data available");
|
|
41589
41663
|
}
|
|
41664
|
+
// Identify new agent widgets (added since last load/save)
|
|
41665
|
+
const currentWidgetIds = new Set(widgets.map(w => w.id));
|
|
41666
|
+
const newAgentWidgetIds = widgets
|
|
41667
|
+
.filter(w => w.type === 'agent' && !originalWidgetIdsRef.current.has(w.id))
|
|
41668
|
+
.map(w => w.id);
|
|
41669
|
+
// Check if there's a filter widget on this dashboard
|
|
41670
|
+
const hasFilterWidget = widgets.some(w => w.type === 'filters');
|
|
41590
41671
|
try {
|
|
41591
41672
|
const response = await fetch(getApiUrl(`/api/pages/${pageId}`), {
|
|
41592
41673
|
method: "PUT",
|
|
@@ -41604,16 +41685,42 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41604
41685
|
throw new Error("Failed to save layout");
|
|
41605
41686
|
}
|
|
41606
41687
|
const savedData = await response.json();
|
|
41607
|
-
//
|
|
41608
|
-
|
|
41609
|
-
// setWidgets(prevWidgets => prevWidgets.map(widget => ({
|
|
41610
|
-
// ...widget,
|
|
41611
|
-
// config: {
|
|
41612
|
-
// ...widget.config,
|
|
41613
|
-
// isFirstLoad: false
|
|
41614
|
-
// }
|
|
41615
|
-
// })));
|
|
41688
|
+
// Update original widget IDs to include newly saved widgets
|
|
41689
|
+
originalWidgetIdsRef.current = currentWidgetIds;
|
|
41616
41690
|
console.log('Layout saved successfully');
|
|
41691
|
+
// If there are new agent widgets and a filter widget exists,
|
|
41692
|
+
// schedule generation of filtered_sql_query for new widgets
|
|
41693
|
+
// Note: This is done asynchronously after save to not block the save operation
|
|
41694
|
+
// The actual generation will happen after the widget agents have run and created sql_query
|
|
41695
|
+
if (newAgentWidgetIds.length > 0 && hasFilterWidget) {
|
|
41696
|
+
console.log(`[WidgetDashboard] New agent widgets detected: ${newAgentWidgetIds.join(', ')}`);
|
|
41697
|
+
console.log('[WidgetDashboard] Filter widget exists - filtered_sql_query will be generated when filters are applied');
|
|
41698
|
+
// Optionally, we could trigger generation after a delay to allow widget agents to initialize
|
|
41699
|
+
// For now, we rely on the auto-generation in /api/filters/apply when filters are applied
|
|
41700
|
+
// Uncomment below to proactively generate after a delay:
|
|
41701
|
+
/*
|
|
41702
|
+
setTimeout(async () => {
|
|
41703
|
+
try {
|
|
41704
|
+
console.log('[WidgetDashboard] Generating filtered_sql_query for new widgets...');
|
|
41705
|
+
const generateResponse = await fetch(getApiUrl('/api/filters/generate-queries'), {
|
|
41706
|
+
method: 'POST',
|
|
41707
|
+
headers: { 'Content-Type': 'application/json' },
|
|
41708
|
+
body: JSON.stringify({
|
|
41709
|
+
dashboard_id: pageId,
|
|
41710
|
+
widget_ids: newAgentWidgetIds,
|
|
41711
|
+
regenerate: false,
|
|
41712
|
+
}),
|
|
41713
|
+
});
|
|
41714
|
+
if (generateResponse.ok) {
|
|
41715
|
+
const result = await generateResponse.json();
|
|
41716
|
+
console.log('[WidgetDashboard] Generate queries result:', result);
|
|
41717
|
+
}
|
|
41718
|
+
} catch (err) {
|
|
41719
|
+
console.warn('[WidgetDashboard] Could not generate filtered queries for new widgets:', err);
|
|
41720
|
+
}
|
|
41721
|
+
}, 5000); // 5 second delay to allow widget agents to initialize
|
|
41722
|
+
*/
|
|
41723
|
+
}
|
|
41617
41724
|
}
|
|
41618
41725
|
catch (err) {
|
|
41619
41726
|
console.error("Save error:", err);
|
|
@@ -41893,10 +42000,10 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41893
42000
|
onCloseWidgetPallete && onCloseWidgetPallete();
|
|
41894
42001
|
}, defaultAgentName: defaultAgentName, hasFiltersWidget: widgets.some(w => w.type === 'filters') }), jsxRuntimeExports.jsx(EditWidgetDialog, { editingWidget: editingWidget, setWidgets: setWidgets, initialText: editInitialQuery, isOpen: showEditModal, onClose: () => setShowEditModal(false), onSubmit: handleEditSubmit }), jsxRuntimeExports.jsx("div", { className: "min-h-full", onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, onClick: () => setSelectedWidget(null), children: isLoading ? (jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: jsxRuntimeExports.jsx(Loader2, { className: "h-8 w-8 animate-spin" }) })) : (jsxRuntimeExports.jsx(RGL, { className: "layout m-0 p-0 gap-2", layouts: { lg: getLayoutFromWidgets() }, breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480 }, cols: { lg: 12, md: 8, sm: 6, xs: 2 }, rowHeight: 60, isDraggable: isEditing, isResizable: isEditing, draggableHandle: ".drag-icon", onLayoutChange: handleLayoutChange, compactType: "vertical", containerPadding: [0, 0], margin: [16, 16], children: widgets.map((w) => {
|
|
41895
42002
|
var _a, _b;
|
|
41896
|
-
const
|
|
41897
|
-
const
|
|
41898
|
-
return (jsxRuntimeExports.jsxs("div", { className: `${(w.type === "text" || w.type === "spacer") ? `${((_b = (_a = w === null || w === void 0 ? void 0 : w.config) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.divider) === "yes" && "border-b border-gray-300"} ${isEditing ? 'shadow-lg rounded-xl border border-primary-300' : 'flex items-center'}` : `shadow-lg rounded-xl border border-primary-300 p-4 ${isEditing ? 'pb-14' : 'pb-5'}`}`, children: [isEditing &&
|
|
41899
|
-
jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-end mb-4 relative ${(w.type === "text" || w.type === "spacer") ? "pl-4 pr-4 pt-4" : ""}`, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center drag-icon cursor-grab absolute left-1/2 -translate-x-1/2", children: [jsxRuntimeExports.jsx(GripHorizontal, { className: "" }), jsxRuntimeExports.jsx(GripHorizontal, { className: "-ml-[3px]" }), jsxRuntimeExports.jsx(GripHorizontal, { className: "-ml-[3px]" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 cursor-pointer justify-end", children: [jsxRuntimeExports.jsx(Trash2, { onClick: () => removeWidget(w.id), className: "w-5 h-5 text-red-700" }), (w.type !== "spacer" && w.type !== "chatbot") && jsxRuntimeExports.jsx(Edit, { onClick: () => onClickSettings && onClickSettings(w), className: "w-5 h-5 text-gray-600" })] })] }),
|
|
42003
|
+
const filterStatus = w.type === 'agent' ? getWidgetFilterStatus(w.id) : null;
|
|
42004
|
+
const badgeInfo = filterStatus ? getFilterStatusBadge(filterStatus.status) : null;
|
|
42005
|
+
return (jsxRuntimeExports.jsxs("div", { className: `${(w.type === "text" || w.type === "spacer") ? `${((_b = (_a = w === null || w === void 0 ? void 0 : w.config) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.divider) === "yes" && "border-b border-gray-300"} ${isEditing ? 'shadow-lg rounded-xl border border-primary-300' : 'flex items-center'}` : `shadow-lg rounded-xl border border-primary-300 p-4 ${isEditing ? 'pb-14' : 'pb-5'}`} relative`, children: [w.type === 'agent' && badgeInfo && !isApplyingFilters && (jsxRuntimeExports.jsx("div", { className: "absolute top-2 right-2 z-10", title: (filterStatus === null || filterStatus === void 0 ? void 0 : filterStatus.reason) || (filterStatus === null || filterStatus === void 0 ? void 0 : filterStatus.error) || '', children: jsxRuntimeExports.jsxs(Badge, { variant: badgeInfo.variant, className: "text-[10px] px-2 py-0.5 gap-1", children: [jsxRuntimeExports.jsx("span", { children: badgeInfo.icon }), jsxRuntimeExports.jsx("span", { children: badgeInfo.label })] }) })), w.type === 'agent' && isApplyingFilters && (jsxRuntimeExports.jsx("div", { className: "absolute top-2 right-2 z-10", children: jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "text-[10px] px-2 py-0.5 gap-1 animate-pulse", children: [jsxRuntimeExports.jsx(Loader2, { className: "w-3 h-3 animate-spin" }), jsxRuntimeExports.jsx("span", { children: "Filtering..." })] }) })), isEditing &&
|
|
42006
|
+
jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-end mb-4 relative ${(w.type === "text" || w.type === "spacer") ? "pl-4 pr-4 pt-4" : ""}`, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center drag-icon cursor-grab absolute left-1/2 -translate-x-1/2", children: [jsxRuntimeExports.jsx(GripHorizontal, { className: "" }), jsxRuntimeExports.jsx(GripHorizontal, { className: "-ml-[3px]" }), jsxRuntimeExports.jsx(GripHorizontal, { className: "-ml-[3px]" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 cursor-pointer justify-end", children: [jsxRuntimeExports.jsx(Trash2, { onClick: () => removeWidget(w.id), className: "w-5 h-5 text-red-700" }), (w.type !== "spacer" && w.type !== "chatbot") && jsxRuntimeExports.jsx(Edit, { onClick: () => onClickSettings && onClickSettings(w), className: "w-5 h-5 text-gray-600" })] })] }), jsxRuntimeExports.jsxs("div", { className: `${((w === null || w === void 0 ? void 0 : w.type) === 'text' || (w === null || w === void 0 ? void 0 : w.type) === 'spacer') ? `${isEditing ? 'px-4' : ''}` : "h-full"} w-full relative`, children: [(w === null || w === void 0 ? void 0 : w.type) === "chatbot" &&
|
|
41900
42007
|
jsxRuntimeExports.jsxs("div", { className: "relative z-50", children: [jsxRuntimeExports.jsx("div", { onClick: () => handleClearChat(w === null || w === void 0 ? void 0 : w.id), onMouseOver: () => setVisibleClearButton(w === null || w === void 0 ? void 0 : w.id), onMouseLeave: () => setVisibleClearButton(""), className: "absolute top-[12px] right-0 z-40 flex align-middle justify-center gap-2 text-sm px-4 py-2 border-primary-300 rounded-l-sm w-fit bg-primary-700 text-white cursor-pointer shadow-md transition-all", children: jsxRuntimeExports.jsx(MessageCircleX, { className: "w-5 h-5" }) }), jsxRuntimeExports.jsx("span", { className: `absolute top-[56px] right-[16px] z-50 w-max py-1 text-xs px-2 rounded-sm text-white bg-gray-950 ${visibleClearButton === (w === null || w === void 0 ? void 0 : w.id) ? "block" : "hidden"}`, children: "Clear Chat" })] }), jsxRuntimeExports.jsx(WidgetRenderer, { widget: w, widgetBackendUrl: widgetBackendUrl, onResetReady: handleResetReady, widgetIds: widgets.filter(widget => widget.type !== 'chatbot').map(widget => widget.id), datasetId: datasetId, pageId: pageId, onApplyFilters: onApplyFilters, isEditing: isEditing })] })] }, w.id));
|
|
41901
42008
|
}) })) })] }));
|
|
41902
42009
|
}
|
|
@@ -44794,7 +44901,6 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44794
44901
|
const [pages, setPages] = useState([]);
|
|
44795
44902
|
const [isLoading, setIsLoading] = useState(true);
|
|
44796
44903
|
const [error, setError] = useState(null);
|
|
44797
|
-
const [activeFilters, setActiveFilters] = useState({});
|
|
44798
44904
|
// Helper function to get API URL
|
|
44799
44905
|
const getApiUrl = (endpoint) => {
|
|
44800
44906
|
const baseUrl = widgetBackendUrl || '';
|
|
@@ -44803,10 +44909,6 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44803
44909
|
useEffect(() => {
|
|
44804
44910
|
loadPages();
|
|
44805
44911
|
}, []);
|
|
44806
|
-
const handleApplyFilters = (pageId) => (filters) => {
|
|
44807
|
-
console.log('Filters applied for page:', pageId, filters);
|
|
44808
|
-
setActiveFilters(prev => (Object.assign(Object.assign({}, prev), { [pageId]: filters })));
|
|
44809
|
-
};
|
|
44810
44912
|
const loadPages = async () => {
|
|
44811
44913
|
try {
|
|
44812
44914
|
setIsLoading(true);
|
|
@@ -44851,7 +44953,7 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44851
44953
|
}
|
|
44852
44954
|
return (jsxRuntimeExports.jsxs("div", { className: "container mx-auto p-6 h-screen flex flex-col", children: [jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [jsxRuntimeExports.jsx("h1", { className: "text-2xl font-bold", children: "Dashboard Pages" }), jsxRuntimeExports.jsx("p", { className: "text-muted-foreground", children: "View all your saved pages in dashboard mode" })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: jsxRuntimeExports.jsxs(Tabs, { defaultValue: (_a = pages[0]) === null || _a === void 0 ? void 0 : _a.id, className: "h-full flex flex-col", children: [jsxRuntimeExports.jsx(TabsList, { className: "grid w-full grid-cols-auto gap-1 mb-4", style: {
|
|
44853
44955
|
gridTemplateColumns: `repeat(${pages.length}, minmax(120px, 1fr))`
|
|
44854
|
-
}, children: pages.map((page) => (jsxRuntimeExports.jsx(TabsTrigger, { value: page.id, className: "truncate px-3 py-2 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-lg border-2 data-[state=active]:border-primary data-[state=inactive]:border-transparent hover:bg-accent hover:text-accent-foreground transition-all duration-200", title: page.title, children: page.title }, page.id))) }), pages.map((page) => (jsxRuntimeExports.jsx(TabsContent, { value: page.id, className: "flex-1 overflow-hidden m-0", children: jsxRuntimeExports.jsx("div", { className: "h-full border rounded-lg overflow-hidden", children: jsxRuntimeExports.jsx(WidgetDashboard, { pageId: page.id, isEditing: false, widgetBackendUrl: widgetBackendUrl
|
|
44956
|
+
}, children: pages.map((page) => (jsxRuntimeExports.jsx(TabsTrigger, { value: page.id, className: "truncate px-3 py-2 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-lg border-2 data-[state=active]:border-primary data-[state=inactive]:border-transparent hover:bg-accent hover:text-accent-foreground transition-all duration-200", title: page.title, children: page.title }, page.id))) }), pages.map((page) => (jsxRuntimeExports.jsx(TabsContent, { value: page.id, className: "flex-1 overflow-hidden m-0", children: jsxRuntimeExports.jsx("div", { className: "h-full border rounded-lg overflow-hidden", children: jsxRuntimeExports.jsx(WidgetDashboard, { pageId: page.id, isEditing: false, widgetBackendUrl: widgetBackendUrl }) }) }, page.id)))] }) })] }));
|
|
44855
44957
|
}
|
|
44856
44958
|
|
|
44857
44959
|
export { Button, DashboardPages, Input, SavedPages, WidgetDashboard, WidgetPalette, WidgetSettingsPanel, cn };
|
package/dist/index.js
CHANGED
|
@@ -2013,6 +2013,29 @@ function WidgetPalette({ widgetBackendUrl } = {}) {
|
|
|
2013
2013
|
}, className: "cursor-move hover:bg-accent transition-colors", children: jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [React.createElement(widget.icon, {}), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h4", { className: "font-medium text-sm", children: widget.name }), jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: widget.description })] })] }) }) }, widget.type))) }) })] }));
|
|
2014
2014
|
}
|
|
2015
2015
|
|
|
2016
|
+
const badgeVariants = classVarianceAuthority.cva("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
2017
|
+
variants: {
|
|
2018
|
+
variant: {
|
|
2019
|
+
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
2020
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
2021
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
2022
|
+
outline: "text-foreground",
|
|
2023
|
+
// Filter status variants
|
|
2024
|
+
success: "border-transparent bg-green-100 text-green-800 hover:bg-green-200",
|
|
2025
|
+
warning: "border-transparent bg-amber-100 text-amber-800 hover:bg-amber-200",
|
|
2026
|
+
muted: "border-transparent bg-gray-100 text-gray-600 hover:bg-gray-200",
|
|
2027
|
+
error: "border-transparent bg-red-100 text-red-800 hover:bg-red-200",
|
|
2028
|
+
},
|
|
2029
|
+
},
|
|
2030
|
+
defaultVariants: {
|
|
2031
|
+
variant: "default",
|
|
2032
|
+
},
|
|
2033
|
+
});
|
|
2034
|
+
function Badge(_a) {
|
|
2035
|
+
var { className, variant } = _a, props = __rest(_a, ["className", "variant"]);
|
|
2036
|
+
return (jsxRuntimeExports.jsx("div", Object.assign({ className: cn(badgeVariants({ variant }), className) }, props)));
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2016
2039
|
const borderRadiusMap$2 = {
|
|
2017
2040
|
none: "0px",
|
|
2018
2041
|
rounded: "0.375rem",
|
|
@@ -39354,6 +39377,10 @@ const parseAndUpdateFilterState = (apiResponse, setFilterState) => {
|
|
|
39354
39377
|
if (filterData.agent_message) {
|
|
39355
39378
|
newFilterState.agent_message = filterData.agent_message;
|
|
39356
39379
|
}
|
|
39380
|
+
// Handle error key as a fallback for agent_message
|
|
39381
|
+
if (filterData.error && !newFilterState.agent_message) {
|
|
39382
|
+
newFilterState.agent_message = filterData.error;
|
|
39383
|
+
}
|
|
39357
39384
|
// Handle confirmation state
|
|
39358
39385
|
if (filterData.status) {
|
|
39359
39386
|
newFilterState.status = filterData.status;
|
|
@@ -39409,9 +39436,9 @@ function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message
|
|
|
39409
39436
|
onConfirm(selectedTables);
|
|
39410
39437
|
};
|
|
39411
39438
|
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(
|
|
39439
|
+
return (jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full p-4 bg-white overflow-hidden", children: [jsxRuntimeExports.jsxs("div", { className: "mb-4 flex-shrink-0", 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 flex-shrink-0", 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("div", { className: "flex-1 overflow-y-auto mb-4 min-h-0 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", 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
39440
|
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" })] })] }));
|
|
39441
|
+
}, 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 flex-shrink-0", 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
39442
|
}
|
|
39416
39443
|
function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
|
|
39417
39444
|
var _a;
|
|
@@ -39526,19 +39553,19 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
|
|
|
39526
39553
|
if (isEmpty) {
|
|
39527
39554
|
return createLoadingComponent$4();
|
|
39528
39555
|
}
|
|
39529
|
-
return (jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col bg-white rounded-lg", children: [showHeader && (jsxRuntimeExports.jsx("div", { className: "px-4 py-3 border-b border-gray-100", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntimeExports.jsx(lucideReact.Bot, { className: "h-4 w-4" }), jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-800", children: "Filters" })] }) })), jsxRuntimeExports.jsx(
|
|
39556
|
+
return (jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col bg-white rounded-lg overflow-hidden", children: [showHeader && (jsxRuntimeExports.jsx("div", { className: "px-4 py-3 border-b border-gray-100 flex-shrink-0", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntimeExports.jsx(lucideReact.Bot, { className: "h-4 w-4" }), jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-800", children: "Filters" })] }) })), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto min-h-0 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", children: jsxRuntimeExports.jsx("div", { className: "p-2", children: filterGroups.map((group) => {
|
|
39530
39557
|
const isExpanded = expandedGroups[group.id];
|
|
39531
39558
|
const selectedCount = getSelectedCount(group.id);
|
|
39532
39559
|
const filteredOptions = getFilteredOptions(group);
|
|
39533
39560
|
return (jsxRuntimeExports.jsxs("div", { className: "mb-2 border border-gray-100 rounded-lg overflow-hidden", children: [jsxRuntimeExports.jsxs("button", { onClick: () => toggleGroup(group.id), className: cn("w-full flex items-center justify-between px-3 py-2.5", "bg-gray-50 hover:bg-gray-100 transition-colors", "focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-inset"), children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [isExpanded ? (jsxRuntimeExports.jsx(lucideReact.ChevronDown, { className: "w-4 h-4 text-primary-600" })) : (jsxRuntimeExports.jsx(lucideReact.ChevronRight, { className: "w-4 h-4 text-gray-500" })), jsxRuntimeExports.jsx("span", { className: "font-medium text-sm text-gray-700", children: group.name }), selectedCount > 0 && (jsxRuntimeExports.jsx("span", { className: "ml-1 px-1.5 py-0.5 text-xs font-medium bg-primary-100 text-primary-700 rounded-full", children: selectedCount }))] }), selectedCount > 0 && (jsxRuntimeExports.jsx("button", { onClick: (e) => {
|
|
39534
39561
|
e.stopPropagation();
|
|
39535
39562
|
clearGroupFilters(group.id);
|
|
39536
|
-
}, className: "text-xs text-primary-600 hover:text-primary-800 hover:underline", children: "Clear" }))] }), jsxRuntimeExports.jsx("div", { className: cn("overflow-hidden transition-all duration-200 ease-in-out", isExpanded ? "max-h-[
|
|
39563
|
+
}, className: "text-xs text-primary-600 hover:text-primary-800 hover:underline", children: "Clear" }))] }), jsxRuntimeExports.jsx("div", { className: cn("overflow-hidden transition-all duration-200 ease-in-out", isExpanded ? "max-h-[500px]" : "max-h-0"), children: jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 bg-white", children: [group.options.length > 5 && (jsxRuntimeExports.jsxs("div", { className: "relative mb-2", children: [jsxRuntimeExports.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 text-gray-400" }), jsxRuntimeExports.jsx(Input, { type: "text", placeholder: `Search ${group.name.toLowerCase()}...`, value: searchQueries[group.id] || "", onChange: (e) => handleSearchChange(group.id, e.target.value), className: "pl-8 h-8 text-sm border-gray-200 focus:border-primary-400 focus:ring-primary-400" })] })), jsxRuntimeExports.jsx("div", { className: "space-y-1 max-h-[350px] overflow-y-auto pr-1 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent", children: filteredOptions.length === 0 ? (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 py-2 text-center", children: "No options found" })) : (filteredOptions.map((option) => {
|
|
39537
39564
|
var _a;
|
|
39538
39565
|
const isChecked = ((_a = selectedFilters[group.id]) === null || _a === void 0 ? void 0 : _a.includes(option.id)) || false;
|
|
39539
39566
|
return (jsxRuntimeExports.jsxs("label", { className: cn("flex items-center gap-2.5 px-2 py-1.5 rounded-md cursor-pointer", "hover:bg-gray-50 transition-colors", isChecked && "bg-primary-50"), children: [jsxRuntimeExports.jsx(Checkbox, { checked: isChecked, onCheckedChange: (checked) => handleCheckboxChange(group.id, option.id, checked), className: cn("h-4 w-4 rounded border-gray-300", "data-[state=checked]:bg-primary-600 data-[state=checked]:border-primary-600") }), jsxRuntimeExports.jsx("span", { className: cn("text-sm flex-1 truncate", isChecked ? "text-primary-700 font-medium" : "text-gray-600"), title: option.label, children: option.label }), option.count !== undefined && (jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400", children: ["(", option.count, ")"] }))] }, option.id));
|
|
39540
39567
|
})) })] }) })] }, group.id));
|
|
39541
|
-
}) }) }), jsxRuntimeExports.jsx("div", { className: "px-4 py-2 border-t border-gray-100 bg-gray-50", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [Object.values(selectedFilters).some((arr) => arr.length > 0) ? (jsxRuntimeExports.jsx("button", { onClick: () => {
|
|
39568
|
+
}) }) }), jsxRuntimeExports.jsx("div", { className: "px-4 py-2 border-t border-gray-100 bg-gray-50 flex-shrink-0", children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [Object.values(selectedFilters).some((arr) => arr.length > 0) ? (jsxRuntimeExports.jsx("button", { onClick: () => {
|
|
39542
39569
|
setSelectedFilters({});
|
|
39543
39570
|
if (onFilterChange) {
|
|
39544
39571
|
onFilterChange({});
|
|
@@ -41437,7 +41464,7 @@ const IconMap = {
|
|
|
41437
41464
|
'pie-chart': lucideReact.PieChart,
|
|
41438
41465
|
'chatbot': lucideReact.Bot,
|
|
41439
41466
|
};
|
|
41440
|
-
function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters,
|
|
41467
|
+
function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters, filterResults, isApplyingFilters = false }) {
|
|
41441
41468
|
const [widgets, setWidgets] = React.useState([]);
|
|
41442
41469
|
const [datasetId, setDatasetId] = React.useState('');
|
|
41443
41470
|
const [availableWidgets, setAvailableWidgets] = React.useState([]);
|
|
@@ -41452,6 +41479,31 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41452
41479
|
const [editInitialQuery, setEditInitialQuery] = React.useState("");
|
|
41453
41480
|
const [editingWidget, setEditingWidget] = React.useState(null);
|
|
41454
41481
|
const [widgetResetFunctions, setWidgetResetFunctions] = React.useState(new Map());
|
|
41482
|
+
// Helper to get filter status for a widget
|
|
41483
|
+
const getWidgetFilterStatus = React.useCallback((widgetId) => {
|
|
41484
|
+
if (!filterResults)
|
|
41485
|
+
return null;
|
|
41486
|
+
// Only show status for agent widgets
|
|
41487
|
+
const result = filterResults.results.find(r => r.widgetId === widgetId);
|
|
41488
|
+
if (!result)
|
|
41489
|
+
return null;
|
|
41490
|
+
return result;
|
|
41491
|
+
}, [filterResults]);
|
|
41492
|
+
// Helper to get badge variant based on filter status
|
|
41493
|
+
const getFilterStatusBadge = (status) => {
|
|
41494
|
+
switch (status) {
|
|
41495
|
+
case "updated":
|
|
41496
|
+
return { variant: "success", label: "Filtered", icon: "✓" };
|
|
41497
|
+
case "no_data":
|
|
41498
|
+
return { variant: "warning", label: "No Data", icon: "⚠" };
|
|
41499
|
+
case "skipped":
|
|
41500
|
+
return { variant: "muted", label: "Skipped", icon: "−" };
|
|
41501
|
+
case "failed":
|
|
41502
|
+
return { variant: "error", label: "Failed", icon: "✕" };
|
|
41503
|
+
default:
|
|
41504
|
+
return { variant: "muted", label: status, icon: "?" };
|
|
41505
|
+
}
|
|
41506
|
+
};
|
|
41455
41507
|
// Use external selectedWidget if provided, otherwise use internal state
|
|
41456
41508
|
const currentSelectedWidget = selectedWidget !== undefined ? selectedWidget : internalSelectedWidget;
|
|
41457
41509
|
const setSelectedWidget = onWidgetSelect || setInternalSelectedWidget;
|
|
@@ -41516,6 +41568,19 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41516
41568
|
}
|
|
41517
41569
|
});
|
|
41518
41570
|
window.dispatchEvent(event);
|
|
41571
|
+
// If filters have been applied (filter widget exists), regenerate filtered_sql_query for this widget
|
|
41572
|
+
// This handles the case where a widget's query is changed after filters have been applied
|
|
41573
|
+
const hasFilterWidget = widgets.some(w => w.type === 'filters');
|
|
41574
|
+
if (hasFilterWidget && editingWidget.type === 'agent' && widgetBackendUrl) {
|
|
41575
|
+
// Dispatch event to notify that filtered query needs regeneration for this widget
|
|
41576
|
+
const regenerateEvent = new CustomEvent('regenerateFilteredQuery', {
|
|
41577
|
+
detail: {
|
|
41578
|
+
widgetId: editingWidget.id,
|
|
41579
|
+
dashboardId: pageId
|
|
41580
|
+
}
|
|
41581
|
+
});
|
|
41582
|
+
window.dispatchEvent(regenerateEvent);
|
|
41583
|
+
}
|
|
41519
41584
|
}
|
|
41520
41585
|
};
|
|
41521
41586
|
const handleResetReady = React.useCallback((widgetId, resetFn) => {
|
|
@@ -41607,6 +41672,15 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41607
41672
|
};
|
|
41608
41673
|
loadWidgetTypes();
|
|
41609
41674
|
}, []);
|
|
41675
|
+
// Track original widget IDs from initial load
|
|
41676
|
+
const originalWidgetIdsRef = React.useRef(new Set());
|
|
41677
|
+
// Update original widget IDs when widgets are loaded from server
|
|
41678
|
+
React.useEffect(() => {
|
|
41679
|
+
if (pageData === null || pageData === void 0 ? void 0 : pageData.widgets) {
|
|
41680
|
+
const ids = new Set(pageData.widgets.map((w) => w.id));
|
|
41681
|
+
originalWidgetIdsRef.current = ids;
|
|
41682
|
+
}
|
|
41683
|
+
}, [pageData]);
|
|
41610
41684
|
// Use ref to store the latest save function without causing re-renders
|
|
41611
41685
|
const saveLayoutRef = React.useRef();
|
|
41612
41686
|
// Update the ref whenever dependencies change
|
|
@@ -41614,6 +41688,13 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41614
41688
|
if (!pageData) {
|
|
41615
41689
|
throw new Error("No page data available");
|
|
41616
41690
|
}
|
|
41691
|
+
// Identify new agent widgets (added since last load/save)
|
|
41692
|
+
const currentWidgetIds = new Set(widgets.map(w => w.id));
|
|
41693
|
+
const newAgentWidgetIds = widgets
|
|
41694
|
+
.filter(w => w.type === 'agent' && !originalWidgetIdsRef.current.has(w.id))
|
|
41695
|
+
.map(w => w.id);
|
|
41696
|
+
// Check if there's a filter widget on this dashboard
|
|
41697
|
+
const hasFilterWidget = widgets.some(w => w.type === 'filters');
|
|
41617
41698
|
try {
|
|
41618
41699
|
const response = await fetch(getApiUrl(`/api/pages/${pageId}`), {
|
|
41619
41700
|
method: "PUT",
|
|
@@ -41631,16 +41712,42 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41631
41712
|
throw new Error("Failed to save layout");
|
|
41632
41713
|
}
|
|
41633
41714
|
const savedData = await response.json();
|
|
41634
|
-
//
|
|
41635
|
-
|
|
41636
|
-
// setWidgets(prevWidgets => prevWidgets.map(widget => ({
|
|
41637
|
-
// ...widget,
|
|
41638
|
-
// config: {
|
|
41639
|
-
// ...widget.config,
|
|
41640
|
-
// isFirstLoad: false
|
|
41641
|
-
// }
|
|
41642
|
-
// })));
|
|
41715
|
+
// Update original widget IDs to include newly saved widgets
|
|
41716
|
+
originalWidgetIdsRef.current = currentWidgetIds;
|
|
41643
41717
|
console.log('Layout saved successfully');
|
|
41718
|
+
// If there are new agent widgets and a filter widget exists,
|
|
41719
|
+
// schedule generation of filtered_sql_query for new widgets
|
|
41720
|
+
// Note: This is done asynchronously after save to not block the save operation
|
|
41721
|
+
// The actual generation will happen after the widget agents have run and created sql_query
|
|
41722
|
+
if (newAgentWidgetIds.length > 0 && hasFilterWidget) {
|
|
41723
|
+
console.log(`[WidgetDashboard] New agent widgets detected: ${newAgentWidgetIds.join(', ')}`);
|
|
41724
|
+
console.log('[WidgetDashboard] Filter widget exists - filtered_sql_query will be generated when filters are applied');
|
|
41725
|
+
// Optionally, we could trigger generation after a delay to allow widget agents to initialize
|
|
41726
|
+
// For now, we rely on the auto-generation in /api/filters/apply when filters are applied
|
|
41727
|
+
// Uncomment below to proactively generate after a delay:
|
|
41728
|
+
/*
|
|
41729
|
+
setTimeout(async () => {
|
|
41730
|
+
try {
|
|
41731
|
+
console.log('[WidgetDashboard] Generating filtered_sql_query for new widgets...');
|
|
41732
|
+
const generateResponse = await fetch(getApiUrl('/api/filters/generate-queries'), {
|
|
41733
|
+
method: 'POST',
|
|
41734
|
+
headers: { 'Content-Type': 'application/json' },
|
|
41735
|
+
body: JSON.stringify({
|
|
41736
|
+
dashboard_id: pageId,
|
|
41737
|
+
widget_ids: newAgentWidgetIds,
|
|
41738
|
+
regenerate: false,
|
|
41739
|
+
}),
|
|
41740
|
+
});
|
|
41741
|
+
if (generateResponse.ok) {
|
|
41742
|
+
const result = await generateResponse.json();
|
|
41743
|
+
console.log('[WidgetDashboard] Generate queries result:', result);
|
|
41744
|
+
}
|
|
41745
|
+
} catch (err) {
|
|
41746
|
+
console.warn('[WidgetDashboard] Could not generate filtered queries for new widgets:', err);
|
|
41747
|
+
}
|
|
41748
|
+
}, 5000); // 5 second delay to allow widget agents to initialize
|
|
41749
|
+
*/
|
|
41750
|
+
}
|
|
41644
41751
|
}
|
|
41645
41752
|
catch (err) {
|
|
41646
41753
|
console.error("Save error:", err);
|
|
@@ -41920,10 +42027,10 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
|
|
|
41920
42027
|
onCloseWidgetPallete && onCloseWidgetPallete();
|
|
41921
42028
|
}, defaultAgentName: defaultAgentName, hasFiltersWidget: widgets.some(w => w.type === 'filters') }), jsxRuntimeExports.jsx(EditWidgetDialog, { editingWidget: editingWidget, setWidgets: setWidgets, initialText: editInitialQuery, isOpen: showEditModal, onClose: () => setShowEditModal(false), onSubmit: handleEditSubmit }), jsxRuntimeExports.jsx("div", { className: "min-h-full", onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, onClick: () => setSelectedWidget(null), children: isLoading ? (jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: jsxRuntimeExports.jsx(lucideReact.Loader2, { className: "h-8 w-8 animate-spin" }) })) : (jsxRuntimeExports.jsx(RGL, { className: "layout m-0 p-0 gap-2", layouts: { lg: getLayoutFromWidgets() }, breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480 }, cols: { lg: 12, md: 8, sm: 6, xs: 2 }, rowHeight: 60, isDraggable: isEditing, isResizable: isEditing, draggableHandle: ".drag-icon", onLayoutChange: handleLayoutChange, compactType: "vertical", containerPadding: [0, 0], margin: [16, 16], children: widgets.map((w) => {
|
|
41922
42029
|
var _a, _b;
|
|
41923
|
-
const
|
|
41924
|
-
const
|
|
41925
|
-
return (jsxRuntimeExports.jsxs("div", { className: `${(w.type === "text" || w.type === "spacer") ? `${((_b = (_a = w === null || w === void 0 ? void 0 : w.config) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.divider) === "yes" && "border-b border-gray-300"} ${isEditing ? 'shadow-lg rounded-xl border border-primary-300' : 'flex items-center'}` : `shadow-lg rounded-xl border border-primary-300 p-4 ${isEditing ? 'pb-14' : 'pb-5'}`}`, children: [isEditing &&
|
|
41926
|
-
jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-end mb-4 relative ${(w.type === "text" || w.type === "spacer") ? "pl-4 pr-4 pt-4" : ""}`, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center drag-icon cursor-grab absolute left-1/2 -translate-x-1/2", children: [jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "" }), jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "-ml-[3px]" }), jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "-ml-[3px]" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 cursor-pointer justify-end", children: [jsxRuntimeExports.jsx(lucideReact.Trash2, { onClick: () => removeWidget(w.id), className: "w-5 h-5 text-red-700" }), (w.type !== "spacer" && w.type !== "chatbot") && jsxRuntimeExports.jsx(lucideReact.Edit, { onClick: () => onClickSettings && onClickSettings(w), className: "w-5 h-5 text-gray-600" })] })] }),
|
|
42030
|
+
const filterStatus = w.type === 'agent' ? getWidgetFilterStatus(w.id) : null;
|
|
42031
|
+
const badgeInfo = filterStatus ? getFilterStatusBadge(filterStatus.status) : null;
|
|
42032
|
+
return (jsxRuntimeExports.jsxs("div", { className: `${(w.type === "text" || w.type === "spacer") ? `${((_b = (_a = w === null || w === void 0 ? void 0 : w.config) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.divider) === "yes" && "border-b border-gray-300"} ${isEditing ? 'shadow-lg rounded-xl border border-primary-300' : 'flex items-center'}` : `shadow-lg rounded-xl border border-primary-300 p-4 ${isEditing ? 'pb-14' : 'pb-5'}`} relative`, children: [w.type === 'agent' && badgeInfo && !isApplyingFilters && (jsxRuntimeExports.jsx("div", { className: "absolute top-2 right-2 z-10", title: (filterStatus === null || filterStatus === void 0 ? void 0 : filterStatus.reason) || (filterStatus === null || filterStatus === void 0 ? void 0 : filterStatus.error) || '', children: jsxRuntimeExports.jsxs(Badge, { variant: badgeInfo.variant, className: "text-[10px] px-2 py-0.5 gap-1", children: [jsxRuntimeExports.jsx("span", { children: badgeInfo.icon }), jsxRuntimeExports.jsx("span", { children: badgeInfo.label })] }) })), w.type === 'agent' && isApplyingFilters && (jsxRuntimeExports.jsx("div", { className: "absolute top-2 right-2 z-10", children: jsxRuntimeExports.jsxs(Badge, { variant: "secondary", className: "text-[10px] px-2 py-0.5 gap-1 animate-pulse", children: [jsxRuntimeExports.jsx(lucideReact.Loader2, { className: "w-3 h-3 animate-spin" }), jsxRuntimeExports.jsx("span", { children: "Filtering..." })] }) })), isEditing &&
|
|
42033
|
+
jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-end mb-4 relative ${(w.type === "text" || w.type === "spacer") ? "pl-4 pr-4 pt-4" : ""}`, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center drag-icon cursor-grab absolute left-1/2 -translate-x-1/2", children: [jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "" }), jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "-ml-[3px]" }), jsxRuntimeExports.jsx(lucideReact.GripHorizontal, { className: "-ml-[3px]" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 cursor-pointer justify-end", children: [jsxRuntimeExports.jsx(lucideReact.Trash2, { onClick: () => removeWidget(w.id), className: "w-5 h-5 text-red-700" }), (w.type !== "spacer" && w.type !== "chatbot") && jsxRuntimeExports.jsx(lucideReact.Edit, { onClick: () => onClickSettings && onClickSettings(w), className: "w-5 h-5 text-gray-600" })] })] }), jsxRuntimeExports.jsxs("div", { className: `${((w === null || w === void 0 ? void 0 : w.type) === 'text' || (w === null || w === void 0 ? void 0 : w.type) === 'spacer') ? `${isEditing ? 'px-4' : ''}` : "h-full"} w-full relative`, children: [(w === null || w === void 0 ? void 0 : w.type) === "chatbot" &&
|
|
41927
42034
|
jsxRuntimeExports.jsxs("div", { className: "relative z-50", children: [jsxRuntimeExports.jsx("div", { onClick: () => handleClearChat(w === null || w === void 0 ? void 0 : w.id), onMouseOver: () => setVisibleClearButton(w === null || w === void 0 ? void 0 : w.id), onMouseLeave: () => setVisibleClearButton(""), className: "absolute top-[12px] right-0 z-40 flex align-middle justify-center gap-2 text-sm px-4 py-2 border-primary-300 rounded-l-sm w-fit bg-primary-700 text-white cursor-pointer shadow-md transition-all", children: jsxRuntimeExports.jsx(lucideReact.MessageCircleX, { className: "w-5 h-5" }) }), jsxRuntimeExports.jsx("span", { className: `absolute top-[56px] right-[16px] z-50 w-max py-1 text-xs px-2 rounded-sm text-white bg-gray-950 ${visibleClearButton === (w === null || w === void 0 ? void 0 : w.id) ? "block" : "hidden"}`, children: "Clear Chat" })] }), jsxRuntimeExports.jsx(WidgetRenderer, { widget: w, widgetBackendUrl: widgetBackendUrl, onResetReady: handleResetReady, widgetIds: widgets.filter(widget => widget.type !== 'chatbot').map(widget => widget.id), datasetId: datasetId, pageId: pageId, onApplyFilters: onApplyFilters, isEditing: isEditing })] })] }, w.id));
|
|
41928
42035
|
}) })) })] }));
|
|
41929
42036
|
}
|
|
@@ -44821,7 +44928,6 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44821
44928
|
const [pages, setPages] = React.useState([]);
|
|
44822
44929
|
const [isLoading, setIsLoading] = React.useState(true);
|
|
44823
44930
|
const [error, setError] = React.useState(null);
|
|
44824
|
-
const [activeFilters, setActiveFilters] = React.useState({});
|
|
44825
44931
|
// Helper function to get API URL
|
|
44826
44932
|
const getApiUrl = (endpoint) => {
|
|
44827
44933
|
const baseUrl = widgetBackendUrl || '';
|
|
@@ -44830,10 +44936,6 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44830
44936
|
React.useEffect(() => {
|
|
44831
44937
|
loadPages();
|
|
44832
44938
|
}, []);
|
|
44833
|
-
const handleApplyFilters = (pageId) => (filters) => {
|
|
44834
|
-
console.log('Filters applied for page:', pageId, filters);
|
|
44835
|
-
setActiveFilters(prev => (Object.assign(Object.assign({}, prev), { [pageId]: filters })));
|
|
44836
|
-
};
|
|
44837
44939
|
const loadPages = async () => {
|
|
44838
44940
|
try {
|
|
44839
44941
|
setIsLoading(true);
|
|
@@ -44878,7 +44980,7 @@ function DashboardPages({ widgetBackendUrl }) {
|
|
|
44878
44980
|
}
|
|
44879
44981
|
return (jsxRuntimeExports.jsxs("div", { className: "container mx-auto p-6 h-screen flex flex-col", children: [jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [jsxRuntimeExports.jsx("h1", { className: "text-2xl font-bold", children: "Dashboard Pages" }), jsxRuntimeExports.jsx("p", { className: "text-muted-foreground", children: "View all your saved pages in dashboard mode" })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: jsxRuntimeExports.jsxs(Tabs, { defaultValue: (_a = pages[0]) === null || _a === void 0 ? void 0 : _a.id, className: "h-full flex flex-col", children: [jsxRuntimeExports.jsx(TabsList, { className: "grid w-full grid-cols-auto gap-1 mb-4", style: {
|
|
44880
44982
|
gridTemplateColumns: `repeat(${pages.length}, minmax(120px, 1fr))`
|
|
44881
|
-
}, children: pages.map((page) => (jsxRuntimeExports.jsx(TabsTrigger, { value: page.id, className: "truncate px-3 py-2 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-lg border-2 data-[state=active]:border-primary data-[state=inactive]:border-transparent hover:bg-accent hover:text-accent-foreground transition-all duration-200", title: page.title, children: page.title }, page.id))) }), pages.map((page) => (jsxRuntimeExports.jsx(TabsContent, { value: page.id, className: "flex-1 overflow-hidden m-0", children: jsxRuntimeExports.jsx("div", { className: "h-full border rounded-lg overflow-hidden", children: jsxRuntimeExports.jsx(WidgetDashboard, { pageId: page.id, isEditing: false, widgetBackendUrl: widgetBackendUrl
|
|
44983
|
+
}, children: pages.map((page) => (jsxRuntimeExports.jsx(TabsTrigger, { value: page.id, className: "truncate px-3 py-2 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-lg border-2 data-[state=active]:border-primary data-[state=inactive]:border-transparent hover:bg-accent hover:text-accent-foreground transition-all duration-200", title: page.title, children: page.title }, page.id))) }), pages.map((page) => (jsxRuntimeExports.jsx(TabsContent, { value: page.id, className: "flex-1 overflow-hidden m-0", children: jsxRuntimeExports.jsx("div", { className: "h-full border rounded-lg overflow-hidden", children: jsxRuntimeExports.jsx(WidgetDashboard, { pageId: page.id, isEditing: false, widgetBackendUrl: widgetBackendUrl }) }) }, page.id)))] }) })] }));
|
|
44882
44984
|
}
|
|
44883
44985
|
|
|
44884
44986
|
exports.Button = Button;
|