import { useAppDispatch, useAppSelector } from '@/app/hooks' import { getCalendars } from '@/features/Calendars/CalendarApi' import { Calendar } from '@/features/Calendars/CalendarTypes' import { addSharedCalendarAsync } from '@/features/Calendars/services' import { CalendarData } from '@/features/Calendars/types/CalendarData' import { renameDefault } from '@/utils/renameDefault' import { Avatar, Box, Button, IconButton, TextField, Typography, useTheme } from '@linagora/twake-mui' import CloseIcon from '@mui/icons-material/Close' import { useState } from 'react' import { useI18n } from 'twake-i18n' import { PeopleSearch } from '../Attendees/PeopleSearch' import { User } from '../Attendees/types' import { ResponsiveDialog } from '../Dialog' import { stringAvatar } from '../Event/utils/eventUtils' import { ColorPicker } from './CalendarColorPicker' import { getAccessiblePair } from '@/utils/getAccessiblePair' import { defaultColors } from '@/utils/defaultColors' interface CalendarWithOwner { cal: CalendarData owner: User } function CalendarItem({ cal, onRemove, onColorChange }: { cal: CalendarWithOwner onRemove: () => void onColorChange: (color: Record) => void }) { const theme = useTheme() const { t } = useI18n() return ( {renameDefault( cal.cal['dav:name'], cal.owner.displayName, t, false )} {cal.owner.email} ) } function SelectedCalendarsList({ calendars, selectedCal, onRemove, onColorChange }: { calendars: Record selectedCal: CalendarWithOwner[] onRemove: (cal: CalendarWithOwner) => void onColorChange: (cal: CalendarWithOwner, color: Record) => void }) { const { t } = useI18n() if (selectedCal.length === 0) return null const groupedByOwner = selectedCal.reduce< Record< string, { owner: User visibleCals: CalendarWithOwner[] alreadyExisting: boolean } > >((acc, cal) => { const exists = Object.values(calendars).some( (existing: Calendar) => existing.id === cal.cal?._links?.self?.href ?.replace('/calendars/', '') .replace('.json', '') ) if (!acc[cal.owner.email]) { acc[cal.owner.email] = { owner: cal.owner, visibleCals: [], alreadyExisting: false } } if (exists) { acc[cal.owner.email].alreadyExisting = true } else { acc[cal.owner.email].visibleCals.push(cal) } return acc }, {}) return ( {t('common.name')} {Object.values(groupedByOwner).map( ({ owner, visibleCals, alreadyExisting }) => ( {visibleCals.length > 0 ? ( visibleCals.map(cal => cal.cal ? ( onRemove(cal)} onColorChange={color => onColorChange(cal, color)} /> ) : ( {t('calendar.noPublicCalendarsFor', { name: owner.displayName })} ) ) ) : alreadyExisting ? ( {t('calendar.noMoreCalendarsFor', { name: owner.displayName })} ) : null} ) )} ) } export default function CalendarSearch({ open, onClose }: { open: boolean onClose: ( result?: string[] | Record, reason?: 'backdropClick' | 'escapeKeyDown' ) => void }) { const dispatch = useAppDispatch() const theme = useTheme() const openpaasId = useAppSelector(state => state.user.userData?.openpaasId) ?? '' const calendars = useAppSelector(state => state.calendars.list) const [selectedCal, setSelectedCalendars] = useState([]) const [selectedUsers, setSelectedUsers] = useState([]) const handleSave = async () => { if (selectedCal.length > 0) { const idList = await Promise.all( selectedCal.map(async cal => { const calId = crypto.randomUUID() const exists = Object.values(calendars).some( (existing: Calendar) => existing.id === cal.cal?._links?.self?.href ?.replace('/calendars/', '') .replace('.json', '') ) if (!exists && cal.cal) { await dispatch( addSharedCalendarAsync({ userId: openpaasId, calId, cal: { ...cal, color: cal.cal['apple:color'] ? { light: cal.cal['apple:color'], dark: getAccessiblePair(cal.cal['apple:color'], theme) } : defaultColors[0] } }) ) return cal.cal._links.self?.href ?.replace('/calendars/', '') .replace('.json', '') } return null }) ) onClose(idList.filter(Boolean) as string[]) setSelectedCalendars([]) setSelectedUsers([]) } } const { t } = useI18n() return ( { onClose({}, 'backdropClick') setSelectedCalendars([]) setSelectedUsers([]) }} title={t('calendar.browseOtherCalendars')} actions={ <> } > } onChange={async (_event: React.SyntheticEvent, value: User[]) => { setSelectedUsers(value) const cals = await Promise.all( value.map(async (user: User) => { if (user?.openpaasId) { const cals = await getCalendars( user.openpaasId, 'sharedPublic=true&' ) return cals._embedded?.['dav:calendar'] ? cals._embedded['dav:calendar'].map(cal => ({ cal, owner: user })) : { cal: undefined, owner: user } } return null }) ) setSelectedCalendars( cals.flat().filter(Boolean) as CalendarWithOwner[] ) }} /> { if (!cal.cal?._links?.self?.href) return setSelectedCalendars(prev => prev.filter( c => c.cal?._links?.self?.href !== cal.cal._links.self?.href ) ) if ( !selectedCal.find( c => cal.owner.email === c.owner.email && c.cal?._links?.self?.href !== cal.cal._links.self?.href ) ) { setSelectedUsers(prev => prev.filter(u => u.email !== cal.owner.email) ) } }} onColorChange={(cal, color) => setSelectedCalendars(prev => prev.map(prevcal => prevcal.owner.email === cal.owner.email && prevcal.cal._links.self?.href === cal.cal._links.self?.href ? { ...prevcal, cal: { ...prevcal.cal, 'apple:color': color.light } } : prevcal ) ) } /> ) }