@edifice.io/react 2.6.7-develop-integration.20261005091442 → 2.6.7-develop-pedago.20261005162423

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 (47) hide show
  1. package/dist/components/Layout/Layout.js +4 -3
  2. package/dist/components/Tree/utilities/tree.js +1 -21
  3. package/dist/homepage.js +2 -1
  4. package/dist/hooks/index.d.ts +0 -2
  5. package/dist/hooks/useBackground/useBackground.d.ts +1 -0
  6. package/dist/hooks/useBackground/useBackground.js +2 -0
  7. package/dist/index.js +182 -194
  8. package/dist/modules/editor/components/EditorToolbar/EditorToolbar.Typography.js +3 -3
  9. package/dist/modules/homepage/components/Communities/Communities.d.ts +2 -1
  10. package/dist/modules/homepage/components/Communities/Communities.js +14 -13
  11. package/dist/modules/homepage/components/Communities/CommunitiesContainer.d.ts +1 -1
  12. package/dist/modules/homepage/components/Communities/CommunitiesContainer.js +9 -5
  13. package/dist/modules/homepage/components/Communities/CommunitiesSkeleton.js +4 -7
  14. package/dist/modules/homepage/components/Communities/useCommunities.d.ts +4 -1
  15. package/dist/modules/homepage/components/Communities/useCommunities.js +8 -3
  16. package/dist/modules/homepage/components/HomeCard/HomeCardHeader.js +2 -2
  17. package/dist/modules/multimedia/FileCard/index.d.ts +0 -4
  18. package/dist/modules/multimedia/Linker/InternalLinker/InternalLinker.d.ts +1 -7
  19. package/dist/modules/multimedia/Linker/InternalLinker/InternalLinker.js +0 -2
  20. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.d.ts +2 -2
  21. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.js +12 -48
  22. package/dist/modules/multimedia/MediaLibrary/innertabs/index.d.ts +0 -2
  23. package/dist/modules/multimedia/MediaLibrary/innertabs/index.js +0 -4
  24. package/dist/modules/multimedia/Workspace/Workspace.js +5 -8
  25. package/dist/modules/multimedia/index.d.ts +0 -2
  26. package/dist/multimedia.js +18 -26
  27. package/package.json +6 -6
  28. package/dist/hooks/useGoogleDriveSearch/index.d.ts +0 -1
  29. package/dist/hooks/useGoogleDriveSearch/useGoogleDriveSearch.d.ts +0 -14
  30. package/dist/hooks/useGoogleDriveSearch/useGoogleDriveSearch.js +0 -60
  31. package/dist/hooks/useNextcloudSearch/index.d.ts +0 -1
  32. package/dist/hooks/useNextcloudSearch/useNextcloudSearch.d.ts +0 -14
  33. package/dist/hooks/useNextcloudSearch/useNextcloudSearch.js +0 -64
  34. package/dist/modules/multimedia/FileCard/GoogleDriveFileCard.d.ts +0 -25
  35. package/dist/modules/multimedia/FileCard/GoogleDriveFileCard.js +0 -102
  36. package/dist/modules/multimedia/FileCard/NextcloudFileCard.d.ts +0 -25
  37. package/dist/modules/multimedia/FileCard/NextcloudFileCard.js +0 -102
  38. package/dist/modules/multimedia/GoogleDrive/GoogleDrive.d.ts +0 -24
  39. package/dist/modules/multimedia/GoogleDrive/GoogleDrive.js +0 -100
  40. package/dist/modules/multimedia/GoogleDrive/index.d.ts +0 -2
  41. package/dist/modules/multimedia/MediaLibrary/innertabs/GoogleDrive.d.ts +0 -1
  42. package/dist/modules/multimedia/MediaLibrary/innertabs/GoogleDrive.js +0 -61
  43. package/dist/modules/multimedia/MediaLibrary/innertabs/Nextcloud.d.ts +0 -1
  44. package/dist/modules/multimedia/MediaLibrary/innertabs/Nextcloud.js +0 -48
  45. package/dist/modules/multimedia/Nextcloud/Nextcloud.d.ts +0 -24
  46. package/dist/modules/multimedia/Nextcloud/Nextcloud.js +0 -124
  47. package/dist/modules/multimedia/Nextcloud/index.d.ts +0 -2
@@ -1,32 +1,33 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import illuCommunities from "@edifice.io/bootstrap/dist/images/homepage/illu-communities.svg";
3
- import { useMeasure } from "@uidotdev/usehooks";
4
3
  import { useTranslation } from "react-i18next";
5
4
  import SvgIconArrowRight from "../../../icons/components/IconArrowRight.js";
6
5
  import CommunityItem from "./CommunityItem.js";
7
6
  import HomeCard from "../HomeCard/HomeCard.js";
8
7
  import Flex from "../../../../components/Flex/Flex.js";
9
8
  import Image from "../../../../components/Image/Image.js";
10
- const NARROW_CONTAINER_WIDTH = 800, MAX_ITEMS = 4, MAX_ITEMS_NARROW = 3, Communities = ({
9
+ const Communities = ({
11
10
  communitiesList = [],
12
- handleActionClick
11
+ handleActionClick,
12
+ canCreateCommunity = !1
13
13
  }) => {
14
14
  const {
15
15
  t
16
- } = useTranslation(), [containerRef, {
17
- width
18
- }] = useMeasure(), maxItems = width !== null && width < NARROW_CONTAINER_WIDTH ? MAX_ITEMS_NARROW : MAX_ITEMS, visibleCommunities = communitiesList.slice(0, maxItems), itemWidth = `${100 / maxItems}%`;
16
+ } = useTranslation();
19
17
  return /* @__PURE__ */ jsxs(HomeCard, { variant: "primary", children: [
20
- /* @__PURE__ */ jsx(HomeCard.Header, { actionLabel: communitiesList.length > 0 ? t("homepage.communities.actionLabel.seeMore") : t("homepage.communities.actionLabel.create"), actionRightIcon: /* @__PURE__ */ jsx(SvgIconArrowRight, {}), onActionClick: handleActionClick, title: t("homepage.communities.title") }),
21
- /* @__PURE__ */ jsx(HomeCard.Content, { children: /* @__PURE__ */ jsx(Flex, { ref: containerRef, gap: "16", children: visibleCommunities.length > 0 ? visibleCommunities.map((community, index) => /* @__PURE__ */ jsx(CommunityItem, { title: community.title, communityImage: community.communityImage, onActionClick: community.onActionClick, nbNotifications: community.nbNotifications, width: itemWidth }, index)) : /* @__PURE__ */ jsxs("div", { className: "communities-empty", children: [
18
+ /* @__PURE__ */ jsx(HomeCard.Header, { actionLabel: communitiesList.length > 0 || !canCreateCommunity ? t("homepage.communities.actionLabel.seeMore", "Voir plus") : t("homepage.communities.actionLabel.create", "Créer une communauté"), actionRightIcon: /* @__PURE__ */ jsx(SvgIconArrowRight, {}), onActionClick: handleActionClick, title: t("homepage.communities.title", "Mes communautés") }),
19
+ /* @__PURE__ */ jsx(HomeCard.Content, { className: "communities-content", children: /* @__PURE__ */ jsx(Flex, { gap: "16", children: communitiesList.length > 0 ? /* @__PURE__ */ jsx("div", { className: "communities-list", children: communitiesList.map((community, index) => /* @__PURE__ */ jsx(CommunityItem, { title: community.title, communityImage: community.communityImage, onActionClick: community.onActionClick, nbNotifications: community.nbNotifications, width: "auto" }, index)) }) : /* @__PURE__ */ jsxs("div", { className: "communities-empty", children: [
22
20
  /* @__PURE__ */ jsx(Image, { src: illuCommunities, alt: "", "aria-hidden": "true", style: {
23
21
  width: 80,
24
22
  height: 80
25
23
  } }),
26
- /* @__PURE__ */ jsxs("div", { className: "communities-empty-content", children: [
27
- /* @__PURE__ */ jsx("p", { className: "communities-empty-title", children: t("homepage.communities.subtitle", "Créez votre première communauté pour animer votre classe !") }),
28
- /* @__PURE__ */ jsx("p", { className: "communities-empty-description", children: t("homepage.communities.description", "Vous pouvez centraliser et organiser les documents et les ressources pour vos élèves.") })
29
- ] })
24
+ /* @__PURE__ */ jsx("div", { className: "communities-empty-content", children: canCreateCommunity ? /* @__PURE__ */ jsxs(Fragment, { children: [
25
+ /* @__PURE__ */ jsx("p", { className: "communities-empty-title", children: t("homepage.communities.subtitle.teacher", "Réunissez vos élèves avec Communautés !") }),
26
+ /* @__PURE__ */ jsx("p", { className: "communities-empty-description", children: t("homepage.communities.description.teacher", "Centralisez et organisez les documents et les ressources pour vos groupes d'élèves.") })
27
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ /* @__PURE__ */ jsx("p", { className: "communities-empty-title", children: t("homepage.communities.subtitle.student", "Retrouvez toutes vos communautés ici ! ") }),
29
+ /* @__PURE__ */ jsx("p", { className: "communities-empty-description", children: t("homepage.communities.description.student", `Consultez l'onglet "Nouveaux partages" pour découvrir si vous avez été ajouté à une nouvelle communauté.`) })
30
+ ] }) })
30
31
  ] }) }) })
31
32
  ] });
32
33
  };
@@ -5,7 +5,7 @@ export type CommunitiesContainerProps = {
5
5
  /** Handle a click on the header action button. If undefined, communities (or the community creation flow) will be opened. */
6
6
  onHeaderActionClick?: () => void;
7
7
  };
8
- export declare function CommunitiesContainer({ onCommunityClick: handleCommunityClick, onHeaderActionClick: handleHeaderActionClick, }: CommunitiesContainerProps): import("react/jsx-runtime").JSX.Element | "An error occurred while loading communities.";
8
+ export declare function CommunitiesContainer({ onCommunityClick: handleCommunityClick, onHeaderActionClick: handleHeaderActionClick, }: CommunitiesContainerProps): import("react/jsx-runtime").JSX.Element | "An error occurred while loading communities." | null;
9
9
  export declare namespace CommunitiesContainer {
10
10
  var displayName: string;
11
11
  }
@@ -3,28 +3,32 @@ import { useCallback, useMemo } from "react";
3
3
  import Communities from "./Communities.js";
4
4
  import CommunitiesSkeleton from "./CommunitiesSkeleton.js";
5
5
  import { useCommunities } from "./useCommunities.js";
6
+ import useHasWorkflow from "../../../../hooks/useHasWorkflow/useHasWorkflow.js";
7
+ const COMMUNITY_ACCESS_WORKFLOW = "community.access", COMMUNITY_CREATE_WORKFLOW = "community.create", COMMUNITY_WORKFLOWS = [COMMUNITY_ACCESS_WORKFLOW, COMMUNITY_CREATE_WORKFLOW];
6
8
  function CommunitiesContainer({
7
9
  onCommunityClick: handleCommunityClick = (community) => {
8
10
  window.open(`/communities/id/${community.id}/home`, "_self");
9
11
  },
10
12
  onHeaderActionClick: handleHeaderActionClick
11
13
  }) {
12
- const {
14
+ const rights = useHasWorkflow(COMMUNITY_WORKFLOWS), canCreateCommunity = (rights == null ? void 0 : rights[COMMUNITY_CREATE_WORKFLOW]) === !0, hasCommunitiesRight = canCreateCommunity || (rights == null ? void 0 : rights[COMMUNITY_ACCESS_WORKFLOW]) === !0, {
13
15
  communities,
14
16
  isLoading,
15
17
  error
16
- } = useCommunities(), handleActionClick = useCallback(() => {
18
+ } = useCommunities({
19
+ enabled: hasCommunitiesRight
20
+ }), handleActionClick = useCallback(() => {
17
21
  if (handleHeaderActionClick) {
18
22
  handleHeaderActionClick();
19
23
  return;
20
24
  }
21
- window.open(communities.length > 0 ? "/communities" : "/communities/create/step-type", "_self");
22
- }, [handleHeaderActionClick, communities.length]), mappedCommunities = useMemo(() => communities.map((community) => ({
25
+ window.open(communities.length === 0 && canCreateCommunity ? "/communities/create/step-type" : "/communities", "_self");
26
+ }, [handleHeaderActionClick, communities.length, canCreateCommunity]), mappedCommunities = useMemo(() => communities.map((community) => ({
23
27
  title: community.title,
24
28
  communityImage: community.image ?? "",
25
29
  onActionClick: () => handleCommunityClick(community)
26
30
  })), [communities, handleCommunityClick]);
27
- return isLoading ? /* @__PURE__ */ jsx(CommunitiesSkeleton, {}) : error ? "An error occurred while loading communities." : /* @__PURE__ */ jsx(Communities, { communitiesList: mappedCommunities, handleActionClick });
31
+ return rights === void 0 || isLoading ? /* @__PURE__ */ jsx(CommunitiesSkeleton, {}) : hasCommunitiesRight ? error ? "An error occurred while loading communities." : /* @__PURE__ */ jsx(Communities, { communitiesList: mappedCommunities, handleActionClick, canCreateCommunity }) : null;
28
32
  }
29
33
  export {
30
34
  CommunitiesContainer
@@ -3,17 +3,14 @@ import HomeCard from "../HomeCard/HomeCard.js";
3
3
  import Flex from "../../../../components/Flex/Flex.js";
4
4
  import TextSkeleton from "../../../../components/Skeleton/TextSkeleton.js";
5
5
  import ButtonSkeleton from "../../../../components/Skeleton/ButtonSkeleton.js";
6
- const primaryTitleWidths = ["80%", "64%", "88%", "72%"], secondaryTitleWidths = ["56%", "44%", "60%", "48%"], CommunitiesSkeleton = () => /* @__PURE__ */ jsxs(HomeCard, { variant: "primary", "data-testid": "communities-skeleton", children: [
6
+ const primaryTitleWidths = ["80%", "64%", "88%", "72%", "76%", "68%"], secondaryTitleWidths = ["56%", "44%", "60%", "48%", "52%", "40%"], CommunitiesSkeleton = () => /* @__PURE__ */ jsxs(HomeCard, { variant: "primary", "data-testid": "communities-skeleton", children: [
7
7
  /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", gap: "8", className: "home-card-header", children: [
8
8
  /* @__PURE__ */ jsx(TextSkeleton, { size: "lg", className: "col-5" }),
9
9
  /* @__PURE__ */ jsx(ButtonSkeleton, { "aria-hidden": "true", size: "sm", className: "px-24", color: "tertiary" })
10
10
  ] }),
11
- /* @__PURE__ */ jsx(HomeCard.Content, { children: /* @__PURE__ */ jsx(Flex, { gap: "16", children: primaryTitleWidths.map((primaryWidth, index) => /* @__PURE__ */ jsxs("div", { className: "communities-item", style: {
12
- width: "25%"
13
- }, "aria-hidden": "true", children: [
11
+ /* @__PURE__ */ jsx(HomeCard.Content, { className: "communities-content", children: /* @__PURE__ */ jsx(Flex, { gap: "16", children: /* @__PURE__ */ jsx("div", { className: "communities-list", children: primaryTitleWidths.map((primaryWidth, index) => /* @__PURE__ */ jsxs("div", { className: "communities-item", "aria-hidden": "true", children: [
14
12
  /* @__PURE__ */ jsx("div", { className: "communities-item-image placeholder rounded", style: {
15
- display: "block",
16
- aspectRatio: "1 / 1"
13
+ display: "block"
17
14
  } }),
18
15
  /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "4", className: "mt-8", children: [
19
16
  /* @__PURE__ */ jsx("div", { style: {
@@ -25,7 +22,7 @@ const primaryTitleWidths = ["80%", "64%", "88%", "72%"], secondaryTitleWidths =
25
22
  alignSelf: "center"
26
23
  }, children: /* @__PURE__ */ jsx(TextSkeleton, { className: "col-12", size: "sm" }) })
27
24
  ] })
28
- ] }, primaryWidth)) }) })
25
+ ] }, primaryWidth)) }) }) })
29
26
  ] });
30
27
  export {
31
28
  CommunitiesSkeleton as default
@@ -3,7 +3,10 @@ export interface CommunitiesModel {
3
3
  title: string;
4
4
  image?: string;
5
5
  }
6
- export declare function useCommunities(): {
6
+ export declare const COMMUNITIES_PREVIEW_SIZE = 6;
7
+ export declare function useCommunities({ enabled }?: {
8
+ enabled?: boolean;
9
+ }): {
7
10
  communities: CommunitiesModel[];
8
11
  isLoading: boolean;
9
12
  error: Error | null;
@@ -1,6 +1,9 @@
1
1
  import { odeServices } from "@edifice.io/client";
2
2
  import { useQuery, queryOptions } from "@tanstack/react-query";
3
- function useCommunities() {
3
+ const COMMUNITIES_PREVIEW_SIZE = 6;
4
+ function useCommunities({
5
+ enabled = !0
6
+ } = {}) {
4
7
  const {
5
8
  data,
6
9
  isLoading,
@@ -8,11 +11,12 @@ function useCommunities() {
8
11
  } = useQuery(queryOptions({
9
12
  queryKey: ["communities", "preview"],
10
13
  queryFn: async () => {
11
- const http = odeServices.http(), response = await http.get("/communities/api/communities?page=1&size=4");
14
+ const http = odeServices.http(), response = await http.get(`/communities/api/communities?page=1&size=${COMMUNITIES_PREVIEW_SIZE}`);
12
15
  if (http.isResponseError())
13
16
  throw new Error(http.latestResponse.statusText);
14
17
  return response.items;
15
- }
18
+ },
19
+ enabled
16
20
  }));
17
21
  return {
18
22
  communities: data ?? [],
@@ -21,5 +25,6 @@ function useCommunities() {
21
25
  };
22
26
  }
23
27
  export {
28
+ COMMUNITIES_PREVIEW_SIZE,
24
29
  useCommunities
25
30
  };
@@ -13,9 +13,9 @@ const HomeCardHeader = ({
13
13
  ...rest
14
14
  }) => {
15
15
  const hasAction = !!actionLabel && !!onActionClick;
16
- return /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", gap: "8", className: clsx("home-card-header", className), ...rest, children: [
16
+ return /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", gap: "8", wrap: "wrap", className: clsx("home-card-header", className), ...rest, children: [
17
17
  /* @__PURE__ */ jsx("h3", { className: "home-card-header-title", children: title }),
18
- hasAction && /* @__PURE__ */ jsx(ButtonBeta, { color: "tertiary", size: "sm", variant: "ghost", onClick: onActionClick, leftIcon: actionLeftIcon, rightIcon: actionRightIcon, "data-testid": "home-card-header-action", ...actionProps, children: actionLabel })
18
+ hasAction && /* @__PURE__ */ jsx(ButtonBeta, { color: "tertiary", size: "sm", variant: "ghost", onClick: onActionClick, className: "home-card-header-action", leftIcon: actionLeftIcon, rightIcon: actionRightIcon, "data-testid": "home-card-header-action", ...actionProps, children: actionLabel })
19
19
  ] });
20
20
  };
21
21
  export {
@@ -1,6 +1,2 @@
1
1
  export { default as FileCard } from './FileCard';
2
2
  export * from './FileCard';
3
- export { default as GoogleDriveFileCard } from './GoogleDriveFileCard';
4
- export * from './GoogleDriveFileCard';
5
- export { default as NextcloudFileCard } from './NextcloudFileCard';
6
- export * from './NextcloudFileCard';
@@ -1,4 +1,3 @@
1
- import { ReactNode } from 'react';
2
1
  import { App, ILinkedResource } from '@edifice.io/client';
3
2
  /**
4
3
  * Definition of an internal link.
@@ -33,11 +32,6 @@ export interface InternalLinkerProps {
33
32
  applicationList?: ApplicationOption[];
34
33
  /** Whether to show the application selector */
35
34
  showApplicationSelector?: boolean;
36
- /**
37
- * Rendered on the search row, where the application selector sits, for
38
- * consumers that hide that selector but still need a filter of their own.
39
- */
40
- searchFilter?: ReactNode;
41
35
  /** Disable application selecetor */
42
36
  disableApplicationSelector?: boolean;
43
37
  /** Optional callback to filter resources after loading. Applied in addition to search filters. */
@@ -55,5 +49,5 @@ export interface InternalLinkerProps {
55
49
  /** Label for the "load more" button. Defaults to the `bbm.linker.see.more` i18n key. */
56
50
  loadMoreLabel?: string;
57
51
  }
58
- export declare const InternalLinker: ({ appCode, defaultAppCode, defaultResourceId, onChange, onSelect, multiple, resourceList, applicationList, showApplicationSelector, searchFilter, disableApplicationSelector, resourceFilter, onSearch, hasMoreResources, onLoadMore, loadMoreLabel, }: InternalLinkerProps) => import("react/jsx-runtime").JSX.Element;
52
+ export declare const InternalLinker: ({ appCode, defaultAppCode, defaultResourceId, onChange, onSelect, multiple, resourceList, applicationList, showApplicationSelector, disableApplicationSelector, resourceFilter, onSearch, hasMoreResources, onLoadMore, loadMoreLabel, }: InternalLinkerProps) => import("react/jsx-runtime").JSX.Element;
59
53
  export default InternalLinker;
@@ -23,7 +23,6 @@ const InternalLinker = ({
23
23
  resourceList,
24
24
  applicationList,
25
25
  showApplicationSelector = !0,
26
- searchFilter,
27
26
  disableApplicationSelector = !1,
28
27
  resourceFilter,
29
28
  onSearch,
@@ -132,7 +131,6 @@ const InternalLinker = ({
132
131
  ] }), variant: "ghost", size: "md", disabled: disableApplicationSelector }),
133
132
  /* @__PURE__ */ jsx(Dropdown.Menu, { children: options == null ? void 0 : options.map((option) => /* @__PURE__ */ jsx(Dropdown.Item, { icon: option.icon, onClick: () => handleOptionClick(option), children: option.displayName }, option.application)) })
134
133
  ] }) }),
135
- !showApplicationSelector && searchFilter && /* @__PURE__ */ jsx("div", { className: "flex-shrink-1 px-8 py-12 border-end align-self-center", children: searchFilter }),
136
134
  /* @__PURE__ */ jsx("div", { className: "flex-grow-1 align-self-center", children: /* @__PURE__ */ jsx("form", { className: "gap-16 d-flex w-100 align-items-center px-16 py-8", onSubmit: handleSubmit, children: /* @__PURE__ */ jsx(SearchBar, { isVariant: !0, placeholder: t("search"), size: "lg", className: "w-100", disabled: !selectedApplication, onChange: handleSearchChange }) }) })
137
135
  ] }),
138
136
  /* @__PURE__ */ jsxs("div", { className: "internal-linker flex-grow-1 w-100 rounded-bottom border gap-0 overflow-auto", children: [
@@ -1,4 +1,4 @@
1
- import { NextcloudDocument, WorkspaceElement, WorkspaceVisibility } from '@edifice.io/client';
1
+ import { WorkspaceElement, WorkspaceVisibility } from '@edifice.io/client';
2
2
  import { TabsItemProps } from '../../../components';
3
3
  import { ExternalLinkTabProps } from './innertabs/ExternalLink';
4
4
  import { InternalLinkTabProps, InternalLinkTabResult } from './innertabs/InternalLink';
@@ -54,7 +54,7 @@ export interface MediaLibraryRef {
54
54
  /**
55
55
  * The resulting type depends on the actual selected Tab when modal is closed.
56
56
  */
57
- export type MediaLibraryResult = WorkspaceElement[] | WorkspaceElement | NextcloudDocument[] | InternalLinkTabResult | string | /*TODO type des autres résultats ?*/ any;
57
+ export type MediaLibraryResult = WorkspaceElement[] | WorkspaceElement | InternalLinkTabResult | string | /*TODO type des autres résultats ?*/ any;
58
58
  /**
59
59
  * MediaLibrary component properties
60
60
  */
@@ -5,7 +5,6 @@ import { useTranslation } from "react-i18next";
5
5
  import SvgIconApplications from "../../icons/components/IconApplications.js";
6
6
  import SvgIconCode from "../../icons/components/IconCode.js";
7
7
  import SvgIconFolder from "../../icons/components/IconFolder.js";
8
- import SvgIconGlobe2 from "../../icons/components/IconGlobe2.js";
9
8
  import SvgIconGlobe from "../../icons/components/IconGlobe.js";
10
9
  import SvgIconMic from "../../icons/components/IconMic.js";
11
10
  import SvgIconRecordVideo from "../../icons/components/IconRecordVideo.js";
@@ -13,7 +12,6 @@ import SvgIconSmartphone from "../../icons/components/IconSmartphone.js";
13
12
  import { InnerTabs } from "./innertabs/index.js";
14
13
  import { MediaLibraryContext } from "./MediaLibraryContext.js";
15
14
  import useHasWorkflow from "../../../hooks/useHasWorkflow/useHasWorkflow.js";
16
- import usePublicConf from "../../../hooks/usePublicConf/usePublicConf.js";
17
15
  import useHttpErrorToast from "../../../hooks/useHttpErrorToast/useHttpErrorToast.js";
18
16
  import Modal from "../../../components/Modal/Modal.js";
19
17
  import { Tabs } from "../../../components/Tabs/components/Tabs.js";
@@ -31,13 +29,9 @@ const orderedTabs = [
31
29
  // Filesystem browser + drag'n'drop of files
32
30
  "workspace",
33
31
  // Media browser
34
- "nextcloud",
35
- // Nextcloud media browser
36
- "google-drive",
37
- // Google Drive media browser
38
32
  "video-embedder"
39
33
  // Link to a hosted video
40
- ], GOOGLE_DRIVE_VIEW_WORKFLOW = "io.edifice.google.drive.controller.GoogleDriveController|view", mediaLibraryTypes = {
34
+ ], mediaLibraryTypes = {
41
35
  none: null,
42
36
  audio: {
43
37
  title: "bbm.audio.modal.title",
@@ -76,7 +70,7 @@ const orderedTabs = [
76
70
  onCancel,
77
71
  onTabChange
78
72
  }, ref) => {
79
- var _a, _b, _c;
73
+ var _a;
80
74
  const linkTabProps = useRef(), refModal = useRef(null);
81
75
  useImperativeHandle(ref, () => ({
82
76
  show,
@@ -87,9 +81,7 @@ const orderedTabs = [
87
81
  }));
88
82
  const {
89
83
  t
90
- } = useTranslation(), workspaceCreateWorkflow = useHasWorkflow("org.entcore.workspace.controllers.WorkspaceController|addDocument"), videoCaptureWorkflow = useHasWorkflow("com.opendigitaleducation.video.controllers.VideoController|capture"), nextcloudViewWorkflow = useHasWorkflow("fr.openent.nextcloud.controller.NextcloudController|view"), googleDriveViewWorkflow = useHasWorkflow(GOOGLE_DRIVE_VIEW_WORKFLOW), {
91
- data: workspacePublicConf
92
- } = usePublicConf("workspace"), enableNextcloudTab = ((_a = workspacePublicConf == null ? void 0 : workspacePublicConf["folder-service"]) == null ? void 0 : _a.includes("nextcloud")) && nextcloudViewWorkflow, enableGoogleDriveTab = ((_b = workspacePublicConf == null ? void 0 : workspacePublicConf["folder-service"]) == null ? void 0 : _b.includes("google-drive")) && googleDriveViewWorkflow, [type, setType] = useState(null);
84
+ } = useTranslation(), workspaceCreateWorkflow = useHasWorkflow("org.entcore.workspace.controllers.WorkspaceController|addDocument"), videoCaptureWorkflow = useHasWorkflow("com.opendigitaleducation.video.controllers.VideoController|capture"), [type, setType] = useState(null);
93
85
  useHttpErrorToast({
94
86
  active: !!type,
95
87
  isDismissible: !0,
@@ -104,23 +96,6 @@ const orderedTabs = [
104
96
  availableFor: ["audio", "video", "image", "attachment"],
105
97
  isEnable: null
106
98
  },
107
- nextcloud: {
108
- id: "nextcloud",
109
- icon: /* @__PURE__ */ jsx(SvgIconGlobe2, {}),
110
- label: t("bbm.nextcloud"),
111
- content: /* @__PURE__ */ jsx(InnerTabs.Nextcloud, {}),
112
- availableFor: ["audio", "video", "image", "attachment"],
113
- isEnable: () => !!enableNextcloudTab
114
- },
115
- "google-drive": {
116
- id: "google-drive",
117
- // FIXME No Google Drive icon in the pack yet; reusing the generic one.
118
- icon: /* @__PURE__ */ jsx(SvgIconGlobe2, {}),
119
- label: t("bbm.google-drive"),
120
- content: /* @__PURE__ */ jsx(InnerTabs.GoogleDrive, {}),
121
- availableFor: ["audio", "video", "image", "attachment"],
122
- isEnable: () => !!enableGoogleDriveTab
123
- },
124
99
  upload: {
125
100
  id: "upload",
126
101
  icon: /* @__PURE__ */ jsx(SvgIconSmartphone, {}),
@@ -187,7 +162,7 @@ const orderedTabs = [
187
162
  ), [defaultTabId, setDefaultTabId] = useState(), defaultTabIdx = useMemo(() => {
188
163
  const index = tabs.findIndex((t2) => t2.id === defaultTabId);
189
164
  return 0 > index || index >= tabs.length ? 0 : index;
190
- }, [tabs, defaultTabId]), [resultCounter, setResultCounter] = useState(), [result, setResult] = useState(), [deletionsOnCancel, setDeletionsOnCancel] = useState([]), [onSuccessAction, setPreSuccess] = useState(), [isSubmitting, setIsSubmitting] = useState(!1);
165
+ }, [tabs, defaultTabId]), [resultCounter, setResultCounter] = useState(), [result, setResult] = useState(), [deletionsOnCancel, setDeletionsOnCancel] = useState([]), [onSuccessAction, setPreSuccess] = useState();
191
166
  function setVisibleTab(tab) {
192
167
  throw tabs.findIndex((t2) => t2.id === tab) < 0 ? "tab.not.visible" : "not.implemented.yet";
193
168
  }
@@ -202,33 +177,22 @@ const orderedTabs = [
202
177
  linkTabProps.current = props, "resourceId" in props || "appPrefix" in props || setDefaultTabId("external-link"), setType("hyperlink");
203
178
  };
204
179
  useEffect(() => {
205
- var _a2, _b2;
180
+ var _a2, _b;
206
181
  const typeKey = type || "none";
207
- !defaultTabId && typeof ((_a2 = mediaLibraryTypes[typeKey]) == null ? void 0 : _a2.defaultTab) == "string" && setDefaultTabId((_b2 = mediaLibraryTypes[typeKey]) == null ? void 0 : _b2.defaultTab);
182
+ !defaultTabId && typeof ((_a2 = mediaLibraryTypes[typeKey]) == null ? void 0 : _a2.defaultTab) == "string" && setDefaultTabId((_b = mediaLibraryTypes[typeKey]) == null ? void 0 : _b.defaultTab);
208
183
  }, [defaultTabId, type]);
209
- const modalHeader = t(((_c = mediaLibraryTypes[type ?? "none"]) == null ? void 0 : _c.title) ?? "bbm"), resetState = () => {
184
+ const modalHeader = t(((_a = mediaLibraryTypes[type ?? "none"]) == null ? void 0 : _a.title) ?? "bbm"), resetState = () => {
210
185
  linkTabProps.current = void 0, setResult(void 0), setResultCounter(void 0), setDefaultTabId(void 0), setPreSuccess(void 0), setDeletionsOnCancel([]);
211
186
  }, handleTabChange = (tab) => {
212
187
  onTabChange == null || onTabChange(tab, deletionsOnCancel), resetState();
213
188
  }, handleOnSuccess = useCallback(() => {
214
- if (isSubmitting) return;
215
189
  const triggerSuccess = async (result2) => {
216
190
  result2 instanceof Array && ["protected", "public"].findIndex((v) => v === visibility) >= 0 && (result2 = await odeServices.workspace().transferDocuments(result2, appCode ?? "media-library", visibility)), onSuccess(result2);
217
191
  };
218
- (async () => {
219
- setIsSubmitting(!0);
220
- try {
221
- if (onSuccessAction) {
222
- const asyncResult = await onSuccessAction();
223
- await triggerSuccess(asyncResult);
224
- } else result && await triggerSuccess(result);
225
- resetState();
226
- } catch {
227
- } finally {
228
- setIsSubmitting(!1);
229
- }
230
- })();
231
- }, [isSubmitting, onSuccessAction, result, onSuccess, visibility, appCode]), handleOnCancel = () => {
192
+ onSuccessAction ? onSuccessAction().then((result2) => {
193
+ triggerSuccess(result2);
194
+ }) : result && triggerSuccess(result), resetState();
195
+ }, [onSuccessAction, result, onSuccess, visibility, appCode]), handleOnCancel = () => {
232
196
  onCancel(deletionsOnCancel), resetState();
233
197
  };
234
198
  return type && /* @__PURE__ */ jsx(MediaLibraryContext.Provider, { value: {
@@ -250,7 +214,7 @@ const orderedTabs = [
250
214
  ] }) }),
251
215
  /* @__PURE__ */ jsxs(Modal.Footer, { children: [
252
216
  /* @__PURE__ */ jsx(Button, { type: "button", color: "tertiary", variant: "ghost", onClick: handleOnCancel, children: t("cancel") }),
253
- /* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "filled", disabled: typeof result > "u" || isSubmitting, onClick: handleOnSuccess, children: resultCounter && resultCounter > 1 ? t("addMultiple", {
217
+ /* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "filled", disabled: typeof result > "u", onClick: handleOnSuccess, children: resultCounter && resultCounter > 1 ? t("addMultiple", {
254
218
  number: resultCounter
255
219
  }) : t("add") })
256
220
  ] })
@@ -4,8 +4,6 @@ export declare const InnerTabs: {
4
4
  Upload: () => import("react/jsx-runtime").JSX.Element;
5
5
  ExternalLink: ({ link, multiNodeSelected, }: import('./ExternalLink').ExternalLinkTabProps) => import("react/jsx-runtime").JSX.Element;
6
6
  Workspace: () => import("react/jsx-runtime").JSX.Element;
7
- Nextcloud: () => import("react/jsx-runtime").JSX.Element;
8
- GoogleDrive: () => import("react/jsx-runtime").JSX.Element;
9
7
  InternalLink: ({ target, resourceId, appPrefix, }: import('./InternalLink').InternalLinkTabProps) => import("react/jsx-runtime").JSX.Element;
10
8
  Iframe: () => import("react/jsx-runtime").JSX.Element;
11
9
  VideoEmbedder: () => import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,7 @@
1
1
  import { Audio } from "./Audio.js";
2
2
  import { ExternalLink } from "./ExternalLink.js";
3
- import { GoogleDrive } from "./GoogleDrive.js";
4
3
  import { Iframe } from "./Iframe.js";
5
4
  import { InternalLink } from "./InternalLink.js";
6
- import { Nextcloud } from "./Nextcloud.js";
7
5
  import { Upload } from "./Upload.js";
8
6
  import { Video } from "./Video.js";
9
7
  import { VideoEmbedder } from "./VideoEmbedder.js";
@@ -14,8 +12,6 @@ const InnerTabs = {
14
12
  Upload,
15
13
  ExternalLink,
16
14
  Workspace,
17
- Nextcloud,
18
- GoogleDrive,
19
15
  InternalLink,
20
16
  Iframe,
21
17
  VideoEmbedder
@@ -6,7 +6,6 @@ import SvgIconSortAscendingLetters from "../../icons/components/IconSortAscendin
6
6
  import SvgIconSortDescendingLetters from "../../icons/components/IconSortDescendingLetters.js";
7
7
  import SvgIconSortTime from "../../icons/components/IconSortTime.js";
8
8
  import illuTrash from "@edifice.io/bootstrap/dist/images/emptyscreen/illu-trash.svg";
9
- import useHasWorkflow from "../../../hooks/useHasWorkflow/useHasWorkflow.js";
10
9
  import useWorkspaceSearch from "../../../hooks/useWorkspaceSearch/useWorkspaceSearch.js";
11
10
  import { Grid } from "../../../components/Grid/Grid.js";
12
11
  import TreeView from "../../../components/TreeView/TreeView.js";
@@ -16,7 +15,7 @@ import LoadingScreen from "../../../components/LoadingScreen/LoadingScreen.js";
16
15
  import FileCard from "../FileCard/FileCard.js";
17
16
  import EmptyScreen from "../../../components/EmptyScreen/EmptyScreen.js";
18
17
  import { findTreeNode } from "../../../components/TreeView/utilities/treeview.js";
19
- const WORKSPACE_VIEW_WORKFLOW = "org.entcore.workspace.controllers.WorkspaceController|view", Workspace = ({
18
+ const Workspace = ({
20
19
  roles,
21
20
  onSelect,
22
21
  multiple = !0,
@@ -26,7 +25,7 @@ const WORKSPACE_VIEW_WORKFLOW = "org.entcore.workspace.controllers.WorkspaceCont
26
25
  }) => {
27
26
  const {
28
27
  t
29
- } = useTranslation(), hasWorkspaceViewRight = useHasWorkflow(WORKSPACE_VIEW_WORKFLOW), canViewPersonalFolders = !!hasWorkspaceViewRight, {
28
+ } = useTranslation(), {
30
29
  root: ownerRoot,
31
30
  loadContent: loadOwnerDocs
32
31
  } = useWorkspaceSearch("root", t("workspace.tree.owner"), "owner", roles), {
@@ -112,9 +111,7 @@ const WORKSPACE_VIEW_WORKFLOW = "org.entcore.workspace.controllers.WorkspaceCont
112
111
  return;
113
112
  }
114
113
  (_a = ref == null ? void 0 : ref.current) == null || _a.select("root");
115
- }, [currentFilter]), useEffect(() => {
116
- hasWorkspaceViewRight === !1 && (currentFilter === "owner" || currentFilter === "shared") && selectAndLoadContent("protected", "root");
117
- }, [hasWorkspaceViewRight]), useEffect(loadContent, [loadContent]), useEffect(() => {
114
+ }, [currentFilter]), useEffect(loadContent, [loadContent]), useEffect(() => {
118
115
  if (currentNode.files) {
119
116
  let list = [].concat(currentNode.files);
120
117
  searchTerm && (list = list.filter((f) => f.name.indexOf(searchTerm) >= 0));
@@ -143,8 +140,8 @@ const WORKSPACE_VIEW_WORKFLOW = "org.entcore.workspace.controllers.WorkspaceCont
143
140
  top: 0,
144
141
  paddingTop: "1.2rem"
145
142
  }, children: [
146
- canViewPersonalFolders && /* @__PURE__ */ jsx(TreeView, { ref: ownerRef, data: ownerRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("owner", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("owner", nodeId) }),
147
- canViewPersonalFolders && /* @__PURE__ */ jsx(TreeView, { ref: sharedRef, data: sharedRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("shared", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("shared", nodeId) }),
143
+ /* @__PURE__ */ jsx(TreeView, { ref: ownerRef, data: ownerRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("owner", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("owner", nodeId) }),
144
+ /* @__PURE__ */ jsx(TreeView, { ref: sharedRef, data: sharedRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("shared", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("shared", nodeId) }),
148
145
  /* @__PURE__ */ jsx(TreeView, { ref: protectRef, data: protectRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("protected", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("protected", nodeId) }),
149
146
  showPublicFolder && /* @__PURE__ */ jsx(TreeView, { ref: publicRef, data: publicRoot, onTreeItemClick: (nodeId) => selectAndLoadContent("public", nodeId), onTreeItemUnfold: (nodeId) => selectAndLoadContent("public", nodeId) })
150
147
  ] }) }),
@@ -5,8 +5,6 @@ export * from './ImagePicker';
5
5
  export * from './FileCard';
6
6
  export * from './Linker';
7
7
  export * from './MediaLibrary';
8
- export * from './GoogleDrive';
9
- export * from './Nextcloud';
10
8
  export * from './UploadCard';
11
9
  export * from './VideoEmbed';
12
10
  export * from './VideoRecorder';
@@ -1,19 +1,15 @@
1
1
  import { default as default2 } from "./modules/multimedia/AudioRecorder/AudioRecorder.js";
2
2
  import { default as default3 } from "./modules/multimedia/Embed/Embed.js";
3
3
  import { default as default4 } from "./modules/multimedia/FileCard/FileCard.js";
4
- import { default as default5 } from "./modules/multimedia/GoogleDrive/GoogleDrive.js";
5
- import { default as default6 } from "./modules/multimedia/FileCard/GoogleDriveFileCard.js";
6
- import { default as default7 } from "./modules/multimedia/ImageEditor/components/ImageEditor.js";
7
- import { default as default8 } from "./modules/multimedia/ImagePicker/ImagePicker.js";
8
- import { default as default9 } from "./modules/multimedia/MediaLibrary/MediaLibrary.js";
9
- import { default as default10 } from "./modules/multimedia/Nextcloud/Nextcloud.js";
10
- import { default as default11 } from "./modules/multimedia/FileCard/NextcloudFileCard.js";
11
- import { default as default12 } from "./modules/multimedia/UploadCard/UploadCard.js";
12
- import { default as default13 } from "./modules/multimedia/UploadFiles/UploadFiles.js";
13
- import { default as default14 } from "./modules/multimedia/VideoEmbed/VideoEmbed.js";
14
- import { default as default15 } from "./modules/multimedia/VideoRecorder/VideoRecorder.js";
15
- import { default as default16 } from "./modules/multimedia/Workspace/Workspace.js";
16
- import { default as default17 } from "./modules/multimedia/WorkspaceFolders/WorkspaceFolders.js";
4
+ import { default as default5 } from "./modules/multimedia/ImageEditor/components/ImageEditor.js";
5
+ import { default as default6 } from "./modules/multimedia/ImagePicker/ImagePicker.js";
6
+ import { default as default7 } from "./modules/multimedia/MediaLibrary/MediaLibrary.js";
7
+ import { default as default8 } from "./modules/multimedia/UploadCard/UploadCard.js";
8
+ import { default as default9 } from "./modules/multimedia/UploadFiles/UploadFiles.js";
9
+ import { default as default10 } from "./modules/multimedia/VideoEmbed/VideoEmbed.js";
10
+ import { default as default11 } from "./modules/multimedia/VideoRecorder/VideoRecorder.js";
11
+ import { default as default12 } from "./modules/multimedia/Workspace/Workspace.js";
12
+ import { default as default13 } from "./modules/multimedia/WorkspaceFolders/WorkspaceFolders.js";
17
13
  import { ExternalLinker } from "./modules/multimedia/Linker/ExternalLinker/ExternalLinker.js";
18
14
  import { InternalLinker } from "./modules/multimedia/Linker/InternalLinker/InternalLinker.js";
19
15
  import { Upload } from "./modules/multimedia/MediaLibrary/innertabs/Upload.js";
@@ -22,19 +18,15 @@ export {
22
18
  default3 as Embed,
23
19
  ExternalLinker,
24
20
  default4 as FileCard,
25
- default5 as GoogleDrive,
26
- default6 as GoogleDriveFileCard,
27
- default7 as ImageEditor,
28
- default8 as ImagePicker,
21
+ default5 as ImageEditor,
22
+ default6 as ImagePicker,
29
23
  InternalLinker,
30
- default9 as MediaLibrary,
31
- default10 as Nextcloud,
32
- default11 as NextcloudFileCard,
24
+ default7 as MediaLibrary,
33
25
  Upload,
34
- default12 as UploadCard,
35
- default13 as UploadFiles,
36
- default14 as VideoEmbed,
37
- default15 as VideoRecorder,
38
- default16 as Workspace,
39
- default17 as WorkspaceFolders
26
+ default8 as UploadCard,
27
+ default9 as UploadFiles,
28
+ default10 as VideoEmbed,
29
+ default11 as VideoRecorder,
30
+ default12 as Workspace,
31
+ default13 as WorkspaceFolders
40
32
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.6.7-develop-integration.20261005091442",
3
+ "version": "2.6.7-develop-pedago.20261005162423",
4
4
  "description": "Edifice React Library",
5
5
  "keywords": [
6
6
  "react",
@@ -140,9 +140,9 @@
140
140
  "swiper": "10.1.0",
141
141
  "ua-parser-js": "1.0.36",
142
142
  "zustand": "4.5.7",
143
- "@edifice.io/bootstrap": "2.6.7-develop-integration.20261005091442",
144
- "@edifice.io/tiptap-extensions": "2.6.7-develop-integration.20261005091442",
145
- "@edifice.io/utilities": "2.6.7-develop-integration.20261005091442"
143
+ "@edifice.io/tiptap-extensions": "2.6.7-develop-pedago.20261005162423",
144
+ "@edifice.io/utilities": "2.6.7-develop-pedago.20261005162423",
145
+ "@edifice.io/bootstrap": "2.6.7-develop-pedago.20261005162423"
146
146
  },
147
147
  "devDependencies": {
148
148
  "@babel/plugin-transform-react-pure-annotations": "7.27.1",
@@ -173,8 +173,8 @@
173
173
  "vite": "5.4.14",
174
174
  "vite-plugin-dts": "4.5.4",
175
175
  "vite-tsconfig-paths": "5.1.4",
176
- "@edifice.io/client": "2.6.7-develop-integration.20261005091442",
177
- "@edifice.io/config": "2.6.7-develop-integration.20261005091442"
176
+ "@edifice.io/client": "2.6.7-develop-pedago.20261005162423",
177
+ "@edifice.io/config": "2.6.7-develop-pedago.20261005162423"
178
178
  },
179
179
  "peerDependencies": {
180
180
  "@react-spring/web": "9.7.5",
@@ -1 +0,0 @@
1
- export { default as useGoogleDriveSearch } from './useGoogleDriveSearch';
@@ -1,14 +0,0 @@
1
- import { GoogleDriveDocument, ID } from '@edifice.io/client';
2
- import { TreeItem } from '../../components/Tree/types';
3
- export type GoogleDriveFolderNode = TreeItem & {
4
- files?: GoogleDriveDocument[];
5
- };
6
- export default function useGoogleDriveSearch(rootId: string, rootName: string, userId?: string): {
7
- root: GoogleDriveFolderNode;
8
- needsAuth: boolean;
9
- isCheckingAuth: boolean;
10
- isAuthError: boolean;
11
- refetchAuthStatus: () => void;
12
- loadContent: (folderId?: ID) => void;
13
- loadError: unknown;
14
- };