perf(web): streamline table actions and destructive dialogs (#5645)

* perf(data-table): autosize action columns

- exclude actions columns from shared table width calculations so action cells size to their content.
- remove fixed size and w-* width overrides from feature action columns to preserve content-based layout.

* perf(data-table): streamline row action controls

- expose common edit and status actions directly while moving secondary actions into overflow menus.
- add shared row action menu helpers so static and table rows use consistent action controls.
- let action columns size to their content instead of relying on fixed widths.

* fix(web): localize destructive dialog copy

- route delete, reset, and batch update confirmation text through i18n.
- add locale entries for affected channel, model, system settings, and user dialogs.

* perf(web): unify destructive dialog actions

- align delete and cleanup confirmation buttons with the shared destructive variant.
- replace custom destructive color overrides with semantic button variants.
- clean up lint errors in touched dialog files before committing.

* fix(web): add user action success translations

- add localized success messages for user delete, status, and role changes.
- keep user management toast copy available across all frontend locales.

* fix(data-table): prevent mobile badge clipping

- expose badge cell slots so mobile card styles can target nested badge wrappers.
- reset badge margins in card rows to keep provider icons fully visible on small screens.
This commit is contained in:
QuentinHsu
2026-06-25 13:13:41 +08:00
committed by GitHub
parent b191f47375
commit 9ba251ce5f
61 changed files with 1340 additions and 1131 deletions
+28 -21
View File
@@ -125,11 +125,12 @@ export function PasskeyCard({ loading: pageLoading }: PasskeyCardProps) {
const handleRemove = useCallback(async () => {
const methods = await fetchVerificationMethods()
const required: VerificationMethod | null = methods.has2FA
? '2fa'
: methods.hasPasskey
? 'passkey'
: null
let required: VerificationMethod | null = null
if (methods.has2FA) {
required = '2fa'
} else if (methods.hasPasskey) {
required = 'passkey'
}
if (!required) {
toast.error(
@@ -205,6 +206,24 @@ export function PasskeyCard({ loading: pageLoading }: PasskeyCardProps) {
: t('Not used yet')
const showUnsupportedNotice = !supported && !enabled
let backupStatus: {
label: string
variant: 'success' | 'warning' | 'neutral'
} | null = null
if (status?.backup_eligible !== undefined) {
backupStatus = {
label: t('No backup'),
variant: 'neutral',
}
if (status.backup_eligible) {
backupStatus = {
label: status.backup_state ? t('Backed up') : t('Not backed up'),
variant: status.backup_state ? 'success' : 'warning',
}
}
}
return (
<>
@@ -234,22 +253,10 @@ export function PasskeyCard({ loading: pageLoading }: PasskeyCardProps) {
showDot
copyable={false}
/>
{status?.backup_eligible !== undefined && (
{backupStatus && (
<StatusBadge
label={
status.backup_eligible
? status.backup_state
? t('Backed up')
: t('Not backed up')
: t('No backup')
}
variant={
status.backup_eligible
? status.backup_state
? 'success'
: 'warning'
: 'neutral'
}
label={backupStatus.label}
variant={backupStatus.variant}
showDot
copyable={false}
/>
@@ -310,7 +317,7 @@ export function PasskeyCard({ loading: pageLoading }: PasskeyCardProps) {
{t('Cancel')}
</AlertDialogCancel>
<AlertDialogAction
className='bg-destructive text-destructive-foreground'
variant='destructive'
disabled={removing}
onClick={(event) => {
event.preventDefault()