Co-authored-by: lethemanh <lethemanh@lethemanhs-MacBook-Pro.local>
This commit is contained in:
@@ -111,8 +111,20 @@ describe("addCalendarResourceAsync thunk", () => {
|
|||||||
|
|
||||||
expect(mockedToRejectedError).toHaveBeenCalledWith(errorDetails);
|
expect(mockedToRejectedError).toHaveBeenCalledWith(errorDetails);
|
||||||
|
|
||||||
expect(result.type).toBe("calendars/addCalendarResource/rejected");
|
expect(result.type).toBe("calendars/addCalendarResource/fulfilled");
|
||||||
expect(result.payload).toEqual(mockRejectedErrorResult);
|
expect(result.payload).toEqual({
|
||||||
|
calId: "res-456/cal-123",
|
||||||
|
color: { background: "#000000", foreground: "#FFFFFF" },
|
||||||
|
desc: "A meeting room",
|
||||||
|
link: "/calendars/user-123/cal-123.json",
|
||||||
|
name: "Resource Room A",
|
||||||
|
owner: {
|
||||||
|
firstname: "",
|
||||||
|
lastname: "Resource Room A",
|
||||||
|
emails: [],
|
||||||
|
resource: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle error if addSharedCalendar fails", async () => {
|
it("should handle error if addSharedCalendar fails", async () => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
getOpenPaasUser,
|
getOpenPaasUser,
|
||||||
updateUserConfigurations,
|
updateUserConfigurations,
|
||||||
getResourceDetails,
|
getResourceDetails,
|
||||||
|
getUserDetails,
|
||||||
} from "@/features/User/userAPI";
|
} from "@/features/User/userAPI";
|
||||||
import { api } from "@/utils/apiUtils";
|
import { api } from "@/utils/apiUtils";
|
||||||
|
|
||||||
@@ -25,6 +26,26 @@ describe("getOpenPaasUser", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getUserDetails", () => {
|
||||||
|
it("should fetch and return user details", async () => {
|
||||||
|
const mockUser = {
|
||||||
|
firstname: "John",
|
||||||
|
lastname: "Doe",
|
||||||
|
emails: ["john@test.com"],
|
||||||
|
};
|
||||||
|
const userId = "123";
|
||||||
|
|
||||||
|
(api.get as jest.Mock).mockReturnValue({
|
||||||
|
json: jest.fn().mockResolvedValue(mockUser),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await getUserDetails(userId);
|
||||||
|
|
||||||
|
expect(api.get).toHaveBeenCalledWith(`api/users/${userId}`);
|
||||||
|
expect(result).toEqual(mockUser);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("getResourceDetails", () => {
|
describe("getResourceDetails", () => {
|
||||||
it("should fetch and return resource details", async () => {
|
it("should fetch and return resource details", async () => {
|
||||||
const mockResource = { _id: "res-123", name: "Meeting Room A" };
|
const mockResource = { _id: "res-123", name: "Meeting Room A" };
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import {
|
|||||||
import { getEvent } from "@/features/Events/EventApi";
|
import { getEvent } from "@/features/Events/EventApi";
|
||||||
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||||
import { updateAttendeesAfterTimeChange } from "@/features/Events/updateEventHelpers/updateAttendeesAfterTimeChange";
|
import { updateAttendeesAfterTimeChange } from "@/features/Events/updateEventHelpers/updateAttendeesAfterTimeChange";
|
||||||
import { createAttendee } from "@/features/User/models/attendee.mapper";
|
import {
|
||||||
|
AttendeeOptions,
|
||||||
|
createAttendee,
|
||||||
|
} from "@/features/User/models/attendee.mapper";
|
||||||
import { getDeltaInMilliseconds } from "@/utils/dateUtils";
|
import { getDeltaInMilliseconds } from "@/utils/dateUtils";
|
||||||
import {
|
import {
|
||||||
CalendarApi,
|
CalendarApi,
|
||||||
@@ -70,13 +73,18 @@ export const createEventHandlers = (props: EventHandlersProps) => {
|
|||||||
end: selectInfo?.end
|
end: selectInfo?.end
|
||||||
? formatLocalDateTime(selectInfo?.end, timezone)
|
? formatLocalDateTime(selectInfo?.end, timezone)
|
||||||
: "",
|
: "",
|
||||||
attendee: tempUsers.map((user) =>
|
attendee: tempUsers.map((user) => {
|
||||||
createAttendee({
|
const attendeeOption: AttendeeOptions = {
|
||||||
cal_address: user.email,
|
cal_address: user.email,
|
||||||
cn: user.displayName,
|
cn: user.displayName,
|
||||||
rsvp: "TRUE",
|
rsvp: "TRUE",
|
||||||
})
|
};
|
||||||
),
|
|
||||||
|
if (user.objectType === "resource") {
|
||||||
|
attendeeOption.cutype = "RESOURCE";
|
||||||
|
}
|
||||||
|
return createAttendee(attendeeOption);
|
||||||
|
}),
|
||||||
} as CalendarEvent;
|
} as CalendarEvent;
|
||||||
|
|
||||||
setTempEvent(newEvent);
|
setTempEvent(newEvent);
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ export const addCalendarResourceAsync = createAsyncThunk<
|
|||||||
?.replace(".json", "")
|
?.replace(".json", "")
|
||||||
?.split("/")[0];
|
?.split("/")[0];
|
||||||
|
|
||||||
if (!resourceId) {
|
|
||||||
return rejectWithValue({
|
|
||||||
message: "Unable to extract resource ID from calendar link",
|
|
||||||
} as RejectedError);
|
|
||||||
}
|
|
||||||
|
|
||||||
let owner: OpenPaasUserData = {
|
let owner: OpenPaasUserData = {
|
||||||
firstname: "",
|
firstname: "",
|
||||||
lastname: cal.cal["dav:name"] ?? "",
|
lastname: cal.cal["dav:name"] ?? "",
|
||||||
@@ -46,11 +40,18 @@ export const addCalendarResourceAsync = createAsyncThunk<
|
|||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
await addSharedCalendar(userId, calId, cal);
|
await addSharedCalendar(userId, calId, cal);
|
||||||
const resource = await getResourceDetails(resourceId!);
|
|
||||||
owner = {
|
if (resourceId) {
|
||||||
...(await getUserDetails(resource.creator)),
|
try {
|
||||||
resource: true,
|
const resource = await getResourceDetails(resourceId!);
|
||||||
};
|
owner = {
|
||||||
|
...(await getUserDetails(resource.creator)),
|
||||||
|
resource: true,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
toRejectedError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
calId: cal.cal._links.self?.href
|
calId: cal.cal._links.self?.href
|
||||||
|
|||||||
@@ -96,6 +96,12 @@ function EventPopover({
|
|||||||
displayName: resource.cn,
|
displayName: resource.cn,
|
||||||
}));
|
}));
|
||||||
}, [event?.attendee]);
|
}, [event?.attendee]);
|
||||||
|
const eventAttendees = useMemo(
|
||||||
|
() =>
|
||||||
|
event?.attendee?.filter((attendee) => attendee.cutype !== "RESOURCE") ??
|
||||||
|
[],
|
||||||
|
[event?.attendee]
|
||||||
|
);
|
||||||
|
|
||||||
const [showMore, setShowMore] = useState(false);
|
const [showMore, setShowMore] = useState(false);
|
||||||
const [showDescription, setShowDescription] = useState(
|
const [showDescription, setShowDescription] = useState(
|
||||||
@@ -150,11 +156,8 @@ function EventPopover({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [attendees, setAttendees] = useState<userAttendee[]>(
|
const [attendees, setAttendees] = useState<userAttendee[]>(
|
||||||
event?.attendee
|
eventAttendees
|
||||||
? event.attendee.filter(
|
? eventAttendees.filter((a) => a.cal_address !== organizer?.cal_address)
|
||||||
(a) =>
|
|
||||||
a.cal_address !== organizer?.cal_address && a.cutype !== "RESOURCE"
|
|
||||||
)
|
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
const [alarm, setAlarm] = useState(event?.alarm?.trigger ?? "");
|
const [alarm, setAlarm] = useState(event?.alarm?.trigger ?? "");
|
||||||
@@ -482,11 +485,9 @@ function EventPopover({
|
|||||||
setRepetition(event.repetition ?? ({} as RepetitionObject));
|
setRepetition(event.repetition ?? ({} as RepetitionObject));
|
||||||
setShowRepeat(event.repetition?.freq ? true : false);
|
setShowRepeat(event.repetition?.freq ? true : false);
|
||||||
setAttendees(
|
setAttendees(
|
||||||
event.attendee
|
eventAttendees
|
||||||
? event.attendee.filter(
|
? eventAttendees.filter(
|
||||||
(a) =>
|
(a) => a.cal_address !== organizer?.cal_address
|
||||||
a.cal_address !== organizer?.cal_address &&
|
|
||||||
a.cutype !== "RESOURCE"
|
|
||||||
)
|
)
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
@@ -512,13 +513,10 @@ function EventPopover({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setSelectedResources(resources ?? []);
|
setSelectedResources(resources ?? []);
|
||||||
} else if (event && event.attendee && event.attendee.length > 0) {
|
} else if (event && event.attendee && event.attendee?.length > 0) {
|
||||||
// Handle tempEvent case (no uid but has attendees from temp calendar search)
|
// Handle tempEvent case (no uid but has attendees from temp calendar search)
|
||||||
setAttendees(
|
setAttendees(
|
||||||
event.attendee.filter(
|
eventAttendees.filter((a) => a.cal_address !== organizer?.cal_address)
|
||||||
(a) =>
|
|
||||||
a.cal_address !== organizer?.cal_address && a.cutype !== "RESOURCE"
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
setSelectedResources(resources ?? []);
|
setSelectedResources(resources ?? []);
|
||||||
}
|
}
|
||||||
@@ -528,6 +526,7 @@ function EventPopover({
|
|||||||
resolvedCalendarTimezone,
|
resolvedCalendarTimezone,
|
||||||
defaultCalendarId,
|
defaultCalendarId,
|
||||||
resources,
|
resources,
|
||||||
|
eventAttendees,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Reset state when creating new event (event is empty object or undefined)
|
// Reset state when creating new event (event is empty object or undefined)
|
||||||
@@ -667,7 +666,6 @@ function EventPopover({
|
|||||||
resetAllStateToDefault();
|
resetAllStateToDefault();
|
||||||
setStart("");
|
setStart("");
|
||||||
setEnd("");
|
setEnd("");
|
||||||
setSelectedResources([]);
|
|
||||||
shouldSyncFromRangeRef.current = true; // Reset for next time
|
shouldSyncFromRangeRef.current = true; // Reset for next time
|
||||||
isCalendarIdUserSelectedRef.current = false; // Reset so next open gets fresh default
|
isCalendarIdUserSelectedRef.current = false; // Reset so next open gets fresh default
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { userAttendee } from "./attendee";
|
import { userAttendee } from "./attendee";
|
||||||
|
|
||||||
export function createAttendee(options?: {
|
export interface AttendeeOptions {
|
||||||
cal_address?: string;
|
cal_address?: string;
|
||||||
cn?: string;
|
cn?: string;
|
||||||
role?: userAttendee["role"];
|
role?: userAttendee["role"];
|
||||||
partstat?: userAttendee["partstat"];
|
partstat?: userAttendee["partstat"];
|
||||||
rsvp?: userAttendee["rsvp"];
|
rsvp?: userAttendee["rsvp"];
|
||||||
cutype?: userAttendee["cutype"];
|
cutype?: userAttendee["cutype"];
|
||||||
}): userAttendee {
|
}
|
||||||
|
|
||||||
|
export function createAttendee(options?: AttendeeOptions): userAttendee {
|
||||||
return {
|
return {
|
||||||
cal_address: options?.cal_address ?? "",
|
cal_address: options?.cal_address ?? "",
|
||||||
cn: options?.cn ?? "",
|
cn: options?.cn ?? "",
|
||||||
|
|||||||
@@ -44,9 +44,7 @@ export async function getUserDetails(id: string): Promise<OpenPaasUserData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getResourceDetails(id: string): Promise<ResourceData> {
|
export async function getResourceDetails(id: string): Promise<ResourceData> {
|
||||||
const resource = await api
|
const resource = await api.get(`api/resources/${id}`).json();
|
||||||
.get(`api/resources/${encodeURIComponent(id)}`)
|
|
||||||
.json();
|
|
||||||
return resource as ResourceData;
|
return resource as ResourceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@
|
|||||||
"select_timezone": "Sélectionner le fuseau horaire",
|
"select_timezone": "Sélectionner le fuseau horaire",
|
||||||
"moreOptions": "Plus d'options",
|
"moreOptions": "Plus d'options",
|
||||||
"search": "Rechercher",
|
"search": "Rechercher",
|
||||||
"resource": "Ressources"
|
"resource": "Ressource"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"searchIn": "Rechercher dans",
|
"searchIn": "Rechercher dans",
|
||||||
|
|||||||
@@ -173,5 +173,7 @@ export function restoreFormDataFromTemp(
|
|||||||
) {
|
) {
|
||||||
setters.setHasEndDateChanged(tempData.hasEndDateChanged);
|
setters.setHasEndDateChanged(tempData.hasEndDateChanged);
|
||||||
}
|
}
|
||||||
setters.setSelectedResources?.(tempData.resources ?? []);
|
if (tempData.resources !== undefined) {
|
||||||
|
setters.setSelectedResources?.(tempData.resources);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user