#597 display resource calendar (#630)

This commit is contained in:
lethemanh
2026-03-16 23:35:35 +07:00
committed by GitHub
parent 29f17ce86d
commit 9898278fb5
11 changed files with 313 additions and 6 deletions
+23 -1
View File
@@ -136,7 +136,16 @@ export default function CalendarSelection({
(id) => extractEventBaseUuid(id) !== userId && calendars[id]?.delegated
);
const sharedCalendars = Object.keys(calendars || {}).filter(
(id) => extractEventBaseUuid(id) !== userId && !calendars?.[id]?.delegated
(id) =>
extractEventBaseUuid(id) !== userId &&
!calendars?.[id]?.delegated &&
!calendars?.[id]?.owner?.resource
);
const resourceCalendars = Object.keys(calendars || {}).filter(
(id) =>
extractEventBaseUuid(id) !== userId &&
!calendars?.[id]?.delegated &&
calendars?.[id]?.owner?.resource
);
const handleCalendarToggle = (name: string) => {
@@ -149,6 +158,7 @@ export default function CalendarSelection({
const [anchorElCal, setAnchorElCal] = useState<HTMLElement | null>(null);
const [anchorElCalOthers, setAnchorElCalOthers] =
useState<HTMLElement | null>(null);
// const [anchorElCalResources, setAnchorElCalResources] = useState<HTMLElement | null>(null);
return (
<>
@@ -194,6 +204,18 @@ export default function CalendarSelection({
}}
defaultExpanded
/>
<CalendarAccordion
title={t("calendar.resources")}
calendars={resourceCalendars}
selectedCalendars={selectedCalendars}
showAddButton={false}
handleToggle={handleCalendarToggle}
setOpen={(_) => {
// TO DO: Implement open resource selection
}}
defaultExpanded
/>
</div>
<CalendarPopover
open={Boolean(anchorElCal)}
@@ -1,6 +1,10 @@
import { RootState } from "@/app/store";
import { OpenPaasUserData } from "@/features/User/type/OpenPaasUserData";
import { getOpenPaasUser, getUserDetails } from "@/features/User/userAPI";
import {
getOpenPaasUser,
getResourceDetails,
getUserDetails,
} from "@/features/User/userAPI";
import { defaultColors } from "@/utils/defaultColors";
import { formatReduxError, toRejectedError } from "@/utils/errorUtils";
import { createAsyncThunk } from "@reduxjs/toolkit";
@@ -39,11 +43,42 @@ export const getCalendarsListAsync = createAsyncThunk<
const ownerDataMap = new Map<string, OpenPaasUserData>();
const OWNER_BATCH_SIZE = 20;
const fetchResourceData = async (ownerId: string) => {
try {
const data = await getResourceDetails(ownerId);
const ownerData = await getUserDetails(data.creator);
ownerDataMap.set(ownerId, {
...ownerData,
resource: true,
});
} catch (error) {
console.error(
`Failed to fetch resource details for ${ownerId}:`,
error
);
ownerDataMap.set(ownerId, {
firstname: "",
lastname: "Unknown User",
emails: [],
resource: true,
});
errors.push(formatReduxError(error));
}
};
const fetchOwnerData = async (ownerId: string) => {
try {
const data = await getUserDetails(ownerId);
ownerDataMap.set(ownerId, data);
} catch (error) {
const status = (error as { response?: { status?: number } }).response
?.status;
if (status === 404) {
await fetchResourceData(ownerId);
return;
}
console.error(`Failed to fetch user details for ${ownerId}:`, error);
ownerDataMap.set(ownerId, {
firstname: "",
@@ -9,6 +9,7 @@ export interface OpenPaasUserData {
modules?: ModuleConfiguration[];
};
emails: string[];
resource?: boolean;
}
export function ToUserData(
+19
View File
@@ -0,0 +1,19 @@
export interface ResourceData {
_id: string;
name: string;
description: string;
type: string;
icon: string;
deleted: boolean;
creator: string;
administrators: {
_id: string;
id: string;
objectType: string;
}[];
timestamps: {
creation: string;
updatedAt: string;
};
resource?: boolean;
}
+8
View File
@@ -7,6 +7,7 @@ import {
ModuleConfiguration,
SearchResponseItem,
} from "./userDataTypes";
import { ResourceData } from "./type/ResourceData";
export async function getOpenPaasUser() {
const user = await api.get(`api/user`);
@@ -42,6 +43,13 @@ export async function getUserDetails(id: string): Promise<OpenPaasUserData> {
return user as OpenPaasUserData;
}
export async function getResourceDetails(id: string): Promise<ResourceData> {
const resource = await api
.get(`linagora.esn.resource/api/resources/${id}`)
.json();
return resource as ResourceData;
}
export interface UserConfigurationUpdates {
language?: string;
notifications?: Record<string, unknown>;
+2 -1
View File
@@ -25,7 +25,8 @@
"title": "Remove %{name}?",
"personalWarning": "You will lose all events in this calendar.",
"sharedWarning": "You will lose access to its events. You will still be able to add it back later."
}
},
"resources": "Resources"
},
"actions": {
"modify": "Modify",
+2 -1
View File
@@ -25,7 +25,8 @@
"title": "Supprimer %{name} ?",
"personalWarning": "Vous allez perdre tous les événements de ce calendrier.",
"sharedWarning": "Vous allez perdre laccès à ses événements. Vous pourrez toujours le rajouter plus tard."
}
},
"resources": "Ressources"
},
"actions": {
"modify": "Modifier",
+2 -1
View File
@@ -25,7 +25,8 @@
"title": "Удалить %{name}?",
"personalWarning": "Вы потеряете все события в этом календаре.",
"sharedWarning": "Вы потеряете доступ. Позже можно добавить снова."
}
},
"resources": "Ресурсы"
},
"actions": {
"modify": "Изменить",
+2 -1
View File
@@ -25,7 +25,8 @@
"title": "Xóa %{name}?",
"personalWarning": "Bạn sẽ mất tất cả sự kiện trong lịch này.",
"sharedWarning": "Bạn sẽ mất quyền truy cập các sự kiện của lịch. Bạn vẫn có thể thêm lại sau."
}
},
"resources": "Tài nguyên"
},
"actions": {
"modify": "Chỉnh sửa",