@edifice.io/react 2.6.0-develop-pedago.20260721150256 → 2.6.0-develop-integration.20260722215838

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 (40) hide show
  1. package/dist/components/Badge/Badge.d.ts +13 -24
  2. package/dist/components/Badge/Badge.js +6 -6
  3. package/dist/components/Layout/Layout.js +10 -3
  4. package/dist/components/Layout/components/HeaderNotificationsOverlay.d.ts +5 -0
  5. package/dist/components/Layout/components/HeaderNotificationsOverlay.js +18 -0
  6. package/dist/components/PageLayout/store/overlayStore.js +1 -1
  7. package/dist/homepage.js +12 -10
  8. package/dist/hooks/index.d.ts +2 -0
  9. package/dist/hooks/useBrowserInfo/useBrowserInfo.js +1 -2
  10. package/dist/hooks/useNextcloudSearch/index.d.ts +1 -0
  11. package/dist/hooks/useNextcloudSearch/useNextcloudSearch.d.ts +9 -0
  12. package/dist/hooks/useNextcloudSearch/useNextcloudSearch.js +48 -0
  13. package/dist/hooks/useUiOverride/index.d.ts +1 -0
  14. package/dist/hooks/useUiOverride/useUiOverride.d.ts +5 -0
  15. package/dist/hooks/useUiOverride/useUiOverride.js +13 -0
  16. package/dist/index.js +154 -144
  17. package/dist/modules/homepage/components/Header/Header.d.ts +3 -1
  18. package/dist/modules/homepage/components/Header/Header.js +3 -2
  19. package/dist/modules/homepage/components/MessageFlashList/index.d.ts +1 -0
  20. package/dist/modules/multimedia/FileCard/NextcloudFileCard.d.ts +25 -0
  21. package/dist/modules/multimedia/FileCard/NextcloudFileCard.js +105 -0
  22. package/dist/modules/multimedia/FileCard/index.d.ts +2 -0
  23. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.d.ts +2 -2
  24. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.js +20 -7
  25. package/dist/modules/multimedia/MediaLibrary/innertabs/Nextcloud.d.ts +1 -0
  26. package/dist/modules/multimedia/MediaLibrary/innertabs/Nextcloud.js +35 -0
  27. package/dist/modules/multimedia/MediaLibrary/innertabs/index.d.ts +1 -0
  28. package/dist/modules/multimedia/MediaLibrary/innertabs/index.js +2 -0
  29. package/dist/modules/multimedia/Nextcloud/Nextcloud.d.ts +24 -0
  30. package/dist/modules/multimedia/Nextcloud/Nextcloud.js +93 -0
  31. package/dist/modules/multimedia/Nextcloud/index.d.ts +2 -0
  32. package/dist/modules/multimedia/index.d.ts +1 -0
  33. package/dist/multimedia.js +16 -12
  34. package/dist/providers/MockedProvider/MockedProvider.js +4 -3
  35. package/dist/utilities/create-selectors/create-selectors.d.ts +37 -0
  36. package/dist/utilities/create-selectors/index.d.ts +1 -0
  37. package/dist/utilities/index.d.ts +1 -0
  38. package/package.json +8 -7
  39. package/dist/utilities/create-selectors/createSelectors.d.ts +0 -10
  40. /package/dist/utilities/create-selectors/{createSelectors.js → create-selectors.js} +0 -0
@@ -6,11 +6,6 @@ export type NotificationBadgeVariant = {
6
6
  type: 'notification';
7
7
  level: 'success' | 'warning' | 'danger' | 'info';
8
8
  };
9
- /** Badge variant : status */
10
- export type StatusBadgeVariant = {
11
- type: 'status';
12
- level: 'validate' | 'success' | 'warning' | 'danger' | 'info';
13
- };
14
9
  /** Badge variant : content */
15
10
  export type ContentBadgeVariant = {
16
11
  type: 'content';
@@ -32,29 +27,22 @@ export type LinkBadgeVariant = {
32
27
  type: 'link';
33
28
  };
34
29
  /**
35
- * Badge variant : App Version.
36
- *
37
- * Displays a badge showing the app version, for example: BÊTA, ALPHA, NEW or a custom version label.
38
- *
39
- * Default label is BÊTA unless a label is provided as a children of the component.
40
- * Example of usage:
41
- * <Badge variant={{ type: 'appVersion', app: myApp }}>NEW</Badge>
42
- *
43
- * The color prop allows to customize the badge color to match the app color (Defaults to black if not provided).
44
- * Example of usage:
45
- * <Badge variant={{ type: 'appVersion', color: '#823AA1' }} />
46
- *
47
- * If app prop is provided, the color of the App Version Badge is derived from the application colors,
48
- * for example if the app provided is Blog then the Badge will have the same color as Blog app.
49
- * Example of usage:
50
- * <Badge variant={{ type: 'appVersion', app: blog }} />
30
+ * Badge variant : beta.
31
+ * Beta Badge is used to indicate that a feature is in beta phase.
32
+ * The color prop allows to customize the badge color to match the app color.
33
+ * Defaults to black if not provided.
34
+ * Beta Badge has a fixed text 'BÊTA' unless children is provided.
35
+ * If app is provided, the color of the Beta Badge is derived from the application colors.
36
+ * Example:
37
+ * <Badge variant={{ type: 'beta', color: '#823AA1', app: myApp }} />
38
+ * where myApp is of type IWebApp.
51
39
  */
52
- export type AppVersionBadgeVariant = {
53
- type: 'appVersion';
40
+ export type BetaBadgeVariant = {
41
+ type: 'beta';
54
42
  color?: string;
55
43
  app?: IWebApp;
56
44
  };
57
- export type BadgeVariants = NotificationBadgeVariant | StatusBadgeVariant | ContentBadgeVariant | ProfileBadgeVariant | ChipBadgeVariant | LinkBadgeVariant | AppVersionBadgeVariant;
45
+ export type BadgeVariants = NotificationBadgeVariant | ContentBadgeVariant | ProfileBadgeVariant | ChipBadgeVariant | LinkBadgeVariant | BetaBadgeVariant;
58
46
  export interface BadgeProps extends React.ComponentPropsWithRef<'span'> {
59
47
  /**
60
48
  * Badge variant : notification, link or profile (Teacher|Student|Relative|Personnel)
@@ -63,6 +51,7 @@ export interface BadgeProps extends React.ComponentPropsWithRef<'span'> {
63
51
  variant?: BadgeVariants;
64
52
  /**
65
53
  * Text or icon (or whatever) to render as children elements.
54
+ * Defaults to 'BÊTA' for beta variant.
66
55
  */
67
56
  children?: ReactNode;
68
57
  /**
@@ -16,16 +16,16 @@ const Badge = /* @__PURE__ */ forwardRef(({
16
16
  getBackgroundLightIconClass,
17
17
  getBorderIconClass
18
18
  } = useEdificeIcons();
19
- let appVersionBadgeColorClassName = "";
20
- if (variant.type === "appVersion" && variant.app) {
19
+ let badgeColorClassName = "";
20
+ if (variant.type === "beta" && variant.app) {
21
21
  const colorAppClassName = getIconClass(variant.app), backgroundLightAppClassName = getBackgroundLightIconClass(variant.app), borderAppClassName = getBorderIconClass(variant.app);
22
- appVersionBadgeColorClassName = `${colorAppClassName} ${backgroundLightAppClassName} ${borderAppClassName}`;
22
+ badgeColorClassName = `${colorAppClassName} ${backgroundLightAppClassName} ${borderAppClassName}`;
23
23
  }
24
- const classes = clsx("badge rounded-pill", (variant.type === "content" || variant.type === "user") && "background" in variant ? "bg-gray-200" : (variant.type === "content" || variant.type === "user") && !("background" in variant) ? "border border-0" : "", variant.type === "content" && `text-${variant.level}`, variant.type === "notification" && `badge-notification bg-${variant.level} text-light border border-0`, variant.type === "status" && `badge-status badge-status-${variant.level} caption fw-normal`, variant.type === "user" && `badge-profile-${variant.profile.toLowerCase()}`, variant.type === "link" && "badge-link border border-0", variant.type === "chip" && "bg-gray-200", variant.type === "appVersion" && appVersionBadgeColorClassName, className);
24
+ const classes = clsx("badge rounded-pill", (variant.type === "content" || variant.type === "user") && "background" in variant ? "bg-gray-200" : (variant.type === "content" || variant.type === "user") && !("background" in variant) ? "border border-0" : "", variant.type === "content" && `text-${variant.level}`, variant.type === "notification" && `badge-notification bg-${variant.level} text-light border border-0`, variant.type === "user" && `badge-profile-${variant.profile.toLowerCase()}`, variant.type === "link" && "badge-link border border-0", variant.type === "chip" && "bg-gray-200", variant.type === "beta" && badgeColorClassName, className);
25
25
  return /* @__PURE__ */ jsxs("span", { ref, className: classes, ...restProps, children: [
26
26
  variant.type === "chip" && /* @__PURE__ */ jsx("div", { className: "d-flex fw-800 align-items-center", children }),
27
- variant.type === "appVersion" && (children ?? "BÊTA"),
28
- variant.type !== "chip" && variant.type !== "appVersion" && children
27
+ variant.type === "beta" && (children ?? "BÊTA"),
28
+ variant.type !== "chip" && variant.type !== "beta" && children
29
29
  ] });
30
30
  });
31
31
  export {
@@ -1,15 +1,19 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { Suspense, lazy } from "react";
2
3
  import clsx from "clsx";
3
4
  import { Toaster } from "react-hot-toast";
4
5
  import { useTranslation } from "react-i18next";
5
6
  import { useEdificeTheme } from "../../providers/EdificeThemeProvider/EdificeThemeProvider.hook.js";
6
7
  import Header from "./components/Header.js";
8
+ import HeaderNotificationsOverlay from "./components/HeaderNotificationsOverlay.js";
9
+ import { useOverlay } from "../PageLayout/hook/useOverlay.js";
10
+ import useUiOverride from "../../hooks/useUiOverride/useUiOverride.js";
7
11
  import useCookiesConsent from "../../hooks/useCookiesConsent/useCookiesConsent.js";
8
12
  import useZendeskGuide from "../../hooks/useZendeskGuide/useZendeskGuide.js";
9
13
  import useCantoo from "../../hooks/useCantoo/useCantoo.js";
10
14
  import Alert from "../Alert/Alert.js";
11
15
  import Button from "../Button/Button.js";
12
- const Layout = ({
16
+ const HeaderV2 = /* @__PURE__ */ lazy(() => import("../../modules/homepage/components/Header/Header.js")), Layout = ({
13
17
  children,
14
18
  headless = !1,
15
19
  whiteBg = !0,
@@ -18,7 +22,9 @@ const Layout = ({
18
22
  }) => {
19
23
  const {
20
24
  theme
21
- } = useEdificeTheme(), {
25
+ } = useEdificeTheme(), override = useUiOverride("layout.header"), isHeaderV2 = (override == null ? void 0 : override.variant) === "v2", {
26
+ toggleOverlay
27
+ } = useOverlay(), {
22
28
  t
23
29
  } = useTranslation(), {
24
30
  showCookiesConsent,
@@ -31,11 +37,12 @@ const Layout = ({
31
37
  "container-fluid": !headless,
32
38
  "rounded-4 border": (theme == null ? void 0 : theme.is1d) && !headless,
33
39
  "mt-24": (theme == null ? void 0 : theme.is1d) && !headless
34
- }, className), renderHeader = headless ? null : /* @__PURE__ */ jsx(Header, { is1d: theme == null ? void 0 : theme.is1d, src: theme == null ? void 0 : theme.basePath }), renderCookies = showCookiesConsent && /* @__PURE__ */ jsx(Alert, { type: "info", className: "m-12 rgpd", isConfirm: !0, position: "bottom-right", button: /* @__PURE__ */ jsx(Button, { color: "tertiary", variant: "ghost", onClick: handleConsultCookies, children: t("rgpd.cookies.banner.button.consult") }), onClose: handleCloseCookiesConsent, children: t("rgpd.cookies.banner.text1") }), renderToaster = /* @__PURE__ */ jsx(Toaster, { containerClassName: "toaster-container", toastOptions: {
40
+ }, className), renderHeader = headless ? null : isHeaderV2 ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(HeaderV2, { src: theme == null ? void 0 : theme.basePath, dataProduct: override == null ? void 0 : override.theme, onNotificationsClick: toggleOverlay }) }) : /* @__PURE__ */ jsx(Header, { is1d: theme == null ? void 0 : theme.is1d, src: theme == null ? void 0 : theme.basePath }), renderNotificationsOverlay = !headless && isHeaderV2 && /* @__PURE__ */ jsx(HeaderNotificationsOverlay, {}), renderCookies = showCookiesConsent && /* @__PURE__ */ jsx(Alert, { type: "info", className: "m-12 rgpd", isConfirm: !0, position: "bottom-right", button: /* @__PURE__ */ jsx(Button, { color: "tertiary", variant: "ghost", onClick: handleConsultCookies, children: t("rgpd.cookies.banner.button.consult") }), onClose: handleCloseCookiesConsent, children: t("rgpd.cookies.banner.text1") }), renderToaster = /* @__PURE__ */ jsx(Toaster, { containerClassName: "toaster-container", toastOptions: {
35
41
  position: "top-right"
36
42
  } });
37
43
  return /* @__PURE__ */ jsxs(Fragment, { children: [
38
44
  renderHeader,
45
+ renderNotificationsOverlay,
39
46
  /* @__PURE__ */ jsx("main", { className: classes, ...restProps, children }),
40
47
  renderToaster,
41
48
  renderCookies
@@ -0,0 +1,5 @@
1
+ declare const HeaderNotificationsOverlay: {
2
+ (): import("react/jsx-runtime").JSX.Element;
3
+ displayName: string;
4
+ };
5
+ export default HeaderNotificationsOverlay;
@@ -0,0 +1,18 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { NotificationListContainer } from "../../../modules/homepage/components/Notifications/NotificationListContainer.js";
3
+ import PageLayoutOverlay from "../../PageLayout/components/PageLayoutOverlay.js";
4
+ import { useOverlay } from "../../PageLayout/hook/useOverlay.js";
5
+ const HeaderNotificationsOverlay = () => {
6
+ const {
7
+ isOverlayOpen,
8
+ updateOverlayOpen
9
+ } = useOverlay(), handleClose = () => updateOverlayOpen(!1);
10
+ return (
11
+ // NotificationList renders its own header with a close button, so
12
+ // PageLayoutOverlay's default close button would be redundant (double X).
13
+ /* @__PURE__ */ jsx(PageLayoutOverlay, { onClose: handleClose, closeButton: !1, children: isOverlayOpen && /* @__PURE__ */ jsx(NotificationListContainer, { onCloseNotifications: handleClose }) })
14
+ );
15
+ };
16
+ export {
17
+ HeaderNotificationsOverlay as default
18
+ };
@@ -1,5 +1,5 @@
1
1
  import { create } from "zustand";
2
- import { createSelectors } from "../../../utilities/create-selectors/createSelectors.js";
2
+ import { createSelectors } from "../../../utilities/create-selectors/create-selectors.js";
3
3
  const useOverlayStore = createSelectors(create((set) => ({
4
4
  overlayOpen: !1,
5
5
  updateOverlayOpen: (value) => set((previousState) => ({
package/dist/homepage.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { default as default2 } from "./modules/homepage/components/Header/Header.js";
2
2
  import { default as default3 } from "./modules/homepage/components/HomeCard/HomeCard.js";
3
3
  import { default as default4 } from "./modules/homepage/components/LastInfos/LastInfos.js";
4
- import { default as default5 } from "./modules/homepage/components/MessageFlashList/MessageFlashList.js";
5
- import { default as default6 } from "./modules/homepage/components/Notifications/NotificationItem.js";
6
- import { default as default7 } from "./modules/homepage/components/Notifications/NotificationList.js";
4
+ import { default as default5 } from "./modules/homepage/components/MessageFlashList/MessageFlash.js";
5
+ import { default as default6 } from "./modules/homepage/components/MessageFlashList/MessageFlashList.js";
6
+ import { default as default7 } from "./modules/homepage/components/Notifications/NotificationItem.js";
7
+ import { default as default8 } from "./modules/homepage/components/Notifications/NotificationList.js";
7
8
  import { NotificationListContainer } from "./modules/homepage/components/Notifications/NotificationListContainer.js";
8
- import { default as default8 } from "./modules/homepage/components/SchoolSpace/SchoolSpace.js";
9
- import { default as default9 } from "./modules/homepage/components/UserSpace/UserSpace.js";
9
+ import { default as default9 } from "./modules/homepage/components/SchoolSpace/SchoolSpace.js";
10
+ import { default as default10 } from "./modules/homepage/components/UserSpace/UserSpace.js";
10
11
  import { Favorites } from "./modules/homepage/components/Favorites/Favorites.js";
11
12
  import { FavoritesContainer } from "./modules/homepage/components/Favorites/FavoritesContainer.js";
12
13
  import { LastInfosContainer } from "./modules/homepage/components/LastInfos/LastInfosContainer.js";
@@ -22,13 +23,14 @@ export {
22
23
  default4 as LastInfos,
23
24
  LastInfosContainer,
24
25
  LastInfosList,
25
- default5 as MessageFlashList,
26
+ default5 as MessageFlash,
27
+ default6 as MessageFlashList,
26
28
  MessageFlashListContainer,
27
- default6 as NotificationItem,
28
- default7 as NotificationList,
29
+ default7 as NotificationItem,
30
+ default8 as NotificationList,
29
31
  NotificationListContainer,
30
- default8 as SchoolSpace,
32
+ default9 as SchoolSpace,
31
33
  SchoolSpaceContainer,
32
- default9 as UserSpace,
34
+ default10 as UserSpace,
33
35
  UserSpaceContainer
34
36
  };
@@ -22,6 +22,7 @@ export * from './useIsAdmlcOrAdmc';
22
22
  export * from './useKeyPress';
23
23
  export * from './useLibraryUrl';
24
24
  export * from './useMediaLibrary';
25
+ export * from './useNextcloudSearch';
25
26
  export * from './usePublicConf';
26
27
  export * from './useScreeb';
27
28
  export * from './useScrollToTop';
@@ -30,6 +31,7 @@ export * from './useToast';
30
31
  export * from './useToggle';
31
32
  export * from './useTrapFocus';
32
33
  export * from './useTrashedResource';
34
+ export * from './useUiOverride';
33
35
  export * from './useUpload';
34
36
  export * from './useUploadFiles';
35
37
  export * from './useUser';
@@ -1,7 +1,6 @@
1
1
  import { UAParser } from "ua-parser-js";
2
2
  function useBrowserInfo(userAgent) {
3
- var _a, _b, _c;
4
- const uaParser = new UAParser(userAgent), os = uaParser.getOS(), device = uaParser.getDevice(), browser = uaParser.getBrowser(), isIphone = ((_a = device.model) == null ? void 0 : _a.indexOf("iPhone")) != -1, isIpod = ((_b = device.model) == null ? void 0 : _b.indexOf("iPod")) != -1, isIpad = ((_c = device.model) == null ? void 0 : _c.indexOf("iPad")) != -1;
3
+ const uaParser = new UAParser(userAgent), os = uaParser.getOS(), device = uaParser.getDevice(), browser = uaParser.getBrowser(), deviceModel = device.model ?? "", isIphone = deviceModel.includes("iPhone"), isIpod = deviceModel.includes("iPod"), isIpad = deviceModel.includes("iPad");
5
4
  return {
6
5
  os,
7
6
  device,
@@ -0,0 +1 @@
1
+ export { default as useNextcloudSearch } from './useNextcloudSearch';
@@ -0,0 +1,9 @@
1
+ import { ID, NextcloudDocument } from '@edifice.io/client';
2
+ import { TreeData } from '../../types';
3
+ export type NextcloudFolderNode = TreeData & {
4
+ files?: NextcloudDocument[];
5
+ };
6
+ export default function useNextcloudSearch(rootId: string, rootName: string, userId?: string): {
7
+ root: NextcloudFolderNode;
8
+ loadContent: (folderId?: ID) => void;
9
+ };
@@ -0,0 +1,48 @@
1
+ import { useReducer, useCallback } from "react";
2
+ import { odeServices } from "@edifice.io/client";
3
+ import { useQueryClient } from "@tanstack/react-query";
4
+ import { findNodeById } from "../../components/TreeView/utilities/treeview.js";
5
+ function useNextcloudSearch(rootId, rootName, userId) {
6
+ function treeReducer(state, action) {
7
+ switch (action.type) {
8
+ case "update": {
9
+ const node = findNodeById(state, action.folderId);
10
+ return node && (node.children = action.subfolders.map((f) => ({
11
+ id: f.path,
12
+ name: f.name
13
+ })), node.files = action.files), {
14
+ ...state
15
+ };
16
+ }
17
+ default:
18
+ throw Error("[useNextcloudSearch] Unknown action type: " + action.type);
19
+ }
20
+ }
21
+ const [root, dispatch] = useReducer(treeReducer, {
22
+ id: rootId,
23
+ name: rootName,
24
+ section: !0
25
+ }), queryClient = useQueryClient(), loadContent = useCallback(async (folderId) => {
26
+ if (!userId) return;
27
+ const path = folderId === rootId ? void 0 : folderId, payload = await queryClient.fetchQuery({
28
+ queryKey: ["nextcloud", "documents", userId, path ?? "/"],
29
+ queryFn: () => odeServices.nextcloud().listDocuments(userId, path),
30
+ staleTime: 6e4
31
+ }), subfolders = [], files = [], currentPath = path ?? "/";
32
+ payload.filter((doc) => doc.path !== currentPath).forEach((doc) => {
33
+ doc.isFolder ? subfolders.push(doc) : files.push(doc);
34
+ }), dispatch({
35
+ folderId,
36
+ subfolders,
37
+ files,
38
+ type: "update"
39
+ });
40
+ }, [rootId, userId, queryClient]);
41
+ return {
42
+ root,
43
+ loadContent
44
+ };
45
+ }
46
+ export {
47
+ useNextcloudSearch as default
48
+ };
@@ -0,0 +1 @@
1
+ export { default as useUiOverride } from './useUiOverride';
@@ -0,0 +1,5 @@
1
+ /** Read the platform-driven UI override registered under `key` in the theme-conf, normalized to an object form. */
2
+ export default function useUiOverride(key: string): {
3
+ variant: string;
4
+ theme?: string;
5
+ } | undefined;
@@ -0,0 +1,13 @@
1
+ import { useEdificeTheme } from "../../providers/EdificeThemeProvider/EdificeThemeProvider.hook.js";
2
+ function useUiOverride(key) {
3
+ var _a;
4
+ const {
5
+ theme
6
+ } = useEdificeTheme(), raw = (_a = theme == null ? void 0 : theme.uiOverrides) == null ? void 0 : _a[key];
7
+ return typeof raw == "string" ? {
8
+ variant: raw
9
+ } : raw;
10
+ }
11
+ export {
12
+ useUiOverride as default
13
+ };