PolicyDetailsV2() — supabase Function Reference
Architecture documentation for the PolicyDetailsV2() function in PolicyDetailsV2.tsx from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/studio/components/interfaces/Auth/Policies/PolicyEditorPanel/PolicyDetailsV2.tsx lines 54–321
export const PolicyDetailsV2 = ({
schema,
searchString,
selectedTable,
isEditing,
form,
onUpdateCommand,
authContext,
}: PolicyDetailsV2Props) => {
const { data: project } = useSelectedProjectQuery()
const [open, setOpen] = useState(false)
const { can: canUpdatePolicies } = useAsyncCheckPermissions(
PermissionAction.TENANT_SQL_ADMIN_WRITE,
'tables'
)
const { data: tables, isSuccess: isSuccessTables } = useTablesQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
schema: schema,
sortByProperty: 'name',
includeColumns: true,
})
const { data: dbRoles } = useDatabaseRolesQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
})
const formattedRoles = (dbRoles ?? [])
.map((role) => {
return {
id: role.id,
name: role.name,
value: role.name,
disabled: false,
}
})
.sort((a, b) => a.name.localeCompare(b.name))
useEffect(() => {
if (!isEditing && selectedTable === undefined) {
const table = tables?.find(
(table) =>
table.schema === schema &&
(table.id.toString() === searchString || table.name === searchString)
)
if (table) {
form.setValue('table', table.name)
} else if (isSuccessTables && tables.length > 0) {
form.setValue('table', tables[0].name)
}
}
}, [isEditing, form, searchString, tables, isSuccessTables, selectedTable])
return (
<>
<div className="px-5 py-5 flex flex-col gap-y-4 border-b">
<div className="items-start justify-between gap-4 grid grid-cols-12">
<FormField_Shadcn_
control={form.control}
name="name"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-6 flex flex-col gap-y-1">
<FormLabel_Shadcn_>Policy Name</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<Input_Shadcn_
{...field}
disabled={!canUpdatePolicies}
className="bg-control border-control"
placeholder="Provide a name for your policy"
/>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
)}
/>
<FormField_Shadcn_
control={form.control}
name="table"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-6 flex flex-col gap-y-1">
<FormLabel_Shadcn_>
Table
<code className="text-code-inline">on</code> clause
</FormLabel_Shadcn_>
{authContext === 'database' && (
<FormControl_Shadcn_>
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={false}>
<PopoverTrigger_Shadcn_ asChild>
<Button
type="default"
disabled={!canUpdatePolicies}
className="w-full [&>span]:w-full h-[38px] text-sm"
iconRight={
<ChevronsUpDown
className="text-foreground-muted"
strokeWidth={2}
size={14}
/>
}
>
<div className="w-full flex gap-1">
<span className="text-foreground">
{schema}.{field.value}
</span>
</div>
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_
className="p-0"
side="bottom"
align="start"
sameWidthAsTrigger
>
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Find a table..." />
<CommandList_Shadcn_>
<CommandEmpty_Shadcn_>No tables found</CommandEmpty_Shadcn_>
<CommandGroup_Shadcn_>
<ScrollArea className={(tables ?? []).length > 7 ? 'h-[200px]' : ''}>
{(tables ?? []).map((table) => (
<CommandItem_Shadcn_
key={table.id}
className="cursor-pointer flex items-center justify-between space-x-2 w-full"
onSelect={() => {
form.setValue('table', table.name)
setOpen(false)
}}
onClick={() => {
form.setValue('table', table.name)
setOpen(false)
}}
>
<span className="flex items-center gap-1.5">
{field.value === table.name ? <Check size={13} /> : ''}
{table.name}
</span>
</CommandItem_Shadcn_>
))}
</ScrollArea>
</CommandGroup_Shadcn_>
</CommandList_Shadcn_>
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
</FormControl_Shadcn_>
)}
{authContext === 'realtime' && (
<FormControl_Shadcn_>
<Input_Shadcn_
disabled
value="messages.realtime"
className="bg-control border-control"
/>
</FormControl_Shadcn_>
)}
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
)}
/>
<FormField_Shadcn_
control={form.control}
name="behavior"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-6 flex flex-col gap-y-1">
<FormLabel_Shadcn_>
Policy Behavior <code className="text-code-inline">as</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<Select_Shadcn_
disabled={isEditing}
value={field.value}
onValueChange={(value) => form.setValue('behavior', value)}
>
<SelectTrigger_Shadcn_ className="text-sm h-10 capitalize">
{field.value}
</SelectTrigger_Shadcn_>
<SelectContent_Shadcn_>
<SelectGroup_Shadcn_>
<SelectItem_Shadcn_ value="permissive" className="text-sm">
<p>Permissive</p>
<p className="text-foreground-light text-xs">
Policies are combined using the "OR" Boolean operator
</p>
</SelectItem_Shadcn_>
<SelectItem_Shadcn_ value="restrictive" className="text-sm">
<p>Restrictive</p>
<p className="text-foreground-light text-xs">
Policies are combined using the "AND" Boolean operator
</p>
</SelectItem_Shadcn_>
</SelectGroup_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
)}
/>
<FormField_Shadcn_
control={form.control}
name="command"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-12 flex flex-col gap-y-1">
<FormLabel_Shadcn_>
Policy Command <code className="text-code-inline">for</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<RadioGroup_Shadcn_
disabled={isEditing}
value={field.value}
defaultValue={field.value}
onValueChange={(value) => {
form.setValue('command', value)
onUpdateCommand(value)
}}
className={`grid grid-cols-10 gap-3 ${isEditing ? 'opacity-50' : ''}`}
>
{[
'select',
'insert',
...(authContext === 'database' ? ['update', 'delete', 'all'] : []),
].map((x) => (
<RadioGroupLargeItem_Shadcn_
key={x}
value={x}
disabled={isEditing}
label={x.toLocaleUpperCase()}
className={`col-span-2 w-auto ${isEditing ? 'cursor-not-allowed' : ''}`}
/>
))}
</RadioGroup_Shadcn_>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
)}
/>
<FormField_Shadcn_
control={form.control}
name="roles"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-12 flex flex-col gap-y-1">
<FormLabel_Shadcn_>
Target Roles <code className="text-code-inline">to</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<MultiSelectV2
disabled={!canUpdatePolicies}
options={formattedRoles}
value={field.value.length === 0 ? [] : field.value?.split(', ')}
placeholder="Defaults to all (public) roles if none selected"
searchPlaceholder="Search for a role"
onChange={(roles) => form.setValue('roles', roles.join(', '))}
/>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
)}
/>
</div>
</div>
</>
)
}
Domain
Subdomains
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free