1 import { createSelector } from '@reduxjs/toolkit';
3 import { getBusyScheduledEvent } from '../../containers/calendar/eventHelper';
4 import type { CalendarViewBusyEvent } from '../../containers/calendar/interface';
5 import type { CalendarState } from '../store';
6 import { deduplicateBusySlots } from './busySlotsSelectors.helpers';
7 import type { BusySlotFetchStatus, BusySlotsVisibility } from './busySlotsSlice';
8 import { busySlotsSliceName } from './busySlotsSlice';
10 export const selectAttendeesBusySlots = createSelector(
11 (state: CalendarState) => state[busySlotsSliceName].displayOnGrid,
12 (state: CalendarState) => state[busySlotsSliceName].metadata,
13 (state: CalendarState) => state[busySlotsSliceName].attendees,
14 (state: CalendarState) => state[busySlotsSliceName].attendeeBusySlots,
15 (state: CalendarState) => state[busySlotsSliceName].attendeeVisibility,
16 (state: CalendarState) => state[busySlotsSliceName].attendeeDataAccessible,
17 (state: CalendarState) => state[busySlotsSliceName].attendeeColor,
26 ): CalendarViewBusyEvent[] => {
27 if (!display || !metadata || attendees.length === 0) {
31 return Object.keys(busySlots).reduce<CalendarViewBusyEvent[]>((acc, email) => {
33 attendees.includes(email) &&
34 dataAccessible[email] === true &&
35 availabilities[email] === 'visible' &&
36 busySlots[email].length > 0
38 const deduplicatedBusySlots = deduplicateBusySlots(busySlots[email]);
39 const attendeeFormattedTimeslots = deduplicatedBusySlots.map((busySlot) =>
40 getBusyScheduledEvent(email, busySlot, metadata.tzid, attendeesColor[email] || '')
43 acc = [...acc, ...attendeeFormattedTimeslots];
50 const selectAttendeeColor = (state: CalendarState, email: string): string | undefined =>
51 state[busySlotsSliceName].attendeeColor[email];
52 const selectAttendeeVisibility = (state: CalendarState, email: string): BusySlotsVisibility | undefined =>
53 state[busySlotsSliceName].attendeeVisibility[email];
54 const selectAttendeeAvailability = (state: CalendarState, email: string): boolean =>
55 !!state[busySlotsSliceName].attendeeDataAccessible[email];
56 const selectAttendeeFetchStatus = (state: CalendarState, email: string): BusySlotFetchStatus | undefined =>
57 state[busySlotsSliceName].attendeeFetchStatus[email];
59 export const selectAttendeeBusyData = createSelector(
60 [selectAttendeeColor, selectAttendeeVisibility, selectAttendeeAvailability, selectAttendeeFetchStatus],
61 (color, visibility, hasAvailability, fetchStatus) => {
62 const status: 'loading' | 'available' | 'not-available' = (() => {
63 if (fetchStatus === 'loading') {
67 return hasAvailability ? 'available' : 'not-available';
73 isVisible: visibility === 'visible',
80 * Display availability unknown sentence in the participant rows if at least one attendee has unknown availability
81 * @param state CalendarState
84 export const selectDisplayAvailabilityUnknown = (state: CalendarState) =>
85 Object.entries(state[busySlotsSliceName].attendeeDataAccessible).reduce((acc, [email, attendeeDataAccessible]) => {
86 if (!attendeeDataAccessible && state[busySlotsSliceName].attendees.includes(email)) {