mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## Context This is one chonky boy of a PR, but it's just re-organizing files and folders to clean things up Storage Policies have been using the old Database policy UI (the one with the Dialog), so it makes most sense to shift those files under the `Storage` folder instead of keeping them under `Database`, so it's clearer which files are being consumed by whom, and easier to clean things up as well As part of this clean up, also tore out all the RLS generation logic from the Table Editor which are no longer used as they were affected by the change in files. Deprecated + deleted any unused code too <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced the policy editor with a centralized set of reusable templates, including general table templates plus predefined Realtime and queue access templates. * Updated the table creation flow so it no longer auto-generates additional RLS policy drafts. * **Bug Fixes** * Improved the policy table header badge layout for clearer RLS/API/lock indicators. * Simplified policy preview/save behavior so only meaningful edits are reflected in the applied SQL. * Streamlined the table-creation success messaging to remove conditional failure details. * **Tests** * Updated/removal of policy and table-creation test coverage to match the new behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
153 lines
5.4 KiB
TypeScript
153 lines
5.4 KiB
TypeScript
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
|
import { useParams } from 'common'
|
|
import { noop } from 'lodash'
|
|
import { Lock, Table } from 'lucide-react'
|
|
import { AiIconAnimation, Badge, CardTitle } from 'ui'
|
|
|
|
import type { PolicyTable } from './PolicyTableRow.types'
|
|
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
|
|
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
|
import { EditorTablePageLink } from '@/data/prefetchers/project.$ref.editor.$id'
|
|
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
|
import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
|
|
import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
|
|
|
|
interface PolicyTableRowHeaderProps {
|
|
table: PolicyTable
|
|
isLocked: boolean
|
|
hasApiAccess: boolean
|
|
isLoadingApiAccess: boolean
|
|
onSelectToggleRLS: (table: PolicyTable) => void
|
|
onSelectCreatePolicy: (table: PolicyTable) => void
|
|
}
|
|
|
|
export const PolicyTableRowHeader = ({
|
|
table,
|
|
isLocked,
|
|
hasApiAccess,
|
|
isLoadingApiAccess,
|
|
onSelectToggleRLS = noop,
|
|
onSelectCreatePolicy,
|
|
}: PolicyTableRowHeaderProps) => {
|
|
const { ref } = useParams()
|
|
const aiSnap = useAiAssistantStateSnapshot()
|
|
const { openSidebar } = useSidebarManagerSnapshot()
|
|
|
|
const { can: canCreatePolicies } = useAsyncCheckPermissions(
|
|
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
|
'policies'
|
|
)
|
|
const { can: canToggleRLS } = useAsyncCheckPermissions(
|
|
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
|
'tables'
|
|
)
|
|
|
|
const isRealtimeSchema = table.schema === 'realtime'
|
|
const isRealtimeMessagesTable = isRealtimeSchema && table.name === 'messages'
|
|
const isTableLocked = isRealtimeSchema ? !isRealtimeMessagesTable : isLocked
|
|
|
|
return (
|
|
<div id={table.id.toString()} className="flex w-full items-center justify-between">
|
|
<div className="flex gap-x-4 text-left flex-wrap">
|
|
<EditorTablePageLink
|
|
projectRef={ref}
|
|
id={String(table.id)}
|
|
className="flex items-center gap-3 flex-wrap"
|
|
>
|
|
<Table strokeWidth={1.5} size={16} className="text-foreground-muted" />
|
|
<CardTitle className="m-0 normal-case">{table.name}</CardTitle>
|
|
</EditorTablePageLink>
|
|
<div className="flex items-center gap-x-1">
|
|
{!table.rls_enabled && (
|
|
<Badge variant="warning" className="h-5">
|
|
RLS Disabled
|
|
</Badge>
|
|
)}
|
|
{!isLoadingApiAccess && !hasApiAccess && (
|
|
<Badge variant="default" className="h-5">
|
|
API Disabled
|
|
</Badge>
|
|
)}
|
|
{isTableLocked && (
|
|
<Badge className="h-5">
|
|
<span className="flex gap-x-1 items-center text-foreground-lighter">
|
|
<Lock size={10} /> Locked
|
|
</span>
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{!isTableLocked && (
|
|
<div className="flex-1">
|
|
<div className="flex flex-row justify-end gap-x-2">
|
|
{!isRealtimeMessagesTable && (
|
|
<ButtonTooltip
|
|
variant="default"
|
|
disabled={!canToggleRLS}
|
|
onClick={() => onSelectToggleRLS(table)}
|
|
data-testid={`${table.name}-toggle-rls`}
|
|
tooltip={{
|
|
content: {
|
|
side: 'bottom',
|
|
text: !canToggleRLS
|
|
? 'You need additional permissions to toggle RLS'
|
|
: undefined,
|
|
},
|
|
}}
|
|
>
|
|
{table.rls_enabled ? 'Disable RLS' : 'Enable RLS'}
|
|
</ButtonTooltip>
|
|
)}
|
|
<ButtonTooltip
|
|
variant="default"
|
|
disabled={!canToggleRLS || !canCreatePolicies}
|
|
onClick={() => onSelectCreatePolicy(table)}
|
|
data-testid={`${table.name}-create-policy`}
|
|
tooltip={{
|
|
content: {
|
|
side: 'bottom',
|
|
text: !canToggleRLS
|
|
? !canToggleRLS || !canCreatePolicies
|
|
? 'You need additional permissions to create RLS policies'
|
|
: undefined
|
|
: undefined,
|
|
},
|
|
}}
|
|
>
|
|
Create policy
|
|
</ButtonTooltip>
|
|
|
|
<ButtonTooltip
|
|
variant="default"
|
|
className="px-1"
|
|
onClick={() => {
|
|
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
|
|
aiSnap.newChat({
|
|
name: 'Create new policy',
|
|
initialInput: `Create and name a new policy for the ${table.schema} schema on the ${table.name} table that ...`,
|
|
})
|
|
}}
|
|
tooltip={{
|
|
content: {
|
|
side: 'bottom',
|
|
text:
|
|
!canToggleRLS || !canCreatePolicies
|
|
? 'You need additional permissions to create RLS policies'
|
|
: 'Create with Supabase Assistant',
|
|
},
|
|
}}
|
|
aria-label={
|
|
!canToggleRLS || !canCreatePolicies
|
|
? 'You need additional permissions to create RLS policies'
|
|
: 'Create with Supabase Assistant'
|
|
}
|
|
>
|
|
<AiIconAnimation size={16} />
|
|
</ButtonTooltip>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|