Major new version (#2)
Release Notes Architecture - Component refactor: removed monoliths (`Calendar.vue`, `CalendarGrid.vue`); expanded granular view + header/control components. - Dialog system introduced (`BaseDialog`, `SettingsDialog`). State & Data - Store redesigned: Map-based events + recurrence map; mutation counters. - Local persistence + undo/redo history (custom plugins). Date & Holidays - Migrated all date logic to `date-fns` (+ tz). - Added national holiday support (toggle + loading utilities). Recurrence & Events - Consolidated recurrence handling; fixes for monthly edge days (29–31), annual, multi‑day, and complex weekly repeats. - Reliable splitting/moving/resizing/deletion of repeating and multi‑day events. Interaction & UX - Double‑tap to create events; improved drag (multi‑day + position retention). - Scroll & inertial/momentum navigation; year change via numeric scroller. - Movable event dialog; live settings application. Performance - Progressive / virtual week rendering, reduced off‑screen buffer. - Targeted repaint strategy; minimized full re-renders. Plugins Added - History, undo normalization, persistence, scroll manager, virtual weeks. Styling & Layout - Responsive + compact layout refinements; header restructured. - Simplified visual elements (removed dots/overflow text); holiday styling adjustments. Reliability / Fixes - Numerous recurrence, deletion, orientation/rotation, and event indexing corrections. - Cross-browser fallback (Firefox week info). Dependencies Added - date-fns, date-fns-tz, date-holidays, pinia-plugin-persistedstate. Net Change - 28 files modified; ~4.4K insertions / ~2.2K deletions (major refactor + feature set).
This commit is contained in:
1 parent
86a06acccb
commit
dbe4c99b07
28 files changed
+4465
-2207
No files matched your search
+24
-17
@@ -3,11 +3,13 @@
|
||||
<div class="week-label">W{{ weekNumber }}</div>
|
||||
<div class="days-grid">
|
||||
<DayCell v-for="day in days" :key="day.dateStr" :day="day" />
|
||||
<div class="week-overlay">
|
||||
<!-- Event spans will be rendered here -->
|
||||
</div>
|
||||
<div class="week-overlay"></div>
|
||||
</div>
|
||||
<div v-if="monthLabel" class="month-name-label" :style="{ height: `${monthLabel.weeksSpan * 64}px` }">
|
||||
<div
|
||||
v-if="monthLabel"
|
||||
class="month-name-label"
|
||||
:style="{ height: `${monthLabel.weeksSpan * 64}px` }"
|
||||
>
|
||||
<span>{{ monthLabel.name }} '{{ monthLabel.year }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -16,51 +18,56 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import DayCell from './DayCell.vue'
|
||||
import { isoWeekInfo, toLocalString, getLocalizedMonthName, monthAbbr } from '@/utils/date'
|
||||
import {
|
||||
toLocalString,
|
||||
getLocalizedMonthName,
|
||||
monthAbbr,
|
||||
DEFAULT_TZ,
|
||||
getISOWeek,
|
||||
} from '@/utils/date'
|
||||
import { addDays } from 'date-fns'
|
||||
|
||||
const props = defineProps({
|
||||
week: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const weekNumber = computed(() => {
|
||||
return isoWeekInfo(props.week.monday).week
|
||||
})
|
||||
const weekNumber = computed(() => getISOWeek(props.week.monday))
|
||||
|
||||
const days = computed(() => {
|
||||
const d = new Date(props.week.monday)
|
||||
const result = []
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const dateStr = toLocalString(d)
|
||||
const dateStr = toLocalString(d, DEFAULT_TZ)
|
||||
result.push({
|
||||
date: new Date(d),
|
||||
dateStr,
|
||||
dayOfMonth: d.getDate(),
|
||||
month: d.getMonth(),
|
||||
isFirstDayOfMonth: d.getDate() === 1,
|
||||
monthClass: monthAbbr[d.getMonth()]
|
||||
monthClass: monthAbbr[d.getMonth()],
|
||||
})
|
||||
d.setDate(d.getDate() + 1)
|
||||
d.setTime(addDays(d, 1).getTime())
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
const monthLabel = computed(() => {
|
||||
const firstDayOfMonth = days.value.find(d => d.isFirstDayOfMonth)
|
||||
const firstDayOfMonth = days.value.find((d) => d.isFirstDayOfMonth)
|
||||
if (!firstDayOfMonth) return null
|
||||
|
||||
const month = firstDayOfMonth.month
|
||||
const year = firstDayOfMonth.date.getFullYear()
|
||||
|
||||
|
||||
// This is a simplified calculation for weeksSpan
|
||||
const weeksSpan = 4
|
||||
const weeksSpan = 4
|
||||
|
||||
return {
|
||||
name: getLocalizedMonthName(month),
|
||||
year: String(year).slice(-2),
|
||||
weeksSpan
|
||||
weeksSpan,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
Reference in new issue
Block a user