Files
kemal.earth 8ffdcfc145 feat(studio): scoped pat ui (#38170)
## 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?

Introduces UI for Scoped PAT's.

## Additional context

WIP. Testing endpoints.


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

* **New Features**
* Scoped access tokens: create, view, delete, and manage granular
resource/action permissions with custom expiry options and scoped
creation flows.
* New scoped token UI: modal/sheet creation flow, resource access
selectors, permissions editor, and a scoped token list.

* **UI Improvements**
* Tabbed Classic vs Scoped tokens layout, refreshed tokens page,
improved forms, search/filtering, and table tweaks.

* **Bug Fixes / Maintenance**
  * New data hooks and utilities for scoped tokens and token handling.

* **Removed**
  * Legacy account settings layout and legacy token banner.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-09 11:32:55 +00:00

63 lines
1.6 KiB
TypeScript

import dayjs from 'dayjs'
import { TableCell } from 'ui/src/components/shadcn/ui/table'
import { TimestampInfo } from 'ui-patterns/TimestampInfo'
interface TokenNameCellProps {
name: string
tokenAlias: string
}
export const TokenNameCell = ({ name, tokenAlias }: TokenNameCellProps) => (
<TableCell className="w-auto max-w-96">
<p className="truncate" title={name}>
{name}
</p>
<p
className="font-mono text-foreground-lighter truncate text-xs mt-1 max-w-32 sm:max-w-48 lg:max-w-full"
title={tokenAlias}
>
{tokenAlias}
</p>
</TableCell>
)
interface LastUsedCellProps {
lastUsedAt: string | null | undefined
}
export const LastUsedCell = ({ lastUsedAt }: LastUsedCellProps) => (
<TableCell className="text-foreground-light min-w-28">
{lastUsedAt ? (
<TimestampInfo
utcTimestamp={lastUsedAt}
label={dayjs(lastUsedAt).fromNow()}
className="text-sm"
/>
) : (
<p className="text-foreground-light text-sm">Never used</p>
)}
</TableCell>
)
interface ExpiresCellProps {
expiresAt: string | null | undefined
}
export const ExpiresCell = ({ expiresAt }: ExpiresCellProps) => (
<TableCell className="min-w-28 text-foreground-light">
{expiresAt ? (
dayjs(expiresAt).isBefore(dayjs()) ? (
<TimestampInfo utcTimestamp={expiresAt} label="Expired" className="text-sm" />
) : (
<TimestampInfo
utcTimestamp={expiresAt}
label={dayjs(expiresAt).format('DD MMM YYYY')}
className="text-sm"
/>
)
) : (
<p className="text-foreground-light text-sm">Never</p>
)}
</TableCell>
)