Home / Function/ PolicyDetailsV2() — supabase Function Reference

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>
    </>
  )
}

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free