Merge pull request #19 from AlexisNP/bugfix/event-operations-should-have-a-loading
Bugfix/event operations should have a loading
This commit is contained in:
@@ -74,3 +74,20 @@
|
|||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all .5s ease;
|
||||||
|
}
|
||||||
|
.fade-delay-enter-active,
|
||||||
|
.fade-delay-leave-active {
|
||||||
|
transition: all .5s ease 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to,
|
||||||
|
.fade-delay-enter-from,
|
||||||
|
.fade-delay-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
setCurrentMenu([
|
setCurrentMenu([
|
||||||
{
|
{
|
||||||
phIcon: PhMagnifyingGlass,
|
phIcon: shallowRef(PhMagnifyingGlass),
|
||||||
tooltip: 'Recherche avancée',
|
tooltip: 'Recherche avancée',
|
||||||
action: 'event-search'
|
action: 'event-search'
|
||||||
}
|
}
|
||||||
@@ -116,10 +116,10 @@ onMounted(() => {
|
|||||||
<component :is="currentViewComponent"/>
|
<component :is="currentViewComponent"/>
|
||||||
</KeepAlive>
|
</KeepAlive>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
|
|
||||||
<LazyCalendarSearch />
|
<LazyCalendarSearch />
|
||||||
<LazyCalendarFormUpdateEvent />
|
<LazyCalendarFormUpdateEvent />
|
||||||
<LazyCalendarFormDeleteEvent />
|
<LazyCalendarFormDeleteEvent />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { RPGDate } from '~/models/Date';
|
import type { RPGDate } from '~/models/Date';
|
||||||
|
|
||||||
import { PhAlarm, PhMapPinArea } from '@phosphor-icons/vue'
|
import { PhAlarm, PhCircleNotch, PhMapPinArea } from '@phosphor-icons/vue'
|
||||||
|
|
||||||
const { eventSkeleton } = storeToRefs(useCalendarEvents())
|
const { eventSkeleton, operationInProgress } = storeToRefs(useCalendarEvents())
|
||||||
const { resetSkeleton, submitSkeleton } = useCalendarEvents()
|
const { resetSkeleton, submitSkeleton, cancelLatestRequest } = useCalendarEvents()
|
||||||
const popoverOpen = ref(false)
|
const popoverOpen = ref(false)
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
const formErrors = reactive<{ message: string | null }>({
|
const formErrors = reactive<{ message: string | null }>({
|
||||||
message: null
|
message: null
|
||||||
@@ -20,6 +21,12 @@ const props = defineProps<{
|
|||||||
* Opens event creation's popover
|
* Opens event creation's popover
|
||||||
*/
|
*/
|
||||||
function openEventCreatePopover() {
|
function openEventCreatePopover() {
|
||||||
|
// If another operation is in progress, whether it's another create popup or a modal, don't bother opening it
|
||||||
|
if (operationInProgress.value) {
|
||||||
|
popoverOpen.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
resetSkeleton()
|
resetSkeleton()
|
||||||
|
|
||||||
popoverOpen.value = true
|
popoverOpen.value = true
|
||||||
@@ -31,6 +38,11 @@ function openEventCreatePopover() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
|
// Prevent form submission if already loading
|
||||||
|
if (isLoading.value) return
|
||||||
|
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await submitSkeleton()
|
await submitSkeleton()
|
||||||
|
|
||||||
@@ -39,8 +51,31 @@ async function handleSubmit() {
|
|||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
formErrors.message = err.message
|
formErrors.message = err.message
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
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>
|
||||||
@@ -52,7 +87,13 @@ async function handleSubmit() {
|
|||||||
:align="'center'"
|
:align="'center'"
|
||||||
:side="'right'"
|
:side="'right'"
|
||||||
:collision-padding="60"
|
:collision-padding="60"
|
||||||
|
:disable-outside-pointer-events="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"
|
||||||
>
|
>
|
||||||
<form @submit.prevent="handleSubmit">
|
<form @submit.prevent="handleSubmit">
|
||||||
<div class="grid grid-cols-2 gap-y-4">
|
<div class="grid grid-cols-2 gap-y-4">
|
||||||
@@ -118,8 +159,18 @@ async function handleSubmit() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="flex gap-2 justify-end">
|
||||||
<UiButton size="sm">
|
<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="opacity-50 animate-spin"/>
|
||||||
|
</Transition>
|
||||||
|
|
||||||
Sauvegarder
|
Sauvegarder
|
||||||
</UiButton>
|
</UiButton>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { PhCircleNotch } from '@phosphor-icons/vue';
|
||||||
|
|
||||||
const { isDeleteEventModalOpen } = storeToRefs(useCalendarEvents())
|
const { isDeleteEventModalOpen } = storeToRefs(useCalendarEvents())
|
||||||
|
|
||||||
const { resetSkeleton, deleteEventFromSkeleton } = useCalendarEvents()
|
const { resetSkeleton, deleteEventFromSkeleton, 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
|
||||||
})
|
})
|
||||||
@@ -16,6 +20,10 @@ watch(isDeleteEventModalOpen, (hasOpened, _o) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function handleAction() {
|
async function handleAction() {
|
||||||
|
if (isLoading.value) return
|
||||||
|
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await deleteEventFromSkeleton()
|
await deleteEventFromSkeleton()
|
||||||
|
|
||||||
@@ -26,19 +34,42 @@ 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>
|
||||||
<UiAlertDialog v-model:open="isDeleteEventModalOpen">
|
<UiAlertDialog v-model:open="isDeleteEventModalOpen">
|
||||||
<UiAlertDialogContent
|
<UiAlertDialogContent
|
||||||
:align="'center'"
|
|
||||||
:side="'right'"
|
|
||||||
:collision-padding="60"
|
|
||||||
:disable-outside-pointer-events="true"
|
:disable-outside-pointer-events="true"
|
||||||
:trap-focus="true"
|
:trap-focus="true"
|
||||||
class="min-w-96 bg-slate-900 border-slate-800"
|
class="min-w-96 bg-slate-900 border-slate-800"
|
||||||
|
@escape-key-down="handleClosing"
|
||||||
|
@focus-outside="handleClosing"
|
||||||
|
@interact-outside="handleClosing"
|
||||||
|
@pointer-down-outside="handleClosing"
|
||||||
>
|
>
|
||||||
<UiAlertDialogTitle> Supprimer l'évènement</UiAlertDialogTitle>
|
<UiAlertDialogTitle> Supprimer l'évènement</UiAlertDialogTitle>
|
||||||
|
|
||||||
@@ -46,7 +77,7 @@ async function handleAction() {
|
|||||||
Les données associés à cet évènement seront supprimées et vous ne pourrez plus les récupérer !
|
Les données associés à cet évènement seront supprimées et vous ne pourrez plus les récupérer !
|
||||||
</UiAlertDialogDescription>
|
</UiAlertDialogDescription>
|
||||||
|
|
||||||
<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="text-red-500 ml-8">
|
<div class="text-red-500 ml-8">
|
||||||
<span class="text-sm">
|
<span class="text-sm">
|
||||||
@@ -54,16 +85,23 @@ async function handleAction() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
|
||||||
<UiAlertDialogFooter>
|
<footer class="flex gap-2 justify-end">
|
||||||
<UiAlertDialogCancel>
|
<Transition name="fade-delay">
|
||||||
Annuler
|
<UiButton v-if="isLoading" type="button" size="sm" variant="destructive" @click.prevent="handleCancel">
|
||||||
</UiAlertDialogCancel>
|
Annuler
|
||||||
<UiAlertDialogAction class="destructive" @click="handleAction">
|
</UiButton>
|
||||||
Supprimer
|
</Transition>
|
||||||
</UiAlertDialogAction>
|
|
||||||
</UiAlertDialogFooter>
|
<UiButton size="sm" :disabled="isLoading">
|
||||||
|
<Transition name="fade">
|
||||||
|
<PhCircleNotch v-if="isLoading" size="20" class="animate-spin"/>
|
||||||
|
</Transition>
|
||||||
|
|
||||||
|
Supprimer
|
||||||
|
</UiButton>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
</UiAlertDialogContent>
|
</UiAlertDialogContent>
|
||||||
</UiAlertDialog>
|
</UiAlertDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -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,29 +35,52 @@ 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>
|
||||||
<UiAlertDialog v-model:open="isEditEventModalOpen">
|
<UiDialog v-model:open="isEditEventModalOpen">
|
||||||
<UiAlertDialogContent
|
<UiDialogContent
|
||||||
:align="'center'"
|
|
||||||
:side="'right'"
|
|
||||||
:collision-padding="60"
|
|
||||||
: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="(e) => e.preventDefault()"
|
||||||
>
|
>
|
||||||
<VisuallyHidden>
|
<VisuallyHidden>
|
||||||
<UiAlertDialogTitle> Modifier l'évènement</UiAlertDialogTitle>
|
<UiDialogTitle> Modifier l'évènement</UiDialogTitle>
|
||||||
|
|
||||||
<UiAlertDialogDescription>
|
<UiDialogDescription>
|
||||||
Mettre à jour les données de l'évènement
|
Mettre à jour les données de l'évènement
|
||||||
</UiAlertDialogDescription>
|
</UiDialogDescription>
|
||||||
</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 +144,23 @@ async function handleAction() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<footer 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>
|
||||||
|
|
||||||
|
Enregistrer
|
||||||
|
</UiButton>
|
||||||
|
</footer>
|
||||||
</form>
|
</form>
|
||||||
<UiAlertDialogFooter>
|
</UiDialogContent>
|
||||||
<UiAlertDialogCancel>
|
</UiDialog>
|
||||||
Annuler
|
|
||||||
</UiAlertDialogCancel>
|
|
||||||
<UiAlertDialogAction @click="handleAction">
|
|
||||||
Sauvegarder
|
|
||||||
</UiAlertDialogAction>
|
|
||||||
</UiAlertDialogFooter>
|
|
||||||
</UiAlertDialogContent>
|
|
||||||
</UiAlertDialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ const eventsNotDisplayed: ComputedRef<number> = computed<number>(() => eventsFo
|
|||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<CalendarFormCreateEvent :date btn-class="absolute inset-0 w-full h-full cursor-default z-0" />
|
<LazyCalendarFormCreateEvent :date btn-class="absolute inset-0 w-full h-full cursor-default z-0" />
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import type { ShallowRef } from "vue"
|
||||||
|
|
||||||
export type SidebarMenuActionType = "event-search"
|
export type SidebarMenuActionType = "event-search"
|
||||||
|
|
||||||
export interface SidebarMenuItem {
|
export interface SidebarMenuItem {
|
||||||
phIcon: Component
|
phIcon: ShallowRef
|
||||||
tooltip: string
|
tooltip: string
|
||||||
action?: SidebarMenuActionType
|
action?: SidebarMenuActionType
|
||||||
to?: string
|
to?: string
|
||||||
|
|||||||
@@ -187,6 +187,12 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
|||||||
* EVENT CREATION FUNCTIONS
|
* EVENT CREATION FUNCTIONS
|
||||||
*/
|
*/
|
||||||
const lastActiveEvent = ref<CalendarEvent | null>()
|
const lastActiveEvent = ref<CalendarEvent | null>()
|
||||||
|
const isCreatingEvent = ref<boolean>(false)
|
||||||
|
const isUpdatingEvent = ref<boolean>(false)
|
||||||
|
const isDeletingEvent = ref<boolean>(false)
|
||||||
|
const operationInProgress = computed(() => isCreatingEvent.value || isUpdatingEvent.value || isDeletingEvent.value)
|
||||||
|
let abortController: AbortController | null = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dummy event to hold creation data
|
* Dummy event to hold creation data
|
||||||
*/
|
*/
|
||||||
@@ -205,31 +211,58 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
|||||||
* We assume it's been sanitized by the caller
|
* We assume it's been sanitized by the caller
|
||||||
*/
|
*/
|
||||||
async function submitSkeleton() {
|
async function submitSkeleton() {
|
||||||
|
abortController = new AbortController()
|
||||||
|
isCreatingEvent.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await $fetch('/api/calendars/events/create', { method: 'POST', body: { event : eventSkeleton.value, calendarId: calendarId.value }})
|
const res = await $fetch('/api/calendars/events/create', { method: 'POST', body: { event : eventSkeleton.value, calendarId: calendarId.value }, signal: abortController.signal })
|
||||||
|
|
||||||
baseEvents.value.push(res)
|
baseEvents.value.push(res)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
abortController = null
|
||||||
|
isCreatingEvent.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateEventFromSkeleton() {
|
async function updateEventFromSkeleton() {
|
||||||
|
abortController = new AbortController()
|
||||||
|
isUpdatingEvent.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await $fetch(`/api/calendars/events/${eventSkeleton.value.id}`, { method: 'PATCH', body: { event : eventSkeleton.value, calendarId: calendarId.value }})
|
const res = await $fetch(`/api/calendars/events/${eventSkeleton.value.id}`, { method: 'PATCH', body: { event : eventSkeleton.value, calendarId: calendarId.value }, signal: abortController.signal })
|
||||||
|
|
||||||
const eventIndex = baseEvents.value.findIndex(e => e.id === eventSkeleton.value.id)
|
const eventIndex = baseEvents.value.findIndex(e => e.id === eventSkeleton.value.id)
|
||||||
baseEvents.value[eventIndex] = res
|
baseEvents.value[eventIndex] = res
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
abortController = null
|
||||||
|
isUpdatingEvent.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteEventFromSkeleton() {
|
async function deleteEventFromSkeleton() {
|
||||||
|
abortController = new AbortController()
|
||||||
|
isDeletingEvent.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await $fetch(`/api/calendars/events/${eventSkeleton.value.id}`, { method: 'DELETE' })
|
await $fetch(`/api/calendars/events/${eventSkeleton.value.id}`, { method: 'DELETE', signal: abortController.signal })
|
||||||
|
|
||||||
const eventIndex = baseEvents.value.findIndex(e => e.id === eventSkeleton.value.id)
|
const eventIndex = baseEvents.value.findIndex(e => e.id === eventSkeleton.value.id)
|
||||||
baseEvents.value.splice(eventIndex, 1)
|
baseEvents.value.splice(eventIndex, 1)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
abortController = null
|
||||||
|
isDeletingEvent.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelLatestRequest() {
|
||||||
|
if (abortController) {
|
||||||
|
abortController.abort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +272,11 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
|||||||
currentEvents,
|
currentEvents,
|
||||||
getRelativeEventFromDate,
|
getRelativeEventFromDate,
|
||||||
getRelativeEventFromEvent,
|
getRelativeEventFromEvent,
|
||||||
|
cancelLatestRequest,
|
||||||
|
isCreatingEvent,
|
||||||
|
isUpdatingEvent,
|
||||||
|
isDeletingEvent,
|
||||||
|
operationInProgress,
|
||||||
eventSkeleton,
|
eventSkeleton,
|
||||||
resetSkeleton,
|
resetSkeleton,
|
||||||
submitSkeleton,
|
submitSkeleton,
|
||||||
|
|||||||
Reference in New Issue
Block a user