Merge branch 'tanstack-query' into 'main'

PR: Tanstack Query

See merge request ekresse/htwkalender!33
This commit is contained in:
ekresse
2024-04-04 22:15:32 +00:00
5 changed files with 565 additions and 525 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,8 @@
"@fullcalendar/interaction": "^6.1.11", "@fullcalendar/interaction": "^6.1.11",
"@fullcalendar/timegrid": "^6.1.11", "@fullcalendar/timegrid": "^6.1.11",
"@fullcalendar/vue3": "^6.1.11", "@fullcalendar/vue3": "^6.1.11",
"@tanstack/vue-query": "^5.28.9",
"@tanstack/vue-query-devtools": "^5.28.10",
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.9.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"primeflex": "^3.3.1", "primeflex": "^3.3.1",

View File

@@ -22,6 +22,7 @@ import { RouteRecordName, RouterView } from "vue-router";
import CalendarPreview from "./components/CalendarPreview.vue"; import CalendarPreview from "./components/CalendarPreview.vue";
import moduleStore from "./store/moduleStore.ts"; import moduleStore from "./store/moduleStore.ts";
import { provide, ref } from "vue"; import { provide, ref } from "vue";
import { VueQueryDevtools } from "@tanstack/vue-query-devtools";
const disabledPages = [ const disabledPages = [
"room-finder", "room-finder",
@@ -63,6 +64,8 @@ window.addEventListener("resize", updateMobile);
</RouterView> </RouterView>
<!-- show CalendarPreview but only on specific router views --> <!-- show CalendarPreview but only on specific router views -->
<CalendarPreview v-if="isDisabled($route.name)" /> <CalendarPreview v-if="isDisabled($route.name)" />
<VueQueryDevtools />
<Toast /> <Toast />
</template> </template>

View File

@@ -21,13 +21,16 @@ import FullCalendar from "@fullcalendar/vue3";
import dayGridPlugin from "@fullcalendar/daygrid"; import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction"; import interactionPlugin from "@fullcalendar/interaction";
import timeGridPlugin from "@fullcalendar/timegrid"; import timeGridPlugin from "@fullcalendar/timegrid";
import { computed, ComputedRef, inject, ref, Ref, watch } from "vue"; import { computed, ComputedRef, inject, ref, Ref } from "vue";
import { CalendarOptions, DatesSetArg, EventInput } from "@fullcalendar/core"; import { CalendarOptions, DatesSetArg, EventInput } from "@fullcalendar/core";
import { fetchEventsByRoomAndDuration } from "../api/fetchRoom.ts"; import { fetchEventsByRoomAndDuration } from "../api/fetchRoom.ts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import allLocales from "@fullcalendar/core/locales-all"; import allLocales from "@fullcalendar/core/locales-all";
import router from "@/router"; import router from "@/router";
import { formatYearMonthDay } from "@/helpers/dates"; import { formatYearMonthDay } from "@/helpers/dates";
import { useQuery } from "@tanstack/vue-query";
import { watch } from "vue";
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const props = defineProps({ const props = defineProps({
@@ -37,13 +40,6 @@ const props = defineProps({
}, },
}); });
type CalenderEvent = {
id: number;
start: string;
end: string;
showFree: boolean;
};
const date: Ref<Date> = ref(new Date()); const date: Ref<Date> = ref(new Date());
// Set the selected date from the URL // Set the selected date from the URL
@@ -66,44 +62,33 @@ setDateFromQuery();
const currentDateFrom: Ref<string> = ref(""); const currentDateFrom: Ref<string> = ref("");
const currentDateTo: Ref<string> = ref(""); const currentDateTo: Ref<string> = ref("");
const occupations: Ref<CalenderEvent[]> = ref([]);
const mobilePage = inject("mobilePage") as Ref<boolean>; const mobilePage = inject("mobilePage") as Ref<boolean>;
const selectedRoom = computed(() => props.room); const selectedRoom = computed(() => props.room);
watch(selectedRoom, () => { const { data: occupations } = useQuery({
getOccupation(); queryKey: ["roomOccupation", selectedRoom, currentDateFrom, currentDateTo],
queryFn: () =>
fetchEventsByRoomAndDuration(
selectedRoom.value,
currentDateFrom.value,
currentDateTo.value,
),
select: (data) =>
data.map((event, index) => ({
id: index,
start: event.start.replace(/\s\+\d{4}\s\w+$/, "").replace(" ", "T"),
end: event.end.replace(/\s\+\d{4}\s\w+$/, "").replace(" ", "T"),
showFree: event.free,
})),
enabled: () => selectedRoom.value !== "" && currentDateFrom.value !== "",
staleTime: 5000000, // 500 seconds
}); });
const fullCalendar = ref<InstanceType<typeof FullCalendar>>(); watch(occupations, () => fullCalendar.value?.getApi().refetchEvents());
async function getOccupation() { const fullCalendar = ref<InstanceType<typeof FullCalendar>>();
if (selectedRoom.value === "") {
return;
}
fetchEventsByRoomAndDuration(
selectedRoom.value,
currentDateFrom.value,
currentDateTo.value,
)
.then((events) => {
occupations.value = events?.map((event, index) => {
return {
id: index,
start: event.start.replace(/\s\+\d{4}\s\w+$/, "").replace(" ", "T"),
end: event.end.replace(/\s\+\d{4}\s\w+$/, "").replace(" ", "T"),
showFree: event.free,
};
});
})
.finally(() => {
fullCalendar.value?.getApi().refetchEvents();
})
.catch((error) => {
console.error(error);
});
}
const calendarOptions: ComputedRef<CalendarOptions> = computed(() => ({ const calendarOptions: ComputedRef<CalendarOptions> = computed(() => ({
locales: allLocales, locales: allLocales,
@@ -175,12 +160,12 @@ const calendarOptions: ComputedRef<CalendarOptions> = computed(() => ({
date: formatYearMonthDay(endDate), date: formatYearMonthDay(endDate),
}, },
}); });
getOccupation();
}, },
events: function ( events: function (
_info: unknown, _info: unknown,
successCallback: (events: EventInput[]) => void, successCallback: (events: EventInput[]) => void,
) { ) {
if (!occupations.value) return;
successCallback( successCallback(
occupations.value.map((event) => { occupations.value.map((event) => {
return { return {

View File

@@ -54,9 +54,21 @@ import Checkbox from "primevue/checkbox";
import Skeleton from "primevue/skeleton"; import Skeleton from "primevue/skeleton";
import Calendar from "primevue/calendar"; import Calendar from "primevue/calendar";
import i18n from "./i18n"; import i18n from "./i18n";
import { VueQueryPlugin } from "@tanstack/vue-query";
const app = createApp(App); const app = createApp(App);
const pinia = createPinia(); const pinia = createPinia();
app.use(VueQueryPlugin, {
queryClientConfig: {
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
},
});
app.use(PrimeVue); app.use(PrimeVue);
app.use(router); app.use(router);
app.use(ToastService); app.use(ToastService);