Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user