RealtimeFilterPopover() — supabase Function Reference
Architecture documentation for the RealtimeFilterPopover() function in index.tsx from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/studio/components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx lines 35–259
export const RealtimeFilterPopover = ({ config, onChangeConfig }: RealtimeFilterPopoverProps) => {
const [open, setOpen] = useState(false)
const [applyConfigOpen, setApplyConfigOpen] = useState(false)
const [tempConfig, setTempConfig] = useState(config)
const { ref } = useParams()
const { data: project } = useSelectedProjectQuery()
const { data: org } = useSelectedOrganizationQuery()
const { mutate: sendEvent } = useSendEventMutation()
const { data: publications } = useDatabasePublicationsQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
})
const realtimePublication = (publications ?? []).find(
(publication) => publication.name === 'supabase_realtime'
)
// Update tempConfig when config changes to ensure consistency
useEffect(() => {
setTempConfig(config)
}, [config])
const onOpen = (v: boolean) => {
// when opening, copy the outside config into the intermediate one
if (v === true) {
setTempConfig(config)
}
setOpen(v)
}
// [Joshen] Restricting the schemas to only public as any other schema won’t work out of the box due to missing permissions
// Consequently, SchemaSelector here will also be disabled
const isFiltered = config.table !== '*'
return (
<>
<Popover_Shadcn_ open={open} onOpenChange={onOpen}>
<PopoverTrigger_Shadcn_ asChild>
<Button
icon={<PlusCircle size="16" />}
type={isFiltered ? 'primary' : 'dashed'}
className={cn('rounded-full px-1 text-xs h-[26px]')}
size="small"
>
{isFiltered ? (
<>
<span className="mr-1">Filtered by </span>
<Badge variant="success">table: {config.table}</Badge>
</>
) : (
<span className="mr-1">Filter messages</span>
)}
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="p-0 w-[365px]" align="start">
<div className="border-b border-overlay text-xs px-4 py-3 text-foreground">
Listen to event types
</div>
<div className="py-3 px-4 border-b border-overlay">
<div className="flex items-center justify-between gap-2">
<div className="flex gap-2.5 items-center">
<IconPresence
size="xlarge"
className="bg-foreground rounded text-background-muted"
/>
<label htmlFor="toggle-presence" className="text-sm">
Presence
</label>
</div>
<Toggle
id="toggle-presence"
size="tiny"
checked={tempConfig.enablePresence}
onChange={() =>
setTempConfig({ ...tempConfig, enablePresence: !tempConfig.enablePresence })
}
/>
</div>
<p className="text-xs text-foreground-light pt-1">
Store and synchronize user state consistently across clients
</p>
</div>
<div className="py-3 px-4 border-b border-overlay">
<div className="flex items-center justify-between">
<div className="flex gap-2.5 items-center">
<IconBroadcast
size="xlarge"
className="bg-foreground rounded text-background-muted"
/>
<label htmlFor="toggle-broadcast" className="text-sm">
Broadcast
</label>
</div>
<Toggle
id="toggle-broadcast"
size="tiny"
checked={tempConfig.enableBroadcast}
onChange={() =>
setTempConfig({ ...tempConfig, enableBroadcast: !tempConfig.enableBroadcast })
}
/>
</div>
<p className="text-xs text-foreground-light pt-1">
Send any data to any client subscribed to the same channel
</p>
</div>
<div className="py-3 px-4 border-b border-overlay">
<div className="flex items-center justify-between">
<div className="flex gap-2.5 items-center">
<IconDatabaseChanges
size="xlarge"
className={cn(
'rounded text-background-muted',
config.enableDbChanges ? 'bg-foreground' : 'bg-foreground-lighter'
)}
/>
<label
htmlFor="toggle-db-changes"
className={cn('text-sm', !config.enableDbChanges && 'text-foreground-lighter')}
>
Database changes
</label>
</div>
<Toggle
id="toggle-db-changes"
size="tiny"
checked={tempConfig.enableDbChanges}
disabled={!config.enableDbChanges}
onChange={() =>
setTempConfig({ ...tempConfig, enableDbChanges: !tempConfig.enableDbChanges })
}
/>
</div>
<p className="text-xs text-foreground-light pt-1">
Listen for Database inserts, updates, deletes and more
</p>
{!config.enableDbChanges && (
<p className="text-xs text-foreground-light mt-2">
Enable{' '}
<InlineLink
href={`/project/${ref}/database/publications${!!realtimePublication ? `/${realtimePublication.id}` : ''}`}
>
realtime publications
</InlineLink>{' '}
for your tables to listen for database changes
</p>
)}
</div>
{tempConfig.enableDbChanges && config.enableDbChanges && (
<>
<div className="border-b border-overlay text-xs px-4 py-3 text-foreground">
Filter messages from database changes
</div>
<div className="flex border-b border-overlay p-4 gap-y-2 flex-col">
<FilterSchema
value={tempConfig.schema}
onChange={(v) => setTempConfig({ ...tempConfig, schema: v, table: '*' })}
/>
<FilterTable
value={tempConfig.table}
schema={tempConfig.schema}
onChange={(table) => setTempConfig({ ...tempConfig, table })}
/>
</div>
<div className="border-b border-overlay p-4 flex flex-col gap-2">
<div className="flex flex-row gap-4 items-center">
<p className="w-[60px] flex justify-end text-sm">AND</p>
<Input
size="tiny"
className="flex-grow"
placeholder="body=eq.hey"
value={tempConfig.filter}
onChange={(v) => setTempConfig({ ...tempConfig, filter: v.target.value })}
/>
</div>
<p className="text-xs text-foreground-light pl-[80px]">
Learn more about realtime filtering in{' '}
<Link
className="underline"
target="_blank"
rel="noreferrer"
href={`${DOCS_URL}/guides/realtime/postgres-changes#available-filters`}
>
our docs
</Link>
</p>
</div>
</>
)}
<div className="px-4 py-2 gap-2 flex justify-end">
<Button type="default" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button onClick={() => setApplyConfigOpen(true)}>Apply</Button>
</div>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
<ConfirmationModal
title="Previously found messages will be lost"
variant="destructive"
confirmLabel="Confirm"
size="small"
visible={applyConfigOpen}
onCancel={() => setApplyConfigOpen(false)}
onConfirm={() => {
sendEvent({
action: 'realtime_inspector_filters_applied',
groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
onChangeConfig(tempConfig)
setApplyConfigOpen(false)
setOpen(false)
}}
>
<p className="text-sm text-foreground-light">
The realtime inspector will clear currently collected messages and start listening for new
messages matching the updated filters.
</p>
</ConfirmationModal>
</>
)
}
Domain
Subdomains
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free