Added reactivity when adding an event
This commit is contained in:
@@ -7,7 +7,7 @@ import CenturyLayout from './state/centennially/Layout.vue'
|
||||
import DecadeLayout from './state/decennially/Layout.vue'
|
||||
import YearLayout from './state/yearly/Layout.vue'
|
||||
|
||||
const { isAdvancedSearchOpen } = storeToRefs(useCalendar())
|
||||
const { isAdvancedSearchOpen, isEditEventModalOpen } = storeToRefs(useCalendar())
|
||||
|
||||
const route = useRoute()
|
||||
const worldId = route.params.id
|
||||
@@ -110,5 +110,6 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<CalendarSearch v-model:model-value="isAdvancedSearchOpen" />
|
||||
<CalendarFormUpdateEvent v-model:model-value="isEditEventModalOpen" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -17,15 +17,15 @@ const isStartEvent = spansMultipleDays && areDatesIdentical(props.tileDate, prop
|
||||
const isEndEvent =
|
||||
spansMultipleDays && props.event.endDate && areDatesIdentical(props.tileDate, props.event.endDate)
|
||||
|
||||
const isPopoverOpen = ref<boolean>(false)
|
||||
const isPopoverDetailsOpen = ref<boolean>(false)
|
||||
|
||||
function handleClosePopover() {
|
||||
isPopoverOpen.value = false
|
||||
isPopoverDetailsOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UiPopover v-model:open="isPopoverOpen">
|
||||
<UiPopover v-model:open="isPopoverDetailsOpen">
|
||||
<UiPopoverTrigger as-child>
|
||||
<button
|
||||
class="text-xs px-2 py-1 block w-full text-left rounded-sm whitespace-nowrap overflow-hidden text-ellipsis"
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
PhDotsThreeOutlineVertical
|
||||
} from '@phosphor-icons/vue'
|
||||
|
||||
const { defaultDate, getFormattedDateTitle, jumpToDate } = useCalendar()
|
||||
const { defaultDate, getFormattedDateTitle, jumpToDate, revealEditEventModal, getRelativeString } = useCalendar()
|
||||
const { lastActiveEvent } = storeToRefs(useCalendarEvents())
|
||||
|
||||
const props = defineProps<{
|
||||
event: CalendarEvent
|
||||
@@ -25,8 +26,6 @@ const eventDetails = ref<HTMLElement>()
|
||||
|
||||
const emit = defineEmits(['query:close-popover'])
|
||||
|
||||
const { getRelativeString } = useCalendar()
|
||||
|
||||
const dateDifference: string = getRelativeString(defaultDate, props.event.startDate)
|
||||
const dateDuration: string | null = props.event.endDate
|
||||
? getRelativeString(props.event.startDate, props.event.endDate, 'compact')
|
||||
@@ -41,11 +40,11 @@ function handleJumpToDate(date: RPGDate) {
|
||||
* Edit event
|
||||
*/
|
||||
const commandMenuOpened = ref(false)
|
||||
const editModelOpened = ref(false)
|
||||
|
||||
function deployEditModal() {
|
||||
lastActiveEvent.value = { ...props.event }
|
||||
revealEditEventModal()
|
||||
commandMenuOpened.value = false
|
||||
editModelOpened.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -154,8 +153,6 @@ function deployEditModal() {
|
||||
</UiPopover>
|
||||
</menu>
|
||||
|
||||
<CalendarFormUpdateEvent v-model:model-value="editModelOpened" :event :anchor="eventDetails" />
|
||||
|
||||
<nav v-if="event.startDate && event.endDate" class="mt-2 flex gap-2">
|
||||
<UiBadge class="hover:opacity-100 hover:bg-slate-300" as-child>
|
||||
<button
|
||||
|
||||
@@ -1,28 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
PhAlarm
|
||||
} from '@phosphor-icons/vue'
|
||||
import type { CalendarEvent } from '~/models/CalendarEvent';
|
||||
import { PhAlarm } from '@phosphor-icons/vue'
|
||||
import { VisuallyHidden } from 'radix-vue'
|
||||
|
||||
import { PopoverAnchor } from 'radix-vue'
|
||||
|
||||
const popoverOpened = defineModel<boolean>()
|
||||
const { eventSkeleton } = storeToRefs(useCalendarEvents())
|
||||
const isModalOpened = defineModel<boolean>({ default: false })
|
||||
const { resetSkeleton } = useCalendarEvents()
|
||||
const { eventSkeleton, lastActiveEvent } = storeToRefs(useCalendarEvents())
|
||||
|
||||
const formErrors = reactive<{ message: string | null }>({
|
||||
message: null
|
||||
})
|
||||
|
||||
const props = defineProps<{
|
||||
event: CalendarEvent,
|
||||
anchor?: HTMLElement
|
||||
}>()
|
||||
|
||||
// Watch the popover state
|
||||
watch(popoverOpened, (hasOpened, _o) => {
|
||||
if (hasOpened) {
|
||||
eventSkeleton.value = { ...props.event }
|
||||
watch(isModalOpened, (hasOpened, _o) => {
|
||||
if (hasOpened && lastActiveEvent.value) {
|
||||
eventSkeleton.value = { ...lastActiveEvent.value }
|
||||
} else {
|
||||
resetSkeleton()
|
||||
}
|
||||
@@ -30,17 +21,26 @@ watch(popoverOpened, (hasOpened, _o) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UiPopover v-model:open="popoverOpened" :modal="true">
|
||||
<PopoverAnchor v-if="anchor" :element="anchor" />
|
||||
<UiPopoverContent
|
||||
<UiDialog v-model:open="isModalOpened" :modal="true">
|
||||
<UiDialogContent
|
||||
:align="'center'"
|
||||
:side="'right'"
|
||||
:collision-padding="60"
|
||||
:disable-outside-pointer-events="true"
|
||||
:trap-focus="true"
|
||||
class="pl-3 min-w-96 bg-slate-900 border-slate-800"
|
||||
>
|
||||
<VisuallyHidden>
|
||||
<UiDialogTitle> Modifier l'évènement</UiDialogTitle>
|
||||
|
||||
<UiDialogDescription>
|
||||
Mettre à jour les données de l'évènement
|
||||
</UiDialogDescription>
|
||||
</VisuallyHidden>
|
||||
|
||||
<form>
|
||||
<div class="grid grid-cols-2 gap-y-4">
|
||||
<div class="col-span-2 pl-8">
|
||||
<div class="col-span-2 ml-8">
|
||||
<input
|
||||
id="new-event-title"
|
||||
v-model="eventSkeleton.title"
|
||||
@@ -51,7 +51,7 @@ watch(popoverOpened, (hasOpened, _o) => {
|
||||
class="w-full -my-1 py-1 -mx-1 px-1 text-lg border-b-[1px] bg-transparent focus-visible:outline-none focus-visible:border-blue-600">
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 pl-8">
|
||||
<div class="col-span-2 ml-8">
|
||||
<textarea
|
||||
id="new-event-description"
|
||||
v-model="eventSkeleton.description"
|
||||
@@ -68,7 +68,7 @@ watch(popoverOpened, (hasOpened, _o) => {
|
||||
<CalendarInputRPGDate
|
||||
v-model:model-value="eventSkeleton.startDate"
|
||||
placeholder="Date de début"
|
||||
:initial-date="props.event.startDate"
|
||||
:initial-date="lastActiveEvent?.startDate"
|
||||
:required="true"
|
||||
/>
|
||||
|
||||
@@ -77,12 +77,12 @@ watch(popoverOpened, (hasOpened, _o) => {
|
||||
<CalendarInputRPGDate
|
||||
v-model:model-value="eventSkeleton.endDate"
|
||||
placeholder="Date de fin"
|
||||
:initial-date="props.event.endDate"
|
||||
:initial-date="lastActiveEvent?.endDate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-red-500 pl-8">
|
||||
<div class="text-red-500 ml-8">
|
||||
<span class="text-sm">
|
||||
{{ formErrors.message }}
|
||||
</span>
|
||||
@@ -95,6 +95,6 @@ watch(popoverOpened, (hasOpened, _o) => {
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</UiPopoverContent>
|
||||
</UiPopover>
|
||||
</UiDialogContent>
|
||||
</UiDialog>
|
||||
</template>
|
||||
|
||||
@@ -19,8 +19,18 @@ export default defineEventHandler(async (event) => {
|
||||
const { data, error } = await client
|
||||
.from('calendar_events')
|
||||
.insert({ start_date: bodyData?.event.startDate, end_date: bodyData.event.endDate, title: bodyData?.event.title, description: bodyData.event.description, calendar_id: bodyData?.calendarId } as never)
|
||||
.select()
|
||||
.returns<CalendarEvent>()
|
||||
.select(`
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
hidden,
|
||||
startDate:start_date,
|
||||
endDate:end_date,
|
||||
wiki,
|
||||
category:calendar_event_categories!calendar_events_category_fkey (*),
|
||||
secondaryCategories:calendar_event_categories!calendar_event_categories_links (*)
|
||||
`)
|
||||
.single<CalendarEvent>()
|
||||
|
||||
if (error) throw error
|
||||
|
||||
|
||||
@@ -294,13 +294,19 @@ export const useCalendar = defineStore('calendar', () => {
|
||||
*/
|
||||
const isAdvancedSearchOpen: Ref<boolean> = ref<boolean>(false)
|
||||
|
||||
/**
|
||||
* Opens the search modal
|
||||
*/
|
||||
function revealAdvancedSearch() {
|
||||
isAdvancedSearchOpen.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* State for advanced search modal
|
||||
*/
|
||||
const isEditEventModalOpen: Ref<boolean> = ref<boolean>(false)
|
||||
|
||||
function revealEditEventModal() {
|
||||
isEditEventModalOpen.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the active viewType
|
||||
*
|
||||
@@ -436,9 +442,17 @@ export const useCalendar = defineStore('calendar', () => {
|
||||
* @returns 1 means the first date comes before the second, -1 means the second comes before the first, and 0 if they're identical
|
||||
*/
|
||||
function compareDates(a: RPGDate, b: RPGDate, order: RPGDateOrder = 'desc'): number {
|
||||
// Reverses the order if specified
|
||||
// Reverses the order if specified
|
||||
const orderFactor: number = order === 'desc' ? 1 : -1
|
||||
|
||||
// If somehow one of the date isn't available
|
||||
if (!b) {
|
||||
return -1 * orderFactor
|
||||
}
|
||||
if (!a) {
|
||||
return 1 * orderFactor
|
||||
}
|
||||
|
||||
// Compare years
|
||||
if (a.year < b.year) return -1 * orderFactor
|
||||
if (a.year > b.year) return 1 * orderFactor
|
||||
@@ -634,11 +648,13 @@ export const useCalendar = defineStore('calendar', () => {
|
||||
getViewTypeTitle,
|
||||
isCurrentScreenActive,
|
||||
isAdvancedSearchOpen,
|
||||
revealAdvancedSearch,
|
||||
isEditEventModalOpen,
|
||||
revealEditEventModal,
|
||||
convertDateToDays,
|
||||
getDifferenceInDays,
|
||||
areDatesIdentical,
|
||||
compareDates,
|
||||
getRelativeString,
|
||||
revealAdvancedSearch
|
||||
}
|
||||
})
|
||||
|
||||
@@ -14,17 +14,19 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
||||
baseEvents.value = data
|
||||
}
|
||||
|
||||
// Order base events by dates
|
||||
const allEvents = computed(() => baseEvents.value.sort((a, b) => {
|
||||
return compareDates(a.startDate, b.startDate, 'desc')
|
||||
}))
|
||||
|
||||
// Gets all current event in its default state
|
||||
const currentEvents: Ref<CalendarEvent[]> = ref(computeCurrentEvents())
|
||||
const currentEvents: Ref<CalendarEvent[]> = ref([])
|
||||
|
||||
// Watch for currentDate changes
|
||||
// Watch for currentDate or events' list changes
|
||||
// This is deep because we're watching an array, and changes need to trigger and mutations like .push and .splice
|
||||
watch([currentDate, allEvents], () => {
|
||||
currentEvents.value = computeCurrentEvents()
|
||||
})
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
/**
|
||||
* Determines if the event can appear in the front end
|
||||
@@ -35,9 +37,6 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
||||
* @returns Whether the event should appear in the current view
|
||||
*/
|
||||
function shouldEventBeDisplayed(event: CalendarEvent): boolean {
|
||||
// const eventStartDateToDays = convertDateToDays(event.startDate)
|
||||
// const eventEndDateToDays: number = event.endDate ? convertDateToDays(event.endDate) : 0
|
||||
|
||||
const isEventOnCurrentScreen =
|
||||
(event.startDate.year === currentDate.currentYear &&
|
||||
event.startDate.month === currentDate.currentMonth) ||
|
||||
@@ -45,25 +44,6 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
||||
event.endDate.year === currentDate.currentYear &&
|
||||
event.endDate.month === currentDate.currentMonth)
|
||||
|
||||
// Check whether the event is on the last 8 tiles
|
||||
// This is to allow leap events from appearing on the last 8 tiles
|
||||
//
|
||||
// This is not used for now
|
||||
//
|
||||
// const firstDayOfCurrentMonth = convertDateToDays({
|
||||
// day: 1,
|
||||
// month: currentDate.currentMonth,
|
||||
// year: currentDate.currentYear
|
||||
// })
|
||||
// const lastDayOfCurrentMonth = firstDayOfCurrentMonth + daysPerMonth
|
||||
// const last8Tiles = lastDayOfCurrentMonth + 8
|
||||
|
||||
// const isEventOnNext8Tiles =
|
||||
// (eventStartDateToDays <= last8Tiles && eventStartDateToDays >= lastDayOfCurrentMonth) ||
|
||||
// (Boolean(event.endDate) &&
|
||||
// eventEndDateToDays <= last8Tiles &&
|
||||
// eventEndDateToDays >= lastDayOfCurrentMonth)
|
||||
|
||||
switch (currentConfig.viewType) {
|
||||
case 'month':
|
||||
return isEventOnCurrentScreen!
|
||||
@@ -188,6 +168,7 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
||||
/**
|
||||
* EVENT CREATION FUNCTIONS
|
||||
*/
|
||||
const lastActiveEvent = ref<CalendarEvent | null>()
|
||||
/**
|
||||
* Dummy event to hold creation data
|
||||
*/
|
||||
@@ -206,8 +187,13 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
|
||||
* We assume it's been sanitized by the caller
|
||||
*/
|
||||
async function submitSkeleton() {
|
||||
return await $fetch(`/api/calendars/events/create`, { method: 'POST', body: { event : eventSkeleton.value, calendarId: calendarId.value }})
|
||||
try {
|
||||
const res = await $fetch(`/api/calendars/events/create`, { method: 'POST', body: { event : eventSkeleton.value, calendarId: calendarId.value }})
|
||||
baseEvents.value.push(res)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
|
||||
return { allEvents, setEvents, currentEvents, getRelativeEventFromDate, getRelativeEventFromEvent, eventSkeleton, resetSkeleton, submitSkeleton }
|
||||
return { allEvents, setEvents, currentEvents, getRelativeEventFromDate, getRelativeEventFromEvent, eventSkeleton, resetSkeleton, submitSkeleton, lastActiveEvent }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user