import { useEffect, useState } from "react"; import { useDashboard } from "../../layouts/Dashboard/useDashboard"; import { useBackend } from "../../layouts/Wrapper"; import React from "react"; import { Button } from "../../tremor/Button"; import { Text, Title } from "../../tremor/Text"; import { MultiSelect } from "../../tremor/MultiSelect"; import { toast } from "sonner"; import { DateRangePicker } from "../../tremor/DatePicker"; import dayjs from "dayjs"; import { DashboardFilter } from "@onvo-ai/js"; import { Slider } from "../../tremor/Slider"; import { PopoverClose } from "../../tremor/Popover"; import { ArrowPathIcon, XMarkIcon } from "@heroicons/react/24/outline"; const presets = [ { label: "Today", dateRange: { from: new Date(), to: new Date(), }, }, { label: "Last 7 days", dateRange: { from: new Date(new Date().setDate(new Date().getDate() - 7)), to: new Date(), }, }, { label: "Last 30 days", dateRange: { from: new Date(new Date().setDate(new Date().getDate() - 30)), to: new Date(), }, }, { label: "Last 3 months", dateRange: { from: new Date(new Date().setMonth(new Date().getMonth() - 3)), to: new Date(), }, }, { label: "Last 6 months", dateRange: { from: new Date(new Date().setMonth(new Date().getMonth() - 6)), to: new Date(), }, }, { label: "Month to date", dateRange: { from: new Date(new Date().setDate(1)), to: new Date(), }, }, { label: "Year to date", dateRange: { from: new Date(new Date().setFullYear(new Date().getFullYear(), 0, 1)), to: new Date(), }, }, ]; export const FilterBar = () => { const { dashboard, setDashboard, refreshing, refreshWidgets } = useDashboard(); const { backend } = useBackend(); const [reloading, setReloading] = useState(false); const [filters, setFilters] = useState([]); const [progress, setProgress] = useState(0); const resetFilters = async () => { setFilters([]); if (!dashboard || !dashboard.id || !backend) return; setReloading(true); await backend.dashboards.update(dashboard.id, { filters: [], }); setDashboard({ ...dashboard, filters, }); try { let data = await backend.dashboard(dashboard?.id).updateCache( (evt) => { if (evt.progress) { setProgress(evt.progress.completed / evt.progress.total); } }, { rejectFilterCache: true, }, ); let newDash = await backend.dashboards.get(dashboard?.id); setDashboard(newDash); refreshWidgets(backend); toast.success("Dashboard filters successfully reset"); setReloading(false); setProgress(0); } catch (e: any) { toast.error("Failed to reset dashboard filters: " + e.message); setReloading(false); setProgress(0); } }; const updateDashboard = async () => { if (!dashboard || !dashboard.id || !backend) return; setReloading(true); await backend.dashboards.update(dashboard.id, { filters, }); setDashboard({ ...dashboard, filters, }); try { const data = await backend.dashboard(dashboard?.id).updateCache( (evt) => { if (evt.progress) { setProgress(evt.progress.completed / evt.progress.total); } }, { rejectFilterCache: true, }, ); refreshWidgets(backend); toast.success("Dashboard filters successfully updated"); setReloading(false); setProgress(0); } catch (e: any) { toast.error("Failed to update dashboard filters: " + e.message); setReloading(false); setProgress(0); } }; const filtersEnabled = dashboard?.settings?.filters; useEffect(() => { setFilters(dashboard?.filters || []); }, [dashboard?.filters]); if (!filtersEnabled) return <>; return ( <> {reloading && (
Applying filters
)}
Filters
{filters.map((filter) => { return (
{filter.label} {filter.type === "text" && ( { setFilters((prev) => prev.map((a) => { if (a.label !== filter.label || a.type !== "text") { return a; } return { ...a, values: e, }; }), ); }} className="onvo-max-w-full" items={filter.options.map((opt) => ({ label: opt === "" ? "(blank)" : opt, value: opt, }))} /> )} {filter.type === "number" && ( { const nextValues: [number, number] = [e[0], e[1]]; setFilters((prev) => prev.map((a) => { if (a.label !== filter.label || a.type !== "number") { return a; } return { ...a, values: nextValues, }; }), ); }} /> )} {filter.type === "date" && ( { if (!e || !e.from || !e?.to) return; const nextValues: [string, string] = [ dayjs(e.from).format("YYYY-MM-DD"), dayjs(e.to).format("YYYY-MM-DD"), ]; setFilters((prev) => prev.map((a) => { if (a.label !== filter.label || a.type !== "date") { return a; } return { ...a, values: nextValues, }; }), ); }} /> )}
); })}
{refreshing ? (

You cannot apply filters while the dashboard is loading

) : (
)}
); };