PublicationsList() — supabase Function Reference
Architecture documentation for the PublicationsList() function in PublicationsList.tsx from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx lines 38–233
export const PublicationsList = () => {
const { ref } = useParams()
const { data: project } = useSelectedProjectQuery()
const [filterString, setFilterString] = useState<string>('')
const {
data = [],
error,
isPending: isLoading,
isSuccess,
isError,
} = useDatabasePublicationsQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
})
const { mutate: updatePublications } = useDatabasePublicationUpdateMutation({
onSuccess: () => {
toast.success('Successfully updated event')
setToggleListenEventValue(null)
},
})
const { can: canUpdatePublications, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
PermissionAction.TENANT_SQL_ADMIN_WRITE,
'publications'
)
const publicationEvents: PublicationEvent[] = [
{ event: 'Insert', key: 'publish_insert' },
{ event: 'Update', key: 'publish_update' },
{ event: 'Delete', key: 'publish_delete' },
{ event: 'Truncate', key: 'publish_truncate' },
]
const publications = (
filterString.length === 0
? data
: data.filter((publication) => publication.name.includes(filterString))
).sort((a, b) => a.id - b.id)
const [toggleListenEventValue, setToggleListenEventValue] = useState<{
publication: any
event: PublicationEvent
currentStatus: any
} | null>(null)
const toggleListenEvent = async () => {
if (!toggleListenEventValue || !project) return
const { publication, event, currentStatus } = toggleListenEventValue
const payload = {
projectRef: project.ref,
connectionString: project.connectionString,
id: publication.id,
} as any
payload[`publish_${event.event.toLowerCase()}`] = !currentStatus
updatePublications(payload)
}
return (
<>
<div className="mb-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<Input
size="tiny"
icon={<Search />}
className="w-48"
placeholder="Search for a publication"
value={filterString}
onChange={(e) => setFilterString(e.target.value)}
/>
</div>
{isPermissionsLoaded && !canUpdatePublications && (
<div className="w-[500px]">
<InformationBox
icon={<AlertCircle className="text-foreground-light" strokeWidth={2} />}
title="You need additional permissions to update database publications"
/>
</div>
)}
</div>
</div>
<div className="w-full overflow-hidden overflow-x-auto">
<Card>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>System ID</TableHead>
<TableHead>Insert</TableHead>
<TableHead>Update</TableHead>
<TableHead>Delete</TableHead>
<TableHead>Truncate</TableHead>
<TableHead />
</TableRow>
</TableHeader>
<TableBody>
{isLoading &&
Array.from({ length: 2 }).map((_, i) => <PublicationSkeleton key={i} index={i} />)}
{isError && (
<TableRow>
<TableCell colSpan={7}>
<AlertError error={error} subject="Failed to retrieve publications" />
</TableCell>
</TableRow>
)}
{isSuccess &&
publications.map((x) => (
<TableRow key={x.name}>
<TableCell>
<div className="flex items-center gap-x-2">
{x.name}
{/* [Joshen] Making this tooltip very specific for these 2 publications */}
{['supabase_realtime', 'supabase_realtime_messages_publication'].includes(
x.name
) && (
<Tooltip>
<TooltipTrigger>
<Info size={14} className="text-foreground-light" />
</TooltipTrigger>
<TooltipContent side="bottom">
{x.name === 'supabase_realtime'
? 'Managed by Supabase and handles Postgres changes'
: x.name === 'supabase_realtime_messages_publication'
? 'Managed by Supabase and handles broadcasts from the database'
: undefined}
</TooltipContent>
</Tooltip>
)}
</div>
</TableCell>
<TableCell>{x.id}</TableCell>
{publicationEvents.map((event) => (
<TableCell key={event.key}>
<Switch
size="small"
checked={(x as any)[event.key]}
disabled={!canUpdatePublications}
onClick={() => {
setToggleListenEventValue({
publication: x,
event,
currentStatus: (x as any)[event.key],
})
}}
/>
</TableCell>
))}
<TableCell>
<div className="flex justify-end">
<Button asChild type="default" style={{ paddingTop: 3, paddingBottom: 3 }}>
<Link href={`/project/${ref}/database/publications/${x.id}`}>
{x.tables === null
? 'All tables'
: `${x.tables.length} ${x.tables.length === 1 ? 'table' : 'tables'}`}
</Link>
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Card>
</div>
{!isLoading && publications.length === 0 && (
<NoSearchResults
searchString={filterString}
onResetFilter={() => setFilterString('')}
className="rounded-t-none border-t-0"
/>
)}
<ConfirmationModal
visible={toggleListenEventValue !== null}
title={`Confirm to toggle sending ${toggleListenEventValue?.event.event.toLowerCase()} events`}
confirmLabel="Confirm"
confirmLabelLoading="Updating"
onCancel={() => setToggleListenEventValue(null)}
onConfirm={() => {
toggleListenEvent()
}}
>
<p className="text-sm text-foreground-light">
Are you sure you want to {toggleListenEventValue?.currentStatus ? 'stop' : 'start'}{' '}
sending {toggleListenEventValue?.event.event.toLowerCase()} events for{' '}
{toggleListenEventValue?.publication.name}?
</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