Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
@@ -15,7 +15,7 @@ export default function UserSearch({
|
||||
placeholder,
|
||||
}: {
|
||||
attendees: userAttendee[];
|
||||
setAttendees: Function;
|
||||
setAttendees: (attendees: userAttendee[]) => void;
|
||||
disabled?: boolean;
|
||||
inputSlot?: (
|
||||
params: ExtendedAutocompleteRenderInputParams
|
||||
@@ -47,7 +47,7 @@ export default function UserSearch({
|
||||
disabled={disabled}
|
||||
inputSlot={inputSlot}
|
||||
placeholder={placeholder}
|
||||
onChange={(event: any, value: User[]) => {
|
||||
onChange={(_event, value: User[]) => {
|
||||
setAttendees(
|
||||
value.map((attendee: User) =>
|
||||
createAttendee({
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
useEffect,
|
||||
useState,
|
||||
type ReactNode,
|
||||
type SyntheticEvent,
|
||||
} from "react";
|
||||
import { useI18n } from "twake-i18n";
|
||||
|
||||
@@ -55,7 +56,7 @@ export function PeopleSearch({
|
||||
customSlotProps,
|
||||
}: {
|
||||
selectedUsers: User[];
|
||||
onChange: (event: any, users: User[]) => void;
|
||||
onChange: (event: SyntheticEvent, users: User[]) => void;
|
||||
objectTypes: string[];
|
||||
disabled?: boolean;
|
||||
freeSolo?: boolean;
|
||||
@@ -155,7 +156,7 @@ export function PeopleSearch({
|
||||
),
|
||||
};
|
||||
|
||||
const enhancedParamsWithInputProps = {
|
||||
const enhancedParams = {
|
||||
...params,
|
||||
InputProps: inputProps,
|
||||
inputProps: {
|
||||
@@ -164,8 +165,6 @@ export function PeopleSearch({
|
||||
},
|
||||
};
|
||||
|
||||
const { InputProps, ...enhancedParams } = enhancedParamsWithInputProps;
|
||||
|
||||
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "Enter" && onToggleEventPreview) {
|
||||
e.preventDefault();
|
||||
@@ -193,7 +192,7 @@ export function PeopleSearch({
|
||||
{t("peopleSearch.label")}
|
||||
</label>
|
||||
{inputSlot({
|
||||
...enhancedParamsWithInputProps,
|
||||
...enhancedParams,
|
||||
error: !!inputError,
|
||||
helperText: inputError,
|
||||
placeholder: searchPlaceholder,
|
||||
@@ -218,6 +217,7 @@ export function PeopleSearch({
|
||||
</>
|
||||
);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[inputError, t, onToggleEventPreview, loading, searchPlaceholder]
|
||||
);
|
||||
|
||||
@@ -296,7 +296,7 @@ export function PeopleSearch({
|
||||
}
|
||||
renderOption={(props, option) => {
|
||||
if (selectedUsers.find((u) => u.email === option.email)) return null;
|
||||
const { key, ...otherProps } = props as any;
|
||||
const { key, ...otherProps } = props;
|
||||
return (
|
||||
<ListItem key={key + option?.email} {...otherProps} disableGutters>
|
||||
<ListItemAvatar>
|
||||
|
||||
@@ -22,7 +22,7 @@ import { SnackbarAlert } from "../Loading/SnackBarAlert";
|
||||
|
||||
export function AccessTab({ calendar }: { calendar: Calendar }) {
|
||||
const { t } = useI18n();
|
||||
const calDAVLink = `${(window as any).CALENDAR_BASE_URL}${calendar.link.replace(".json", "")}`;
|
||||
const calDAVLink = `${window.CALENDAR_BASE_URL}${calendar.link.replace(".json", "")}`;
|
||||
|
||||
const [secretLink, setSecretLink] = useState("");
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -15,6 +15,7 @@ import { extractEventBaseUuid } from "@/utils/extractEventBaseUuid";
|
||||
import { setSelectedCalendars as setSelectedCalendarsToStorage } from "@/utils/storage/setSelectedCalendars";
|
||||
import { useSelectedCalendars } from "@/utils/storage/useSelectedCalendars";
|
||||
import { browserDefaultTimeZone } from "@/utils/timezone";
|
||||
import type { EventApi, LocaleInput } from "@fullcalendar/core";
|
||||
import { CalendarApi, DateSelectArg } from "@fullcalendar/core";
|
||||
import frLocale from "@fullcalendar/core/locales/fr";
|
||||
import ruLocale from "@fullcalendar/core/locales/ru";
|
||||
@@ -47,7 +48,7 @@ import {
|
||||
updateSlotLabelVisibility,
|
||||
} from "./utils/calendarUtils";
|
||||
|
||||
const localeMap: Record<string, any> = {
|
||||
const localeMap: Record<string, LocaleInput | undefined> = {
|
||||
fr: frLocale,
|
||||
ru: ruLocale,
|
||||
vi: viLocale,
|
||||
@@ -221,7 +222,7 @@ export default function CalendarApp({
|
||||
[rangeStart, rangeEnd]
|
||||
);
|
||||
|
||||
let filteredEvents: CalendarEvent[] = extractEvents(
|
||||
const filteredEvents: CalendarEvent[] = extractEvents(
|
||||
selectedCalendars,
|
||||
calendars || {},
|
||||
userData?.email,
|
||||
@@ -233,7 +234,7 @@ export default function CalendarApp({
|
||||
[tempcalendars]
|
||||
);
|
||||
|
||||
let filteredTempEvents: CalendarEvent[] = extractEvents(
|
||||
const filteredTempEvents: CalendarEvent[] = extractEvents(
|
||||
tempCalendarIds,
|
||||
tempcalendars || {},
|
||||
userData?.email,
|
||||
@@ -303,7 +304,7 @@ export default function CalendarApp({
|
||||
},
|
||||
})
|
||||
).unwrap();
|
||||
} catch (error) {
|
||||
} catch {
|
||||
fetchedRangesRef.current[id] = "";
|
||||
}
|
||||
});
|
||||
@@ -323,6 +324,7 @@ export default function CalendarApp({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dispatch, rangeKey, sortedSelectedCalendars, rangeStart, rangeEnd]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -352,6 +354,7 @@ export default function CalendarApp({
|
||||
prefetchedCalendarsRef.current[id] = "";
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [
|
||||
calendarIdsString,
|
||||
selectedCalendars,
|
||||
@@ -458,7 +461,7 @@ export default function CalendarApp({
|
||||
calType: "temp",
|
||||
})
|
||||
).unwrap();
|
||||
} catch (error) {
|
||||
} catch {
|
||||
tempFetchedRangesRef.current[id] = "";
|
||||
}
|
||||
});
|
||||
@@ -521,7 +524,7 @@ export default function CalendarApp({
|
||||
})
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
} catch {
|
||||
// Ignore sessionStorage errors
|
||||
}
|
||||
}
|
||||
@@ -543,10 +546,10 @@ export default function CalendarApp({
|
||||
null
|
||||
);
|
||||
const [, setTypeOfAction] = useState<"solo" | "all" | undefined>(undefined);
|
||||
const [afterChoiceFunc, setAfterChoiceFunc] = useState<Function>();
|
||||
const [selectedEvent, setSelectedEvent] = useState<CalendarEvent>(
|
||||
{} as CalendarEvent
|
||||
);
|
||||
const [afterChoiceFunc, setAfterChoiceFunc] = useState<
|
||||
((type: "solo" | "all" | undefined) => void) | undefined
|
||||
>();
|
||||
const [, setSelectedEvent] = useState<CalendarEvent>({} as CalendarEvent);
|
||||
const [selectedRange, setSelectedRange] = useState<DateSelectArg | null>(
|
||||
null
|
||||
);
|
||||
@@ -587,7 +590,7 @@ export default function CalendarApp({
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV === "test") {
|
||||
(window as any).__calendarRef = calendarRef;
|
||||
window.__calendarRef = calendarRef;
|
||||
}
|
||||
|
||||
const { t, lang } = useI18n();
|
||||
@@ -635,7 +638,6 @@ export default function CalendarApp({
|
||||
<MiniCalendar
|
||||
calendarRef={calendarRef}
|
||||
selectedDate={selectedMiniDate}
|
||||
setSelectedDate={setSelectedDate}
|
||||
setSelectedMiniDate={setSelectedMiniDate}
|
||||
dottedEvents={dottedEvents}
|
||||
/>
|
||||
@@ -697,7 +699,7 @@ export default function CalendarApp({
|
||||
userData?.email,
|
||||
isPending
|
||||
)}
|
||||
eventOrder={(a: any, b: any) =>
|
||||
eventOrder={(a: EventApi, b: EventApi) =>
|
||||
a.extendedProps.priority - b.extendedProps.priority
|
||||
}
|
||||
weekNumbers={
|
||||
@@ -825,10 +827,11 @@ export default function CalendarApp({
|
||||
<EditModeDialog
|
||||
type={openEditModePopup}
|
||||
setOpen={setOpenEditModePopup}
|
||||
event={selectedEvent}
|
||||
eventAction={(type: "solo" | "all" | undefined) => {
|
||||
setTypeOfAction(type);
|
||||
afterChoiceFunc && afterChoiceFunc(type);
|
||||
if (afterChoiceFunc) {
|
||||
afterChoiceFunc(type);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{openEventDisplay && eventDisplayedId && eventDisplayedCalId && (
|
||||
|
||||
@@ -123,11 +123,11 @@ function ColorPickerBox({
|
||||
selectedColor ?? { light: "#ffffff", dark: "#808080" }
|
||||
);
|
||||
const [color, setColor] = useState(oldColor);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
||||
const open = Boolean(anchorEl);
|
||||
const theme = useTheme();
|
||||
|
||||
const handleClick = (event: any) => {
|
||||
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useAppDispatch, useAppSelector } from "@/app/hooks";
|
||||
import SettingsPage from "@/features/Settings/SettingsPage";
|
||||
import { getCalendarRange } from "@/utils/dateUtils";
|
||||
import type { CalendarApi } from "@fullcalendar/core";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { ErrorSnackbar } from "../Error/ErrorSnackbar";
|
||||
import { refreshCalendars } from "../Event/utils/eventUtils";
|
||||
@@ -8,7 +9,7 @@ import { Menubar, MenubarProps } from "../Menubar/Menubar";
|
||||
import CalendarApp from "./Calendar";
|
||||
|
||||
export default function CalendarLayout() {
|
||||
const calendarRef = useRef<any>(null);
|
||||
const calendarRef = useRef<CalendarApi | null>(null);
|
||||
const dispatch = useAppDispatch();
|
||||
const error = useAppSelector((state) => state.calendars.error);
|
||||
const selectedCalendars = useAppSelector((state) => state.calendars.list);
|
||||
|
||||
@@ -138,28 +138,30 @@ function CalendarPopover({
|
||||
newCalColor,
|
||||
newCalVisibility
|
||||
);
|
||||
importedContent &&
|
||||
if (importedContent) {
|
||||
dispatch(
|
||||
importEventFromFileAsync({
|
||||
calLink: `/calendar/${userData.openpaasId}/${calId}.json`,
|
||||
file: importedContent,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
importedContent &&
|
||||
if (importedContent) {
|
||||
dispatch(
|
||||
importEventFromFileAsync({
|
||||
calLink: calendars[importTarget].link,
|
||||
file: importedContent,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
handleClose({}, "backdropClick");
|
||||
};
|
||||
|
||||
const handleClose = (
|
||||
e: {},
|
||||
e: object | null,
|
||||
reason: "backdropClick" | "escapeKeyDown"
|
||||
): void => {
|
||||
onClose(e, reason);
|
||||
@@ -182,7 +184,7 @@ function CalendarPopover({
|
||||
open={open}
|
||||
onClose={() => handleClose({}, "backdropClick")}
|
||||
title={
|
||||
<Tabs value={tab} onChange={(e, v) => setTab(v)}>
|
||||
<Tabs value={tab} onChange={(_e, v) => setTab(v)}>
|
||||
<Tab
|
||||
value="settings"
|
||||
label={
|
||||
@@ -203,7 +205,7 @@ function CalendarPopover({
|
||||
<>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={(e) => handleClose({}, "backdropClick")}
|
||||
onClick={() => handleClose({}, "backdropClick")}
|
||||
>
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -21,7 +21,7 @@ import { ColorPicker } from "./CalendarColorPicker";
|
||||
import { defaultColors, getAccessiblePair } from "./utils/calendarColorsUtils";
|
||||
|
||||
interface CalendarWithOwner {
|
||||
cal: Record<string, any>;
|
||||
cal: Record<string, unknown>;
|
||||
owner: User;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ function SelectedCalendarsList({
|
||||
>
|
||||
>((acc, cal) => {
|
||||
const exists = Object.values(calendars).some(
|
||||
(existing: any) =>
|
||||
(existing: Calendar) =>
|
||||
existing.id ===
|
||||
cal.cal?._links?.self?.href
|
||||
.replace("/calendars/", "")
|
||||
@@ -190,13 +190,14 @@ function SelectedCalendarsList({
|
||||
}
|
||||
|
||||
export default function CalendarSearch({
|
||||
anchorEl,
|
||||
open,
|
||||
onClose,
|
||||
}: {
|
||||
anchorEl: HTMLElement | null;
|
||||
open: boolean;
|
||||
onClose: Function;
|
||||
onClose: (
|
||||
result?: string[] | Record<string, never>,
|
||||
reason?: "backdropClick" | "escapeKeyDown"
|
||||
) => void;
|
||||
}) {
|
||||
const dispatch = useAppDispatch();
|
||||
const theme = useTheme();
|
||||
@@ -214,7 +215,7 @@ export default function CalendarSearch({
|
||||
selectedCal.map(async (cal) => {
|
||||
const calId = crypto.randomUUID();
|
||||
const exists = Object.values(calendars).some(
|
||||
(existing: any) =>
|
||||
(existing: Calendar) =>
|
||||
existing.id ===
|
||||
cal.cal?._links?.self?.href
|
||||
.replace("/calendars/", "")
|
||||
@@ -279,7 +280,7 @@ export default function CalendarSearch({
|
||||
objectTypes={["user"]}
|
||||
selectedUsers={selectedUsers}
|
||||
inputSlot={(params) => <TextField {...params} size="small" />}
|
||||
onChange={async (event: any, value: User[]) => {
|
||||
onChange={async (_event: React.SyntheticEvent, value: User[]) => {
|
||||
setSelectedUsers(value);
|
||||
|
||||
const cals = await Promise.all(
|
||||
@@ -288,10 +289,10 @@ export default function CalendarSearch({
|
||||
const cals = (await getCalendars(
|
||||
user.openpaasId,
|
||||
"sharedPublic=true&"
|
||||
)) as Record<string, any>;
|
||||
)) as Record<string, unknown>;
|
||||
return cals._embedded?.["dav:calendar"]
|
||||
? cals._embedded["dav:calendar"].map(
|
||||
(cal: Record<string, any>) => ({ cal, owner: user })
|
||||
(cal: Record<string, unknown>) => ({ cal, owner: user })
|
||||
)
|
||||
: { cal: undefined, owner: user };
|
||||
}
|
||||
|
||||
@@ -13,12 +13,11 @@ import {
|
||||
ListItem,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Typography,
|
||||
} from "@linagora/twake-mui";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { SetStateAction, useEffect, useMemo, useState } from "react";
|
||||
import { useI18n } from "twake-i18n";
|
||||
import CalendarPopover from "./CalendarModal";
|
||||
import CalendarSearch from "./CalendarSearch";
|
||||
@@ -39,9 +38,9 @@ function CalendarAccordion({
|
||||
selectedCalendars: string[];
|
||||
handleToggle: (id: string) => void;
|
||||
showAddButton?: boolean;
|
||||
onAddClick?: Function;
|
||||
onAddClick?: () => void;
|
||||
defaultExpanded?: boolean;
|
||||
setOpen: Function;
|
||||
setOpen: (id: string) => void;
|
||||
}) {
|
||||
const allCalendars = useAppSelector((state) => state.calendars.list);
|
||||
const { t } = useI18n();
|
||||
@@ -86,8 +85,12 @@ function CalendarAccordion({
|
||||
<IconButton
|
||||
component="span"
|
||||
onClick={(e) => {
|
||||
expended && e.stopPropagation();
|
||||
onAddClick && onAddClick();
|
||||
if (expended) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (onAddClick) {
|
||||
onAddClick();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AddIcon />
|
||||
@@ -116,7 +119,7 @@ export default function CalendarSelection({
|
||||
setSelectedCalendars,
|
||||
}: {
|
||||
selectedCalendars: string[];
|
||||
setSelectedCalendars: Function;
|
||||
setSelectedCalendars: (value: SetStateAction<string[]>) => void;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const userId =
|
||||
@@ -202,7 +205,6 @@ export default function CalendarSelection({
|
||||
}}
|
||||
/>
|
||||
<CalendarSearch
|
||||
anchorEl={anchorElCalOthers}
|
||||
open={Boolean(anchorElCalOthers)}
|
||||
onClose={(newCalIds?: string[]) => {
|
||||
setAnchorElCalOthers(null);
|
||||
@@ -228,7 +230,7 @@ function CalendarSelector({
|
||||
isPersonal: boolean;
|
||||
selectedCalendars: string[];
|
||||
handleCalendarToggle: (name: string) => void;
|
||||
setOpen: Function;
|
||||
setOpen: () => void;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
@@ -24,21 +24,21 @@ export function ImportTab({
|
||||
}: {
|
||||
userId: string;
|
||||
importTarget: string;
|
||||
setImportTarget: Function;
|
||||
setImportedContent: Function;
|
||||
setImportTarget: (target: string) => void;
|
||||
setImportedContent: (content: File | null) => void;
|
||||
newCalParams: {
|
||||
name: string;
|
||||
setName: Function;
|
||||
setName: (name: string) => void;
|
||||
description: string;
|
||||
setDescription: (d: string) => void;
|
||||
color: Record<string, string>;
|
||||
setColor: Function;
|
||||
setColor: (color: Record<string, string>) => void;
|
||||
visibility: "public" | "private";
|
||||
setVisibility: Function;
|
||||
setVisibility: (visibility: "public" | "private") => void;
|
||||
};
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const [importMode, setImportMode] = useState<"file" | "url">("file");
|
||||
const [importMode] = useState<"file" | "url">("file");
|
||||
const [importFile, setImportFile] = useState<File | null>(null);
|
||||
const [importUrl, setImportUrl] = useState("");
|
||||
const calendars = useAppSelector((state) => state.calendars.list);
|
||||
@@ -48,7 +48,7 @@ export function ImportTab({
|
||||
|
||||
useEffect(() => {
|
||||
setImportedContent(importMode === "file" ? importFile : null);
|
||||
}, [importFile, importUrl, importMode]);
|
||||
}, [importFile, importUrl, importMode, setImportedContent]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -13,19 +13,20 @@ import moment from "moment";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useI18n } from "twake-i18n";
|
||||
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||
import type { CalendarApi } from "@fullcalendar/core";
|
||||
|
||||
export function MiniCalendar({
|
||||
calendarRef,
|
||||
selectedDate,
|
||||
setSelectedDate,
|
||||
|
||||
setSelectedMiniDate,
|
||||
dottedEvents,
|
||||
}: {
|
||||
calendarRef: any;
|
||||
calendarRef: React.MutableRefObject<CalendarApi | null>;
|
||||
selectedDate: Date;
|
||||
setSelectedDate: (d: Date) => void;
|
||||
setSelectedMiniDate: (d: Date) => void;
|
||||
dottedEvents: any[];
|
||||
dottedEvents: CalendarEvent[];
|
||||
}) {
|
||||
const dispatch = useAppDispatch();
|
||||
const calendars = useAppSelector((state) => state.calendars);
|
||||
|
||||
@@ -27,13 +27,13 @@ export function SettingsTab({
|
||||
calendar,
|
||||
}: {
|
||||
name: string;
|
||||
setName: Function;
|
||||
setName: (name: string) => void;
|
||||
description: string;
|
||||
setDescription: (d: string) => void;
|
||||
color: Record<string, string>;
|
||||
setColor: Function;
|
||||
setColor: (color: Record<string, string>) => void;
|
||||
visibility: "public" | "private";
|
||||
setVisibility: Function;
|
||||
setVisibility: (visibility: "public" | "private") => void;
|
||||
calendar?: Calendar;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -22,7 +22,7 @@ export function TempCalendarsInput({
|
||||
setTempUsers: (users: User[]) => void;
|
||||
handleToggleEventPreview: () => void;
|
||||
selectedCalendars: string[];
|
||||
setSelectedCalendars: Function;
|
||||
setSelectedCalendars: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
}) {
|
||||
const dispatch = useAppDispatch();
|
||||
const tempcalendars =
|
||||
@@ -34,7 +34,7 @@ export function TempCalendarsInput({
|
||||
const prevUsersRef = useRef<User[]>([]);
|
||||
const userColorsRef = useRef(new Map<string, string>());
|
||||
|
||||
const handleUserChange = async (_: any, users: User[]) => {
|
||||
const handleUserChange = async (_: React.SyntheticEvent, users: User[]) => {
|
||||
setTempUsers(users);
|
||||
|
||||
const prevUsers = prevUsersRef.current;
|
||||
|
||||
@@ -13,7 +13,12 @@ import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||
import { userAttendee } from "@/features/User/models/attendee";
|
||||
import { createAttendee } from "@/features/User/models/attendee.mapper";
|
||||
import { getDeltaInMilliseconds } from "@/utils/dateUtils";
|
||||
import { CalendarApi, DateSelectArg, EventDropArg } from "@fullcalendar/core";
|
||||
import {
|
||||
CalendarApi,
|
||||
DateSelectArg,
|
||||
EventClickArg,
|
||||
EventDropArg,
|
||||
} from "@fullcalendar/core";
|
||||
import { EventResizeDoneArg } from "@fullcalendar/interaction";
|
||||
|
||||
export interface EventHandlersProps {
|
||||
@@ -27,7 +32,9 @@ export interface EventHandlersProps {
|
||||
setEventDisplayedTemp: (temp: boolean) => void;
|
||||
calendars: Record<string, Calendar>;
|
||||
setSelectedEvent: (event: CalendarEvent) => void;
|
||||
setAfterChoiceFunc: (func: Function) => void;
|
||||
setAfterChoiceFunc: (
|
||||
func: ((type: "solo" | "all" | undefined) => void) | undefined
|
||||
) => void;
|
||||
setOpenEditModePopup: (open: string) => void;
|
||||
tempUsers: User[];
|
||||
setTempEvent: (event: CalendarEvent) => void;
|
||||
@@ -87,7 +94,7 @@ export const createEventHandlers = (props: EventHandlersProps) => {
|
||||
setOpenEventDisplay(false);
|
||||
};
|
||||
|
||||
const handleEventClick = (info: any) => {
|
||||
const handleEventClick = (info: EventClickArg) => {
|
||||
info.jsEvent.preventDefault();
|
||||
|
||||
if (info.event.url) {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
interface CalendarHTMLElement extends HTMLElement {
|
||||
__calendarMouseMoveHandler?: (e: MouseEvent) => void;
|
||||
__calendarMouseLeaveHandler?: () => void;
|
||||
}
|
||||
export interface MouseHandlersProps {
|
||||
calendarEl: HTMLElement;
|
||||
calendarEl: CalendarHTMLElement;
|
||||
}
|
||||
|
||||
export const createMouseHandlers = (props: MouseHandlersProps) => {
|
||||
@@ -75,24 +79,24 @@ export const createMouseHandlers = (props: MouseHandlersProps) => {
|
||||
calendarEl.addEventListener("mousemove", handleMouseMove);
|
||||
calendarEl.addEventListener("mouseleave", handleMouseLeave);
|
||||
|
||||
(calendarEl as any).__calendarMouseMoveHandler = handleMouseMove;
|
||||
(calendarEl as any).__calendarMouseLeaveHandler = handleMouseLeave;
|
||||
calendarEl.__calendarMouseMoveHandler = handleMouseMove;
|
||||
calendarEl.__calendarMouseLeaveHandler = handleMouseLeave;
|
||||
};
|
||||
|
||||
const removeMouseEventListeners = () => {
|
||||
if ((calendarEl as any).__calendarMouseMoveHandler) {
|
||||
if (calendarEl.__calendarMouseMoveHandler) {
|
||||
calendarEl.removeEventListener(
|
||||
"mousemove",
|
||||
(calendarEl as any).__calendarMouseMoveHandler
|
||||
calendarEl.__calendarMouseMoveHandler
|
||||
);
|
||||
delete (calendarEl as any).__calendarMouseMoveHandler;
|
||||
delete calendarEl.__calendarMouseMoveHandler;
|
||||
}
|
||||
if ((calendarEl as any).__calendarMouseLeaveHandler) {
|
||||
if (calendarEl.__calendarMouseLeaveHandler) {
|
||||
calendarEl.removeEventListener(
|
||||
"mouseleave",
|
||||
(calendarEl as any).__calendarMouseLeaveHandler
|
||||
calendarEl.__calendarMouseLeaveHandler
|
||||
);
|
||||
delete (calendarEl as any).__calendarMouseLeaveHandler;
|
||||
delete calendarEl.__calendarMouseLeaveHandler;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,14 @@ import { EventErrorHandler } from "@/components/Error/EventErrorHandler";
|
||||
import { EventChip } from "@/components/Event/EventChip/EventChip";
|
||||
import { Calendar } from "@/features/Calendars/CalendarTypes";
|
||||
import { userAttendee } from "@/features/User/models/attendee";
|
||||
import { CalendarApi, NowIndicatorContentArg } from "@fullcalendar/core";
|
||||
import {
|
||||
CalendarApi,
|
||||
DayHeaderMountArg,
|
||||
EventContentArg,
|
||||
EventMountArg,
|
||||
NowIndicatorContentArg,
|
||||
ViewMountArg,
|
||||
} from "@fullcalendar/core";
|
||||
import React from "react";
|
||||
import { createMouseHandlers } from "./mouseHandlers";
|
||||
|
||||
@@ -46,7 +53,7 @@ export const createViewHandlers = (props: ViewHandlersProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDayHeaderDidMount = (arg: any) => {
|
||||
const handleDayHeaderDidMount = (arg: DayHeaderMountArg) => {
|
||||
if (arg.view.type === "timeGridWeek") {
|
||||
const headerEl = arg.el;
|
||||
|
||||
@@ -61,22 +68,19 @@ export const createViewHandlers = (props: ViewHandlersProps) => {
|
||||
};
|
||||
|
||||
headerEl.addEventListener("click", handleDayHeaderClick);
|
||||
(headerEl as any).__dayHeaderClickHandler = handleDayHeaderClick;
|
||||
headerEl.__dayHeaderClickHandler = handleDayHeaderClick;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDayHeaderWillUnmount = (arg: any) => {
|
||||
const handleDayHeaderWillUnmount = (arg: DayHeaderMountArg) => {
|
||||
const headerEl = arg.el;
|
||||
if ((headerEl as any).__dayHeaderClickHandler) {
|
||||
headerEl.removeEventListener(
|
||||
"click",
|
||||
(headerEl as any).__dayHeaderClickHandler
|
||||
);
|
||||
delete (headerEl as any).__dayHeaderClickHandler;
|
||||
if (headerEl.__dayHeaderClickHandler) {
|
||||
headerEl.removeEventListener("click", headerEl.__dayHeaderClickHandler);
|
||||
delete headerEl.__dayHeaderClickHandler;
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewDidMount = (arg: any) => {
|
||||
const handleViewDidMount = (arg: ViewMountArg) => {
|
||||
if (arg.view.type === "timeGridWeek" || arg.view.type === "timeGridDay") {
|
||||
const calendarEl = document.querySelector(".fc") as HTMLElement;
|
||||
if (calendarEl) {
|
||||
@@ -86,15 +90,15 @@ export const createViewHandlers = (props: ViewHandlersProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewWillUnmount = (arg: any) => {
|
||||
if ((arg.el as any).__timeInterval) {
|
||||
clearInterval((arg.el as any).__timeInterval);
|
||||
delete (arg.el as any).__timeInterval;
|
||||
const handleViewWillUnmount = (arg: ViewMountArg) => {
|
||||
if (arg.el.__timeInterval) {
|
||||
clearInterval(arg.el.__timeInterval);
|
||||
delete arg.el.__timeInterval;
|
||||
}
|
||||
|
||||
if ((arg.el as any).__timeObserver) {
|
||||
(arg.el as any).__timeObserver.disconnect();
|
||||
delete (arg.el as any).__timeObserver;
|
||||
if (arg.el.__timeObserver) {
|
||||
arg.el.__timeObserver.disconnect();
|
||||
delete arg.el.__timeObserver;
|
||||
}
|
||||
|
||||
const calendarEl = document.querySelector(".fc") as HTMLElement;
|
||||
@@ -104,7 +108,7 @@ export const createViewHandlers = (props: ViewHandlersProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleEventContent = (arg: any) => {
|
||||
const handleEventContent = (arg: EventContentArg) => {
|
||||
return React.createElement(EventChip, {
|
||||
arg,
|
||||
calendars,
|
||||
@@ -113,7 +117,7 @@ export const createViewHandlers = (props: ViewHandlersProps) => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleEventDidMount = (arg: any) => {
|
||||
const handleEventDidMount = (arg: EventMountArg) => {
|
||||
const attendees = arg.event._def.extendedProps.attendee || [];
|
||||
if (!calendars[arg.event._def.extendedProps.calId]) return;
|
||||
const ownerEmails = new Set(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useCallback } from "react";
|
||||
import {
|
||||
createEventHandlers,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useCallback } from "react";
|
||||
import {
|
||||
createViewHandlers,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { refreshSingularCalendar } from "@/components/Event/utils/eventUtils";
|
||||
import { AppDispatch } from "@/app/store";
|
||||
import { Calendar } from "@/features/Calendars/CalendarTypes";
|
||||
import { getCalendarDetailAsync } from "@/features/Calendars/services";
|
||||
import { AclEntry } from "@/features/Calendars/types/CalendarData";
|
||||
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||
import { formatDateToYYYYMMDDTHHMMSS } from "@/utils/dateUtils";
|
||||
import { extractEventBaseUuid } from "@/utils/extractEventBaseUuid";
|
||||
import { convertEventDateTimeToISO } from "@/utils/timezone";
|
||||
import { SlotLabelContentArg } from "@fullcalendar/core";
|
||||
import { ThunkDispatch } from "@reduxjs/toolkit";
|
||||
import moment from "moment-timezone";
|
||||
import { useI18n } from "twake-i18n";
|
||||
|
||||
@@ -56,7 +56,10 @@ export const checkIfCurrentWeekOrDay = (): boolean => {
|
||||
return !!nowIndicator;
|
||||
};
|
||||
|
||||
export function formatEventChipTitle(e: CalendarEvent, t: Function) {
|
||||
export function formatEventChipTitle(
|
||||
e: CalendarEvent,
|
||||
t: (key: string) => string
|
||||
) {
|
||||
if (!e.title) {
|
||||
return t("event.untitled");
|
||||
}
|
||||
@@ -72,6 +75,7 @@ export const eventToFullCalendarFormat = (
|
||||
userAddress: string | undefined,
|
||||
pending: boolean
|
||||
) => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { t } = useI18n();
|
||||
return filteredEvents
|
||||
.concat(filteredTempEvents.map((e) => ({ ...e, temp: true })))
|
||||
@@ -83,7 +87,11 @@ export const eventToFullCalendarFormat = (
|
||||
: true; // if there are no organizer in the event we assume it was organized by the owner
|
||||
const isPersonnalEvent =
|
||||
extractEventBaseUuid(e.calId) === userId && isOrganiser;
|
||||
const convertedEvent: any = {
|
||||
const convertedEvent: CalendarEvent & {
|
||||
colors: Record<string, string> | undefined;
|
||||
editable: boolean;
|
||||
priority: number;
|
||||
} = {
|
||||
...e,
|
||||
title: formatEventChipTitle(e, t),
|
||||
colors: e.color,
|
||||
@@ -147,7 +155,7 @@ export const updateCalsDetails = (
|
||||
pending: boolean,
|
||||
rangeKey: string,
|
||||
previousRangeKey: string,
|
||||
dispatch: Function,
|
||||
dispatch: AppDispatch,
|
||||
calendarRange: { start: Date; end: Date },
|
||||
calType?: "temp",
|
||||
controllers?: Map<string, AbortController>
|
||||
@@ -223,15 +231,9 @@ export const updateCalsDetails = (
|
||||
}
|
||||
};
|
||||
|
||||
interface AclEntry {
|
||||
privilege: string;
|
||||
principal: string;
|
||||
protected: boolean;
|
||||
}
|
||||
|
||||
export function getCalendarVisibility(acl: AclEntry[]): "private" | "public" {
|
||||
let hasRead = false;
|
||||
let hasFreeBusy = false;
|
||||
// const hasFreeBusy = false;
|
||||
if (acl) {
|
||||
for (const entry of acl) {
|
||||
if (entry.principal !== "{DAV:}authenticated") continue;
|
||||
|
||||
@@ -158,7 +158,7 @@ function ResponsiveDialog({
|
||||
}, [isExpanded]);
|
||||
|
||||
const handleClose = (
|
||||
event: {},
|
||||
event: unknown,
|
||||
reason: "backdropClick" | "escapeKeyDown"
|
||||
) => {
|
||||
if (isExpanded && reason === "backdropClick") {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
@@ -16,12 +15,10 @@ import { useI18n } from "twake-i18n";
|
||||
export function EditModeDialog({
|
||||
type,
|
||||
setOpen,
|
||||
event,
|
||||
eventAction,
|
||||
}: {
|
||||
type: string | null;
|
||||
setOpen: (e: string | null) => void;
|
||||
event: CalendarEvent;
|
||||
eventAction: (type: "solo" | "all" | undefined) => void;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EventErrorHandler } from "@/components/Error/EventErrorHandler";
|
||||
import { EventContentArg } from "@fullcalendar/core";
|
||||
import { Card, Typography } from "@linagora/twake-mui";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
@@ -7,18 +8,30 @@ export function ErrorEventChip({
|
||||
errorHandler,
|
||||
error,
|
||||
}: {
|
||||
event: any;
|
||||
event: EventContentArg["event"];
|
||||
errorHandler: EventErrorHandler;
|
||||
error: any;
|
||||
error: unknown;
|
||||
}) {
|
||||
const hasReported = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasReported.current) {
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: `${error.class} error during rendering ${event._def.extendedProps.uid || event.id}`;
|
||||
let message: string;
|
||||
|
||||
if (error instanceof Error) {
|
||||
message = error.message;
|
||||
} else if (
|
||||
typeof error === "object" &&
|
||||
error !== null &&
|
||||
"class" in error
|
||||
) {
|
||||
message = `${String(
|
||||
(error as { class: string }).class
|
||||
)} error during rendering ${event._def.extendedProps.uid || event.id}`;
|
||||
} else {
|
||||
message = `Unknown error during rendering ${event._def.extendedProps.uid || event.id}`;
|
||||
}
|
||||
|
||||
errorHandler.reportError(
|
||||
event._def.extendedProps.uid || event.id,
|
||||
message
|
||||
|
||||
@@ -59,7 +59,7 @@ export function EventChip({
|
||||
const ownerEmails = new Set(
|
||||
calendar.ownerEmails?.map((e) => e.toLowerCase())
|
||||
);
|
||||
const delegated = calendar.delegated;
|
||||
// const delegated = calendar.delegated;
|
||||
|
||||
// Determine owner attendee
|
||||
const ownerAttendee = getOwnerAttendee(attendees, ownerEmails);
|
||||
@@ -258,7 +258,7 @@ export function EventChip({
|
||||
!event._def.extendedProps.allday &&
|
||||
event._def.extendedProps.organizer &&
|
||||
!showCompact &&
|
||||
(window as any).displayOrgAvatar && (
|
||||
window.displayOrgAvatar && (
|
||||
<Avatar
|
||||
children={OrganizerAvatar.children}
|
||||
color={OrganizerAvatar.color}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { EventErrorHandler } from "@/components/Error/EventErrorHandler";
|
||||
import { Calendar } from "@/features/Calendars/CalendarTypes";
|
||||
import { userAttendee } from "@/features/User/models/attendee";
|
||||
import { EventContentArg } from "@fullcalendar/core";
|
||||
import { getContrastRatio } from "@linagora/twake-mui";
|
||||
import CancelIcon from "@mui/icons-material/Cancel";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
@@ -12,7 +13,7 @@ import { EVENT_DURATION } from "./EventChip";
|
||||
const COMPACT_WIDTH_THRESHOLD = 100;
|
||||
|
||||
export interface EventChipProps {
|
||||
arg: any;
|
||||
arg: EventContentArg["event"];
|
||||
calendars: Record<string, Calendar>;
|
||||
tempcalendars: Record<string, Calendar>;
|
||||
errorHandler: EventErrorHandler;
|
||||
@@ -23,9 +24,9 @@ export interface IconDisplayConfig {
|
||||
needAction: boolean;
|
||||
private: boolean;
|
||||
}
|
||||
export function getEventDuration(event: any): number {
|
||||
return moment(event._instance.range.end).diff(
|
||||
moment(event._instance.range.start),
|
||||
export function getEventDuration(event: EventContentArg["event"]): number {
|
||||
return moment(event._instance?.range.end).diff(
|
||||
moment(event._instance?.range.start),
|
||||
"minutes"
|
||||
);
|
||||
}
|
||||
@@ -34,7 +35,10 @@ export function getBestColor(colors: { light: string; dark: string }): string {
|
||||
const contrastToLight = getContrastRatio(colors?.light, "#fff");
|
||||
return contrastToDark > contrastToLight ? colors?.dark : colors?.light;
|
||||
}
|
||||
export function getEventTimes(event: any, timeZone: string) {
|
||||
export function getEventTimes(
|
||||
event: EventContentArg["event"],
|
||||
timeZone: string
|
||||
) {
|
||||
return {
|
||||
startTime: moment.tz(event.start, timeZone).format("HH:mm"),
|
||||
endTime: moment.tz(event.end, timeZone).format("HH:mm"),
|
||||
@@ -52,7 +56,7 @@ export function getOwnerAttendee(
|
||||
export function getTitleStyle(
|
||||
bestColor: string,
|
||||
partstat?: string,
|
||||
calendar?: any
|
||||
calendar?: Calendar
|
||||
): React.CSSProperties {
|
||||
const baseStyle: React.CSSProperties = {
|
||||
fontFamily: "Roboto",
|
||||
@@ -122,7 +126,7 @@ export function getCardStyle(
|
||||
bestColor: string,
|
||||
eventLength: number,
|
||||
partstat?: string,
|
||||
calendar?: any
|
||||
calendar?: Calendar
|
||||
): React.CSSProperties {
|
||||
const baseStyle: React.CSSProperties = getCardVariantStyle(
|
||||
getEventVariant(eventLength),
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { CalendarEvent } from "@/features/Events/EventsTypes";
|
||||
import { MenuItem } from "@linagora/twake-mui";
|
||||
import { useI18n } from "twake-i18n";
|
||||
|
||||
export default function EventDuplication({
|
||||
onClose,
|
||||
event,
|
||||
onOpenDuplicate,
|
||||
}: {
|
||||
onClose: Function;
|
||||
event: CalendarEvent;
|
||||
onOpenDuplicate?: () => void;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -21,17 +21,15 @@ import {
|
||||
ToggleButton,
|
||||
ToggleButtonGroup,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@linagora/twake-mui";
|
||||
import { alpha } from "@mui/material/styles";
|
||||
import {
|
||||
Close as DeleteIcon,
|
||||
ContentCopy as CopyIcon,
|
||||
Public as PublicIcon,
|
||||
LocationOn as LocationIcon,
|
||||
Public as PublicIcon,
|
||||
} from "@mui/icons-material";
|
||||
import SquareRoundedIcon from "@mui/icons-material/SquareRounded";
|
||||
import LockOutlineIcon from "@mui/icons-material/LockOutline";
|
||||
import SquareRoundedIcon from "@mui/icons-material/SquareRounded";
|
||||
import React from "react";
|
||||
import { useI18n } from "twake-i18n";
|
||||
import AttendeeSelector from "../Attendees/AttendeeSearch";
|
||||
@@ -163,7 +161,6 @@ export default function EventFormFields({
|
||||
onHasEndDateChangedChange,
|
||||
}: EventFormFieldsProps) {
|
||||
const { t } = useI18n();
|
||||
const theme = useTheme();
|
||||
|
||||
// Internal state for 4 separate fields
|
||||
const [startDate, setStartDate] = React.useState("");
|
||||
@@ -377,7 +374,6 @@ export default function EventFormFields({
|
||||
showMore,
|
||||
});
|
||||
}, [
|
||||
title,
|
||||
startDate,
|
||||
startTime,
|
||||
endDate,
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function RepeatEvent({
|
||||
}: {
|
||||
repetition: RepetitionObject;
|
||||
eventStart: Date;
|
||||
setRepetition: Function;
|
||||
setRepetition: (repetition: RepetitionObject) => void;
|
||||
isOwn?: boolean;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -83,7 +83,6 @@ export const DateTimeFields: React.FC<DateTimeFieldsProps> = ({
|
||||
showMore,
|
||||
hasEndDateChanged,
|
||||
showEndDate,
|
||||
onToggleEndDate,
|
||||
validation,
|
||||
onStartDateChange,
|
||||
onStartTimeChange,
|
||||
|
||||
@@ -88,7 +88,7 @@ export const DateTimeSummary: React.FC<DateTimeSummaryProps> = ({
|
||||
const offset = getTimezoneOffset(tz, dateForOffset);
|
||||
const tzName = tz.replace(/_/g, " ");
|
||||
return `(${offset}) ${tzName}`;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return tz.replace(/_/g, " ");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,12 +19,12 @@ import { parseTimeInput } from "../utils/dateTimeHelpers";
|
||||
|
||||
type FieldType = "date" | "time" | "date-time";
|
||||
|
||||
type GenericPickerFieldProps = PickerFieldProps<any, any, any> & {
|
||||
type GenericPickerFieldProps = PickerFieldProps<Dayjs, false, false> & {
|
||||
fieldType: FieldType;
|
||||
validator: (
|
||||
value: any,
|
||||
value: Dayjs | null,
|
||||
context: PickerValidationScope,
|
||||
adapter: PickerFieldAdapter<any>
|
||||
adapter: PickerFieldAdapter<Dayjs>
|
||||
) => string | null;
|
||||
};
|
||||
|
||||
@@ -223,7 +223,7 @@ function EditableTimePickerField(props: GenericPickerFieldProps) {
|
||||
dispatchCloseOtherPickers();
|
||||
};
|
||||
|
||||
const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||
const handleBlur = (_e: React.FocusEvent<HTMLInputElement>) => {
|
||||
// If dropdown is open, don't parse input
|
||||
// MUI will handle selection and sync value via useEffect
|
||||
if (pickerContext.open) {
|
||||
|
||||
@@ -12,15 +12,16 @@ import {
|
||||
useValidation,
|
||||
validateDate,
|
||||
} from "@mui/x-date-pickers/validation";
|
||||
import { Dayjs } from "dayjs";
|
||||
|
||||
type FieldType = "date" | "time" | "date-time";
|
||||
|
||||
type GenericPickerFieldProps = PickerFieldProps<any, any, any> & {
|
||||
type GenericPickerFieldProps = PickerFieldProps<Dayjs, false, false> & {
|
||||
fieldType: FieldType;
|
||||
validator: (
|
||||
value: any,
|
||||
value: Dayjs | null,
|
||||
context: PickerValidationScope,
|
||||
adapter: PickerFieldAdapter<any>
|
||||
adapter: PickerFieldAdapter<Dayjs>
|
||||
) => string | null;
|
||||
};
|
||||
|
||||
|
||||
@@ -119,28 +119,18 @@ export async function handleRSVP(
|
||||
export function handleDelete(
|
||||
isRecurring: boolean,
|
||||
typeOfAction: "solo" | "all" | undefined,
|
||||
onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void,
|
||||
dispatch: Function,
|
||||
onClose: (event: unknown, reason: "backdropClick" | "escapeKeyDown") => void,
|
||||
dispatch: AppDispatch,
|
||||
calendar: Calendar,
|
||||
event: CalendarEvent,
|
||||
calId: string,
|
||||
eventId: string
|
||||
) {
|
||||
if (isRecurring) {
|
||||
onClose({}, "backdropClick");
|
||||
if (typeOfAction === "solo") {
|
||||
dispatch(deleteEventInstanceAsync({ cal: calendar, event }));
|
||||
} else {
|
||||
dispatch(
|
||||
deleteEventAsync({
|
||||
calId,
|
||||
eventId,
|
||||
eventURL: event.URL,
|
||||
})
|
||||
);
|
||||
}
|
||||
onClose({}, "backdropClick");
|
||||
|
||||
if (isRecurring && typeOfAction === "solo") {
|
||||
dispatch(deleteEventInstanceAsync({ cal: calendar, event }));
|
||||
} else {
|
||||
onClose({}, "backdropClick");
|
||||
dispatch(
|
||||
deleteEventAsync({
|
||||
calId,
|
||||
|
||||
@@ -16,7 +16,7 @@ import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||
export function renderAttendeeBadge(
|
||||
a: userAttendee,
|
||||
key: string,
|
||||
t: Function,
|
||||
t: (key: string) => string,
|
||||
isFull?: boolean,
|
||||
isOrganizer?: boolean
|
||||
) {
|
||||
@@ -110,7 +110,9 @@ export async function refreshCalendars(
|
||||
) {
|
||||
if (process.env.NODE_ENV === "test") return;
|
||||
|
||||
!calType && (await dispatch(getCalendarsListAsync()));
|
||||
if (!calType) {
|
||||
await dispatch(getCalendarsListAsync());
|
||||
}
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
calendars.map((calendar) =>
|
||||
|
||||
@@ -8,7 +8,7 @@ export function SnackbarAlert({
|
||||
severity = "success",
|
||||
}: {
|
||||
open: boolean;
|
||||
setOpen: Function;
|
||||
setOpen: (o: boolean) => void;
|
||||
message: string;
|
||||
severity?: AlertColor;
|
||||
}) {
|
||||
|
||||
@@ -142,7 +142,7 @@ export default function SearchBar() {
|
||||
setFilterError(false);
|
||||
};
|
||||
|
||||
const handleContactSelect = (_event: any, contacts: User[]) => {
|
||||
const handleContactSelect = (contacts: User[]) => {
|
||||
setSelectedContacts(contacts);
|
||||
setSearch("");
|
||||
if (contacts.length > 0) {
|
||||
@@ -173,7 +173,9 @@ export default function SearchBar() {
|
||||
dispatch(setView("search"));
|
||||
setAnchorEl(null);
|
||||
} else {
|
||||
filterOpen && setFilterError(true);
|
||||
if (filterOpen) {
|
||||
setFilterError(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -222,8 +224,8 @@ export default function SearchBar() {
|
||||
{extended && (
|
||||
<PeopleSearch
|
||||
selectedUsers={selectedContacts}
|
||||
onChange={(event, users) => {
|
||||
handleContactSelect(event, users);
|
||||
onChange={(_event, users) => {
|
||||
handleContactSelect(users);
|
||||
}}
|
||||
objectTypes={["user", "contact"]}
|
||||
onToggleEventPreview={() => {}}
|
||||
|
||||
@@ -56,9 +56,9 @@ export function Menubar({
|
||||
currentView,
|
||||
onViewChange,
|
||||
}: MenubarProps) {
|
||||
const { t, lang } = useI18n(); // deliberately NOT using f()
|
||||
const { t } = useI18n(); // deliberately NOT using f()
|
||||
const user = useAppSelector((state) => state.user.userData);
|
||||
const applist: AppIconProps[] = (window as any).appList ?? [];
|
||||
const applist: AppIconProps[] = window.appList ?? [];
|
||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
const [userMenuAnchorEl, setUserMenuAnchorEl] = useState<null | HTMLElement>(
|
||||
null
|
||||
|
||||
Reference in New Issue
Block a user