Files
RenewCMS/web/src/composables/useUnsavedChangesGuard.ts
T

54 lines
1.4 KiB
TypeScript

import { onBeforeRouteLeave, onBeforeRouteUpdate } 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
onDiscard?: () => void
}
export function useUnsavedChangesGuard({ isDirty, title, onDiscard }: UnsavedChangesOptions) {
const overlay = useLocalizedOverlay()
async function allowsLeaving() {
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()
if (confirmed) {
return false
}
onDiscard?.()
return true
}
onBeforeRouteLeave(allowsLeaving)
onBeforeRouteUpdate((to, from) => (to.params.id === from.params.id ? true : allowsLeaving()))
}