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:
+28
-21
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user