fix(site): inject time via prop for deterministic analytics story snapshots (#23092)

This commit is contained in:
Michael Suchacz
2026-03-16 12:34:55 +01:00
committed by GitHub
parent 29225252f6
commit cb05419872
3 changed files with 25 additions and 8 deletions
@@ -139,21 +139,25 @@ const UserRow: FC<{
);
};
const UsageContent: FC = () => {
interface UsageContentProps {
now?: dayjs.Dayjs;
}
const UsageContent: FC<UsageContentProps> = ({ now }) => {
const [selectedUser, setSelectedUser] =
useState<TypesGen.ChatCostUserRollup | null>(null);
const [usernameFilter, setUsernameFilter] = useState("");
const debouncedUsername = useDebouncedValue(usernameFilter, 300);
const [page, setPage] = useState(1);
const dateRange = useMemo(() => {
const end = dayjs();
const end = now ?? dayjs();
const start = end.subtract(30, "day");
return {
startDate: start.toISOString(),
endDate: end.toISOString(),
rangeLabel: `${start.format("MMM D")} ${end.format("MMM D, YYYY")}`,
};
}, []);
}, [now]);
const offset = (page - 1) * pageSize;
const usersQuery = useQuery({
@@ -354,6 +358,8 @@ interface ConfigureAgentsDialogProps {
canManageChatModelConfigs: boolean;
canSetSystemPrompt: boolean;
initialSection?: ConfigureAgentsSection;
/** Override the current time for date range calculation. Used for deterministic Storybook snapshots. */
now?: dayjs.Dayjs;
}
export const ConfigureAgentsDialog: FC<ConfigureAgentsDialogProps> = ({
@@ -362,6 +368,7 @@ export const ConfigureAgentsDialog: FC<ConfigureAgentsDialogProps> = ({
canManageChatModelConfigs,
canSetSystemPrompt,
initialSection = "behavior",
now,
}) => {
const queryClient = useQueryClient();
@@ -635,7 +642,7 @@ export const ConfigureAgentsDialog: FC<ConfigureAgentsDialogProps> = ({
/>
)}
{activeSection === "usage" && canManageChatModelConfigs && (
<UsageContent />
<UsageContent now={now} />
)}
</div>
</DialogContent>
@@ -3,7 +3,8 @@ import { withAuthProvider } from "testHelpers/storybook";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { API } from "api/api";
import type * as TypesGen from "api/typesGenerated";
import { fn, spyOn } from "storybook/test";
import dayjs from "dayjs";
import { expect, fn, screen, spyOn, waitFor } from "storybook/test";
import { UserAnalyticsDialog } from "./UserAnalyticsDialog";
const mockSummary: TypesGen.ChatCostSummary = {
@@ -63,5 +64,11 @@ export const Default: Story = {
args: {
open: true,
onOpenChange: fn(),
now: dayjs("2026-03-12T12:00:00Z"),
},
play: async () => {
await waitFor(() => {
expect(screen.getByText(/Feb 10\s*\s*Mar 12, 2026/)).toBeInTheDocument();
});
},
};
@@ -16,8 +16,8 @@ import { useQuery } from "react-query";
import { ChatCostSummaryView } from "./ChatCostSummaryView";
import { SectionHeader } from "./SectionHeader";
const createDateRange = () => {
const end = dayjs();
const createDateRange = (now?: dayjs.Dayjs) => {
const end = now ?? dayjs();
const start = end.subtract(30, "day");
return {
startDate: start.toISOString(),
@@ -29,14 +29,17 @@ const createDateRange = () => {
interface UserAnalyticsDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
/** Override the current time for date range calculation. Used for deterministic Storybook snapshots. */
now?: dayjs.Dayjs;
}
export const UserAnalyticsDialog: FC<UserAnalyticsDialogProps> = ({
open,
onOpenChange,
now,
}) => {
const { user } = useAuthContext();
const dateRange = useMemo(createDateRange, []);
const dateRange = useMemo(() => createDateRange(now), [now]);
const summaryQuery = useQuery({
...chatCostSummary(user?.id ?? "me", {