dp-widgets-framework 1.5.7 → 1.5.9

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
@@ -7,7 +7,7 @@ import * as LabelPrimitive from '@radix-ui/react-label';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import * as SwitchPrimitives from '@radix-ui/react-switch';
9
9
  import * as SelectPrimitive from '@radix-ui/react-select';
10
- import { ChevronDown, ChevronUp, Check, AlertCircle, MoveUp, MoveDown, Trash2, Plus, Bot, Type, Layout, LayoutGrid, BarChart as BarChart$1, Filter, Search, ArrowUp, ArrowDown, ChevronRight, RefreshCw, Send, X, AlignVerticalSpaceAround, LineChart as LineChart$1, PieChart as PieChart$1, Table, FileText, SlidersHorizontal, Loader2, GripHorizontal, Edit, MessageCircleX, Edit2 } from 'lucide-react';
10
+ import { ChevronDown, ChevronUp, Check, AlertCircle, MoveUp, MoveDown, Trash2, Plus, Bot, Type, Layout, LayoutGrid, BarChart as BarChart$1, Filter, Search, ArrowUp, ArrowDown, ChevronRight, RefreshCw, Send, Loader2, X, AlignVerticalSpaceAround, LineChart as LineChart$1, PieChart as PieChart$1, Table, FileText, SlidersHorizontal, GripHorizontal, Edit, MessageCircleX, Edit2 } from 'lucide-react';
11
11
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
12
12
  import { Slot } from '@radix-ui/react-slot';
13
13
  import { debounce as debounce$1 } from 'lodash';
@@ -39387,10 +39387,12 @@ function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message
39387
39387
  }, className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500", children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select a table..." }), col.tables.map((table) => (jsxRuntimeExports.jsx("option", { value: table, children: table }, table)))] })] }, col.column))) }) }), jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-3 border-t border-gray-200", children: [jsxRuntimeExports.jsx(Button, { onClick: onCancel, variant: "outline", className: "flex-1", children: "Cancel" }), jsxRuntimeExports.jsx(Button, { onClick: handleSubmit, disabled: !allSelected, className: "flex-1 bg-primary-600 hover:bg-primary-700 text-white disabled:bg-gray-400", children: "Confirm Selection" })] })] }));
39388
39388
  }
39389
39389
  function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
39390
+ var _a;
39390
39391
  const hasCalledRef = useRef(false);
39391
39392
  const [expandedGroups, setExpandedGroups] = useState({});
39392
39393
  const [selectedFilters, setSelectedFilters] = useState({});
39393
39394
  const [searchQueries, setSearchQueries] = useState({});
39395
+ const [isSubmitting, setIsSubmitting] = useState(false);
39394
39396
  const isEmpty = filterGroups.length === 0;
39395
39397
  const handleRefresh = async () => {
39396
39398
  if (query) {
@@ -39428,6 +39430,29 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39428
39430
  });
39429
39431
  setExpandedGroups(initialExpanded);
39430
39432
  }, [filterGroups]);
39433
+ // Initialize selected filters from widget.config.filters
39434
+ useEffect(() => {
39435
+ var _a;
39436
+ if (((_a = widget.config) === null || _a === void 0 ? void 0 : _a.filters) && filterGroups.length > 0) {
39437
+ const initialSelectedFilters = {};
39438
+ Object.entries(widget.config.filters).forEach(([groupId, labels]) => {
39439
+ const group = filterGroups.find(g => g.id === groupId);
39440
+ if (group && Array.isArray(labels)) {
39441
+ // Convert labels back to option IDs
39442
+ const optionIds = labels
39443
+ .map(label => {
39444
+ const option = group.options.find(opt => opt.label === label);
39445
+ return option === null || option === void 0 ? void 0 : option.id;
39446
+ })
39447
+ .filter((id) => id !== undefined);
39448
+ if (optionIds.length > 0) {
39449
+ initialSelectedFilters[groupId] = optionIds;
39450
+ }
39451
+ }
39452
+ });
39453
+ setSelectedFilters(initialSelectedFilters);
39454
+ }
39455
+ }, [(_a = widget.config) === null || _a === void 0 ? void 0 : _a.filters, filterGroups]);
39431
39456
  const toggleGroup = (groupId) => {
39432
39457
  setExpandedGroups((prev) => (Object.assign(Object.assign({}, prev), { [groupId]: !prev[groupId] })));
39433
39458
  };
@@ -39491,7 +39516,7 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39491
39516
  if (onFilterChange) {
39492
39517
  onFilterChange({});
39493
39518
  }
39494
- }, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
39519
+ }, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: async () => {
39495
39520
  // Convert option IDs back to original label values
39496
39521
  const filtersWithLabels = {};
39497
39522
  filterGroups.forEach((group) => {
@@ -39501,8 +39526,37 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39501
39526
  return (option === null || option === void 0 ? void 0 : option.label) || optionId;
39502
39527
  });
39503
39528
  });
39504
- onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39505
- }, disabled: isEditing, className: `${isEditing ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: "Apply Filters" })] }) })] }));
39529
+ // Call API to update widget config with filters
39530
+ if (widgetBackendUrl && widgetId) {
39531
+ setIsSubmitting(true);
39532
+ try {
39533
+ const response = await fetch(`${widgetBackendUrl}/api/widgets/${widgetId}/config`, {
39534
+ method: 'PATCH',
39535
+ headers: {
39536
+ 'Content-Type': 'application/json',
39537
+ },
39538
+ body: JSON.stringify({
39539
+ config: Object.assign(Object.assign({}, widget.config), { filters: filtersWithLabels }),
39540
+ }),
39541
+ });
39542
+ if (!response.ok) {
39543
+ throw new Error('Failed to update widget config');
39544
+ }
39545
+ // Call the onApplyFilters callback after successful API call
39546
+ onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39547
+ }
39548
+ catch (error) {
39549
+ console.error('Error updating widget config:', error);
39550
+ }
39551
+ finally {
39552
+ setIsSubmitting(false);
39553
+ }
39554
+ }
39555
+ else {
39556
+ // Fallback if no backend URL - just call the callback
39557
+ onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39558
+ }
39559
+ }, disabled: isEditing || isSubmitting, className: `${isEditing || isSubmitting ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: isSubmitting ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Applying..."] })) : ('Apply Filters') })] }) })] }));
39506
39560
  }
39507
39561
  function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, widgetBackendUrl, datasetId, onApplyFilters, isEditing = false, }) {
39508
39562
  var _a, _b, _c, _d, _e, _f, _g, _h;
@@ -41356,7 +41410,7 @@ const IconMap = {
41356
41410
  'pie-chart': PieChart$1,
41357
41411
  'chatbot': Bot,
41358
41412
  };
41359
- function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters }) {
41413
+ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSelect, refreshKey, widgetBackendUrl, onSaveLayoutReady, openWidgetPallete = false, onCloseWidgetPallete, defaultAgentName = "adk-construction-project-agent", userId, onApplyFilters, activeFilters = {} }) {
41360
41414
  const [widgets, setWidgets] = useState([]);
41361
41415
  const [datasetId, setDatasetId] = useState('');
41362
41416
  const [availableWidgets, setAvailableWidgets] = useState([]);
@@ -41839,8 +41893,10 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
41839
41893
  onCloseWidgetPallete && onCloseWidgetPallete();
41840
41894
  }, 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) => {
41841
41895
  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";
41842
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 &&
41843
- 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" &&
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" &&
41844
41900
  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));
41845
41901
  }) })) })] }));
41846
41902
  }
@@ -44738,6 +44794,7 @@ function DashboardPages({ widgetBackendUrl }) {
44738
44794
  const [pages, setPages] = useState([]);
44739
44795
  const [isLoading, setIsLoading] = useState(true);
44740
44796
  const [error, setError] = useState(null);
44797
+ const [activeFilters, setActiveFilters] = useState({});
44741
44798
  // Helper function to get API URL
44742
44799
  const getApiUrl = (endpoint) => {
44743
44800
  const baseUrl = widgetBackendUrl || '';
@@ -44746,6 +44803,10 @@ function DashboardPages({ widgetBackendUrl }) {
44746
44803
  useEffect(() => {
44747
44804
  loadPages();
44748
44805
  }, []);
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
+ };
44749
44810
  const loadPages = async () => {
44750
44811
  try {
44751
44812
  setIsLoading(true);
@@ -44790,7 +44851,7 @@ function DashboardPages({ widgetBackendUrl }) {
44790
44851
  }
44791
44852
  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: {
44792
44853
  gridTemplateColumns: `repeat(${pages.length}, minmax(120px, 1fr))`
44793
- }, 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)))] }) })] }));
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)))] }) })] }));
44794
44855
  }
44795
44856
 
44796
44857
  export { Button, DashboardPages, Input, SavedPages, WidgetDashboard, WidgetPalette, WidgetSettingsPanel, cn };
package/dist/index.js CHANGED
@@ -39414,10 +39414,12 @@ function TableSelectionConfirmation({ ambiguousColumns, resolvedColumns, message
39414
39414
  }, className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500", children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select a table..." }), col.tables.map((table) => (jsxRuntimeExports.jsx("option", { value: table, children: table }, table)))] })] }, col.column))) }) }), jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-3 border-t border-gray-200", children: [jsxRuntimeExports.jsx(Button, { onClick: onCancel, variant: "outline", className: "flex-1", children: "Cancel" }), jsxRuntimeExports.jsx(Button, { onClick: handleSubmit, disabled: !allSelected, className: "flex-1 bg-primary-600 hover:bg-primary-700 text-white disabled:bg-gray-400", children: "Confirm Selection" })] })] }));
39415
39415
  }
39416
39416
  function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appendMessage, query, isFirstLoad, widgetBackendUrl, widgetId, startLoadingTimeout, clearLoadingTimeout, filterState, onApplyFilters, isEditing = false, }) {
39417
+ var _a;
39417
39418
  const hasCalledRef = React.useRef(false);
39418
39419
  const [expandedGroups, setExpandedGroups] = React.useState({});
39419
39420
  const [selectedFilters, setSelectedFilters] = React.useState({});
39420
39421
  const [searchQueries, setSearchQueries] = React.useState({});
39422
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
39421
39423
  const isEmpty = filterGroups.length === 0;
39422
39424
  const handleRefresh = async () => {
39423
39425
  if (query) {
@@ -39455,6 +39457,29 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39455
39457
  });
39456
39458
  setExpandedGroups(initialExpanded);
39457
39459
  }, [filterGroups]);
39460
+ // Initialize selected filters from widget.config.filters
39461
+ React.useEffect(() => {
39462
+ var _a;
39463
+ if (((_a = widget.config) === null || _a === void 0 ? void 0 : _a.filters) && filterGroups.length > 0) {
39464
+ const initialSelectedFilters = {};
39465
+ Object.entries(widget.config.filters).forEach(([groupId, labels]) => {
39466
+ const group = filterGroups.find(g => g.id === groupId);
39467
+ if (group && Array.isArray(labels)) {
39468
+ // Convert labels back to option IDs
39469
+ const optionIds = labels
39470
+ .map(label => {
39471
+ const option = group.options.find(opt => opt.label === label);
39472
+ return option === null || option === void 0 ? void 0 : option.id;
39473
+ })
39474
+ .filter((id) => id !== undefined);
39475
+ if (optionIds.length > 0) {
39476
+ initialSelectedFilters[groupId] = optionIds;
39477
+ }
39478
+ }
39479
+ });
39480
+ setSelectedFilters(initialSelectedFilters);
39481
+ }
39482
+ }, [(_a = widget.config) === null || _a === void 0 ? void 0 : _a.filters, filterGroups]);
39458
39483
  const toggleGroup = (groupId) => {
39459
39484
  setExpandedGroups((prev) => (Object.assign(Object.assign({}, prev), { [groupId]: !prev[groupId] })));
39460
39485
  };
@@ -39518,7 +39543,7 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39518
39543
  if (onFilterChange) {
39519
39544
  onFilterChange({});
39520
39545
  }
39521
- }, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: () => {
39546
+ }, className: "py-1.5 text-sm font-medium text-primary-600 hover:text-primary-800 hover:bg-primary-50 rounded-md transition-colors px-2", children: "Clear All Filters" })) : (jsxRuntimeExports.jsx("div", {})), jsxRuntimeExports.jsx(Button, { onClick: async () => {
39522
39547
  // Convert option IDs back to original label values
39523
39548
  const filtersWithLabels = {};
39524
39549
  filterGroups.forEach((group) => {
@@ -39528,8 +39553,37 @@ function FiltersContent({ filterGroups, showHeader, onFilterChange, widget, appe
39528
39553
  return (option === null || option === void 0 ? void 0 : option.label) || optionId;
39529
39554
  });
39530
39555
  });
39531
- onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39532
- }, disabled: isEditing, className: `${isEditing ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: "Apply Filters" })] }) })] }));
39556
+ // Call API to update widget config with filters
39557
+ if (widgetBackendUrl && widgetId) {
39558
+ setIsSubmitting(true);
39559
+ try {
39560
+ const response = await fetch(`${widgetBackendUrl}/api/widgets/${widgetId}/config`, {
39561
+ method: 'PATCH',
39562
+ headers: {
39563
+ 'Content-Type': 'application/json',
39564
+ },
39565
+ body: JSON.stringify({
39566
+ config: Object.assign(Object.assign({}, widget.config), { filters: filtersWithLabels }),
39567
+ }),
39568
+ });
39569
+ if (!response.ok) {
39570
+ throw new Error('Failed to update widget config');
39571
+ }
39572
+ // Call the onApplyFilters callback after successful API call
39573
+ onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39574
+ }
39575
+ catch (error) {
39576
+ console.error('Error updating widget config:', error);
39577
+ }
39578
+ finally {
39579
+ setIsSubmitting(false);
39580
+ }
39581
+ }
39582
+ else {
39583
+ // Fallback if no backend URL - just call the callback
39584
+ onApplyFilters === null || onApplyFilters === void 0 ? void 0 : onApplyFilters(filtersWithLabels);
39585
+ }
39586
+ }, disabled: isEditing || isSubmitting, className: `${isEditing || isSubmitting ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary-600 hover:bg-primary-700'} text-white`, title: isEditing ? 'Save the layout first to apply filters' : '', children: isSubmitting ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(lucideReact.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Applying..."] })) : ('Apply Filters') })] }) })] }));
39533
39587
  }
39534
39588
  function CopilotKitFilters({ widget, showHeader, onFilterChange, onResetReady, widgetBackendUrl, datasetId, onApplyFilters, isEditing = false, }) {
39535
39589
  var _a, _b, _c, _d, _e, _f, _g, _h;
@@ -41383,7 +41437,7 @@ const IconMap = {
41383
41437
  'pie-chart': lucideReact.PieChart,
41384
41438
  'chatbot': lucideReact.Bot,
41385
41439
  };
41386
- 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, activeFilters = {} }) {
41387
41441
  const [widgets, setWidgets] = React.useState([]);
41388
41442
  const [datasetId, setDatasetId] = React.useState('');
41389
41443
  const [availableWidgets, setAvailableWidgets] = React.useState([]);
@@ -41866,8 +41920,10 @@ function WidgetDashboard({ pageId, isEditing, selectedWidget = null, onWidgetSel
41866
41920
  onCloseWidgetPallete && onCloseWidgetPallete();
41867
41921
  }, 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) => {
41868
41922
  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";
41869
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 &&
41870
- 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" &&
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" &&
41871
41927
  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));
41872
41928
  }) })) })] }));
41873
41929
  }
@@ -44765,6 +44821,7 @@ function DashboardPages({ widgetBackendUrl }) {
44765
44821
  const [pages, setPages] = React.useState([]);
44766
44822
  const [isLoading, setIsLoading] = React.useState(true);
44767
44823
  const [error, setError] = React.useState(null);
44824
+ const [activeFilters, setActiveFilters] = React.useState({});
44768
44825
  // Helper function to get API URL
44769
44826
  const getApiUrl = (endpoint) => {
44770
44827
  const baseUrl = widgetBackendUrl || '';
@@ -44773,6 +44830,10 @@ function DashboardPages({ widgetBackendUrl }) {
44773
44830
  React.useEffect(() => {
44774
44831
  loadPages();
44775
44832
  }, []);
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
+ };
44776
44837
  const loadPages = async () => {
44777
44838
  try {
44778
44839
  setIsLoading(true);
@@ -44817,7 +44878,7 @@ function DashboardPages({ widgetBackendUrl }) {
44817
44878
  }
44818
44879
  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: {
44819
44880
  gridTemplateColumns: `repeat(${pages.length}, minmax(120px, 1fr))`
44820
- }, 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)))] }) })] }));
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)))] }) })] }));
44821
44882
  }
44822
44883
 
44823
44884
  exports.Button = Button;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dp-widgets-framework",
3
- "version": "1.5.7",
3
+ "version": "1.5.9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org"