From 735805f33260658280c82fbfd745a8f238812f36 Mon Sep 17 00:00:00 2001 From: Adrian Hopek Date: Mon, 13 Jan 2025 10:16:49 +0100 Subject: [PATCH 1/5] #510 - handle changing year for dashboard calendar --- app/Http/Controllers/DashboardController.php | 17 ++-- resources/js/Pages/Dashboard.vue | 6 +- .../js/Shared/Widgets/VacationCalendar.vue | 88 +++++++++++++++---- routes/api.php | 3 + routes/web.php | 2 +- 5 files changed, 83 insertions(+), 33 deletions(-) diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 23cf14a5..47ebf2ac 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -7,20 +7,12 @@ use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Inertia\Response; -use Toby\Domain\DailySummaryRetriever; use Toby\Domain\DashboardAggregator; -use Toby\Domain\UserVacationStatsRetriever; -use Toby\Domain\VacationTypeConfigRetriever; class DashboardController extends Controller { - public function __invoke( - Request $request, - UserVacationStatsRetriever $vacationStatsRetriever, - VacationTypeConfigRetriever $configRetriever, - DailySummaryRetriever $dailySummaryRetriever, - DashboardAggregator $dashboardAggregator, - ): Response { + public function index(Request $request, DashboardAggregator $dashboardAggregator): Response + { $user = $request->user(); $year = Carbon::now()->year; @@ -33,4 +25,9 @@ public function __invoke( "stats" => $dashboardAggregator->aggregateStats($user, $year), ]); } + + public function loadCalendar(Request $request, int $year, DashboardAggregator $dashboardAggregator): array + { + return $dashboardAggregator->aggregateCalendarData($request->user(), $year); + } } diff --git a/resources/js/Pages/Dashboard.vue b/resources/js/Pages/Dashboard.vue index 32b57dc0..94b04eb4 100644 --- a/resources/js/Pages/Dashboard.vue +++ b/resources/js/Pages/Dashboard.vue @@ -31,9 +31,9 @@ const { auth } = useGlobalProps() import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/vue/24/solid' import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue' -import { computed, reactive, onMounted } from 'vue' +import { computed, reactive, onMounted, ref } from 'vue' import { DateTime } from 'luxon' import useVacationTypeInfo from '@/Composables/vacationTypeInfo.js' import { useMonthInfo } from '@/Composables/monthInfo.js' import { viewModes, find as findViewMode } from '@/Shared/Widgets/Calendar/ViewModeOptions.js' import DayComponent from '@/Shared/Widgets/Calendar/DayComponent.vue' import { useStorage } from '@vueuse/core' +import axios from 'axios' const props = defineProps({ - holidays: Object, - approvedVacations: Object, - pendingVacations: Object, + initHolidays: Object, + initApprovedVacations: Object, + initPendingVacations: Object, }) const currentDate = DateTime.now() @@ -25,6 +26,11 @@ const calendar = reactive({ date: currentDate.startOf('week'), }) +const holidays = ref(new Map()) +const approvedVacations = ref(new Map()) +const pendingVacations = ref(new Map()) +const loadedYears = ref([]) + const calendarState = reactive({ viewMode: { isWeek: computed(() => calendar.viewMode === 'week'), @@ -36,7 +42,24 @@ const calendarState = reactive({ isNext: computed(() => calendar.date.plus({ [calendar.viewMode]: 1 }).year === currentDate.year), }) -onMounted(() => loadCalendar()) +onMounted(async () => initCalendar()) + +function initCalendar() { + for (const [key, value] of Object.entries(props.initHolidays)) { + holidays.value.set(key, value) + } + + for (const [key, value] of Object.entries(props.initApprovedVacations)) { + approvedVacations.value.set(key, value) + } + + for (const [key, value] of Object.entries(props.initPendingVacations)) { + pendingVacations.value.set(key, value) + } + + loadedYears.value.push(currentDate.year) + loadCalendar() +} function loadCalendar() { let days = [] @@ -50,6 +73,25 @@ function loadCalendar() { calendar.days = days } + +async function loadYear(year) { + const res = await axios.get(`/api/dashboard/calendar/${year}`) + + for (const [key, value] of Object.entries(res.data.holidays)) { + holidays.value.set(key, value) + } + + for (const [key, value] of Object.entries(res.data.approvedVacations)) { + approvedVacations.value.set(key, value) + } + + for (const [key, value] of Object.entries(res.data.pendingVacations)) { + pendingVacations.value.set(key, value) + } + + loadedYears.value.push(year) +} + function prepareDay(day) { const isCurrentMonth = isInCurrentMonth(day) const startDay = { @@ -71,21 +113,33 @@ function prepareDay(day) { } } -function today() { +async function today() { calendar.date = currentDate + if (!loadedYears.value.includes(calendar.date.year)) { + await loadYear(calendar.date.year) + } + loadCalendar() } -function previous() { +async function previous() { calendar.date = calendar.date.minus({ [calendar.viewMode]: 1 }) + if (!loadedYears.value.includes(calendar.date.year)) { + await loadYear(calendar.date.year) + } + loadCalendar() } -function next() { +async function next() { calendar.date = calendar.date.plus({ [calendar.viewMode]: 1 }) + if (!loadedYears.value.includes(calendar.date.year)) { + await loadYear(calendar.date.year) + } + loadCalendar() } @@ -107,19 +161,19 @@ function isToday(date) { } function isHoliday(date) { - return props.holidays[date.toISODate()] !== undefined + return holidays.value.has(date.toISODate()) } function getHolidayInfo(day) { - return props.holidays[day.date] + return holidays.value.get(day.date) } function isVacation(date) { - return props.approvedVacations[date.toISODate()] !== undefined + return approvedVacations.value.has(date.toISODate()) } function isPendingVacation(date) { - return props.pendingVacations[date.toISODate()] !== undefined + return pendingVacations.value.has(date.toISODate()) } function getVacationType(day) { @@ -127,7 +181,7 @@ function getVacationType(day) { } function getVacationInfo(day) { - return day.isVacation ? props.approvedVacations[day.date] : props.pendingVacations[day.date] + return day.isVacation ? approvedVacations.value.get(day.date) : pendingVacations.value.get(day.date) } @@ -141,9 +195,7 @@ function getVacationInfo(day) {