import { zodResolver } from '@hookform/resolvers/zod' import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { HelpCircle } from 'lucide-react' import { useForm } from 'react-hook-form' import { toast } from 'sonner' import { Button, Card, CardContent, CardFooter, Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogSection, DialogSectionSeparator, DialogTitle, DialogTrigger, Form, FormControl, FormField, } from 'ui' import { Admonition } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { PageSection, PageSectionContent, PageSectionMeta, PageSectionSummary, PageSectionTitle, } from 'ui-patterns/PageSection' import ShimmeringLoader, { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import * as z from 'zod' import { DatabaseSelector } from '@/components/ui/DatabaseSelector' import { InlineLink } from '@/components/ui/InlineLink' import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query' import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage' const formSchema = z.object({ defaultDatabase: z.string().optional(), }) export type DashboardPreference = z.infer const DEFAULT_PREFERENCE: DashboardPreference = { defaultDatabase: undefined, } /** * [Joshen] JFYI am not convinced about the UX of this, will iterate over time * and only release to public when we're satisfied with how it behaves * - Where should "Dashboard preferences" live * - Preferences currently only apply to the user via local storage until we have middleware support that will persist the setting on the project for all users * - Should selecting which database to run queries for dashboard be an option for users to configure (or for us to just default to) * - I'd love for this to work seamlessly, but main concern atm is latency which is region dependent * - Also, current database logic only applies to Table Editor atm, will need to extend it further to other pages */ export const DashboardPreferences = () => { const { ref: projectRef } = useParams() const [dashboardPreferences, setDashboardPreferences, { isLoading }] = useLocalStorageQuery( LOCAL_STORAGE_KEYS.DASHBOARD_PREFERENCES(projectRef ?? '_'), DEFAULT_PREFERENCE ) const { isPending } = useReadReplicasQuery({ projectRef }) const form = useForm>({ resolver: zodResolver(formSchema as any), defaultValues: dashboardPreferences, values: dashboardPreferences, mode: 'onSubmit', reValidateMode: 'onBlur', }) const onSubmit = async (values: DashboardPreference) => { if (!projectRef) return console.error('Ref is required') setDashboardPreferences(values) form.reset(values) toast.success('Successfully saved dashboard preferences!') } return ( Queries {/* [Joshen] Ideally we're able to persist this for all users in the project, but will need support in our middleware */} {isLoading ? ( ) : (
( All read queries from the dashboard will run against the selected database by default

} className="[&>div]:md:w-1/2" > {isPending ? ( ) : ( {/* [Joshen] Need to disable unhealthy replicas */} field.onChange(id === projectRef ? undefined : id) } /> )}
)} />
{form.formState.isDirty && ( )}
)}
) } const DashboardQueriesDialog = () => { const { ref } = useParams() return ( How does the dashboard interact with your project's database?

The dashboard queries your project's database to display data across various interfaces, such as the Table Editor, the{' '} Auth Users page, and more.

You can route these queries to a read replica instead, which will help reduce load on your primary database.

) }