Skip to content

Commit cba5451

Browse files
committed
fix: filter annotations outside of the scope
1 parent d66cae0 commit cba5451

File tree

3 files changed

+54
-34
lines changed

3 files changed

+54
-34
lines changed

apps/dashboard/components/charts/metrics-chart-with-annotations.tsx

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
'use client';
22

33
import { useMemo, useState } from 'react';
4+
import { toast } from 'sonner';
45
import { MetricsChart } from './metrics-chart';
56
import { EditAnnotationModal } from './edit-annotation-modal';
67
import { trpc } from '@/lib/trpc';
7-
import { toast } from 'sonner';
88
import { usePersistentState } from '@/hooks/use-persistent-state';
9-
import type { Annotation, ChartContext, CreateAnnotationData, AnnotationFormData } from '@/types/annotations';
109
import { ANNOTATION_STORAGE_KEYS } from '@/lib/annotation-constants';
10+
import type { Annotation, ChartContext, CreateAnnotationData, AnnotationFormData } from '@/types/annotations';
1111

1212
interface MetricsChartWithAnnotationsProps {
1313
websiteId: string;
@@ -40,21 +40,20 @@ export function MetricsChartWithAnnotations({
4040
onRangeSelect,
4141
dateRange,
4242
}: MetricsChartWithAnnotationsProps) {
43-
const createAnnotation = trpc.annotations.create.useMutation();
44-
const updateAnnotation = trpc.annotations.update.useMutation();
45-
const deleteAnnotation = trpc.annotations.delete.useMutation();
46-
4743
const [editingAnnotation, setEditingAnnotation] = useState<Annotation | null>(null);
4844
const [isEditing, setIsEditing] = useState(false);
4945
const [showAnnotations, setShowAnnotations] = usePersistentState(
50-
ANNOTATION_STORAGE_KEYS.visibility(websiteId),
46+
ANNOTATION_STORAGE_KEYS.visibility(websiteId),
5147
true
5248
);
53-
54-
// Build chart context for fetching annotations
49+
50+
const createAnnotation = trpc.annotations.create.useMutation();
51+
const updateAnnotation = trpc.annotations.update.useMutation();
52+
const deleteAnnotation = trpc.annotations.delete.useMutation();
53+
5554
const chartContext = useMemo((): ChartContext | null => {
56-
if (!dateRange || !data || data.length === 0) return null;
57-
55+
if (!dateRange || !data?.length) return null;
56+
5857
return {
5958
dateRange: {
6059
start_date: dateRange.startDate.toISOString(),
@@ -65,8 +64,7 @@ export function MetricsChartWithAnnotations({
6564
};
6665
}, [dateRange, data]);
6766

68-
// Fetch annotations for this chart
69-
const { data: annotations, refetch: refetchAnnotations } = trpc.annotations.list.useQuery(
67+
const { data: allAnnotations, refetch: refetchAnnotations } = trpc.annotations.list.useQuery(
7068
{
7169
websiteId,
7270
chartType: 'metrics' as const,
@@ -77,6 +75,23 @@ export function MetricsChartWithAnnotations({
7775
}
7876
);
7977

78+
const annotations = useMemo(() => {
79+
if (!allAnnotations || !dateRange) return [];
80+
81+
const { startDate, endDate } = dateRange;
82+
83+
return allAnnotations.filter((annotation) => {
84+
const annotationStart = new Date(annotation.xValue);
85+
const annotationEnd = annotation.xEndValue ? new Date(annotation.xEndValue) : annotationStart;
86+
87+
return (
88+
(annotationStart >= startDate && annotationStart <= endDate) ||
89+
(annotationEnd >= startDate && annotationEnd <= endDate) ||
90+
(annotationStart <= startDate && annotationEnd >= endDate)
91+
);
92+
});
93+
}, [allAnnotations, dateRange]);
94+
8095
const handleCreateAnnotation = async (annotation: {
8196
annotationType: 'range';
8297
xValue: string;
@@ -86,13 +101,8 @@ export function MetricsChartWithAnnotations({
86101
color: string;
87102
isPublic: boolean;
88103
}) => {
89-
if (!websiteId) {
90-
toast.error('Website ID is required');
91-
return;
92-
}
93-
94-
if (!chartContext) {
95-
toast.error('Chart context is required');
104+
if (!websiteId || !chartContext) {
105+
toast.error('Missing required data for annotation creation');
96106
return;
97107
}
98108

@@ -119,9 +129,7 @@ export function MetricsChartWithAnnotations({
119129
},
120130
error: (err) => {
121131
console.error('Failed to create annotation:', err);
122-
const errorMessage = err?.message || 'Failed to create annotation';
123-
toast.error(`Failed to create annotation: ${errorMessage}`);
124-
return errorMessage;
132+
return err?.message || 'Failed to create annotation';
125133
},
126134
});
127135

@@ -193,6 +201,7 @@ export function MetricsChartWithAnnotations({
193201
onDeleteAnnotation={handleDeleteAnnotation}
194202
showAnnotations={showAnnotations}
195203
onToggleAnnotations={setShowAnnotations}
204+
websiteId={websiteId}
196205
/>
197206

198207
<EditAnnotationModal

apps/dashboard/components/charts/metrics-chart.tsx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChartLineIcon, EyeIcon, EyeSlashIcon } from '@phosphor-icons/react';
1+
import { ChartLineIcon, EyeIcon, EyeSlashIcon, XIcon } from '@phosphor-icons/react';
22
import { useAtom } from 'jotai';
33
import { useMemo, useState } from 'react';
44
import {
@@ -13,16 +13,12 @@ import {
1313
XAxis,
1414
YAxis,
1515
} from 'recharts';
16-
import {
17-
Card,
18-
CardContent,
19-
CardDescription,
20-
CardHeader,
21-
CardTitle,
22-
} from '@/components/ui/card';
2316
import { Switch } from '@/components/ui/switch';
2417
import { Label } from '@/components/ui/label';
18+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
2519
import { cn } from '@/lib/utils';
20+
import { usePersistentState } from '@/hooks/use-persistent-state';
21+
import { ANNOTATION_STORAGE_KEYS } from '@/lib/annotation-constants';
2622
import {
2723
type ChartDataRow,
2824
METRICS,
@@ -120,6 +116,7 @@ interface MetricsChartProps {
120116
onDeleteAnnotation?: (id: string) => Promise<void>;
121117
showAnnotations?: boolean;
122118
onToggleAnnotations?: (show: boolean) => void;
119+
websiteId?: string;
123120
}
124121

125122
export function MetricsChart({
@@ -138,6 +135,7 @@ export function MetricsChart({
138135
onDeleteAnnotation,
139136
showAnnotations = true,
140137
onToggleAnnotations,
138+
websiteId,
141139
}: MetricsChartProps) {
142140
const rawData = data || [];
143141
const [refAreaLeft, setRefAreaLeft] = useState<string | null>(null);
@@ -146,6 +144,11 @@ export function MetricsChart({
146144
const [popupPosition, setPopupPosition] = useState({ x: 0, y: 0 });
147145
const [selectedDateRange, setSelectedDateRange] = useState<DateRangeState | null>(null);
148146

147+
const [tipDismissed, setTipDismissed] = usePersistentState(
148+
websiteId ? ANNOTATION_STORAGE_KEYS.tipDismissed(websiteId) : 'chart-tip-dismissed',
149+
false
150+
);
151+
149152
const [visibleMetrics] = useAtom(metricVisibilityAtom);
150153
const [, toggleMetric] = useAtom(toggleMetricAtom);
151154

@@ -336,10 +339,17 @@ export function MetricsChart({
336339
</div>
337340
)}
338341

339-
{!refAreaLeft && annotations.length === 0 && (
342+
{!refAreaLeft && annotations.length === 0 && !tipDismissed && (
340343
<div className="absolute top-4 right-4 z-10">
341-
<div className="bg-muted/80 backdrop-blur-sm border border-border/50 px-3 py-2 rounded-lg text-xs text-muted-foreground shadow-sm">
342-
💡 Click or drag on chart to create annotations
344+
<div className="bg-muted/80 backdrop-blur-sm border border-border/50 px-3 py-2 rounded-lg text-xs text-muted-foreground shadow-sm flex items-center gap-2">
345+
<span>💡 Click or drag on chart to create annotations</span>
346+
<button
347+
onClick={() => setTipDismissed(true)}
348+
className="text-muted-foreground hover:text-foreground transition-colors"
349+
aria-label="Dismiss tip"
350+
>
351+
<XIcon size={12} />
352+
</button>
343353
</div>
344354
</div>
345355
)}

apps/dashboard/lib/annotation-constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,5 @@ export const CHART_ANNOTATION_STYLES = {
5454
*/
5555
export const ANNOTATION_STORAGE_KEYS = {
5656
visibility: (websiteId: string) => `chart-annotations-visible-${websiteId}`,
57+
tipDismissed: (websiteId: string) => `chart-annotations-tip-dismissed-${websiteId}`,
5758
} as const;

0 commit comments

Comments
 (0)