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 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(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) => {
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(ScrollArea, { className: "flex-1", children: jsxRuntimeExports.jsx("div", { className: "p-2", children: filterGroups.map((group) => {
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-[400px]" : "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-[250px] overflow-y-auto pr-1", children: filteredOptions.length === 0 ? (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 py-2 text-center", children: "No options found" })) : (filteredOptions.map((option) => {
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, activeFilters = {} }) {
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
- // setPageData(savedData);
41608
- // // Update local widgets state to clear isFirstLoad flag
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 hasActiveFilters = Object.keys(activeFilters).length > 0 && Object.values(activeFilters).some(arr => arr.length > 0);
41897
- const shouldShowFilterBadge = hasActiveFilters && w.type !== "filters" && w.type !== "text" && w.type !== "spacer" && w.type !== "divider" && w.type !== "header" && w.type !== "footer";
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" })] })] }), !isEditing && shouldShowFilterBadge && (jsxRuntimeExports.jsxs("div", { className: "absolute top-2 right-2 z-10 bg-primary-600 text-white px-2 py-1 rounded-md shadow-md flex items-center gap-1.5 text-xs font-medium", children: [jsxRuntimeExports.jsx(Filter, { className: "w-3 h-3" }), jsxRuntimeExports.jsx("span", { children: "Filtered" })] })), 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" &&
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, onApplyFilters: handleApplyFilters(page.id), activeFilters: activeFilters[page.id] || {} }) }) }, page.id)))] }) })] }));
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(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) => {
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(ScrollArea, { className: "flex-1", children: jsxRuntimeExports.jsx("div", { className: "p-2", children: filterGroups.map((group) => {
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-[400px]" : "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-[250px] overflow-y-auto pr-1", children: filteredOptions.length === 0 ? (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 py-2 text-center", children: "No options found" })) : (filteredOptions.map((option) => {
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, activeFilters = {} }) {
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
- // setPageData(savedData);
41635
- // // Update local widgets state to clear isFirstLoad flag
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 hasActiveFilters = Object.keys(activeFilters).length > 0 && Object.values(activeFilters).some(arr => arr.length > 0);
41924
- const shouldShowFilterBadge = hasActiveFilters && w.type !== "filters" && w.type !== "text" && w.type !== "spacer" && w.type !== "divider" && w.type !== "header" && w.type !== "footer";
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" })] })] }), !isEditing && shouldShowFilterBadge && (jsxRuntimeExports.jsxs("div", { className: "absolute top-2 right-2 z-10 bg-primary-600 text-white px-2 py-1 rounded-md shadow-md flex items-center gap-1.5 text-xs font-medium", children: [jsxRuntimeExports.jsx(lucideReact.Filter, { className: "w-3 h-3" }), jsxRuntimeExports.jsx("span", { children: "Filtered" })] })), 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" &&
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, onApplyFilters: handleApplyFilters(page.id), activeFilters: activeFilters[page.id] || {} }) }) }, page.id)))] }) })] }));
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dp-widgets-framework",
3
- "version": "1.5.9",
3
+ "version": "1.6.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org"