@edifice.io/react 2.5.23-develop.20260623093925 → 2.5.23-develop.20260623104003

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/components/AppIcon/AppIcon.js +4 -1
  2. package/dist/components/Avatar/Avatar.d.ts +1 -1
  3. package/dist/components/Avatar/Avatar.js +2 -1
  4. package/dist/components/BetaSwitch/BetaSwitch.d.ts +13 -0
  5. package/dist/components/BetaSwitch/BetaSwitch.js +27 -0
  6. package/dist/components/BetaSwitch/index.d.ts +1 -0
  7. package/dist/components/ButtonBeta/ButtonBeta.d.ts +47 -0
  8. package/dist/components/ButtonBeta/ButtonBeta.js +34 -0
  9. package/dist/components/ButtonBeta/index.d.ts +2 -0
  10. package/dist/components/Flex/Flex.js +5 -1
  11. package/dist/components/Logo/index.d.ts +1 -1
  12. package/dist/components/LogoBeta/LogoBeta.d.ts +7 -0
  13. package/dist/components/LogoBeta/LogoBeta.js +14 -0
  14. package/dist/components/LogoBeta/index.d.ts +2 -0
  15. package/dist/components/PageLayout/PageLayout.d.ts +45 -0
  16. package/dist/components/PageLayout/PageLayout.js +94 -0
  17. package/dist/components/PageLayout/PageLayoutContext.d.ts +14 -0
  18. package/dist/components/PageLayout/PageLayoutContext.js +8 -0
  19. package/dist/components/PageLayout/components/PageLayoutBreadcrumb.d.ts +9 -0
  20. package/dist/components/PageLayout/components/PageLayoutBreadcrumb.js +10 -0
  21. package/dist/components/PageLayout/components/PageLayoutContent.d.ts +9 -0
  22. package/dist/components/PageLayout/components/PageLayoutContent.js +18 -0
  23. package/dist/components/PageLayout/components/PageLayoutHeader.d.ts +10 -0
  24. package/dist/components/PageLayout/components/PageLayoutHeader.js +18 -0
  25. package/dist/components/PageLayout/components/PageLayoutOverlay.d.ts +15 -0
  26. package/dist/components/PageLayout/components/PageLayoutOverlay.js +51 -0
  27. package/dist/components/PageLayout/components/PageLayoutSidebarLeft.d.ts +9 -0
  28. package/dist/components/PageLayout/components/PageLayoutSidebarLeft.js +18 -0
  29. package/dist/components/PageLayout/components/PageLayoutSidebarRight.d.ts +9 -0
  30. package/dist/components/PageLayout/components/PageLayoutSidebarRight.js +18 -0
  31. package/dist/components/PageLayout/hook/useOverlay.d.ts +5 -0
  32. package/dist/components/PageLayout/hook/useOverlay.js +15 -0
  33. package/dist/components/PageLayout/index.d.ts +4 -0
  34. package/dist/components/PageLayout/store/overlayStore.d.ts +15 -0
  35. package/dist/components/PageLayout/store/overlayStore.js +12 -0
  36. package/dist/components/index.d.ts +4 -0
  37. package/dist/homepage.js +34 -0
  38. package/dist/hooks/index.d.ts +1 -1
  39. package/dist/hooks/useEdificeIcons/useEdificeIcons.js +10 -9
  40. package/dist/icons-nav.js +38 -28
  41. package/dist/index.js +215 -202
  42. package/dist/modules/homepage/components/Favorites/Favorites.d.ts +6 -0
  43. package/dist/modules/homepage/components/Favorites/Favorites.js +28 -0
  44. package/dist/modules/homepage/components/Favorites/FavoritesContainer.d.ts +4 -0
  45. package/dist/modules/homepage/components/Favorites/FavoritesContainer.js +10 -0
  46. package/dist/modules/homepage/components/Favorites/index.d.ts +2 -0
  47. package/dist/modules/homepage/components/Header/Header.d.ts +9 -0
  48. package/dist/modules/homepage/components/Header/Header.js +80 -0
  49. package/dist/modules/homepage/components/Header/index.d.ts +2 -0
  50. package/dist/modules/homepage/components/HomeCard/HomeCard.d.ts +37 -0
  51. package/dist/modules/homepage/components/HomeCard/HomeCard.js +17 -0
  52. package/dist/modules/homepage/components/HomeCard/HomeCardContent.d.ts +7 -0
  53. package/dist/modules/homepage/components/HomeCard/HomeCardContent.js +10 -0
  54. package/dist/modules/homepage/components/HomeCard/HomeCardHeader.d.ts +18 -0
  55. package/dist/modules/homepage/components/HomeCard/HomeCardHeader.js +22 -0
  56. package/dist/modules/homepage/components/HomeCard/index.d.ts +4 -0
  57. package/dist/modules/homepage/components/LastInfos/LastInfos.d.ts +49 -0
  58. package/dist/modules/homepage/components/LastInfos/LastInfos.js +58 -0
  59. package/dist/modules/homepage/components/LastInfos/LastInfosContainer.d.ts +4 -0
  60. package/dist/modules/homepage/components/LastInfos/LastInfosContainer.js +37 -0
  61. package/dist/modules/homepage/components/LastInfos/LastInfosList.d.ts +13 -0
  62. package/dist/modules/homepage/components/LastInfos/LastInfosList.js +31 -0
  63. package/dist/modules/homepage/components/LastInfos/index.d.ts +4 -0
  64. package/dist/modules/homepage/components/LastInfos/useLastInfos.d.ts +18 -0
  65. package/dist/modules/homepage/components/LastInfos/useLastInfos.js +25 -0
  66. package/dist/modules/homepage/components/MessageFlashList/MessageFlash.d.ts +12 -0
  67. package/dist/modules/homepage/components/MessageFlashList/MessageFlash.js +65 -0
  68. package/dist/modules/homepage/components/MessageFlashList/MessageFlashList.d.ts +12 -0
  69. package/dist/modules/homepage/components/MessageFlashList/MessageFlashList.js +10 -0
  70. package/dist/modules/homepage/components/MessageFlashList/MessageFlashListContainer.d.ts +5 -0
  71. package/dist/modules/homepage/components/MessageFlashList/MessageFlashListContainer.js +14 -0
  72. package/dist/modules/homepage/components/MessageFlashList/hooks/useMessageFlashList.d.ts +16 -0
  73. package/dist/modules/homepage/components/MessageFlashList/hooks/useMessageFlashList.js +19 -0
  74. package/dist/modules/homepage/components/MessageFlashList/index.d.ts +4 -0
  75. package/dist/modules/homepage/components/MessageFlashList/services/api/index.d.ts +4 -0
  76. package/dist/modules/homepage/components/MessageFlashList/services/api/index.js +5 -0
  77. package/dist/modules/homepage/components/MessageFlashList/services/api/messagesFlashService.d.ts +20 -0
  78. package/dist/modules/homepage/components/MessageFlashList/services/api/messagesFlashService.js +21 -0
  79. package/dist/modules/homepage/components/MessageFlashList/services/queries/messagesFlash.d.ts +13 -0
  80. package/dist/modules/homepage/components/MessageFlashList/services/queries/messagesFlash.js +31 -0
  81. package/dist/modules/homepage/components/Notifications/Notification.d.ts +20 -0
  82. package/dist/modules/homepage/components/Notifications/Notification.js +16 -0
  83. package/dist/modules/homepage/components/Notifications/NotificationList.d.ts +18 -0
  84. package/dist/modules/homepage/components/Notifications/NotificationList.js +44 -0
  85. package/dist/modules/homepage/components/Notifications/NotificationListContainer.d.ts +9 -0
  86. package/dist/modules/homepage/components/Notifications/NotificationListContainer.js +20 -0
  87. package/dist/modules/homepage/components/Notifications/NotificationListSkeleton.d.ts +5 -0
  88. package/dist/modules/homepage/components/Notifications/NotificationListSkeleton.js +17 -0
  89. package/dist/modules/homepage/components/Notifications/NotificationSkeleton.d.ts +3 -0
  90. package/dist/modules/homepage/components/Notifications/NotificationSkeleton.js +19 -0
  91. package/dist/modules/homepage/components/Notifications/components/NotificationItem.d.ts +24 -0
  92. package/dist/modules/homepage/components/Notifications/components/NotificationItem.js +28 -0
  93. package/dist/modules/homepage/components/Notifications/components/NotificationResource.d.ts +15 -0
  94. package/dist/modules/homepage/components/Notifications/components/NotificationResource.js +19 -0
  95. package/dist/modules/homepage/components/Notifications/components/SystemNotification.d.ts +15 -0
  96. package/dist/modules/homepage/components/Notifications/components/SystemNotification.js +20 -0
  97. package/dist/modules/homepage/components/Notifications/components/UserNotification.d.ts +15 -0
  98. package/dist/modules/homepage/components/Notifications/components/UserNotification.js +25 -0
  99. package/dist/modules/homepage/components/Notifications/components/notificationAdapter.d.ts +27 -0
  100. package/dist/modules/homepage/components/Notifications/components/notificationAdapter.js +53 -0
  101. package/dist/modules/homepage/components/Notifications/hooks/useNotificationList.d.ts +20 -0
  102. package/dist/modules/homepage/components/Notifications/hooks/useNotificationList.js +26 -0
  103. package/dist/modules/homepage/components/Notifications/index.d.ts +6 -0
  104. package/dist/modules/homepage/components/Notifications/services/api/index.d.ts +4 -0
  105. package/dist/modules/homepage/components/Notifications/services/api/index.js +5 -0
  106. package/dist/modules/homepage/components/Notifications/services/api/notificationService.d.ts +15 -0
  107. package/dist/modules/homepage/components/Notifications/services/api/notificationService.js +22 -0
  108. package/dist/modules/homepage/components/Notifications/services/queries/notification.d.ts +20 -0
  109. package/dist/modules/homepage/components/Notifications/services/queries/notification.js +40 -0
  110. package/dist/modules/homepage/components/SchoolSpace/SchoolSpace.d.ts +15 -0
  111. package/dist/modules/homepage/components/SchoolSpace/SchoolSpace.js +29 -0
  112. package/dist/modules/homepage/components/SchoolSpace/SchoolSpaceContainer.d.ts +4 -0
  113. package/dist/modules/homepage/components/SchoolSpace/SchoolSpaceContainer.js +13 -0
  114. package/dist/modules/homepage/components/SchoolSpace/index.d.ts +3 -0
  115. package/dist/modules/homepage/components/SchoolSpace/useUserSchools.d.ts +6 -0
  116. package/dist/modules/homepage/components/SchoolSpace/useUserSchools.js +39 -0
  117. package/dist/modules/homepage/components/UserSpace/UserSpace.d.ts +13 -0
  118. package/dist/modules/homepage/components/UserSpace/UserSpace.js +28 -0
  119. package/dist/modules/homepage/components/UserSpace/UserSpaceContainer.d.ts +7 -0
  120. package/dist/modules/homepage/components/UserSpace/UserSpaceContainer.js +19 -0
  121. package/dist/modules/homepage/components/UserSpace/index.d.ts +3 -0
  122. package/dist/modules/homepage/components/index.d.ts +8 -0
  123. package/dist/modules/homepage/hooks/useWidget.d.ts +6 -0
  124. package/dist/modules/homepage/hooks/useWidget.js +83 -0
  125. package/dist/modules/homepage/hooks/useWidgetPreferences.d.ts +6 -0
  126. package/dist/modules/homepage/hooks/useWidgetPreferences.js +34 -0
  127. package/dist/modules/homepage/index.d.ts +1 -0
  128. package/dist/modules/icons/components/nav/IconCommunitiesBeta.d.ts +7 -0
  129. package/dist/modules/icons/components/nav/IconCommunitiesBeta.js +18 -0
  130. package/dist/modules/icons/components/nav/IconHomeBeta.d.ts +7 -0
  131. package/dist/modules/icons/components/nav/IconHomeBeta.js +13 -0
  132. package/dist/modules/icons/components/nav/IconMessagesBeta.d.ts +7 -0
  133. package/dist/modules/icons/components/nav/IconMessagesBeta.js +18 -0
  134. package/dist/modules/icons/components/nav/IconMyAppsBeta.d.ts +7 -0
  135. package/dist/modules/icons/components/nav/IconMyAppsBeta.js +13 -0
  136. package/dist/modules/icons/components/nav/IconNotificationBeta.d.ts +7 -0
  137. package/dist/modules/icons/components/nav/IconNotificationBeta.js +14 -0
  138. package/dist/modules/icons/components/nav/index.d.ts +5 -0
  139. package/dist/modules/modals/OnboardingModal/index.d.ts +1 -1
  140. package/dist/providers/EdificeClientProvider/EdificeClientProvider.d.ts +0 -7
  141. package/dist/utilities/create-selectors/createSelectors.d.ts +10 -0
  142. package/dist/utilities/create-selectors/createSelectors.js +11 -0
  143. package/package.json +13 -8
@@ -0,0 +1,4 @@
1
+ export declare const messageFlashService: {
2
+ getMessagesFlash(): Promise<import('@edifice.io/client').IFlashMessageModel[]>;
3
+ markAsRead(message: import('@edifice.io/client').IFlashMessageModel): Promise<void>;
4
+ };
@@ -0,0 +1,5 @@
1
+ import { createMessagesFlashService } from "./messagesFlashService.js";
2
+ const messageFlashService = createMessagesFlashService("");
3
+ export {
4
+ messageFlashService
5
+ };
@@ -0,0 +1,20 @@
1
+ import { IFlashMessageModel } from '@edifice.io/client';
2
+ /**
3
+ * Creates a message flash service with methods to interact with flash messages.
4
+ *
5
+ * @param baseURL The base URL for the message flash service API.
6
+ * @returns A service exposing methods to retrieve flash messages and mark them as read.
7
+ */
8
+ export declare const createMessagesFlashService: (baseURL: string) => {
9
+ /**
10
+ * Get message flash.
11
+ * @returns a message flash object
12
+ */
13
+ getMessagesFlash(): Promise<IFlashMessageModel[]>;
14
+ /**
15
+ * Mark a flash message as read.
16
+ * @param message - The flash message to mark as read
17
+ * @returns A promise that resolves when the operation is complete
18
+ */
19
+ markAsRead(message: IFlashMessageModel): Promise<void>;
20
+ };
@@ -0,0 +1,21 @@
1
+ import { odeServices } from "@edifice.io/client";
2
+ const createMessagesFlashService = (baseURL) => ({
3
+ /**
4
+ * Get message flash.
5
+ * @returns a message flash object
6
+ */
7
+ getMessagesFlash() {
8
+ return odeServices.http().get(`${baseURL}/timeline/flashmsg/listuser`);
9
+ },
10
+ /**
11
+ * Mark a flash message as read.
12
+ * @param message - The flash message to mark as read
13
+ * @returns A promise that resolves when the operation is complete
14
+ */
15
+ markAsRead(message) {
16
+ return odeServices.http().put(`${baseURL}/timeline/flashmsg/` + message.id + "/markasread");
17
+ }
18
+ });
19
+ export {
20
+ createMessagesFlashService
21
+ };
@@ -0,0 +1,13 @@
1
+ import { IFlashMessageModel } from '@edifice.io/client';
2
+ export declare const messagesFlashQueryKeys: {
3
+ all: () => readonly ["messagesFlash"];
4
+ };
5
+ export declare const messagesFlashQueryOptions: {
6
+ getMessagesFlash(): import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<IFlashMessageModel[], Error, IFlashMessageModel[], import('@tanstack/react-query').QueryKey>, "queryFn"> & {
7
+ queryFn?: import('@tanstack/react-query').QueryFunction<IFlashMessageModel[], import('@tanstack/react-query').QueryKey, never> | undefined;
8
+ } & {
9
+ queryKey: import('@tanstack/react-query').DataTag<import('@tanstack/react-query').QueryKey, IFlashMessageModel[]>;
10
+ };
11
+ };
12
+ export declare const useMessagesFlash: () => import('@tanstack/react-query').UseQueryResult<IFlashMessageModel[], Error>;
13
+ export declare const useMarkAsRead: () => import('@tanstack/react-query').UseMutationResult<void, Error, IFlashMessageModel, void>;
@@ -0,0 +1,31 @@
1
+ import { useQuery, useQueryClient, useMutation, queryOptions } from "@tanstack/react-query";
2
+ import { messageFlashService } from "../api/index.js";
3
+ const messagesFlashQueryKeys = {
4
+ all: () => ["messagesFlash"]
5
+ }, messagesFlashQueryOptions = {
6
+ getMessagesFlash() {
7
+ return queryOptions({
8
+ queryKey: messagesFlashQueryKeys.all(),
9
+ queryFn: async () => messageFlashService.getMessagesFlash()
10
+ });
11
+ }
12
+ }, useMessagesFlash = () => useQuery(messagesFlashQueryOptions.getMessagesFlash()), useMarkAsRead = () => {
13
+ const queryClient = useQueryClient();
14
+ return useMutation({
15
+ mutationFn: (message) => messageFlashService.markAsRead(message),
16
+ onMutate: async (message) => {
17
+ queryClient.setQueryData(messagesFlashQueryKeys.all(), (oldMessages) => oldMessages.filter((msg) => msg.id !== message.id));
18
+ },
19
+ onError() {
20
+ queryClient.invalidateQueries({
21
+ queryKey: messagesFlashQueryKeys.all()
22
+ });
23
+ }
24
+ });
25
+ };
26
+ export {
27
+ messagesFlashQueryKeys,
28
+ messagesFlashQueryOptions,
29
+ useMarkAsRead,
30
+ useMessagesFlash
31
+ };
@@ -0,0 +1,20 @@
1
+ import { NotificationModel } from '@edifice.io/client';
2
+ export type { SystemWebNotification, UserWebNotification, WebNotification, } from './components/notificationAdapter';
3
+ export type NotificationProps = {
4
+ notification: NotificationModel;
5
+ };
6
+ /**
7
+ * Renders a single notification from a raw `NotificationModel`.
8
+ *
9
+ * Internally adapts the model into one of two display variants:
10
+ * - **user** — triggered by another user (e.g. shared a resource); shows their avatar.
11
+ * - **system** — triggered by an application event; shows the app icon.
12
+ *
13
+ * @example
14
+ * <Notification notification={notificationModel} />
15
+ */
16
+ declare const Notification: {
17
+ ({ notification }: NotificationProps): import("react/jsx-runtime").JSX.Element;
18
+ displayName: string;
19
+ };
20
+ export default Notification;
@@ -0,0 +1,16 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import SystemNotification from "./components/SystemNotification.js";
3
+ import UserNotification from "./components/UserNotification.js";
4
+ import { notificationAdapter } from "./components/notificationAdapter.js";
5
+ const Notification = ({
6
+ notification
7
+ }) => {
8
+ const notif = notificationAdapter(notification);
9
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
10
+ notif.type === "user" && /* @__PURE__ */ jsx(UserNotification, { notification: notif }),
11
+ notif.type === "system" && /* @__PURE__ */ jsx(SystemNotification, { notification: notif })
12
+ ] });
13
+ };
14
+ export {
15
+ Notification as default
16
+ };
@@ -0,0 +1,18 @@
1
+ import { NotificationModel } from '@edifice.io/client';
2
+ export type NotificationListProps = {
3
+ /** List of notifications to display */
4
+ notifications?: NotificationModel[];
5
+ /** Callback when the notifications list is closed */
6
+ onCloseNotifications?: () => void;
7
+ /** Callback to load the next page of notifications, used for infinite scrolling */
8
+ onLoadNextPage?: () => void;
9
+ /** Indicates if there are more notifications to load, used for infinite scrolling */
10
+ hasNextPage?: boolean;
11
+ /** Loading state for fetching notifications, used to prevent multiple simultaneous fetches */
12
+ isLoading?: boolean;
13
+ };
14
+ declare const NotificationList: {
15
+ ({ notifications, onCloseNotifications, onLoadNextPage, hasNextPage, isLoading, }: NotificationListProps): import("react/jsx-runtime").JSX.Element;
16
+ displayName: string;
17
+ };
18
+ export default NotificationList;
@@ -0,0 +1,44 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import illuEmptyNotification from "@edifice.io/bootstrap/dist/images/emptyscreen/illu-notifications.png";
3
+ import { useTranslation } from "react-i18next";
4
+ import SvgIconClose from "../../../icons/components/IconClose.js";
5
+ import Notification from "./Notification.js";
6
+ import NotificationListSkeleton from "./NotificationListSkeleton.js";
7
+ import NotificationSkeleton from "./NotificationSkeleton.js";
8
+ import useInfiniteScroll from "../../../../hooks/useInfiniteScroll/useInfiniteScroll.js";
9
+ import Flex from "../../../../components/Flex/Flex.js";
10
+ import ButtonBeta from "../../../../components/ButtonBeta/ButtonBeta.js";
11
+ import EmptyScreen from "../../../../components/EmptyScreen/EmptyScreen.js";
12
+ import Divider from "../../../../components/Divider/Divider.js";
13
+ const NotificationList = ({
14
+ notifications,
15
+ onCloseNotifications,
16
+ onLoadNextPage,
17
+ hasNextPage,
18
+ isLoading
19
+ }) => {
20
+ const {
21
+ t
22
+ } = useTranslation(), loadNextRef = useInfiniteScroll({
23
+ callback: () => onLoadNextPage == null ? void 0 : onLoadNextPage()
24
+ }), handleCloseClick = () => {
25
+ onCloseNotifications && onCloseNotifications();
26
+ };
27
+ return /* @__PURE__ */ jsx("section", { role: "region", className: "notification-list", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
28
+ /* @__PURE__ */ jsxs(Flex, { justify: "between", align: "center", wrap: "nowrap", className: "py-16 ps-24 pe-8", children: [
29
+ /* @__PURE__ */ jsx("h4", { className: "text-truncate", children: t("homepage.notifications-list.title") }),
30
+ onCloseNotifications && /* @__PURE__ */ jsx(ButtonBeta, { color: "tertiary", variant: "ghost", rightIcon: /* @__PURE__ */ jsx(SvgIconClose, {}), onClick: handleCloseClick, "aria-label": t("homepage.notifications-list.close"), title: t("homepage.notifications-list.close"), "data-testid": "notification-list-close-button" })
31
+ ] }),
32
+ (notifications == null ? void 0 : notifications.length) === 0 ? /* @__PURE__ */ jsx("div", { className: "mx-24", children: /* @__PURE__ */ jsx(EmptyScreen, { size: 120, imageSrc: illuEmptyNotification, imageAlt: t("homepage.notifications-list.empty.description"), text: t("homepage.notifications-list.empty.description") }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
33
+ /* @__PURE__ */ jsx("ul", { children: notifications == null ? void 0 : notifications.map((notification, index) => /* @__PURE__ */ jsxs("li", { children: [
34
+ /* @__PURE__ */ jsx(Notification, { notification }),
35
+ /* @__PURE__ */ jsx(Divider, { className: "border-grey-300 my-0" })
36
+ ] }, "notification-list-" + notification._id + "-" + index)) }),
37
+ hasNextPage && /* @__PURE__ */ jsx(NotificationSkeleton, { ref: loadNextRef }),
38
+ isLoading && /* @__PURE__ */ jsx(NotificationListSkeleton, {})
39
+ ] })
40
+ ] }) });
41
+ };
42
+ export {
43
+ NotificationList as default
44
+ };
@@ -0,0 +1,9 @@
1
+ export type NotificationListContainerProps = {
2
+ /** Callback when the notifications list is closed */
3
+ onCloseNotifications?: () => void;
4
+ };
5
+ export declare const NotificationListContainer: {
6
+ ({ onCloseNotifications, }: NotificationListContainerProps): import("react/jsx-runtime").JSX.Element;
7
+ displayName: string;
8
+ };
9
+ export default NotificationListContainer;
@@ -0,0 +1,20 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import NotificationList from "./NotificationList.js";
3
+ import { useNotificationListContainer } from "./hooks/useNotificationList.js";
4
+ const NotificationListContainer = ({
5
+ onCloseNotifications
6
+ }) => {
7
+ const {
8
+ notifications,
9
+ hasNextPage,
10
+ loadNextPage,
11
+ isLoading
12
+ } = useNotificationListContainer();
13
+ return /* @__PURE__ */ jsx(NotificationList, { notifications, onCloseNotifications, onLoadNextPage: () => {
14
+ hasNextPage && !isLoading && loadNextPage();
15
+ }, hasNextPage, isLoading });
16
+ };
17
+ export {
18
+ NotificationListContainer,
19
+ NotificationListContainer as default
20
+ };
@@ -0,0 +1,5 @@
1
+ declare const NotificationListSkeleton: {
2
+ (): import("react/jsx-runtime").JSX.Element;
3
+ displayName: string;
4
+ };
5
+ export default NotificationListSkeleton;
@@ -0,0 +1,17 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import NotificationSkeleton from "./NotificationSkeleton.js";
3
+ import Divider from "../../../../components/Divider/Divider.js";
4
+ const NotificationListSkeleton = () => /* @__PURE__ */ jsxs("ul", { children: [
5
+ /* @__PURE__ */ jsxs("li", { children: [
6
+ /* @__PURE__ */ jsx(NotificationSkeleton, {}),
7
+ /* @__PURE__ */ jsx(Divider, { className: "border-grey-300 my-0" })
8
+ ] }),
9
+ /* @__PURE__ */ jsxs("li", { children: [
10
+ /* @__PURE__ */ jsx(NotificationSkeleton, {}),
11
+ /* @__PURE__ */ jsx(Divider, { className: "border-grey-300 my-0" })
12
+ ] }),
13
+ /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(NotificationSkeleton, {}) })
14
+ ] });
15
+ export {
16
+ NotificationListSkeleton as default
17
+ };
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ declare const NotificationSkeleton: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
3
+ export default NotificationSkeleton;
@@ -0,0 +1,19 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import Flex from "../../../../components/Flex/Flex.js";
4
+ import Avatar from "../../../../components/Avatar/Avatar.js";
5
+ import TextSkeleton from "../../../../components/Skeleton/TextSkeleton.js";
6
+ const NotificationSkeleton = /* @__PURE__ */ React.forwardRef((_props, ref) => /* @__PURE__ */ jsx(Flex, { direction: "column", className: "notification", gap: "8", ref, children: /* @__PURE__ */ jsxs(Flex, { direction: "row", gap: "8", children: [
7
+ /* @__PURE__ */ jsx("div", { className: "notification-picture", children: /* @__PURE__ */ jsx(Avatar, { alt: "Notification Picture", variant: "circle", className: "notification-avatar" }) }),
8
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "8", className: "notification-message", children: [
9
+ /* @__PURE__ */ jsx(TextSkeleton, {}),
10
+ /* @__PURE__ */ jsx(TextSkeleton, {}),
11
+ /* @__PURE__ */ jsx("div", { className: "placeholder col-4", style: {
12
+ height: "2rem"
13
+ } }),
14
+ /* @__PURE__ */ jsx(TextSkeleton, { className: "col-2" })
15
+ ] })
16
+ ] }) }));
17
+ export {
18
+ NotificationSkeleton as default
19
+ };
@@ -0,0 +1,24 @@
1
+ import { ReactNode } from 'react';
2
+ export type NotificationItemProps = {
3
+ picture: ReactNode;
4
+ message: string;
5
+ date: Date;
6
+ uri?: string;
7
+ children?: ReactNode;
8
+ };
9
+ /**
10
+ * Base layout for a single notification row.
11
+ *
12
+ * Renders a picture slot (avatar or app icon), a clickable message linking to
13
+ * `uri`, a relative timestamp (e.g. "2 hours ago"), and an optional `children`
14
+ * area for extra content below the message.
15
+ *
16
+ * This is a presentational component — it does not know whether the
17
+ * notification comes from a user or a system event. Use `UserNotification` or
18
+ * `SystemNotification` instead of consuming this directly.
19
+ */
20
+ declare const NotificationItem: {
21
+ ({ picture, message, date, uri, children, }: NotificationItemProps): import("react/jsx-runtime").JSX.Element;
22
+ displayName: string;
23
+ };
24
+ export default NotificationItem;
@@ -0,0 +1,28 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import useDate from "../../../../../hooks/useDate/useDate.js";
3
+ import Flex from "../../../../../components/Flex/Flex.js";
4
+ const NotificationItem = ({
5
+ picture,
6
+ message,
7
+ date,
8
+ uri,
9
+ children
10
+ }) => {
11
+ const {
12
+ formatTimeAgo,
13
+ formatDate
14
+ } = useDate();
15
+ return /* @__PURE__ */ jsx(Flex, { direction: "column", className: "notification", gap: "8", children: /* @__PURE__ */ jsxs(Flex, { direction: "row", gap: "8", children: [
16
+ /* @__PURE__ */ jsx("div", { className: "notification-picture", children: picture }),
17
+ /* @__PURE__ */ jsx("a", { href: uri, "data-testid": "notification-content", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "8", children: [
18
+ /* @__PURE__ */ jsx("div", { className: "notification-message", dangerouslySetInnerHTML: {
19
+ __html: message
20
+ } }),
21
+ children,
22
+ /* @__PURE__ */ jsx("p", { className: "notification-date", title: formatDate(date, "LLL"), children: formatTimeAgo(date) })
23
+ ] }) })
24
+ ] }) });
25
+ };
26
+ export {
27
+ NotificationItem as default
28
+ };
@@ -0,0 +1,15 @@
1
+ export type NotificationResourceProps = {
2
+ appCode: string;
3
+ };
4
+ /**
5
+ * Displays the originating application of a notification as a small icon + label.
6
+ *
7
+ * Resolves the human-readable app name via i18n key `<appCode>` present in entcore/portal/backend/src/main/resources/i18n/fr.json,
8
+ * falling back to the raw `appCode` if no translation exists.
9
+ *
10
+ */
11
+ declare const NotificationResource: {
12
+ ({ appCode }: NotificationResourceProps): import("react/jsx-runtime").JSX.Element;
13
+ displayName: string;
14
+ };
15
+ export default NotificationResource;
@@ -0,0 +1,19 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from "react-i18next";
3
+ import AppIcon from "../../../../../components/AppIcon/AppIcon.js";
4
+ const NotificationResource = ({
5
+ appCode
6
+ }) => {
7
+ const {
8
+ t
9
+ } = useTranslation(), appLabel = t(`${appCode}`, {
10
+ defaultValue: appCode
11
+ }), appCssClass = `app-${appCode}`;
12
+ return /* @__PURE__ */ jsxs("div", { className: `notification-resource ${appCssClass} bg-app-light`, children: [
13
+ /* @__PURE__ */ jsx("span", { className: "notification-resource-icon", children: /* @__PURE__ */ jsx(AppIcon, { app: appCode, size: "24", iconFit: "contain" }) }),
14
+ /* @__PURE__ */ jsx("span", { className: "notification-resource-name color-app", children: appLabel })
15
+ ] });
16
+ };
17
+ export {
18
+ NotificationResource as default
19
+ };
@@ -0,0 +1,15 @@
1
+ import { SystemWebNotification } from './notificationAdapter';
2
+ export type SystemNotificationProps = {
3
+ notification: SystemWebNotification;
4
+ };
5
+ /**
6
+ * Renders a system notification (no sender) using an app icon as the picture.
7
+ *
8
+ * Wraps `NotificationItem` — prefer using `Notification` at the top level
9
+ * rather than this component directly.
10
+ */
11
+ declare const SystemNotification: {
12
+ ({ notification }: SystemNotificationProps): import("react/jsx-runtime").JSX.Element;
13
+ displayName: string;
14
+ };
15
+ export default SystemNotification;
@@ -0,0 +1,20 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from "react-i18next";
3
+ import NotificationItem from "./NotificationItem.js";
4
+ import AppIcon from "../../../../../components/AppIcon/AppIcon.js";
5
+ const SystemNotification = ({
6
+ notification
7
+ }) => {
8
+ const {
9
+ params,
10
+ message,
11
+ date,
12
+ uri
13
+ } = notification, {
14
+ t
15
+ } = useTranslation(), appName = t(params.appCode);
16
+ return /* @__PURE__ */ jsx(NotificationItem, { uri, message, date, picture: /* @__PURE__ */ jsx("a", { href: uri, title: appName, "data-testid": "notification-app-icon", "aria-label": t("homepage.notifications.app-icon.placeholder"), children: /* @__PURE__ */ jsx(AppIcon, { app: params.appCode, size: "24", variant: "square", className: "notification-app-icon" }) }) });
17
+ };
18
+ export {
19
+ SystemNotification as default
20
+ };
@@ -0,0 +1,15 @@
1
+ import { UserWebNotification } from './notificationAdapter';
2
+ export type UserNotificationProps = {
3
+ notification: UserWebNotification;
4
+ };
5
+ /**
6
+ * Renders a user-triggered notification using the sender's avatar as the picture.
7
+ *
8
+ * The avatar and its link are resolved via `useDirectory`. Wraps `NotificationItem`
9
+ * — prefer using `Notification` at the top level rather than this component directly.
10
+ */
11
+ declare const UserNotification: {
12
+ ({ notification }: UserNotificationProps): import("react/jsx-runtime").JSX.Element;
13
+ displayName: string;
14
+ };
15
+ export default UserNotification;
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from "react-i18next";
3
+ import NotificationItem from "./NotificationItem.js";
4
+ import NotificationResource from "./NotificationResource.js";
5
+ import useDirectory from "../../../../../hooks/useDirectory/useDirectory.js";
6
+ import Avatar from "../../../../../components/Avatar/Avatar.js";
7
+ const UserNotification = ({
8
+ notification
9
+ }) => {
10
+ const {
11
+ getAvatarURL,
12
+ getUserbookURL
13
+ } = useDirectory(), {
14
+ params,
15
+ message,
16
+ date,
17
+ uri
18
+ } = notification, {
19
+ t
20
+ } = useTranslation(), userName = t(params.username);
21
+ return /* @__PURE__ */ jsx(NotificationItem, { uri, message, date, picture: /* @__PURE__ */ jsx("a", { href: getUserbookURL(params.userId, "user"), title: userName, "data-testid": "notification-avatar", children: /* @__PURE__ */ jsx(Avatar, { "aria-label": t("homepage.notifications.avatar.placeholder"), src: getAvatarURL(params.userId, "user"), alt: userName, variant: "circle", className: "notification-avatar" }) }), children: /* @__PURE__ */ jsx(NotificationResource, { appCode: params.appCode }) });
22
+ };
23
+ export {
24
+ UserNotification as default
25
+ };
@@ -0,0 +1,27 @@
1
+ import { NotificationModel } from '@edifice.io/client';
2
+ type WebNotificationBase = {
3
+ id: string;
4
+ uri?: string;
5
+ message: string;
6
+ date: Date;
7
+ };
8
+ /** Notification triggered by another user (e.g. shared a resource). */
9
+ export type UserWebNotification = WebNotificationBase & {
10
+ type: 'user';
11
+ params: {
12
+ appCode: string;
13
+ username: string;
14
+ userId: string;
15
+ };
16
+ };
17
+ /** Notification triggered by an application event (no sender). */
18
+ export type SystemWebNotification = WebNotificationBase & {
19
+ type: 'system';
20
+ params: {
21
+ appCode: string;
22
+ };
23
+ };
24
+ /** Discriminated union — narrow on `type` to get the specific variant. */
25
+ export type WebNotification = UserWebNotification | SystemWebNotification;
26
+ export declare const notificationAdapter: (notification: NotificationModel) => WebNotification;
27
+ export {};
@@ -0,0 +1,53 @@
1
+ const resolveNotificationResourceUri = (params, type) => {
2
+ if (type === "user")
3
+ return params.resourceUri || params.uri;
4
+ for (const [key, value] of Object.entries(params))
5
+ if (typeof value == "string" && value.length > 0 && key.endsWith("Uri") && key !== "profilUri" && key !== "resourceFolderUri")
6
+ return value;
7
+ }, parseNotificationMessage = (message) => message.replace(/<\/a>/gi, "</strong>").replace(/<a\b[^>]*>/gi, "<strong>"), getAppCode = (appCode) => {
8
+ switch (appCode = appCode.toLowerCase(), appCode) {
9
+ case "collaborativewall":
10
+ return "collaborative-wall";
11
+ case "formulaire":
12
+ return "forms";
13
+ case "messagerie":
14
+ return "conversation";
15
+ case "news":
16
+ return "actualites";
17
+ case "homeworks":
18
+ return "cahier-de-texte";
19
+ case "userbook_motto":
20
+ case "userbook_mood":
21
+ case "userbook_discovervisiblegroups":
22
+ return "userbook";
23
+ default:
24
+ return appCode.replace(/_/g, "-");
25
+ }
26
+ }, notificationAdapter = (notification) => {
27
+ const type = notification.sender ? "user" : "system", uri = resolveNotificationResourceUri(notification.params, type), date = new Date(notification.date.$date), appCode = getAppCode(notification.type), message = parseNotificationMessage(notification.message), base = {
28
+ id: notification._id,
29
+ uri,
30
+ message,
31
+ date
32
+ };
33
+ return type === "user" ? {
34
+ ...base,
35
+ type: "user",
36
+ params: {
37
+ username: notification.params.username,
38
+ // cannot be undefined if sender is present (user type)
39
+ userId: notification.sender,
40
+ // cannot be undefined if sender is present (user type)
41
+ appCode
42
+ }
43
+ } : {
44
+ ...base,
45
+ type: "system",
46
+ params: {
47
+ appCode
48
+ }
49
+ };
50
+ };
51
+ export {
52
+ notificationAdapter
53
+ };
@@ -0,0 +1,20 @@
1
+ import { NotificationModel } from '@edifice.io/client';
2
+ export interface UseNotificationListContainerReturn {
3
+ /** Array of notifications */
4
+ notifications: NotificationModel[] | undefined;
5
+ /** Array of notification types */
6
+ notificationTypes: string[] | undefined;
7
+ /** Indicates if there are more notifications to load */
8
+ hasNextPage: boolean | undefined;
9
+ /** Callback to load the next page of notifications */
10
+ loadNextPage: () => void;
11
+ /** Loading state for fetching notifications */
12
+ isLoading: boolean;
13
+ /** Error state from fetching notifications */
14
+ error: Error | null;
15
+ }
16
+ /**
17
+ * Custom hook that provides notifications data and handlers with exposed loading states
18
+ * @returns Object containing notifications, loading state, and error state
19
+ */
20
+ export declare const useNotificationListContainer: () => UseNotificationListContainerReturn;
@@ -0,0 +1,26 @@
1
+ import { useNotificationTypes, useNotifications } from "../services/queries/notification.js";
2
+ const useNotificationListContainer = () => {
3
+ const {
4
+ data: notificationTypes,
5
+ isLoading: isLoadingTypes,
6
+ isFetched: isFetchedTypes,
7
+ error: errorTypes
8
+ } = useNotificationTypes(), {
9
+ data: notifications,
10
+ hasNextPage,
11
+ isLoading: isLoadingNotifications,
12
+ error: errorNotifications,
13
+ fetchNextPage
14
+ } = useNotifications(notificationTypes ?? [], isFetchedTypes && !!notificationTypes);
15
+ return {
16
+ notifications,
17
+ notificationTypes,
18
+ hasNextPage,
19
+ loadNextPage: () => fetchNextPage(),
20
+ isLoading: isLoadingTypes || isLoadingNotifications,
21
+ error: errorTypes || errorNotifications
22
+ };
23
+ };
24
+ export {
25
+ useNotificationListContainer
26
+ };
@@ -0,0 +1,6 @@
1
+ export * from './Notification';
2
+ export { default as Notification } from './Notification';
3
+ export * from './NotificationList';
4
+ export { default as NotificationList } from './NotificationList';
5
+ export * from './NotificationListContainer';
6
+ export { default as NotificationListContainer } from './NotificationListContainer';
@@ -0,0 +1,4 @@
1
+ export declare const notificationService: {
2
+ getNotifications(types: string[], page: number): Promise<import('@edifice.io/client').NotificationModel[]>;
3
+ getNotificationTypes(): Promise<string[]>;
4
+ };
@@ -0,0 +1,5 @@
1
+ import { createNotificationService } from "./notificationService.js";
2
+ const notificationService = createNotificationService("");
3
+ export {
4
+ notificationService
5
+ };
@@ -0,0 +1,15 @@
1
+ import { NotificationModel } from '@edifice.io/client';
2
+ /**
3
+ * Creates a notification service with methods to interact with notifications.
4
+ *
5
+ * @param baseURL The base URL for the notification service API.
6
+ * @returns A service exposing methods to retrieve notifications.
7
+ */
8
+ export declare const createNotificationService: (baseURL: string) => {
9
+ /**
10
+ * Get notifications.
11
+ * @returns list of notification objects
12
+ */
13
+ getNotifications(types: string[], page: number): Promise<NotificationModel[]>;
14
+ getNotificationTypes(): Promise<string[]>;
15
+ };