fix: ConfirmDialog accessibility and standardize destructive action confirmations
- Add focus trap, Escape key handling, ARIA attributes to ConfirmDialog - Replace native confirm() with ConfirmDialog for stage, registry, user deletion - Add confirmation dialogs for env variable and volume deletion
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
import { toasts } from '$lib/stores/toast';
|
||||
import { t } from '$lib/i18n';
|
||||
import { IconPlus, IconLoader, IconEdit, IconTrash, IconWifi } from '$lib/components/icons';
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
|
||||
|
||||
let registries = $state<Registry[]>([]);
|
||||
let loading = $state(true);
|
||||
@@ -22,6 +23,7 @@
|
||||
let testingId = $state<string | null>(null);
|
||||
let healthStatus = $state<Record<string, 'checking' | 'healthy' | 'unhealthy'>>({});
|
||||
|
||||
let registryDeleteTarget = $state<Registry | null>(null);
|
||||
let errors = $state<Record<string, string>>({});
|
||||
|
||||
function validateForm(): boolean {
|
||||
@@ -59,7 +61,6 @@
|
||||
}
|
||||
|
||||
async function handleDelete(registry: Registry) {
|
||||
if (!confirm($t('settingsRegistries.deleteConfirm', { name: registry.name }))) return;
|
||||
try { await deleteRegistry(registry.id); toasts.success($t('settingsRegistries.registryDeleted', { name: registry.name })); await loadRegistryList(); }
|
||||
catch (err) { toasts.error(err instanceof Error ? err.message : $t('settingsRegistries.deleteFailed')); }
|
||||
}
|
||||
@@ -174,10 +175,24 @@
|
||||
{testingId === registry.id ? $t('settingsRegistries.testing') : $t('settingsRegistries.test')}
|
||||
</button>
|
||||
<button onclick={() => startEdit(registry)} class="rounded-lg p-2 text-[var(--text-tertiary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-link)] transition-colors"><IconEdit size={16} /></button>
|
||||
<button onclick={() => handleDelete(registry)} class="rounded-lg p-2 text-[var(--text-tertiary)] hover:bg-red-50 hover:text-red-600 transition-colors"><IconTrash size={16} /></button>
|
||||
<button onclick={() => { registryDeleteTarget = registry; }} class="rounded-lg p-2 text-[var(--text-tertiary)] hover:bg-red-50 hover:text-red-600 transition-colors"><IconTrash size={16} /></button>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
open={registryDeleteTarget !== null}
|
||||
title={$t('settingsRegistries.deleteTitle')}
|
||||
message={$t('settingsRegistries.deleteConfirm', { name: registryDeleteTarget?.name ?? '' })}
|
||||
confirmLabel={$t('common.delete')}
|
||||
confirmVariant="danger"
|
||||
onconfirm={async () => {
|
||||
const reg = registryDeleteTarget;
|
||||
registryDeleteTarget = null;
|
||||
if (reg) await handleDelete(reg);
|
||||
}}
|
||||
oncancel={() => { registryDeleteTarget = null; }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user