Update all non-major dependencies
[ProtonMail-WebClient.git] / applications / calendar / src / app / store / busySlots / busySlotsSelectors.ts
blob3d4a7913cf765b230ae7a6412f55f977c189a34b
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,
18     (
19         display,
20         metadata,
21         attendees,
22         busySlots,
23         availabilities,
24         dataAccessible,
25         attendeesColor
26     ): CalendarViewBusyEvent[] => {
27         if (!display || !metadata || attendees.length === 0) {
28             return [];
29         }
31         return Object.keys(busySlots).reduce<CalendarViewBusyEvent[]>((acc, email) => {
32             if (
33                 attendees.includes(email) &&
34                 dataAccessible[email] === true &&
35                 availabilities[email] === 'visible' &&
36                 busySlots[email].length > 0
37             ) {
38                 const deduplicatedBusySlots = deduplicateBusySlots(busySlots[email]);
39                 const attendeeFormattedTimeslots = deduplicatedBusySlots.map((busySlot) =>
40                     getBusyScheduledEvent(email, busySlot, metadata.tzid, attendeesColor[email] || '')
41                 );
43                 acc = [...acc, ...attendeeFormattedTimeslots];
44             }
45             return acc;
46         }, []);
47     }
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') {
64                 return 'loading';
65             }
67             return hasAvailability ? 'available' : 'not-available';
68         })();
70         return {
71             color,
72             hasAvailability,
73             isVisible: visibility === 'visible',
74             status,
75         };
76     }
79 /**
80  * Display availability unknown sentence in the participant rows if at least one attendee has unknown availability
81  * @param state CalendarState
82  * @returns boolean
83  */
84 export const selectDisplayAvailabilityUnknown = (state: CalendarState) =>
85     Object.entries(state[busySlotsSliceName].attendeeDataAccessible).reduce((acc, [email, attendeeDataAccessible]) => {
86         if (!attendeeDataAccessible && state[busySlotsSliceName].attendees.includes(email)) {
87             acc = true;
88         }
89         return acc;
90     }, false);