Files
dbb153042e feat(studio): cleaned up view permissions sheet (#49144)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Breaking down #49007 into smaller PR's. Part 1 merged in.

More to follow...


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Redesigned token capability details with expandable cards and dense
views for larger permission sets.
  * Added filtering by all, read, and read-write capabilities.
* Improved endpoint and MCP tool attribution, display, and endpoint
copying.
  * Added risk banners with permission and access warnings.
* Enhanced resource badges, responsive layouts, relative timestamps, and
dismissible creation guidance.

* **Bug Fixes**
  * Corrected MCP tool attribution across alternative permission scopes.
  * Improved handling and display of inaccessible resources.

* **Tests**
* Expanded coverage for capability views, filtering, risk messaging, and
permission evaluation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-08-18 10:58:56 +01:00

44 lines
1.5 KiB
TypeScript

import { Button, cn } from 'ui'
import type { CapabilityLevelFilter } from './TokenCapabilities.utils'
interface CapabilityLevelToggleProps {
value: CapabilityLevelFilter
onChange: (value: CapabilityLevelFilter) => void
}
const OPTIONS: { value: CapabilityLevelFilter; label: string }[] = [
{ value: 'all', label: 'All' },
{ value: 'read', label: 'Read' },
{ value: 'readwrite', label: 'Read-write' },
]
/**
* Segmented control matching the "Show all / Error only" pattern from Auth's UserLogs: adjacent
* Buttons with their variant swapped on selection, glued together via rounding/border removal
* and a thin divider, rather than a dedicated segmented-control primitive.
*/
export const CapabilityLevelToggle = ({ value, onChange }: CapabilityLevelToggleProps) => (
<div className="flex items-center">
{OPTIONS.map(({ value: optionValue, label }, index) => (
<div key={optionValue} className="flex items-center">
{index > 0 && <div className="border-button border border-l-0 py-3" />}
<Button
type="button"
size="tiny"
variant={value === optionValue ? 'secondary' : 'default'}
aria-pressed={value === optionValue}
className={cn(
index === 0 && 'rounded-r-none border-r-0',
index === OPTIONS.length - 1 && 'rounded-l-none border-l-0',
index > 0 && index < OPTIONS.length - 1 && 'rounded-none border-x-0'
)}
onClick={() => onChange(optionValue)}
>
{label}
</Button>
</div>
))}
</div>
)