46 lines
1.1 KiB
TypeScript
46 lines
1.1 KiB
TypeScript
import { onBeforeRouteLeave } from 'vue-router'
|
|
import { t } from '@/i18n'
|
|
import { useLocalizedOverlay } from '@/i18n/presentation'
|
|
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
|
import { authRedirectPending } from '@/composables/useApi'
|
|
|
|
interface UnsavedChangesOptions {
|
|
isDirty: () => boolean
|
|
title: () => string
|
|
}
|
|
|
|
export function useUnsavedChangesGuard({ isDirty, title }: UnsavedChangesOptions) {
|
|
const overlay = useLocalizedOverlay()
|
|
|
|
onBeforeRouteLeave(async () => {
|
|
if (authRedirectPending.value || !isDirty()) {
|
|
return true
|
|
}
|
|
const confirmed = await overlay
|
|
.create(ConfirmDialog, {
|
|
props: {
|
|
get title() {
|
|
return t('Leave without saving?')
|
|
},
|
|
get description() {
|
|
return t("Your changes to \u0022{0}\u0022 haven't been saved.", [title()])
|
|
},
|
|
get confirmLabel() {
|
|
return t('Keep editing')
|
|
},
|
|
get cancelLabel() {
|
|
return t('Discard changes')
|
|
},
|
|
get pendingLabel() {
|
|
return t('Keep editing')
|
|
},
|
|
tone: 'neutral',
|
|
action: async () => {},
|
|
dismissResolvesTo: 'confirm',
|
|
},
|
|
})
|
|
.open()
|
|
return !confirmed
|
|
})
|
|
}
|