Newer
Older
<template>
<ADialog ref="dialog" is-modal class="tw-max-w-2xl tw-w-full">
<form :id="id" @submit.prevent.stop="doSave">
<slot />
</form>
<template #footer>
<slot name="footer" :close="close">
<div class="tw-flex tw-items-center tw-gap-3">
<button
type="submit"
class="btn tw-bg-aura-primary tw-text-white"
:form="id"
:disabled="isSaving || canSave === false"
>
<Loading v-if="isSaving" class="tw-h-1.5 tw-mr-1" />
{{ saveLabel ?? t('save') }}
</button>
<button type="button" class="btn" :disabled="isSaving" @click="dialog.close()">
{{ cancelLabel ?? t('cancel') }}
</button>
<slot name="footer-buttons-extra" :is-saving="isSaving" />
</slot>
</template>
</ADialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from '@/i18n'
import { useId } from '@/util'
import ADialog from '@/components/generic/ADialog.vue'
import Loading from '@/components/generic/Loading.vue'
defineOptions({ compatConfig: { MODE: 3 } })
const props = withDefaults(
defineProps<{
save?: () => unknown
canSave?: boolean | undefined
saveLabel?: string
cancelLabel?: string
}>(),
{
save: undefined,
canSave: undefined,
saveLabel: undefined,
cancelLabel: undefined,
},
)
const { t } = useI18n()
const id = useId('dialog-form')
const dialog = ref()
function open() {
dialog.value.open()
}
function close() {
dialog.value.close()
}
async function doSave() {
const save = props?.save
if (!save) return
isSaving.value = true
try {
await save()
} finally {
isSaving.value = false
}
}
defineExpose({
open,
close,
})
</script>