Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
@@ -330,7 +330,15 @@ describe("CalendarSlice", () => {
|
|||||||
it("getCalendarDetailAsync.fulfilled adds calendar events", () => {
|
it("getCalendarDetailAsync.fulfilled adds calendar events", () => {
|
||||||
const payload = { calId: "c1", events: [{ uid: "e1" }] as any[] };
|
const payload = { calId: "c1", events: [{ uid: "e1" }] as any[] };
|
||||||
const state = reducer(
|
const state = reducer(
|
||||||
initialState,
|
{
|
||||||
|
...initialState,
|
||||||
|
list: {
|
||||||
|
["c1"]: {
|
||||||
|
id: "c1",
|
||||||
|
events: {},
|
||||||
|
} as unknown as Calendars,
|
||||||
|
},
|
||||||
|
},
|
||||||
getCalendarDetailAsync.fulfilled(payload, "req11", {
|
getCalendarDetailAsync.fulfilled(payload, "req11", {
|
||||||
calId: "c1",
|
calId: "c1",
|
||||||
match: { start: "", end: "" },
|
match: { start: "", end: "" },
|
||||||
|
|||||||
@@ -211,6 +211,10 @@ export default function CalendarApp({
|
|||||||
const [prevTempCalendars, setPrevTempCalendars] = useState<string[]>([]);
|
const [prevTempCalendars, setPrevTempCalendars] = useState<string[]>([]);
|
||||||
const [prevRangeKey, setPrevRangeKey] = useState<string>("");
|
const [prevRangeKey, setPrevRangeKey] = useState<string>("");
|
||||||
|
|
||||||
|
const tempCalendarControllersRef = useRef<Map<string, AbortController>>(
|
||||||
|
new Map()
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateCalsDetails(
|
updateCalsDetails(
|
||||||
Object.keys(tempcalendars),
|
Object.keys(tempcalendars),
|
||||||
@@ -220,9 +224,21 @@ export default function CalendarApp({
|
|||||||
prevRangeKey,
|
prevRangeKey,
|
||||||
dispatch,
|
dispatch,
|
||||||
calendarRange,
|
calendarRange,
|
||||||
"temp"
|
"temp",
|
||||||
|
tempCalendarControllersRef.current
|
||||||
);
|
);
|
||||||
|
|
||||||
|
prevTempCalendars.forEach((calId) => {
|
||||||
|
if (!Object.keys(tempcalendars).includes(calId)) {
|
||||||
|
const controller = tempCalendarControllersRef.current.get(calId);
|
||||||
|
if (controller) {
|
||||||
|
controller.abort();
|
||||||
|
tempCalendarControllersRef.current.delete(calId);
|
||||||
|
}
|
||||||
|
delete fetchedRangesRef.current[calId];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setPrevTempCalendars(Object.keys(tempcalendars));
|
setPrevTempCalendars(Object.keys(tempcalendars));
|
||||||
setPrevRangeKey(rangeKey);
|
setPrevRangeKey(rangeKey);
|
||||||
}, [rangeKey, Object.keys(tempcalendars).join(","), pending]);
|
}, [rangeKey, Object.keys(tempcalendars).join(","), pending]);
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ export const updateCalsDetails = (
|
|||||||
previousRangeKey: string,
|
previousRangeKey: string,
|
||||||
dispatch: Function,
|
dispatch: Function,
|
||||||
calendarRange: { start: Date; end: Date },
|
calendarRange: { start: Date; end: Date },
|
||||||
calType?: "temp"
|
calType?: "temp",
|
||||||
|
controllers?: Map<string, AbortController>
|
||||||
) => {
|
) => {
|
||||||
if (pending || !rangeKey) return;
|
if (pending || !rangeKey) return;
|
||||||
|
|
||||||
@@ -116,31 +117,65 @@ export const updateCalsDetails = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
newCalendars.forEach((id) => {
|
newCalendars.forEach((id) => {
|
||||||
dispatch(
|
if (controllers) {
|
||||||
getCalendarDetailAsync({
|
const controller = new AbortController();
|
||||||
calId: id,
|
controllers.set(id, controller);
|
||||||
match: {
|
|
||||||
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
dispatch(
|
||||||
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
getCalendarDetailAsync({
|
||||||
},
|
calId: id,
|
||||||
calType,
|
match: {
|
||||||
})
|
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
||||||
);
|
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
||||||
|
},
|
||||||
|
calType,
|
||||||
|
signal: controller.signal,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
getCalendarDetailAsync({
|
||||||
|
calId: id,
|
||||||
|
match: {
|
||||||
|
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
||||||
|
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
||||||
|
},
|
||||||
|
calType,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (rangeKey !== previousRangeKey) {
|
if (rangeKey !== previousRangeKey) {
|
||||||
selectedCalendars?.forEach((id) => {
|
selectedCalendars?.forEach((id) => {
|
||||||
if (id) {
|
if (id) {
|
||||||
dispatch(
|
if (controllers) {
|
||||||
getCalendarDetailAsync({
|
const controller = new AbortController();
|
||||||
calId: id,
|
controllers.set(id, controller);
|
||||||
match: {
|
|
||||||
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
dispatch(
|
||||||
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
getCalendarDetailAsync({
|
||||||
},
|
calId: id,
|
||||||
calType,
|
match: {
|
||||||
})
|
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
||||||
);
|
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
||||||
|
},
|
||||||
|
calType,
|
||||||
|
signal: controller.signal,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
getCalendarDetailAsync({
|
||||||
|
calId: id,
|
||||||
|
match: {
|
||||||
|
start: formatDateToYYYYMMDDTHHMMSS(calendarRange.start),
|
||||||
|
end: formatDateToYYYYMMDDTHHMMSS(calendarRange.end),
|
||||||
|
},
|
||||||
|
calType,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ import { api } from "../../utils/apiUtils";
|
|||||||
|
|
||||||
export async function getCalendars(
|
export async function getCalendars(
|
||||||
userId: string,
|
userId: string,
|
||||||
scope: string = "personal=true&sharedDelegationStatus=accepted&sharedPublicSubscription=true&withRights=true"
|
scope: string = "personal=true&sharedDelegationStatus=accepted&sharedPublicSubscription=true&withRights=true",
|
||||||
|
signal?: AbortSignal
|
||||||
) {
|
) {
|
||||||
const calendars = await api
|
const calendars = await api
|
||||||
.get(`dav/calendars/${userId}.json?${scope}`, {
|
.get(`dav/calendars/${userId}.json?${scope}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/calendar+json",
|
Accept: "application/calendar+json",
|
||||||
},
|
},
|
||||||
|
signal,
|
||||||
})
|
})
|
||||||
.json();
|
.json();
|
||||||
return calendars;
|
return calendars;
|
||||||
@@ -16,7 +18,8 @@ export async function getCalendars(
|
|||||||
|
|
||||||
export async function getCalendar(
|
export async function getCalendar(
|
||||||
id: string,
|
id: string,
|
||||||
match: { start: string; end: string }
|
match: { start: string; end: string },
|
||||||
|
signal?: AbortSignal
|
||||||
) {
|
) {
|
||||||
const response = await api(`dav/calendars/${id}.json`, {
|
const response = await api(`dav/calendars/${id}.json`, {
|
||||||
method: "REPORT",
|
method: "REPORT",
|
||||||
@@ -26,6 +29,7 @@ export async function getCalendar(
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
match,
|
match,
|
||||||
}),
|
}),
|
||||||
|
signal,
|
||||||
});
|
});
|
||||||
const calendar = await response.json();
|
const calendar = await response.json();
|
||||||
return calendar;
|
return calendar;
|
||||||
|
|||||||
@@ -171,13 +171,21 @@ export const getTempCalendarsListAsync = createAsyncThunk<
|
|||||||
|
|
||||||
export const getCalendarDetailAsync = createAsyncThunk<
|
export const getCalendarDetailAsync = createAsyncThunk<
|
||||||
{ calId: string; events: CalendarEvent[]; calType?: string },
|
{ calId: string; events: CalendarEvent[]; calType?: string },
|
||||||
{ calId: string; match: { start: string; end: string }; calType?: string },
|
{
|
||||||
|
calId: string;
|
||||||
|
match: { start: string; end: string };
|
||||||
|
calType?: string;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
},
|
||||||
{ rejectValue: RejectedError }
|
{ rejectValue: RejectedError }
|
||||||
>(
|
>(
|
||||||
"calendars/getCalendarDetails",
|
"calendars/getCalendarDetails",
|
||||||
async ({ calId, match, calType }, { rejectWithValue }) => {
|
async ({ calId, match, calType, signal }, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const calendar = (await getCalendar(calId, match)) as Record<string, any>;
|
const calendar = (await getCalendar(calId, match, signal)) as Record<
|
||||||
|
string,
|
||||||
|
any
|
||||||
|
>;
|
||||||
const color = calendar["apple:color"];
|
const color = calendar["apple:color"];
|
||||||
const events: CalendarEvent[] = calendar._embedded["dav:item"].flatMap(
|
const events: CalendarEvent[] = calendar._embedded["dav:item"].flatMap(
|
||||||
(eventdata: any) => {
|
(eventdata: any) => {
|
||||||
@@ -736,10 +744,7 @@ const CalendarSlice = createSlice({
|
|||||||
const type = action.payload.calType === "temp" ? "templist" : "list";
|
const type = action.payload.calType === "temp" ? "templist" : "list";
|
||||||
|
|
||||||
if (!state[type][action.payload.calId]) {
|
if (!state[type][action.payload.calId]) {
|
||||||
state[type][action.payload.calId] = {
|
return;
|
||||||
id: action.payload.calId,
|
|
||||||
events: {},
|
|
||||||
} as Calendars;
|
|
||||||
}
|
}
|
||||||
action.payload.events.forEach((event) => {
|
action.payload.events.forEach((event) => {
|
||||||
state[type][action.payload.calId].events[event.uid] = event;
|
state[type][action.payload.calId].events[event.uid] = event;
|
||||||
@@ -998,6 +1003,12 @@ const CalendarSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(getTempCalendarsListAsync.rejected, (state, action) => {
|
.addCase(getTempCalendarsListAsync.rejected, (state, action) => {
|
||||||
state.pending = false;
|
state.pending = false;
|
||||||
|
if (
|
||||||
|
action.payload?.message.includes("aborted") ||
|
||||||
|
action.error.name === "AbortError"
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
state.error =
|
state.error =
|
||||||
action.payload?.message ||
|
action.payload?.message ||
|
||||||
action.error.message ||
|
action.error.message ||
|
||||||
@@ -1005,6 +1016,12 @@ const CalendarSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(getCalendarDetailAsync.rejected, (state, action) => {
|
.addCase(getCalendarDetailAsync.rejected, (state, action) => {
|
||||||
state.pending = false;
|
state.pending = false;
|
||||||
|
if (
|
||||||
|
action.payload?.message.includes("aborted") ||
|
||||||
|
action.error.name === "AbortError"
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
state.error =
|
state.error =
|
||||||
action.payload?.message ||
|
action.payload?.message ||
|
||||||
action.error.message ||
|
action.error.message ||
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ export const api = ky.extend({
|
|||||||
: null;
|
: null;
|
||||||
const access_token = saved?.access_token;
|
const access_token = saved?.access_token;
|
||||||
|
|
||||||
const modifiedRequest = new Request(request);
|
request.headers.set("Authorization", `Bearer ${access_token}`);
|
||||||
modifiedRequest.headers.set("Authorization", `Bearer ${access_token}`);
|
return request;
|
||||||
return modifiedRequest;
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
afterResponse: [
|
afterResponse: [
|
||||||
|
|||||||
Reference in New Issue
Block a user