From eb173f91552bd552ce807d8aea71ede4548db6e4 Mon Sep 17 00:00:00 2001 From: tanjiro <56165694+NANDINI-star@users.noreply.github.com> Date: Sat, 2 Aug 2025 23:54:49 +0900 Subject: [PATCH] Add advanced date picker to all the tabs on the usage page (#13221) * advancedatepicker for tag usage and team usage * reduce white space in date picker * selected time range option is visible * dont wait for apply button to select relative time options --- .../src/components/entity_usage.tsx | 4 +- .../shared/advanced_date_picker.tsx | 92 ++++++++++++++++--- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/ui/litellm-dashboard/src/components/entity_usage.tsx b/ui/litellm-dashboard/src/components/entity_usage.tsx index bd12bb256b..a481de0868 100644 --- a/ui/litellm-dashboard/src/components/entity_usage.tsx +++ b/ui/litellm-dashboard/src/components/entity_usage.tsx @@ -21,7 +21,7 @@ import { TabPanels, Subtitle, } from "@tremor/react"; -import UsageDatePicker from "./shared/usage_date_picker"; +import AdvancedDatePicker from "./shared/advanced_date_picker"; import { Select } from 'antd'; import { ActivityMetrics, processActivityData } from './activity_metrics'; import { DailyData, BreakdownMetrics, KeyMetricWithMetadata, EntityMetricWithMetadata } from './usage/types'; @@ -328,7 +328,7 @@ const EntityUsage: React.FC = ({
- + {entityList && entityList.length > 0 && ( diff --git a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx index ae60b284f5..4ec4c83dfb 100644 --- a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx +++ b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx @@ -71,6 +71,7 @@ const AdvancedDatePicker: React.FC = ({ }) => { const [isOpen, setIsOpen] = useState(false) const [tempValue, setTempValue] = useState(value) + const [selectedOption, setSelectedOption] = useState(null) // Custom date inputs only - removed time inputs const [startDate, setStartDate] = useState("") @@ -78,6 +79,31 @@ const AdvancedDatePicker: React.FC = ({ const dropdownRef = useRef(null) + // Function to check if current value matches a relative time option + const getMatchingOption = useCallback((currentValue: DateRangePickerValue): string | null => { + if (!currentValue.from || !currentValue.to) return null + + for (const option of relativeTimeOptions) { + const optionRange = option.getValue() + + // Compare dates with some tolerance (to account for time differences) + const fromMatches = moment(currentValue.from).isSame(moment(optionRange.from), "day") + const toMatches = moment(currentValue.to).isSame(moment(optionRange.to), "day") + + if (fromMatches && toMatches) { + return option.shortLabel + } + } + + return null + }, []) + + // Update selected option when value changes + useEffect(() => { + const matchingOption = getMatchingOption(value) + setSelectedOption(matchingOption) + }, [value, getMatchingOption]) + // Validation logic - simplified for dates only const validateDateRange = useCallback(() => { if (!startDate || !endDate) { @@ -171,11 +197,29 @@ const AdvancedDatePicker: React.FC = ({ const handleRelativeTimeSelect = (option: RelativeTimeOption) => { const { from, to } = option.getValue() const newValue = { from, to } + + // Immediately apply the selected option + onValueChange(newValue) + + // Apply the same background adjustment logic as the original component + requestIdleCallback( + () => { + const adjustedValue = adjustDateRange(newValue) + onValueChange(adjustedValue) + }, + { timeout: 100 }, + ) + + // Update local state to reflect the selection setTempValue(newValue) + setSelectedOption(option.shortLabel) // Update the form inputs to reflect the selection setStartDate(moment(from).format("YYYY-MM-DD")) setEndDate(moment(to).format("YYYY-MM-DD")) + + // Close the dropdown + setIsOpen(false) } const updateTempValueFromInputs = useCallback(() => { @@ -186,13 +230,18 @@ const AdvancedDatePicker: React.FC = ({ const to = moment(endDate, "YYYY-MM-DD").endOf("day") if (from.isValid() && to.isValid()) { - setTempValue({ from: from.toDate(), to: to.toDate() }) + const newValue = { from: from.toDate(), to: to.toDate() } + setTempValue(newValue) + + // Check if this matches any preset option + const matchingOption = getMatchingOption(newValue) + setSelectedOption(matchingOption) } } } catch (error) { console.warn("Invalid date format:", error) } - }, [startDate, endDate, validation.isValid]) + }, [startDate, endDate, validation.isValid, getMatchingOption]) // Update tempValue when inputs change useEffect(() => { @@ -229,6 +278,10 @@ const AdvancedDatePicker: React.FC = ({ setEndDate(moment(value.to).format("YYYY-MM-DD")) } + // Reset selected option + const matchingOption = getMatchingOption(value) + setSelectedOption(matchingOption) + setIsOpen(false) } @@ -267,17 +320,30 @@ const AdvancedDatePicker: React.FC = ({
Relative time (today, 7d, 30d, MTD, YTD)
-
- {relativeTimeOptions.map((option) => ( -
handleRelativeTimeSelect(option)} - > - {option.label} - {option.shortLabel} -
- ))} +
+ {relativeTimeOptions.map((option) => { + const isSelected = selectedOption === option.shortLabel + return ( +
handleRelativeTimeSelect(option)} + > + + {option.label} + + + {option.shortLabel} + +
+ ) + })}