vkurko / calendar

Full-sized drag & drop JavaScript event calendar with resource & timeline views
https://vkurko.github.io/calendar/
MIT License
964 stars 82 forks source link

Issue with setOption for scrollTime #270

Closed Arenz2001 closed 1 month ago

Arenz2001 commented 1 month ago

Hi,

I have an issue with the scrollTime. What I'd like to achieve is that, when all my data are fetched, compare all the hours and set the scrollTime to the one with the earliest one.

The issue is that, even if I can get the earliest value, I can't set the scrollTime with the setOption function or even when doing options.scrollTime = newScrollTime.

I did check the value of the scrollTime with some console.log and it does seem to change but not visually. I haven't seen anyone with the same issue as me so I don't know if it's a known bug or if my code is just too horendous to work as is.

If you have any question or simply want a more simplified version let me know.

Here's a "simplified" version of my code :

Thank you for your time.

<script lang="ts">
    import '../../app.postcss';
    import Calendar from '@event-calendar/core';
    import TimeGrid from '@event-calendar/time-grid';
    import { onMount } from 'svelte';

    // Initialize variables and calendar options
    let plugins = [TimeGrid];
    let scrollTime: string = '00:00:00'; 
    let calendarRef: HTMLElement | null = null;
    let resaData: any;
    let uniqueRooms: any = [];

    let earliestTime: string;
    let earliestTimeSeconds: number;

    // Calendar options configuration
    let options = {
        firstDay: 1,
        height: '100%',
        scrollTime: scrollTime,
        events: [],
        datesSet: function(info: any) {
            const formattedStart = formatDateTime(info.startStr);
            const formattedEnd = formatDateTime(info.endStr);
            loadReservations(formattedStart, formattedEnd);
        },
    };

    // Function to format date-time string
    function formatDateTime(dateTimeStr: any) {
        return dateTimeStr.replace('T', ' ');
    }

    // Convert time string to seconds
    function toSeconds(time: any) {
        const [hours, minutes, seconds] = time.split(':').map(Number);
        return hours * 3600 + minutes * 60 + seconds;
    }

    // Find the earliest time in reservations
    function findEarliestTime(reservations: any) {
        return reservations.reduce((earliest: any, reservation: any) => {
            const currentSeconds = toSeconds(reservation.processedStart);
            const earliestSeconds = toSeconds(earliest);
            return currentSeconds < earliestSeconds ? reservation.processedStart : earliest;
        }, '23:59:59');
    }

    // Function to load reservations using hardcoded data
    async function loadReservations(startDate: string | null = null, endDate: string | null = null) {
        const data = {
            "data": [
                {
                    "id": 383,
                    "title": "test delete user",
                    "roomId": 2,
                    "start": "2024-05-15 03:00:00",
                    "end": "2024-05-15 05:00:00",
                },
                {
                    "id": 385,
                    "title": "errgegrgreg",
                    "roomId": 6,
                    "start": "2024-05-15 05:00:00",
                    "end": "2024-05-15 06:00:00",
                },
            ]
        };

        let processedReservations = data.data.map((reservation: any) => ({
            ...reservation,
            processedStart: reservation.start.slice(11, 19),
            processedEnd: reservation.end.slice(11, 19),
            roomName: reservation.roomName,
        }));
        options.events = processedReservations as never[];
        resaData = data.data;
        uniqueRooms = resaData.reduce((acc: any, reservation: any) => {
            const roomExists = acc.find((room: { roomName: any; }) => room.roomName === reservation.roomName);
            if (!roomExists) {
                acc.push({ roomName: reservation.roomName, backgroundColor: reservation.backgroundColor });
            }
            return acc;
        }, []);

        earliestTime = findEarliestTime(processedReservations);
        earliestTimeSeconds = toSeconds(earliestTime);
        options.scrollTime = earliestTimeSeconds.toString();
        return data.data;
    }
</script>

<div class="flex m-4 main-content">
    <div class="flex-grow mr-2 overflow-auto calendar-container">
        <div class="calendar-content">
            <Calendar bind:this={calendarRef} {plugins} {options}  />
        </div>
    </div>
</div>
vkurko commented 1 month ago

Hello,

Thanks for reporting the problem. Indeed, the scrollTime option had broken reactivity. I fixed this in version 2.7.2. Please check.

Also I recommend you to use eventSources to load data instead of datesSet.

Arenz2001 commented 1 month ago

Thank you !

It works really well now. I'll look into the eventSources too. I might redo the whole page too because the 5 months ago me did some nasty code lol.

Again, a big thank you for your reactivity.