Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / calendar / src / app / components / eventModal / inputs / CreateEventCalendarSelect.tsx
bloba571426d275dc23a9e650c2f9f90fbb7d5ee8522
1 import { useGetAddresses } from '@proton/account/addresses/hooks';
2 import { useGetCalendarBootstrap } from '@proton/calendar/calendarBootstrap/hooks';
3 import CalendarSelect from '@proton/components/components/calendarSelect/CalendarSelect';
4 import type { SelectTwoProps } from '@proton/components/components/selectTwo/SelectTwo';
5 import { useLoading } from '@proton/hooks';
6 import { notificationsToModel } from '@proton/shared/lib/calendar/alarms/notificationsToModel';
7 import type { CalendarMember, EventModel } from '@proton/shared/lib/interfaces/calendar';
9 import { getIsAvailableCalendar } from '../../../helpers/event';
10 import { getInitialMemberModel, getOrganizerAndSelfAddressModel } from '../eventForm/state';
12 export interface Props extends Omit<SelectTwoProps<string>, 'children'> {
13     model: EventModel;
14     setModel: (value: EventModel) => void;
15     isCreateEvent: boolean;
16     frozen?: boolean;
17     isColorPerEventEnabled: boolean;
20 const CreateEventCalendarSelect = ({
21     model,
22     setModel,
23     isCreateEvent,
24     frozen = false,
25     isColorPerEventEnabled,
26     ...rest
27 }: Props) => {
28     const [loading, withLoading] = useLoading();
29     const getCalendarBootstrap = useGetCalendarBootstrap();
30     const getAddresses = useGetAddresses();
32     const {
33         organizer,
34         calendars,
35         calendar: { id: calendarID },
36     } = model;
38     const options = calendars
39         .filter(
40             ({ value: id, isOwned, isWritable }) =>
41                 id === calendarID ||
42                 getIsAvailableCalendar({
43                     isOwnedCalendar: isOwned,
44                     isCalendarWritable: isWritable,
45                     isInvitation: !!organizer,
46                 })
47         )
48         .map(({ value, text, color, permissions, isOwned, isSubscribed, isWritable, isUnknown }) => ({
49             id: value,
50             name: text,
51             color,
52             permissions,
53             isOwned,
54             isSubscribed,
55             isWritable,
56             isUnknown,
57         }));
58     const { name } = options.find(({ id }) => id === calendarID) || options[0];
60     if (frozen) {
61         return (
62             <div className="py-2 flex w-full">
63                 <span className="text-ellipsis" title={name}>
64                     {name}
65                 </span>
66             </div>
67         );
68     }
70     const handleChangeCalendar = async (newId: string) => {
71         const { color, permissions, isOwned, isSubscribed, isWritable, isUnknown } =
72             options.find(({ id }) => id === newId) || options[0];
74         // grab members and default settings for the new calendar
75         const {
76             Members,
77             CalendarSettings: {
78                 DefaultEventDuration: defaultEventDuration,
79                 DefaultPartDayNotifications,
80                 DefaultFullDayNotifications,
81             },
82         } = await getCalendarBootstrap(newId);
83         const addresses = await getAddresses();
85         const [Member = { ID: '', Email: '' } as CalendarMember] = Members;
86         const memberEmail = Member.Email;
87         const address = addresses.find(({ Email }) => Email === memberEmail);
88         if (!memberEmail || !address) {
89             throw new Error('Address does not exist');
90         }
91         const newDefaultPartDayNotifications = notificationsToModel(DefaultPartDayNotifications, false);
92         const newDefaultFullDayNotifications = notificationsToModel(DefaultFullDayNotifications, true);
94         const partDayNotifications = model.hasPartDayDefaultNotifications
95             ? newDefaultPartDayNotifications
96             : model.partDayNotifications;
98         const fullDayNotifications = model.hasFullDayDefaultNotifications
99             ? newDefaultFullDayNotifications
100             : model.fullDayNotifications;
102         setModel({
103             ...model,
104             calendar: { id: newId, color, permissions, isOwned, isSubscribed, isWritable, isUnknown },
105             ...getInitialMemberModel(addresses, Members, Member, address),
106             ...getOrganizerAndSelfAddressModel({
107                 attendees: model.attendees,
108                 addresses,
109                 addressID: address.ID,
110                 isAttendee: model.isAttendee,
111             }),
112             defaultEventDuration,
113             partDayNotifications,
114             fullDayNotifications,
115         });
116     };
118     return (
119         <CalendarSelect
120             calendarID={calendarID}
121             displayColor={isColorPerEventEnabled ? false : options.length > 1}
122             options={options}
123             onChange={({ value }) => withLoading(handleChangeCalendar(value))}
124             loading={loading}
125             {...rest}
126         />
127     );
130 export default CreateEventCalendarSelect;