From 6f4ff060471f1935134df14e6fb5a2179361acb7 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Wed, 27 Aug 2025 09:09:19 -0600 Subject: [PATCH] Refactor modules for consistency --- src/components/EventDialog.vue | 26 ++++++++++----------- src/components/EventOverlay.vue | 12 +++------- src/stores/CalendarStore.js | 41 +++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/components/EventDialog.vue b/src/components/EventDialog.vue index 2d04cce..81f0514 100644 --- a/src/components/EventDialog.vue +++ b/src/components/EventDialog.vue @@ -29,7 +29,7 @@ const anchorElement = ref(null) const dialogMode = ref('create') // 'create' or 'edit' const editingEventId = ref(null) const unsavedCreateId = ref(null) -const occurrenceContext = ref(null) // { baseId, occurrenceIndex, weekday, occurrenceDate } +const occurrenceContext = ref(null) // { baseId, n } const initialWeekday = ref(null) const title = computed({ get() { @@ -304,17 +304,13 @@ function openEditDialog(payload) { const baseId = payload.id let n = payload.n || 0 let weekday = null - let occurrenceDate = null const event = calendarStore.getEventById(baseId) if (!event) return if (event.recur && n >= 0) { const occStr = getOccurrenceDate(event, n, DEFAULT_TZ) - if (occStr) { - occurrenceDate = fromLocalString(occStr, DEFAULT_TZ) - weekday = occurrenceDate.getDay() - } + if (occStr) weekday = fromLocalString(occStr, DEFAULT_TZ).getDay() } dialogMode.value = 'edit' editingEventId.value = baseId @@ -344,9 +340,9 @@ function openEditDialog(payload) { if (event.recur) { if (event.recur.freq === 'weeks' && n >= 0) { - occurrenceContext.value = { baseId, occurrenceIndex: n, weekday, occurrenceDate } + occurrenceContext.value = { baseId, n } } else if (event.recur.freq === 'months' && n > 0) { - occurrenceContext.value = { baseId, occurrenceIndex: n, weekday: null, occurrenceDate } + occurrenceContext.value = { baseId, n } } } // anchor to base event start date @@ -471,11 +467,13 @@ const isLastOccurrence = computed(() => { if (!event || !event.recur) return false if (event.recur.count === 'unlimited' || recurrenceOccurrences.value === 0) return false const totalCount = parseInt(event.recur.count, 10) || 0 - return occurrenceContext.value.occurrenceIndex === totalCount - 1 + return occurrenceContext.value.n === totalCount - 1 }) const formattedOccurrenceShort = computed(() => { - if (occurrenceContext.value?.occurrenceDate) { - return formatDateShort(occurrenceContext.value.occurrenceDate) + if (occurrenceContext.value?.n != null) { + const ev = calendarStore.getEventById(editingEventId.value) + const occStr = ev ? getOccurrenceDate(ev, occurrenceContext.value.n, DEFAULT_TZ) : null + if (occStr) return formatDateShort(fromLocalString(occStr, DEFAULT_TZ)) } if (isRepeatingBaseEdit.value && editingEventId.value) { const ev = calendarStore.getEventById(editingEventId.value) @@ -487,8 +485,10 @@ const formattedOccurrenceShort = computed(() => { }) const headerDateShort = computed(() => { - if (occurrenceContext.value?.occurrenceDate) { - return formatDateShort(occurrenceContext.value.occurrenceDate) + if (occurrenceContext.value?.n != null) { + const ev = calendarStore.getEventById(editingEventId.value) + const occStr = ev ? getOccurrenceDate(ev, occurrenceContext.value.n, DEFAULT_TZ) : null + if (occStr) return formatDateShort(fromLocalString(occStr, DEFAULT_TZ)) } if (editingEventId.value) { const ev = calendarStore.getEventById(editingEventId.value) diff --git a/src/components/EventOverlay.vue b/src/components/EventOverlay.vue index b138298..f77d7bf 100644 --- a/src/components/EventOverlay.vue +++ b/src/components/EventOverlay.vue @@ -325,7 +325,7 @@ function onDragPointerMove(e) { if (st.mode === 'move') { if (st.n && st.n > 0) { if (!st.realizedId) { - const newId = store.splitMoveVirtualOccurrence(st.id, st.startDate, ns, ne, st.n) + const newId = store.splitMoveVirtualOccurrence(st.id, ns, ne, st.n) if (newId) { st.realizedId = newId st.id = newId @@ -357,13 +357,7 @@ function onDragPointerMove(e) { if (!st.realizedId) { const initialStart = ns const initialEnd = ne - const newId = store.splitMoveVirtualOccurrence( - st.id, - st.startDate, - initialStart, - initialEnd, - st.n, - ) + const newId = store.splitMoveVirtualOccurrence(st.id, initialStart, initialEnd, st.n) if (newId) { st.realizedId = newId st.id = newId @@ -446,7 +440,7 @@ function applyRangeDuringDrag(st, startDate, endDate) { if (st.n && st.n > 0) { if (st.mode !== 'move') return // no resize for virtual occurrence // Split-move: occurrence being dragged treated as first of new series - store.splitMoveVirtualOccurrence(st.id, st.startDate, startDate, endDate, st.n) + store.splitMoveVirtualOccurrence(st.id, startDate, endDate, st.n) return } store.setEventRange(st.id, startDate, endDate, { mode: st.mode }) diff --git a/src/stores/CalendarStore.js b/src/stores/CalendarStore.js index 971143c..516923b 100644 --- a/src/stores/CalendarStore.js +++ b/src/stores/CalendarStore.js @@ -7,6 +7,7 @@ import { DEFAULT_TZ, } from '@/utils/date' import { differenceInCalendarDays, addDays } from 'date-fns' +import { getDate } from '@/utils/events' import { initializeHolidays, getAvailableCountries, getAvailableStates } from '@/utils/holidays' export const useCalendarStore = defineStore('calendar', { @@ -202,30 +203,30 @@ export const useCalendarStore = defineStore('calendar', { }, deleteSingleOccurrence(ctx) { - const { baseId, occurrenceIndex } = ctx || {} - if (occurrenceIndex == null) return + const { baseId, n } = ctx || {} + if (n == null) return const base = this.getEventById(baseId) if (!base) return if (!base.recur) { - if (occurrenceIndex === 0) this.deleteEvent(baseId) + if (n === 0) this.deleteEvent(baseId) return } - if (occurrenceIndex === 0) { + if (n === 0) { this.deleteFirstOccurrence(baseId) return } const snapshot = { ...base } snapshot.recur = snapshot.recur ? { ...snapshot.recur } : null - if (base.recur.count === occurrenceIndex + 1) { - base.recur.count = occurrenceIndex + if (base.recur.count === n + 1) { + base.recur.count = n return } - base.recur.count = occurrenceIndex + base.recur.count = n const originalNumeric = snapshot.recur.count === 'unlimited' ? Infinity : parseInt(snapshot.recur.count, 10) let remainingCount = 'unlimited' if (originalNumeric !== Infinity) { - const rem = originalNumeric - (occurrenceIndex + 1) + const rem = originalNumeric - (n + 1) if (rem <= 0) return remainingCount = String(rem) } @@ -247,14 +248,14 @@ export const useCalendarStore = defineStore('calendar', { }, deleteFromOccurrence(ctx) { - const { baseId, occurrenceIndex } = ctx + const { baseId, n } = ctx const base = this.getEventById(baseId) if (!base || !base.recur) return - if (occurrenceIndex === 0) { + if (n === 0) { this.deleteEvent(baseId) return } - this._terminateRepeatSeriesAtIndex(baseId, occurrenceIndex) + this._terminateRepeatSeriesAtIndex(baseId, n) this.notifyEventsChanged() }, @@ -289,10 +290,16 @@ export const useCalendarStore = defineStore('calendar', { this.notifyEventsChanged() }, - splitMoveVirtualOccurrence(baseId, occurrenceDateStr, newStartStr, newEndStr, occurrenceIndex) { + // Split a recurring series at occurrence index n, moving that occurrence (n) into its own new series + splitMoveVirtualOccurrence(baseId, newStartStr, newEndStr, n) { const base = this.events.get(baseId) if (!base || !base.recur) return const originalCountRaw = base.recur.count + // Derive occurrence date from n (first occurrence n=0 is base.startDate) + let occurrenceDateStr = null + if (n === 0) occurrenceDateStr = base.startDate + else occurrenceDateStr = getDate(base, n, DEFAULT_TZ) + if (!occurrenceDateStr) return const occurrenceDate = fromLocalString(occurrenceDateStr, DEFAULT_TZ) const baseStart = fromLocalString(base.startDate, DEFAULT_TZ) // If series effectively has <=1 occurrence, treat as simple move (no split) and flatten @@ -310,8 +317,8 @@ export const useCalendarStore = defineStore('calendar', { this.setEventRange(baseId, newStartStr, newEndStr, { mode: 'move', rotatePattern: true }) return baseId } - // Use occurrenceIndex when provided to detect first occurrence (n == 0) - if (occurrenceIndex === 0 || occurrenceDate.getTime() === baseStart.getTime()) { + // First occurrence: just move the event + if (n === 0) { this.setEventRange(baseId, newStartStr, newEndStr, { mode: 'move' }) return baseId } @@ -406,16 +413,16 @@ export const useCalendarStore = defineStore('calendar', { return newId }, - splitRepeatSeries(baseId, occurrenceIndex, newStartStr, _newEndStr) { + splitRepeatSeries(baseId, n, newStartStr, _newEndStr) { const base = this.events.get(baseId) if (!base || !base.recur) return null const originalCountRaw = base.recur.count - this._terminateRepeatSeriesAtIndex(baseId, occurrenceIndex) + this._terminateRepeatSeriesAtIndex(baseId, n) let newSeriesCount = 'unlimited' if (originalCountRaw !== 'unlimited') { const originalNum = parseInt(originalCountRaw, 10) if (!isNaN(originalNum)) { - const remaining = originalNum - occurrenceIndex + const remaining = originalNum - n newSeriesCount = String(Math.max(1, remaining)) } }