Added client side realtime for calendars
This commit is contained in:
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PhX } from "@phosphor-icons/vue";
|
import { PhX } from "@phosphor-icons/vue";
|
||||||
import type { Calendar } from "~/models/CalendarConfig";
|
import type { Calendar } from "~/models/CalendarConfig";
|
||||||
|
import type { World } from "~/models/World";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
calendarId: number,
|
calendar: Calendar | null,
|
||||||
|
world: World | null,
|
||||||
modalState?: boolean
|
modalState?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { data: calendar } = await useFetch<{ data: Calendar }>("/api/calendars/query", { query: { id: props.calendarId } })
|
const calendarSkeletonName = ref<string>(props.calendar?.name ?? "")
|
||||||
|
|
||||||
const calendarSkeletonName = ref<string>("")
|
|
||||||
|
|
||||||
function onChangedName(newName: string) {
|
function onChangedName(newName: string) {
|
||||||
calendarSkeletonName.value = newName
|
calendarSkeletonName.value = newName
|
||||||
@@ -28,7 +28,7 @@ function handleClose() {
|
|||||||
<UiAlertDialogContent class="grid grid-rows-[auto_1fr_auto] items-start min-h-[66vh] max-w-4xl gap-6" @close-auto-focus="(e) => e.preventDefault()">
|
<UiAlertDialogContent class="grid grid-rows-[auto_1fr_auto] items-start min-h-[66vh] max-w-4xl gap-6" @close-auto-focus="(e) => e.preventDefault()">
|
||||||
<UiAlertDialogTitle>
|
<UiAlertDialogTitle>
|
||||||
<span class="text-2xl">
|
<span class="text-2xl">
|
||||||
<strong class="font-bold">{{ calendar?.data.world?.name }}</strong>
|
<strong class="font-bold">{{ world?.name }}</strong>
|
||||||
<span class="opacity-30"> — </span>
|
<span class="opacity-30"> — </span>
|
||||||
<span v-if="calendarSkeletonName">
|
<span v-if="calendarSkeletonName">
|
||||||
{{ calendarSkeletonName }}
|
{{ calendarSkeletonName }}
|
||||||
@@ -43,7 +43,7 @@ function handleClose() {
|
|||||||
<PhX size="20" />
|
<PhX size="20" />
|
||||||
</UiButton>
|
</UiButton>
|
||||||
|
|
||||||
<CalendarFormUpdate v-if="calendar?.data" :calendar="calendar.data" @on-changed-name="onChangedName" @on-close="handleClose" />
|
<CalendarFormUpdate v-if="calendar" :world="world" :calendar="calendar" @on-changed-name="onChangedName" @on-close="handleClose" />
|
||||||
</UiAlertDialogContent>
|
</UiAlertDialogContent>
|
||||||
</UiAlertDialog>
|
</UiAlertDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Calendar } from "~/models/CalendarConfig";
|
import type { Calendar } from "~/models/CalendarConfig";
|
||||||
import { PhCircleNotch, PhWrench } from "@phosphor-icons/vue";
|
import { PhCircleNotch, PhWrench } from "@phosphor-icons/vue";
|
||||||
|
import type { World } from "~/models/World";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
calendar: Calendar | null,
|
calendar: Calendar | null,
|
||||||
|
world: World | null,
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const calendarSkeleton = ref<Calendar>({ ...props.calendar } as Calendar)
|
const calendarSkeleton = ref<Calendar>({ ...props.calendar } as Calendar)
|
||||||
@@ -34,7 +36,7 @@ const isUpdatingCalendar = ref<boolean>(false)
|
|||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
try {
|
try {
|
||||||
isUpdatingCalendar.value = true
|
isUpdatingCalendar.value = true
|
||||||
await $fetch(`/api/calendars/${calendarSkeleton.value.id}`, { method: "PATCH", body: { ...calendarSkeleton.value, worldId: props.calendar?.world?.id } })
|
await $fetch(`/api/calendars/${calendarSkeleton.value.id}`, { method: "PATCH", body: { ...calendarSkeleton.value, worldId: props.world?.id } })
|
||||||
|
|
||||||
emit("on-close")
|
emit("on-close")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -47,27 +47,6 @@ function handleInsertedCalendar(newCalendar: CalendarChannelPayload) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handles calendar insertion realtime events */
|
|
||||||
function handleUpdatedCalendar(newCalendar: CalendarChannelPayload) {
|
|
||||||
if (!world.value) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
world.value.data.calendars = world.value.data.calendars?.map(c => {
|
|
||||||
if (c.id === newCalendar.id) {
|
|
||||||
const eventNb = c.eventNb
|
|
||||||
c = newCalendar
|
|
||||||
c.createdAt = newCalendar.created_at
|
|
||||||
c.updatedAt = newCalendar.updated_at
|
|
||||||
c.eventNb = eventNb
|
|
||||||
}
|
|
||||||
|
|
||||||
return c
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handles calendar deletion realtime events */
|
/** Handles calendar deletion realtime events */
|
||||||
function handleDeletedCalendar(id: number) {
|
function handleDeletedCalendar(id: number) {
|
||||||
if (!world.value) return
|
if (!world.value) return
|
||||||
@@ -84,7 +63,7 @@ onMounted(() => {
|
|||||||
.on(
|
.on(
|
||||||
"postgres_changes",
|
"postgres_changes",
|
||||||
{ event: "*", schema: "public", table: "calendars" },
|
{ event: "*", schema: "public", table: "calendars" },
|
||||||
(payload) => {
|
async (payload) => {
|
||||||
switch (payload.eventType) {
|
switch (payload.eventType) {
|
||||||
case "INSERT":
|
case "INSERT":
|
||||||
handleInsertedCalendar(payload.new as Calendar)
|
handleInsertedCalendar(payload.new as Calendar)
|
||||||
@@ -94,8 +73,11 @@ onMounted(() => {
|
|||||||
handleDeletedCalendar(payload.old.id)
|
handleDeletedCalendar(payload.old.id)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// Maybe this case could be handled better than doing a separate API call
|
||||||
case "UPDATE":
|
case "UPDATE":
|
||||||
handleUpdatedCalendar(payload.new as Calendar)
|
if (!world.value?.data) return
|
||||||
|
|
||||||
|
world.value.data = (await $fetch<{ data: World }>("/api/worlds/query", { query: { id, full: true } })).data
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -249,7 +231,7 @@ function hideEditModal() {
|
|||||||
|
|
||||||
<WorldDialogEdit :world="world.data" :modal-state="isEditWorldModalOpen" @on-close="hideEditModal" />
|
<WorldDialogEdit :world="world.data" :modal-state="isEditWorldModalOpen" @on-close="hideEditModal" />
|
||||||
<CalendarDialogCreate :world="world.data" :modal-state="isCreateCalendarModalOpen" @on-close="hideCreateDialog" />
|
<CalendarDialogCreate :world="world.data" :modal-state="isCreateCalendarModalOpen" @on-close="hideCreateDialog" />
|
||||||
<CalendarDialogUpdate v-if="markedCalendar?.id" :calendar-id="markedCalendar.id" :modal-state="isUpdateCalendarModalOpen" @on-close="hideUpdateDialog" />
|
<CalendarDialogUpdate v-if="markedCalendar?.id" :world="world.data" :calendar="markedCalendar" :modal-state="isUpdateCalendarModalOpen" @on-close="hideUpdateDialog" />
|
||||||
<CalendarDialogDelete :calendar="markedCalendar" :modal-state="isDeleteCalendarModalOpen" @on-close="hideDeleteCalendarModal"/>
|
<CalendarDialogDelete :calendar="markedCalendar" :modal-state="isDeleteCalendarModalOpen" @on-close="hideDeleteCalendarModal"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ export default defineEventHandler(async (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bodyError) {
|
if (bodyError) {
|
||||||
|
console.log(bodyData)
|
||||||
|
console.log(bodyError)
|
||||||
const error = createError({
|
const error = createError({
|
||||||
cause: "Utilisateur",
|
cause: "Utilisateur",
|
||||||
fatal: false,
|
fatal: false,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
name: bodyData.name,
|
name: bodyData.name,
|
||||||
today: bodyData.today,
|
today: bodyData.today,
|
||||||
color: bodyData.color,
|
color: bodyData.color,
|
||||||
|
state: bodyData.state,
|
||||||
world_id: bodyData.worldId
|
world_id: bodyData.worldId
|
||||||
} as never
|
} as never
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
color,
|
color,
|
||||||
today,
|
today,
|
||||||
state,
|
state,
|
||||||
|
months:calendar_months(*),
|
||||||
createdAt:created_at,
|
createdAt:created_at,
|
||||||
updatedAt:updated_at,
|
updatedAt:updated_at,
|
||||||
eventNb:calendar_events(count)
|
eventNb:calendar_events(count)
|
||||||
@@ -43,6 +44,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
calendars (
|
calendars (
|
||||||
createdAt:created_at,
|
createdAt:created_at,
|
||||||
updatedAt:updated_at,
|
updatedAt:updated_at,
|
||||||
|
months:calendar_months(*),
|
||||||
eventNb:calendar_events(count)
|
eventNb:calendar_events(count)
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|||||||
Reference in New Issue
Block a user