import { ArchiveIcon, InboxIcon } from 'lucide-react' import { useMemo, useRef, useState } from 'react' import { toast } from 'sonner' import AlertError from 'components/ui/AlertError' import InfiniteList from 'components/ui/InfiniteList' import ShimmeringLoader, { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useNotificationsArchiveAllMutation } from 'data/notifications/notifications-v2-archive-all-mutation' import { useNotificationsV2Query } from 'data/notifications/notifications-v2-query' import { useNotificationsSummaryQuery } from 'data/notifications/notifications-v2-summary-query' import { useNotificationsV2UpdateMutation } from 'data/notifications/notifications-v2-update-mutation' import { useOrganizationsQuery } from 'data/organizations/organizations-query' import { useProjectsQuery } from 'data/projects/projects-query' import { useNotificationsStateSnapshot } from 'state/notifications' import { Button, CriticalIcon, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_, Tabs_Shadcn_, WarningIcon, cn, } from 'ui' import NotificationRow from './NotificationRow' import { NotificationsFilter } from './NotificationsFilter' const NotificationsPopoverV2 = () => { const [open, setOpen] = useState(false) const [activeTab, setActiveTab] = useState<'inbox' | 'archived'>('inbox') const snap = useNotificationsStateSnapshot() // Storing in ref as no re-rendering required const markedRead = useRef([]) // [Joshen] Just FYI this variable row heights logic should ideally live in InfiniteList // but I ran into some infinite loops issues when I was trying to implement it there // so opting to simplify and implement it here for now const rowHeights = useRef<{ [key: number]: number }>({}) const { data: projects } = useProjectsQuery({ enabled: open }) const { data: organizations } = useOrganizationsQuery({ enabled: open }) const { data, error, isLoading, isError, isSuccess, hasNextPage, isFetchingNextPage, fetchNextPage, } = useNotificationsV2Query( { status: activeTab === 'archived' ? 'archived' : snap.filterStatuses.includes('unread') ? 'new' : undefined, filters: { priority: snap.filterPriorities, organizations: snap.filterOrganizations, projects: snap.filterProjects, }, }, { enabled: open } ) const { data: summary } = useNotificationsSummaryQuery() const { mutate: updateNotifications } = useNotificationsV2UpdateMutation() const { mutate: archiveAllNotifications, isLoading: isArchiving } = useNotificationsArchiveAllMutation({ onSuccess: () => toast.success('Successfully archived all notifications'), }) const notifications = useMemo(() => data?.pages.flatMap((page) => page) ?? [], [data?.pages]) const hasNewNotifications = summary?.unread_count ?? 0 > 0 const hasWarning = summary?.has_warning const hasCritical = summary?.has_critical const markNotificationsRead = () => { if (markedRead.current.length > 0) { updateNotifications({ ids: markedRead.current, status: 'seen' }) } } return ( { setOpen(open) if (!open) markNotificationsRead() }} > )} ) } export default NotificationsPopoverV2