From 5f92ec5c4900e6a23316b96e887e1d0372b77518 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Sun, 13 Sep 2026 22:30:30 -0700 Subject: [PATCH] Update annotation date picker and place annotation actions beside chart legend --- package.json | 2 +- pnpm-lock.yaml | 10 +-- .../websites/[websiteId]/WebsiteChart.tsx | 5 +- .../websites/[websiteId]/WebsitePage.tsx | 6 +- .../annotations/AnnotationEditForm.tsx | 64 +++---------------- .../annotations/AnnotationsModal.tsx | 6 +- src/components/charts/Chart.tsx | 22 ++++++- 7 files changed, 44 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 098eb3de1..099891a72 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "@tanstack/react-query": "^5.102.8", "@umami/api-client": "workspace:*", "@umami/mcp": "workspace:*", - "@umami/react-zen": "^0.253.0", + "@umami/react-zen": "^0.254.0", "bcryptjs": "^3.0.2", "chalk": "^5.6.2", "chart.js": "^4.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 400f69b89..9d944c80a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,8 +62,8 @@ importers: specifier: workspace:* version: link:packages/mcp '@umami/react-zen': - specifier: ^0.253.0 - version: 0.253.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(date-fns@4.4.0)(immer@11.1.18)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.3.0)) + specifier: ^0.254.0 + version: 0.254.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(date-fns@4.4.0)(immer@11.1.18)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.3.0)) bcryptjs: specifier: ^3.0.2 version: 3.0.3 @@ -2774,8 +2774,8 @@ packages: '@umami/api-client@0.81.0': resolution: {integrity: sha512-cwkQbe8U/m+zEgfe+nNExU0AoY8BSd+x4Qs7i5nfR2gGrktfoH6Y375e237OFYpmvhJr5BJdML1Vzuu6v7+kmw==} - '@umami/react-zen@0.253.0': - resolution: {integrity: sha512-ilprZZ+CM+ryHYcNFJKh2+DJFdnyby2y8UPa458e9hG5dXTtv5qpnhVcr6xSTxBfZqoMSC992vcXbWsn+PhjRg==} + '@umami/react-zen@0.254.0': + resolution: {integrity: sha512-1Ip3C3UuL+ltBTjGmLLB5y1IgxwNBtxYY8z/jkYyfVIpX3mNMP6NKdQIqZGHgrbgcq7hj88dslfD9Gc2SzJk1w==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -7955,7 +7955,7 @@ snapshots: '@umami/api-client@0.81.0': {} - '@umami/react-zen@0.253.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(date-fns@4.4.0)(immer@11.1.18)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.3.0))': + '@umami/react-zen@0.254.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(date-fns@4.4.0)(immer@11.1.18)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.3.0))': dependencies: '@base-ui/react': 1.8.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@react-spring/web': 9.7.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) diff --git a/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx b/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx index 56b45482d..69f41508d 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx @@ -1,5 +1,5 @@ import { isSameDay } from 'date-fns'; -import { useCallback, useMemo } from 'react'; +import { type ReactNode, useCallback, useMemo } from 'react'; import type { ChartAnnotation } from '@/components/charts/ChartAnnotationMarkers'; import { LoadingPanel } from '@/components/common/LoadingPanel'; import { @@ -19,11 +19,13 @@ export function WebsiteChart({ compareMode, showAnnotations, onAnnotationMoreClick, + legendActions, }: { websiteId: string; compareMode?: boolean; showAnnotations?: boolean; onAnnotationMoreClick?: (range: AnnotationRange) => void; + legendActions?: ReactNode; }) { const { timezone, localFromUtc, localToUtc } = useTimezone(); const { dateRange, dateCompare } = useDateRange({ timezone: timezone }); @@ -135,6 +137,7 @@ export function WebsiteChart({ } /> - - - diff --git a/src/app/(main)/websites/[websiteId]/annotations/AnnotationEditForm.tsx b/src/app/(main)/websites/[websiteId]/annotations/AnnotationEditForm.tsx index 7dc80bcef..7382b361a 100644 --- a/src/app/(main)/websites/[websiteId]/annotations/AnnotationEditForm.tsx +++ b/src/app/(main)/websites/[websiteId]/annotations/AnnotationEditForm.tsx @@ -1,23 +1,17 @@ import { Button, - Calendar as ZenCalendar, Column, - DialogTrigger, + DatePicker, Form, FormButtons, FormField, FormSubmitButton, - Icon, - Label, - Popover, Text, TextField, } from '@umami/react-zen'; import { startOfDay } from 'date-fns'; import { useMemo, useState } from 'react'; import { useLocale, useMessages, useTimezone, useUpdateQuery } from '@/components/hooks'; -import { Calendar } from '@/components/icons'; -import { formatDate } from '@/lib/date'; export interface Annotation { id: string; @@ -27,51 +21,6 @@ export interface Annotation { note: string; } -function AnnotationDatePicker({ - date, - label, - locale, - onChange, -}: { - date: Date; - label: string; - locale: string; - onChange: (date: Date) => void; -}) { - const [isOpen, setIsOpen] = useState(false); - - const handleChange = (value: Date) => { - onChange(value); - setIsOpen(false); - }; - - return ( - - - - - - - - - - ); -} - export function AnnotationEditForm({ annotation, websiteId, @@ -127,11 +76,16 @@ export function AnnotationEditForm({ return ( - { + if (value) { + setDate(value); + } + }} /> diff --git a/src/app/(main)/websites/[websiteId]/annotations/AnnotationsModal.tsx b/src/app/(main)/websites/[websiteId]/annotations/AnnotationsModal.tsx index d39b1c2b1..64c959a18 100644 --- a/src/app/(main)/websites/[websiteId]/annotations/AnnotationsModal.tsx +++ b/src/app/(main)/websites/[websiteId]/annotations/AnnotationsModal.tsx @@ -13,7 +13,6 @@ import { formatAnnotationDate } from '@/components/charts/ChartAnnotationMarkers import { Empty } from '@/components/common/Empty'; import { IconLabel } from '@/components/common/IconLabel'; import { Pager } from '@/components/common/Pager'; -import { FilterButtons } from '@/components/input/FilterButtons'; import { useLocale, useMessages, @@ -24,6 +23,7 @@ import { useWebsiteAnnotationsQuery, } from '@/components/hooks'; import { Edit, Plus } from '@/components/icons'; +import { FilterButtons } from '@/components/input/FilterButtons'; import { type AnnotationRange, getAnnotationDateRangeValue } from '@/lib/annotations'; import { AnnotationDeleteButton } from './AnnotationDeleteButton'; import { type Annotation, AnnotationEditForm } from './AnnotationEditForm'; @@ -99,7 +99,7 @@ export function AnnotationsModal({ const rows: Annotation[] = data?.data || []; return ( - + {t(labels.notes)} {!share && ( @@ -155,7 +155,7 @@ export function AnnotationsModal({ )} {onClose && ( - + )} diff --git a/src/components/charts/Chart.tsx b/src/components/charts/Chart.tsx index a68a575b0..51eff3a04 100644 --- a/src/components/charts/Chart.tsx +++ b/src/components/charts/Chart.tsx @@ -5,7 +5,7 @@ import ChartJS, { type LegendItem, type UpdateMode, } from 'chart.js/auto'; -import { useEffect, useMemo, useRef, useState } from 'react'; +import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { type AnnotationMarker, type ChartAnnotation, @@ -26,6 +26,7 @@ export interface ChartProps extends BoxProps { onTooltip?: (model: any) => void; hiddenLabels?: Set; onLegendClick?: (label: string, willBeHidden: boolean) => void; + legendActions?: ReactNode; annotations?: ChartAnnotation[]; onAnnotationClick?: (annotations: ChartAnnotation[]) => void; onAnnotationMoreClick?: (annotations: ChartAnnotation[]) => void; @@ -53,6 +54,7 @@ export function Chart({ chartOptions, hiddenLabels, onLegendClick, + legendActions, annotations, onAnnotationClick, onAnnotationMoreClick, @@ -234,7 +236,23 @@ export function Chart({ )} - + {legendActions ? ( +
+
+ +
+
{legendActions}
+
+ ) : ( + + )}
); }