fix(ui): use styled confirm dialog for salary and recurring-invoice destructive actions (#1036)
* fix(ui): use styled confirm dialog for salary and recurring-invoice destructive actions Replace native window.confirm() with the existing DestructiveConfirmDialog / useDestructiveConfirm() primitive at the six sites from #839: recurring invoice schedule delete, employee deactivation, salary run draft delete, remove employee from run, salary calendar bulk delete (all variant 'destructive'), and the nollkorning-to-review guard (variant 'warning'). Confirmation copy is preserved as the dialog description; new title keys added to both messages/sv.json and messages/en.json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): lock delete and deactivate actions while the request is in flight The styled confirm dialog resolves before the DELETE settles, so the trigger button could be clicked again and fire a duplicate request. Add an in-flight guard (deletingId / deactivating) and disable the button until the request completes, mirroring the runNow pattern. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a95872928e
commit
f8611f2e89
@@ -29,6 +29,10 @@ import {
|
||||
} from 'lucide-react'
|
||||
import { useLocale, useTranslations } from 'next-intl'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
DestructiveConfirmDialog,
|
||||
useDestructiveConfirm,
|
||||
} from '@/components/ui/destructive-confirm-dialog'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -123,6 +127,7 @@ export function SalaryCalendar({
|
||||
}: SalaryCalendarProps) {
|
||||
const t = useTranslations('salary_calendar')
|
||||
const locale = useLocale()
|
||||
const { dialogProps, confirm: confirmAction } = useDestructiveConfirm()
|
||||
const dateLocale = locale === 'en' ? enUS : sv
|
||||
const isHourly = salaryType === 'hourly'
|
||||
const periodStartDate = useMemo(() => parseISO(periodStart), [periodStart])
|
||||
@@ -277,7 +282,13 @@ export function SalaryCalendar({
|
||||
|
||||
const handleBulkDelete = async () => {
|
||||
if (selected.size === 0 || readOnly) return
|
||||
if (!confirm(t('confirm_bulk_delete', { count: selected.size }))) return
|
||||
const ok = await confirmAction({
|
||||
title: t('confirm_bulk_delete_title'),
|
||||
description: t('confirm_bulk_delete', { count: selected.size }),
|
||||
confirmLabel: t('delete'),
|
||||
variant: 'destructive',
|
||||
})
|
||||
if (!ok) return
|
||||
setDeleting(true)
|
||||
setError(null)
|
||||
try {
|
||||
@@ -557,6 +568,8 @@ export function SalaryCalendar({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<DestructiveConfirmDialog {...dialogProps} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user