Added loading and cancelling to updating popover

This commit is contained in:
Alexis
2024-06-08 21:53:16 +02:00
parent a07afc8351
commit 721e26d8e4
3 changed files with 67 additions and 20 deletions

View File

@@ -75,13 +75,19 @@
} }
} }
.fade-cancel-enter-active, .fade-enter-active,
.fade-cancel-leave-active { .fade-leave-active {
transition: all .5s ease;
}
.fade-delay-enter-active,
.fade-delay-leave-active {
transition: all .5s ease 1s; transition: all .5s ease 1s;
} }
.fade-cancel-enter-from, .fade-enter-from,
.fade-cancel-leave-to { .fade-leave-to,
.fade-delay-enter-from,
.fade-delay-leave-to {
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
} }

View File

@@ -21,14 +21,12 @@ const props = defineProps<{
* Opens event creation's popover * Opens event creation's popover
*/ */
function openEventCreatePopover() { function openEventCreatePopover() {
console.log(operationInProgress.value) // If another operation is in progress, whether it's another create popup or a modal, don't bother opening it
if (operationInProgress.value) { if (operationInProgress.value) {
popoverOpen.value = false popoverOpen.value = false
return return
} }
console.log('open still what ?')
resetSkeleton() resetSkeleton()
popoverOpen.value = true popoverOpen.value = true
@@ -59,6 +57,7 @@ async function handleSubmit() {
} }
/** /**
* Prevents the modal from closing if's still loading
* *
* @param e The closing event (can be keydown or click) * @param e The closing event (can be keydown or click)
*/ */
@@ -70,6 +69,8 @@ function handleClosing(e: Event) {
/** /**
* Click on the cancel button * Click on the cancel button
*
* Must cancel the abortController in the store, and stop the loading
*/ */
function handleCancel() { function handleCancel() {
cancelLatestRequest() cancelLatestRequest()
@@ -159,14 +160,14 @@ function handleCancel() {
</div> </div>
<div class="flex gap-2 justify-end"> <div class="flex gap-2 justify-end">
<Transition name="fade-cancel"> <Transition name="fade-delay">
<UiButton v-if="isLoading" type="button" size="sm" variant="destructive" @click.prevent="handleCancel"> <UiButton v-if="isLoading" type="button" size="sm" variant="destructive" @click.prevent="handleCancel">
Annuler Annuler
</UiButton> </UiButton>
</Transition> </Transition>
<UiButton size="sm" :disabled="isLoading"> <UiButton size="sm" :disabled="isLoading">
<Transition name="fade-cancel"> <Transition name="fade">
<PhCircleNotch v-if="isLoading" size="20" class="opacity-50 animate-spin"/> <PhCircleNotch v-if="isLoading" size="20" class="opacity-50 animate-spin"/>
</Transition> </Transition>

View File

@@ -1,12 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { PhAlarm, PhMapPinArea } from '@phosphor-icons/vue' import { PhAlarm, PhCircleNotch, PhMapPinArea } from '@phosphor-icons/vue'
import { VisuallyHidden } from 'radix-vue' import { VisuallyHidden } from 'radix-vue'
const { isEditEventModalOpen } = storeToRefs(useCalendarEvents()) const { isEditEventModalOpen } = storeToRefs(useCalendarEvents())
const { resetSkeleton, updateEventFromSkeleton } = useCalendarEvents() const { resetSkeleton, updateEventFromSkeleton, cancelLatestRequest } = useCalendarEvents()
const { eventSkeleton, lastActiveEvent } = storeToRefs(useCalendarEvents()) const { eventSkeleton, lastActiveEvent } = storeToRefs(useCalendarEvents())
const isLoading = ref(false)
const formErrors = reactive<{ message: string | null }>({ const formErrors = reactive<{ message: string | null }>({
message: null message: null
}) })
@@ -19,6 +21,10 @@ watch(isEditEventModalOpen, (hasOpened, _o) => {
}) })
async function handleAction() { async function handleAction() {
if (isLoading.value) return
isLoading.value = true
try { try {
await updateEventFromSkeleton() await updateEventFromSkeleton()
@@ -29,8 +35,30 @@ async function handleAction() {
} }
} finally { } finally {
resetSkeleton() resetSkeleton()
isLoading.value = false
} }
} }
/**
* Prevents the modal from closing if's still loading
*
* @param e The closing event (can be keydown or click)
*/
function handleClosing(e: Event) {
if (isLoading.value) {
e.preventDefault()
}
}
/**
* Click on the cancel button
*
* Must cancel the abortController in the store, and stop the loading
*/
function handleCancel() {
cancelLatestRequest()
isLoading.value = false
}
</script> </script>
<template> <template>
@@ -42,6 +70,10 @@ async function handleAction() {
:disable-outside-pointer-events="true" :disable-outside-pointer-events="true"
:trap-focus="true" :trap-focus="true"
class="pl-3 min-w-96 bg-slate-900 border-slate-800" class="pl-3 min-w-96 bg-slate-900 border-slate-800"
@escape-key-down="handleClosing"
@focus-outside="handleClosing"
@interact-outside="handleClosing"
@pointer-down-outside="handleClosing"
> >
<VisuallyHidden> <VisuallyHidden>
<UiAlertDialogTitle> Modifier l'évènement</UiAlertDialogTitle> <UiAlertDialogTitle> Modifier l'évènement</UiAlertDialogTitle>
@@ -51,7 +83,7 @@ async function handleAction() {
</UiAlertDialogDescription> </UiAlertDialogDescription>
</VisuallyHidden> </VisuallyHidden>
<form> <form @submit.prevent="handleAction">
<div class="grid grid-cols-2 gap-y-4"> <div class="grid grid-cols-2 gap-y-4">
<div class="col-span-2 ml-8"> <div class="col-span-2 ml-8">
<input <input
@@ -115,15 +147,23 @@ async function handleAction() {
</span> </span>
</div> </div>
</div> </div>
<div class="flex gap-2 justify-end">
<Transition name="fade-delay">
<UiButton v-if="isLoading" type="button" size="sm" variant="destructive" @click.prevent="handleCancel">
Annuler
</UiButton>
</Transition>
<UiButton size="sm" :disabled="isLoading">
<Transition name="fade">
<PhCircleNotch v-if="isLoading" size="20" class="animate-spin"/>
</Transition>
Sauvegarder
</UiButton>
</div>
</form> </form>
<UiAlertDialogFooter>
<UiAlertDialogCancel>
Annuler
</UiAlertDialogCancel>
<UiAlertDialogAction @click="handleAction">
Sauvegarder
</UiAlertDialogAction>
</UiAlertDialogFooter>
</UiAlertDialogContent> </UiAlertDialogContent>
</UiAlertDialog> </UiAlertDialog>
</template> </template>