[#142] prefill event creation for any way of creating (#226)

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-10-21 14:12:08 +02:00
committed by GitHub
parent e99c56f03f
commit 89ea554b1f
5 changed files with 118 additions and 35 deletions
+70
View File
@@ -256,6 +256,10 @@ describe("calendar Availability search", () => {
sid: "mockSid", sid: "mockSid",
openpaasId: "user1", openpaasId: "user1",
}, },
organiserData: {
cn: "test",
cal_address: "test@test.com",
},
tokens: { accessToken: "token" }, tokens: { accessToken: "token" },
}, },
calendars: { calendars: {
@@ -324,6 +328,72 @@ describe("calendar Availability search", () => {
expect(spy).not.toHaveBeenCalledWith(); expect(spy).not.toHaveBeenCalledWith();
}); });
it("open window with attendees filled after temp search on create event button click", async () => {
const spy = jest
.spyOn(eventThunks, "getTempCalendarsListAsync")
.mockImplementation((payload) => {
return () => Promise.resolve(payload) as any;
});
mockedSearchUsers.mockResolvedValue([
{
email: "newuser@example.com",
displayName: "New User",
avatarUrl: "image.png",
openpaasId: "1234567890",
},
]);
renderWithProviders(<CalendarTestWrapper />, preloadedState);
const input = screen.getByPlaceholderText(/start typing a name or email/i);
userEvent.type(input, "New");
const option = await screen.findByText("New User");
fireEvent.click(option);
expect(spy).toHaveBeenCalled();
fireEvent.click(screen.getByRole("button", { name: /create event/i }));
await waitFor(() => {
expect(screen.getAllByText(/Create Event/i)).toHaveLength(2);
expect(screen.getAllByText(/New User/i)).toHaveLength(2);
});
});
it("open window with attendees filled after temp search on enter in temp input", async () => {
const spy = jest
.spyOn(eventThunks, "getTempCalendarsListAsync")
.mockImplementation((payload) => {
return () => Promise.resolve(payload) as any;
});
mockedSearchUsers.mockResolvedValue([
{
email: "newuser@example.com",
displayName: "New User",
avatarUrl: "image.png",
openpaasId: "1234567890",
},
]);
renderWithProviders(<CalendarTestWrapper />, preloadedState);
const input = screen.getByPlaceholderText(/start typing a name or email/i);
userEvent.type(input, "New");
const option = await screen.findByText("New User");
fireEvent.click(option);
expect(spy).toHaveBeenCalled();
fireEvent.keyDown(input, { key: "Enter" });
await waitFor(() => {
expect(screen.getAllByText(/Create Event/i)).toHaveLength(2);
expect(screen.getAllByText(/New User/i)).toHaveLength(2);
});
});
it("BUGFIX: can untoggle all personnal calendars", () => { it("BUGFIX: can untoggle all personnal calendars", () => {
renderWithProviders(<CalendarTestWrapper />, { renderWithProviders(<CalendarTestWrapper />, {
user: preloadedState.user, user: preloadedState.user,
+10 -11
View File
@@ -16,14 +16,11 @@ import {
} from "../../features/Calendars/CalendarSlice"; } from "../../features/Calendars/CalendarSlice";
import ImportAlert from "../../features/Events/ImportAlert"; import ImportAlert from "../../features/Events/ImportAlert";
import { import {
computeStartOfTheWeek,
formatDateToYYYYMMDDTHHMMSS, formatDateToYYYYMMDDTHHMMSS,
getCalendarRange, getCalendarRange,
} from "../../utils/dateUtils"; } from "../../utils/dateUtils";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import { push } from "redux-first-history"; import { push } from "redux-first-history";
import EventPreviewModal from "../../features/Events/EventDisplayPreview"; import EventPreviewModal from "../../features/Events/EventDisplayPreview";
import { createSelector } from "@reduxjs/toolkit";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import { TempCalendarsInput } from "./TempCalendarsInput"; import { TempCalendarsInput } from "./TempCalendarsInput";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
@@ -41,13 +38,8 @@ import { EventErrorHandler } from "../Error/EventErrorHandler";
import { EventErrorSnackbar } from "../Error/ErrorSnackbar"; import { EventErrorSnackbar } from "../Error/ErrorSnackbar";
import momentTimezonePlugin from "@fullcalendar/moment-timezone"; import momentTimezonePlugin from "@fullcalendar/moment-timezone";
import { TimezoneSelector } from "./TimezoneSelector"; import { TimezoneSelector } from "./TimezoneSelector";
import { DateCalendar } from "@mui/x-date-pickers/DateCalendar";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
import moment from "moment";
import { DayCalendarSkeleton } from "@mui/x-date-pickers/DayCalendarSkeleton";
import { PickersDay } from "@mui/x-date-pickers/PickersDay";
import { MiniCalendar } from "./MiniCalendar"; import { MiniCalendar } from "./MiniCalendar";
import { User } from "../Attendees/PeopleSearch";
interface CalendarAppProps { interface CalendarAppProps {
calendarRef: React.RefObject<CalendarApi | null>; calendarRef: React.RefObject<CalendarApi | null>;
@@ -224,6 +216,7 @@ export default function CalendarApp({
null null
); );
const [tempUsers, setTempUsers] = useState<User[]>([]);
const [tempEvent, setTempEvent] = useState<CalendarEvent>( const [tempEvent, setTempEvent] = useState<CalendarEvent>(
{} as CalendarEvent {} as CalendarEvent
); );
@@ -245,6 +238,9 @@ export default function CalendarApp({
setSelectedEvent, setSelectedEvent,
setAfterChoiceFunc, setAfterChoiceFunc,
setOpenEditModePopup, setOpenEditModePopup,
tempUsers,
setTempEvent,
timezone,
}); });
// View handlers // View handlers
@@ -300,10 +296,13 @@ export default function CalendarApp({
dottedEvents={dottedEvents} dottedEvents={dottedEvents}
/> />
<TempCalendarsInput <TempCalendarsInput
setAnchorEl={setAnchorEl} tempUsers={tempUsers}
setTempUsers={setTempUsers}
handleToggleEventPreview={() => {
eventHandlers.handleDateSelect(null as unknown as DateSelectArg);
}}
selectedCalendars={selectedCalendars} selectedCalendars={selectedCalendars}
setSelectedCalendars={setSelectedCalendars} setSelectedCalendars={setSelectedCalendars}
setTempEvent={setTempEvent}
/> />
<div className="calendarList"> <div className="calendarList">
<CalendarSelection <CalendarSelection
+7 -24
View File
@@ -1,27 +1,27 @@
import { useState, useRef } from "react"; import { useRef } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks"; import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { import {
getTempCalendarsListAsync, getTempCalendarsListAsync,
removeTempCal, removeTempCal,
} from "../../features/Calendars/CalendarSlice"; } from "../../features/Calendars/CalendarSlice";
import { Calendars } from "../../features/Calendars/CalendarTypes"; import { Calendars } from "../../features/Calendars/CalendarTypes";
import { CalendarEvent } from "../../features/Events/EventsTypes";
import { User, PeopleSearch } from "../Attendees/PeopleSearch"; import { User, PeopleSearch } from "../Attendees/PeopleSearch";
const requestControllers = new Map<string, AbortController>(); const requestControllers = new Map<string, AbortController>();
export function TempCalendarsInput({ export function TempCalendarsInput({
setAnchorEl, tempUsers,
setTempEvent, setTempUsers,
handleToggleEventPreview,
selectedCalendars, selectedCalendars,
setSelectedCalendars, setSelectedCalendars,
}: { }: {
setAnchorEl: Function; tempUsers: User[];
setTempEvent: Function; setTempUsers: (users: User[]) => void;
handleToggleEventPreview: () => void;
selectedCalendars: string[]; selectedCalendars: string[];
setSelectedCalendars: Function; setSelectedCalendars: Function;
}) { }) {
const [tempUsers, setTempUsers] = useState<User[]>([]);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const tempcalendars = const tempcalendars =
useAppSelector((state) => state.calendars.templist) ?? {}; useAppSelector((state) => state.calendars.templist) ?? {};
@@ -86,23 +86,6 @@ export function TempCalendarsInput({
} }
}; };
const handleToggleEventPreview = () => {
const newEvent: CalendarEvent = {
title: "New Event",
attendee: tempUsers.map((u) => ({
cn: u.displayName,
cal_address: u.email,
partstat: "NEED-ACTION",
role: "REQ-PARTICIPANT",
rsvp: "TRUE",
cutype: "INDIVIDUAL",
})),
} as CalendarEvent;
setTempEvent(newEvent);
setAnchorEl(document.body);
};
return ( return (
<PeopleSearch <PeopleSearch
objectTypes={["user"]} objectTypes={["user"]}
@@ -15,6 +15,8 @@ import { formatDateToYYYYMMDDTHHMMSS } from "../../../utils/dateUtils";
import { getEvent } from "../../../features/Events/EventApi"; import { getEvent } from "../../../features/Events/EventApi";
import { refreshCalendars } from "../../Event/utils/eventUtils"; import { refreshCalendars } from "../../Event/utils/eventUtils";
import { updateTempCalendar } from "../utils/calendarUtils"; import { updateTempCalendar } from "../utils/calendarUtils";
import { User } from "../../Attendees/PeopleSearch";
import { formatLocalDateTime } from "../../../features/Events/EventModal";
export interface EventHandlersProps { export interface EventHandlersProps {
setSelectedRange: (range: DateSelectArg | null) => void; setSelectedRange: (range: DateSelectArg | null) => void;
@@ -32,6 +34,9 @@ export interface EventHandlersProps {
setSelectedEvent: (event: CalendarEvent) => void; setSelectedEvent: (event: CalendarEvent) => void;
setAfterChoiceFunc: (func: Function) => void; setAfterChoiceFunc: (func: Function) => void;
setOpenEditModePopup: (open: string) => void; setOpenEditModePopup: (open: string) => void;
tempUsers: User[];
setTempEvent: (event: CalendarEvent) => void;
timezone: string;
} }
export const createEventHandlers = (props: EventHandlersProps) => { export const createEventHandlers = (props: EventHandlersProps) => {
@@ -51,10 +56,33 @@ export const createEventHandlers = (props: EventHandlersProps) => {
setSelectedEvent, setSelectedEvent,
setAfterChoiceFunc, setAfterChoiceFunc,
setOpenEditModePopup, setOpenEditModePopup,
tempUsers,
setTempEvent,
timezone,
} = props; } = props;
const handleDateSelect = (selectInfo: DateSelectArg) => { const handleDateSelect = (selectInfo: DateSelectArg) => {
setSelectedRange(selectInfo); setSelectedRange(selectInfo);
if (tempUsers) {
const newEvent: CalendarEvent = {
start: selectInfo?.start
? formatLocalDateTime(selectInfo?.start, timezone)
: "",
end: selectInfo?.end
? formatLocalDateTime(selectInfo?.end, timezone)
: "",
attendee: tempUsers.map((u) => ({
cn: u.displayName,
cal_address: u.email,
partstat: "NEED-ACTION",
role: "REQ-PARTICIPANT",
rsvp: "TRUE",
cutype: "INDIVIDUAL",
})),
} as CalendarEvent;
setTempEvent(newEvent);
}
setAnchorEl(document.body); setAnchorEl(document.body);
}; };
@@ -11,6 +11,9 @@ export const useCalendarEventHandlers = (props: EventHandlersProps) => {
handleDateSelect: useCallback(eventHandlers.handleDateSelect, [ handleDateSelect: useCallback(eventHandlers.handleDateSelect, [
props.setSelectedRange, props.setSelectedRange,
props.setAnchorEl, props.setAnchorEl,
props.setTempEvent,
props.tempUsers,
props.timezone,
]), ]),
handleClosePopover: useCallback(eventHandlers.handleClosePopover, [ handleClosePopover: useCallback(eventHandlers.handleClosePopover, [
props.calendarRef, props.calendarRef,