import { PermissionAction } from '@supabase/shared-types/out/constants' import { Plus } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useState } from 'react' import { toast } from 'sonner' import { useParams } from 'common' import { CreateReportModal } from 'components/interfaces/Reports/Reports.CreateReportModal' import { UpdateCustomReportModal } from 'components/interfaces/Reports/Reports.UpdateModal' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import ShimmeringLoader from 'components/ui/ShimmeringLoader' import { useContentDeleteMutation } from 'data/content/content-delete-mutation' import { Content, useContentQuery } from 'data/content/content-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useProfile } from 'lib/profile' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, Menu, cn } from 'ui' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { ReportMenuItem } from './ReportMenuItem' const ReportsMenu = () => { const router = useRouter() const { profile } = useProfile() const { ref, id } = useParams() const pageKey = (id || router.pathname.split('/')[4]) as string const storageEnabled = useIsFeatureEnabled('project_storage:all') const canCreateCustomReport = useCheckPermissions(PermissionAction.CREATE, 'user_content', { resource: { type: 'report', owner_id: profile?.id }, subject: { id: profile?.id }, }) const { data: content, isLoading } = useContentQuery(ref) const { mutate: deleteReport, isLoading: isDeleting } = useContentDeleteMutation({ onSuccess: () => { setDeleteModalOpen(false) toast.success('Successfully deleted report') router.push(`/project/${ref}/reports`) }, onError: (error) => { toast.error(`Failed to delete report: ${error.message}`) }, }) const [deleteModalOpen, setDeleteModalOpen] = useState(false) const [showNewReportModal, setShowNewReportModal] = useState(false) const [selectedReportToDelete, setSelectedReportToDelete] = useState() const [selectedReportToUpdate, setSelectedReportToUpdate] = useState() const onConfirmDeleteReport = () => { if (ref === undefined) return console.error('Project ref is required') if (selectedReportToDelete?.id === undefined) return console.error('Report ID is required') deleteReport({ projectRef: ref, ids: [selectedReportToDelete.id] }) } function getReportMenuItems() { if (!content) return [] const reports = content?.content.filter((c) => c.type === 'report') const sortedReports = reports?.sort((a, b) => { if (a.name < b.name) { return -1 } if (a.name > b.name) { return 1 } return 0 }) const reportMenuItems = sortedReports.map((r, idx) => ({ id: r.id, name: r.name, description: r.description || '', key: r.id || idx + '-report', url: `/project/${ref}/reports/${r.id}`, hasDropdownActions: true, report: r, })) return reportMenuItems } const reportMenuItems = getReportMenuItems() const menuItems = [ { title: 'Built-in reports', key: 'builtin-reports', items: [ { name: 'API', key: 'api-overview', url: `/project/${ref}/reports/api-overview`, }, ...(storageEnabled ? [ { name: 'Storage', key: 'storage', url: `/project/${ref}/reports/storage`, }, ] : []), { name: 'Database', key: 'database', url: `/project/${ref}/reports/database`, }, ], }, ] return ( {isLoading ? (
) : (
} disabled={!canCreateCustomReport} className="justify-start flex-grow" onClick={() => { setShowNewReportModal(true) }} tooltip={{ content: { side: 'bottom', text: 'You need additional permissions to create custom reports', }, }} > New custom report
{reportMenuItems.length > 0 ? (
Your custom reports} /> {reportMenuItems.map((item) => ( { setSelectedReportToUpdate(item.report) }} onSelectDelete={() => { setSelectedReportToDelete(item.report) setDeleteModalOpen(true) }} /> ))}
) : null} {menuItems.map((item) => (
{item.items ? ( <> {item.title}} />
{item.items.map((subItem) => (
  • {subItem.name}
  • ))}
    ) : null}
    ))} {/* [Joshen] Temp notice while we shift some pages on 040424 - can probably remove in 3 months perhaps */} Query Performance and Project Linter reports have been shifted

    They can now be found in the menu under the database section.

    setSelectedReportToUpdate(undefined)} selectedReport={selectedReportToUpdate} initialValues={{ name: selectedReportToUpdate?.name || '', description: selectedReportToUpdate?.description || '', }} /> setDeleteModalOpen(false)} onConfirm={onConfirmDeleteReport} >

    Are you sure you want to delete '{selectedReportToDelete?.name}'?

    setShowNewReportModal(false)} afterSubmit={() => setShowNewReportModal(false)} />
    )}
    ) } export default ReportsMenu