@edifice.io/react 2.1.0-develop-enabling.0 → 2.1.0-develop-b2school.20250204153130

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 (93) hide show
  1. package/README.md +3 -3
  2. package/dist/components/AppIcon/AppIcon.js +2 -2
  3. package/dist/components/Attachment/Attachment.js +1 -1
  4. package/dist/components/Button/Button.js +1 -1
  5. package/dist/components/Dropdown/DropdownTrigger.js +5 -1
  6. package/dist/components/Form/FormContext.js +1 -1
  7. package/dist/components/Form/FormControl.js +1 -1
  8. package/dist/components/Layout/components/Header.js +5 -4
  9. package/dist/components/Layout/components/WidgetApps.js +1 -1
  10. package/dist/{hooks/useHeader → components/Layout/hooks}/useHeader.js +6 -6
  11. package/dist/components/List/List.d.ts +9 -1
  12. package/dist/components/List/List.js +9 -9
  13. package/dist/components/Modal/Modal.js +1 -1
  14. package/dist/components/SearchBar/SearchBar.d.ts +1 -1
  15. package/dist/components/SearchBar/SearchBar.js +3 -1
  16. package/dist/components/Tree/components/SortableTree.js +3 -2
  17. package/dist/components/Tree/types/index.d.ts +1 -0
  18. package/dist/components/Tree/utilities/tree.d.ts +2 -1
  19. package/dist/hooks/index.d.ts +1 -5
  20. package/dist/hooks/useCheckable/useCheckable.js +1 -1
  21. package/dist/hooks/useConf/useConf.d.ts +2 -2
  22. package/dist/hooks/useConversation/useConversation.d.ts +1 -1
  23. package/dist/hooks/useConversation/useConversation.js +13 -17
  24. package/dist/hooks/useDropdown/useDropdown.js +1 -1
  25. package/dist/hooks/useDropzone/useDropzone.js +1 -1
  26. package/dist/hooks/useHasWorkflow/useHasWorkflow.js +3 -11
  27. package/dist/hooks/useHttpErrorToast/index.d.ts +1 -0
  28. package/dist/hooks/useHttpErrorToast/useHttpErrorToast.d.ts +3 -0
  29. package/dist/hooks/useHttpErrorToast/useHttpErrorToast.js +21 -0
  30. package/dist/hooks/useSession/useSession.d.ts +2 -1
  31. package/dist/hooks/useTrapFocus/useTrapFocus.d.ts +1 -1
  32. package/dist/hooks/useTrapFocus/useTrapFocus.js +3 -2
  33. package/dist/hooks/useUploadFiles/useUploadFiles.js +1 -1
  34. package/dist/hooks/useWorkspaceSearch/useWorkspaceSearch.js +3 -11
  35. package/dist/icons-apps.js +220 -218
  36. package/dist/icons.js +116 -112
  37. package/dist/index.js +138 -144
  38. package/dist/modules/audience/ReactionChoice.d.ts +13 -0
  39. package/dist/modules/audience/ReactionModal.Card.js +4 -4
  40. package/dist/modules/audience/ReactionModal.d.ts +24 -6
  41. package/dist/modules/audience/ReactionModal.js +12 -9
  42. package/dist/modules/audience/ReactionSummary.d.ts +9 -0
  43. package/dist/modules/audience/ViewsCounter.d.ts +10 -0
  44. package/dist/modules/audience/ViewsModal.d.ts +13 -1
  45. package/dist/modules/audience/ViewsModal.js +22 -19
  46. package/dist/modules/comments/components/Comment.js +10 -7
  47. package/dist/modules/comments/components/CommentAvatar.js +1 -1
  48. package/dist/modules/comments/components/DeleteModal.d.ts +7 -0
  49. package/dist/modules/comments/components/DeleteModal.js +19 -0
  50. package/dist/modules/comments/context/Context.d.ts +2 -0
  51. package/dist/modules/comments/hooks/useComments.d.ts +5 -2
  52. package/dist/modules/comments/hooks/useComments.js +1 -1
  53. package/dist/modules/comments/hooks/useCommentsContext.d.ts +1 -0
  54. package/dist/modules/comments/hooks/useProfileQueries.d.ts +4 -1
  55. package/dist/modules/comments/provider/CommentProvider.js +3 -2
  56. package/dist/modules/comments/types.d.ts +5 -1
  57. package/dist/modules/editor/components/Editor/Editor.js +2 -2
  58. package/dist/modules/editor/components/{Editor → MathsModal}/MathsModal.d.ts +1 -1
  59. package/dist/modules/editor/components/{Editor → MathsModal}/MathsModal.js +2 -3
  60. package/dist/modules/editor/components/MathsModal/index.d.ts +1 -0
  61. package/dist/modules/editor/components/Renderer/AttachmentRenderer.js +12 -7
  62. package/dist/modules/editor/components/Renderer/AudioRenderer.js +4 -1
  63. package/dist/modules/editor/components/Renderer/LinkerRenderer.js +1 -1
  64. package/dist/modules/editor/components/Renderer/MediaRenderer.js +10 -2
  65. package/dist/modules/editor/hooks/useCommentEditor.d.ts +1 -1
  66. package/dist/modules/editor/hooks/useSpeechRecognition.js +2 -0
  67. package/dist/modules/editor/hooks/useSpeechSynthetisis.js +2 -0
  68. package/dist/modules/editor/hooks/useTipTapEditor.d.ts +1 -1
  69. package/dist/modules/editor/hooks/useTipTapEditor.js +4 -4
  70. package/dist/modules/icons/components/IconReadMail.d.ts +7 -0
  71. package/dist/modules/icons/components/IconReadMail.js +16 -0
  72. package/dist/modules/icons/components/IconUnreadMail.d.ts +7 -0
  73. package/dist/modules/icons/components/IconUnreadMail.js +16 -0
  74. package/dist/modules/icons/components/apps/IconAppointments.d.ts +7 -0
  75. package/dist/modules/icons/components/apps/IconAppointments.js +12 -0
  76. package/dist/modules/icons/components/apps/index.d.ts +1 -0
  77. package/dist/modules/icons/components/index.d.ts +2 -0
  78. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.js +5 -1
  79. package/dist/modules/multimedia/UploadCard/UploadCard.js +2 -2
  80. package/dist/modules/multimedia/index.d.ts +2 -0
  81. package/dist/multimedia.js +10 -6
  82. package/dist/providers/MockedProvider/MockedProvider.d.ts +4 -0
  83. package/dist/providers/MockedProvider/MockedProvider.js +20 -0
  84. package/dist/providers/index.d.ts +1 -0
  85. package/package.json +57 -54
  86. package/dist/hooks/useAvatar/index.d.ts +0 -1
  87. package/dist/hooks/useAvatar/useAvatar.d.ts +0 -6
  88. package/dist/hooks/useAvatar/useAvatar.js +0 -30
  89. package/dist/hooks/useHeader/index.d.ts +0 -1
  90. package/dist/hooks/useHeader/useHeader.d.ts +0 -5
  91. package/dist/providers/MockedDataProvider/MockedDataProvider.d.ts +0 -28
  92. package/dist/providers/MockedDataProvider/MockedDataProvider.js +0 -9
  93. package/dist/providers/MockedDataProvider/index.d.ts +0 -1
@@ -1,7 +1,20 @@
1
1
  import { ReactionSummaryData, ReactionType } from '@edifice.io/client';
2
+ /**
3
+ * Props for the ReactionChoice component.
4
+ */
2
5
  export interface ReactionChoiceProps {
6
+ /**
7
+ * An array of available reactions that can be chosen.
8
+ */
3
9
  availableReactions: ReactionType[];
10
+ /**
11
+ * Optional summary data of the reactions.
12
+ */
4
13
  summary?: ReactionSummaryData;
14
+ /**
15
+ * Optional callback function that is called when a reaction is chosen.
16
+ * @param chosenReaction - The reaction that was chosen.
17
+ */
5
18
  onChange?: (chosenReaction?: ReactionType) => void;
6
19
  }
7
20
  declare const ReactionChoice: {
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useTranslation } from "react-i18next";
3
3
  import useReactionIcons from "./hooks/useReactionIcons.js";
4
- import useAvatar from "../../hooks/useAvatar/useAvatar.js";
4
+ import useDirectory from "../../hooks/useDirectory/useDirectory.js";
5
5
  import Avatar from "../../components/Avatar/Avatar.js";
6
6
  function ReactionModalCard({
7
7
  reaction
@@ -9,14 +9,14 @@ function ReactionModalCard({
9
9
  const {
10
10
  t
11
11
  } = useTranslation(), {
12
- avatarURL
13
- } = useAvatar(reaction.userId, reaction.profile), {
12
+ getAvatarURL
13
+ } = useDirectory(), {
14
14
  getReactionIcon,
15
15
  getReactionLabel
16
16
  } = useReactionIcons();
17
17
  return /* @__PURE__ */ jsxs("div", { className: "reaction-modal-card w-100 d-flex gap-8", children: [
18
18
  /* @__PURE__ */ jsxs("div", { className: "position-relative p-8", children: [
19
- /* @__PURE__ */ jsx(Avatar, { variant: "circle", size: "md", src: avatarURL, alt: reaction.displayName }),
19
+ /* @__PURE__ */ jsx(Avatar, { variant: "circle", size: "md", src: getAvatarURL(reaction.userId, "user"), alt: reaction.displayName }),
20
20
  /* @__PURE__ */ jsx("div", { className: "position-absolute end-0 bottom-0", children: getReactionIcon(reaction.reactionType, !0) })
21
21
  ] }),
22
22
  /* @__PURE__ */ jsxs("div", { className: "d-flex flex-column w-100 pt-8", children: [
@@ -1,19 +1,37 @@
1
1
  import { ReactionDetailsData } from '@edifice.io/client';
2
2
  import { ReactionModalCard } from './ReactionModal.Card';
3
+ /**
4
+ * Props for the ReactionModal component.
5
+ */
3
6
  export interface ReactionModalProps {
4
- /** Id of resource. */
7
+ /**
8
+ * The unique identifier for the resource.
9
+ */
5
10
  resourceId: string;
6
- /** Number of results per page, defaults to 30. */
11
+ /**
12
+ * The number of items to display per page. Optional.
13
+ */
7
14
  pageSize?: number;
8
- /** Display modal ? */
15
+ /**
16
+ * Indicates whether the modal is open.
17
+ */
9
18
  isOpen: boolean;
10
- /** Close button handler. */
19
+ /**
20
+ * Callback function to handle the modal close event.
21
+ */
11
22
  onModalClose(): void;
12
- /** Function for loading reactions to the resource. */
23
+ /**
24
+ * Function to load reaction details for a given resource.
25
+ *
26
+ * @param resourceId - The unique identifier for the resource.
27
+ * @param page - The current page number.
28
+ * @param size - The number of items to display per page.
29
+ * @returns A promise that resolves to the reaction details data or undefined.
30
+ */
13
31
  reactionDetailsLoader: (resourceId: string, page: number, size: number) => Promise<ReactionDetailsData | undefined>;
14
32
  }
15
33
  declare const ReactionModal: {
16
- ({ resourceId, pageSize, reactionDetailsLoader: loadReactionDetails, onModalClose, ...restProps }: ReactionModalProps): import('react').ReactPortal;
34
+ ({ resourceId, pageSize, reactionDetailsLoader: loadReactionDetails, onModalClose, ...restProps }: ReactionModalProps): import("react/jsx-runtime").JSX.Element;
17
35
  displayName: string;
18
36
  Card: typeof ReactionModalCard;
19
37
  };
@@ -1,4 +1,4 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
2
  import { ReactionTypes } from "@edifice.io/client";
3
3
  import { StringUtils } from "@edifice.io/utilities";
4
4
  import { useState, useId, useCallback, useMemo, useEffect } from "react";
@@ -57,14 +57,17 @@ const ALL_TAB_ID = "all", ReactionModal = ({
57
57
  const handleTabChange = (tab) => {
58
58
  setCurrentTabId(tab.id);
59
59
  }, hasMore = reactions.length < counters.allReactionsCounter;
60
- return /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id, ...restProps, onModalClose, size: "md", scrollable: !0, children: [
61
- /* @__PURE__ */ jsx(Modal.Header, { onModalClose, children: t("audience.reaction.modal.header") }),
62
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(Tabs, { items: tabs, defaultId: ALL_TAB_ID, onChange: handleTabChange }) }),
63
- /* @__PURE__ */ jsxs(Modal.Footer, { children: [
64
- hasMore && /* @__PURE__ */ jsx(Button, { color: "tertiary", onClick: loadNextPage, children: t("audience.reaction.modal.more") }),
65
- /* @__PURE__ */ jsx(Button, { color: "primary", onClick: onModalClose, type: "button", variant: "filled", children: t("close") })
66
- ] })
67
- ] }), document.getElementById("portal"));
60
+ return (
61
+ // Using a fragment to ensure Storybook correctly interprets JSDoc comments: https://github.com/storybookjs/storybook/issues/27169
62
+ /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id, ...restProps, onModalClose, size: "md", scrollable: !0, children: [
63
+ /* @__PURE__ */ jsx(Modal.Header, { onModalClose, children: t("audience.reaction.modal.header") }),
64
+ /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(Tabs, { items: tabs, defaultId: ALL_TAB_ID, onChange: handleTabChange }) }),
65
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
66
+ hasMore && /* @__PURE__ */ jsx(Button, { color: "tertiary", onClick: loadNextPage, children: t("audience.reaction.modal.more") }),
67
+ /* @__PURE__ */ jsx(Button, { color: "primary", onClick: onModalClose, type: "button", variant: "filled", children: t("close") })
68
+ ] })
69
+ ] }), document.getElementById("portal")) })
70
+ );
68
71
  };
69
72
  ReactionModal.Card = ReactionModalCard;
70
73
  export {
@@ -1,6 +1,15 @@
1
1
  import { ReactionSummaryData } from '@edifice.io/client';
2
+ /**
3
+ * Props for the ReactionSummary component.
4
+ */
2
5
  export interface ReactionSummaryProps {
6
+ /**
7
+ * An optional summary of reaction data.
8
+ */
3
9
  summary?: ReactionSummaryData;
10
+ /**
11
+ * An optional click handler function.
12
+ */
4
13
  onClick?: () => void;
5
14
  }
6
15
  declare const ReactionSummary: {
@@ -1,6 +1,16 @@
1
1
  export interface ViewsCounterProps {
2
+ /**
3
+ * The number of views to display.
4
+ *
5
+ */
2
6
  viewsCounter: number;
7
+ /**
8
+ * Optional click handler for the counter button.
9
+ */
3
10
  onClick?: (event?: React.MouseEvent<HTMLButtonElement>) => void;
11
+ /**
12
+ * Optional CSS class name to apply to the counter component.
13
+ */
4
14
  className?: string;
5
15
  }
6
16
  declare const ViewsCounter: {
@@ -1,11 +1,23 @@
1
1
  import { ViewsDetails } from '@edifice.io/client';
2
+ /**
3
+ * Props for the ViewsModal component.
4
+ */
2
5
  export interface ViewsModalProps {
6
+ /**
7
+ * Details of the views to be displayed in the modal.
8
+ */
3
9
  viewsDetails: ViewsDetails;
10
+ /**
11
+ * Boolean flag indicating whether the modal is open.
12
+ */
4
13
  isOpen: boolean;
14
+ /**
15
+ * Callback function to be called when the modal is closed.
16
+ */
5
17
  onModalClose: () => void;
6
18
  }
7
19
  declare const ViewsModal: {
8
- ({ viewsDetails, isOpen, onModalClose, }: ViewsModalProps): import('react').ReactPortal;
20
+ ({ viewsDetails, isOpen, onModalClose, }: ViewsModalProps): import("react/jsx-runtime").JSX.Element;
9
21
  displayName: string;
10
22
  };
11
23
  export default ViewsModal;
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
1
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
2
  import { StringUtils } from "@edifice.io/utilities";
3
3
  import { createPortal } from "react-dom";
4
4
  import { useTranslation } from "react-i18next";
@@ -16,25 +16,28 @@ const ViewsModal = ({
16
16
  const {
17
17
  t
18
18
  } = useTranslation(), hasUniqueViews = viewsDetails.uniqueViewsCounter !== void 0;
19
- return /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id: "ViewsModal", isOpen, onModalClose, children: [
20
- /* @__PURE__ */ jsx(Modal.Header, { onModalClose, children: t("audience.views.title") }),
21
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
22
- /* @__PURE__ */ jsxs("div", { className: "views-detail-line p-8 mb-12", children: [
23
- /* @__PURE__ */ jsx("div", { className: "views-detail-icon rounded p-8", children: /* @__PURE__ */ jsx(SvgIconSee, {}) }),
24
- /* @__PURE__ */ jsx("div", { className: "h3", children: StringUtils.toCounter(viewsDetails.viewsCounter) }),
25
- /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.viewsCounter") })
19
+ return (
20
+ // Using a fragment to ensure Storybook correctly interprets JSDoc comments: https://github.com/storybookjs/storybook/issues/27169
21
+ /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id: "ViewsModal", isOpen, onModalClose, children: [
22
+ /* @__PURE__ */ jsx(Modal.Header, { onModalClose, children: t("audience.views.title") }),
23
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
24
+ /* @__PURE__ */ jsxs("div", { className: "views-detail-line p-8 mb-12", children: [
25
+ /* @__PURE__ */ jsx("div", { className: "views-detail-icon rounded p-8", children: /* @__PURE__ */ jsx(SvgIconSee, {}) }),
26
+ /* @__PURE__ */ jsx("div", { className: "h3", children: StringUtils.toCounter(viewsDetails.viewsCounter) }),
27
+ /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.viewsCounter") })
28
+ ] }),
29
+ /* @__PURE__ */ jsxs("div", { className: "views-detail-line p-8 mb-12", children: [
30
+ /* @__PURE__ */ jsx("div", { className: "views-detail-icon rounded p-8", children: /* @__PURE__ */ jsx(SvgIconUsers, {}) }),
31
+ hasUniqueViews ? /* @__PURE__ */ jsxs(Fragment, { children: [
32
+ /* @__PURE__ */ jsx("div", { className: "h3", children: StringUtils.toCounter(viewsDetails.uniqueViewsCounter) }),
33
+ /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.uniqueViewsCounter") })
34
+ ] }) : /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.noUniqueViews") })
35
+ ] }),
36
+ hasUniqueViews ? (_a = viewsDetails.uniqueViewsPerProfile) == null ? void 0 : _a.map((viewsByProfile) => /* @__PURE__ */ jsx(ViewsByProfileCard, { viewsByProfile }, viewsByProfile.profile)) : null
26
37
  ] }),
27
- /* @__PURE__ */ jsxs("div", { className: "views-detail-line p-8 mb-12", children: [
28
- /* @__PURE__ */ jsx("div", { className: "views-detail-icon rounded p-8", children: /* @__PURE__ */ jsx(SvgIconUsers, {}) }),
29
- hasUniqueViews ? /* @__PURE__ */ jsxs(Fragment, { children: [
30
- /* @__PURE__ */ jsx("div", { className: "h3", children: StringUtils.toCounter(viewsDetails.uniqueViewsCounter) }),
31
- /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.uniqueViewsCounter") })
32
- ] }) : /* @__PURE__ */ jsx("div", { children: t("audience.views.detail.noUniqueViews") })
33
- ] }),
34
- hasUniqueViews ? (_a = viewsDetails.uniqueViewsPerProfile) == null ? void 0 : _a.map((viewsByProfile) => /* @__PURE__ */ jsx(ViewsByProfileCard, { viewsByProfile }, viewsByProfile.profile)) : null
35
- ] }),
36
- /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsx(Button, { color: "primary", onClick: onModalClose, type: "button", variant: "filled", children: t("audience.views.cancel") }) })
37
- ] }), document.getElementById("portal"));
38
+ /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsx(Button, { color: "primary", onClick: onModalClose, type: "button", variant: "filled", children: t("audience.views.cancel") }) })
39
+ ] }), document.getElementById("portal")) })
40
+ );
38
41
  };
39
42
  export {
40
43
  ViewsModal as default
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import { useState, Suspense, lazy } from "react";
3
3
  import { useTranslation } from "react-i18next";
4
4
  import SvgIconSave from "../../icons/components/IconSave.js";
5
5
  import { useAutosizeTextarea } from "../hooks/useAutosizeTextarea.js";
@@ -10,7 +10,8 @@ import { CommentDate } from "./CommentDate.js";
10
10
  import { CommentTitle } from "./CommentTitle.js";
11
11
  import { TextCounter } from "./TextCounter.js";
12
12
  import Button from "../../../components/Button/Button.js";
13
- const Comment = ({
13
+ import LoadingScreen from "../../../components/LoadingScreen/LoadingScreen.js";
14
+ const DeleteModal = /* @__PURE__ */ lazy(() => import("./DeleteModal.js")), Comment = ({
14
15
  comment,
15
16
  userId,
16
17
  profile
@@ -22,12 +23,13 @@ const Comment = ({
22
23
  createdAt,
23
24
  updatedAt,
24
25
  comment: content
25
- } = comment, [ref, onFocus, resizeTextarea] = useAutosizeTextarea(!0), {
26
+ } = comment, [ref, onFocus, resizeTextarea] = useAutosizeTextarea(!0), [isDeleteModalOpen, setIsDeleteModalOpen] = useState(!1), {
26
27
  t
27
28
  } = useTranslation(), {
28
29
  editCommentId,
29
30
  options,
30
31
  type,
32
+ userRights,
31
33
  handleDeleteComment: onDeleteComment,
32
34
  handleModifyComment,
33
35
  handleReset,
@@ -57,14 +59,15 @@ const Comment = ({
57
59
  ] })
58
60
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
59
61
  /* @__PURE__ */ jsx("div", { className: "mt-8 mb-4", children: content }),
60
- userId === authorId && type === "edit" && /* @__PURE__ */ jsxs("div", { className: "ms-n8", children: [
61
- /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", size: "sm", onClick: () => {
62
+ type === "edit" && /* @__PURE__ */ jsxs("div", { className: "ms-n8", children: [
63
+ userId === authorId && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", size: "sm", onClick: () => {
62
64
  handleModifyComment(comment.id), setValue(content);
63
65
  }, children: t("comment.edit") }),
64
- /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", size: "sm", onClick: () => onDeleteComment(id), children: t("comment.remove") })
66
+ (userId === authorId || (userRights == null ? void 0 : userRights.manager)) && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", size: "sm", onClick: () => setIsDeleteModalOpen(!0), children: t("comment.remove") })
65
67
  ] })
66
68
  ] })
67
- ] })
69
+ ] }),
70
+ /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingScreen, { position: !1 }), children: isDeleteModalOpen && /* @__PURE__ */ jsx(DeleteModal, { isOpen: isDeleteModalOpen, onCancel: () => setIsDeleteModalOpen(!1), onSuccess: () => onDeleteComment(id) }) })
68
71
  ] }, id);
69
72
  };
70
73
  export {
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useTranslation } from "react-i18next";
3
- import Avatar from "../../../components/Avatar/Avatar.js";
4
3
  import useDirectory from "../../../hooks/useDirectory/useDirectory.js";
4
+ import Avatar from "../../../components/Avatar/Avatar.js";
5
5
  const CommentAvatar = ({
6
6
  id
7
7
  }) => {
@@ -0,0 +1,7 @@
1
+ interface DeleteModalProps {
2
+ isOpen: boolean;
3
+ onCancel: () => void;
4
+ onSuccess: () => void;
5
+ }
6
+ export declare const DeleteModal: ({ isOpen, onCancel, onSuccess, }: DeleteModalProps) => import("react/jsx-runtime").JSX.Element;
7
+ export default DeleteModal;
@@ -0,0 +1,19 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import Modal from "../../../components/Modal/Modal.js";
3
+ import Button from "../../../components/Button/Button.js";
4
+ const DeleteModal = ({
5
+ isOpen,
6
+ onCancel,
7
+ onSuccess
8
+ }) => /* @__PURE__ */ jsxs(Modal, { isOpen, onModalClose: onCancel, id: "delete-comment-modal", children: [
9
+ /* @__PURE__ */ jsx(Modal.Header, { onModalClose: onCancel, children: "Suppression de commentaire" }),
10
+ /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx("p", { children: "Voulez-vous vraiment supprimer ce commentaire ?" }) }),
11
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
12
+ /* @__PURE__ */ jsx(Button, { color: "tertiary", onClick: onCancel, type: "button", variant: "ghost", children: "Annuler" }),
13
+ /* @__PURE__ */ jsx(Button, { color: "danger", onClick: onSuccess, type: "button", variant: "filled", children: "Supprimer le commentaire" })
14
+ ] })
15
+ ] });
16
+ export {
17
+ DeleteModal,
18
+ DeleteModal as default
19
+ };
@@ -1,3 +1,4 @@
1
+ import { RightRole } from '@edifice.io/client';
1
2
  import { CommentOptions, CommentProps, CommentType, UserProfileResult } from '../types';
2
3
  export declare const CommentContext: import('react').Context<{
3
4
  comments: CommentProps[] | undefined;
@@ -6,6 +7,7 @@ export declare const CommentContext: import('react').Context<{
6
7
  profiles: (UserProfileResult | undefined)[];
7
8
  options: Partial<CommentOptions>;
8
9
  type: CommentType;
10
+ userRights?: Record<RightRole, boolean>;
9
11
  setEditCommentId: (value: string | null) => void;
10
12
  handleModifyComment: (commentId: string) => void;
11
13
  handleChangeContent: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
@@ -6,7 +6,10 @@ export declare const useComments: ({ defaultComments, options, type, callbacks,
6
6
  callbacks: CommentCallbacks | null;
7
7
  }) => {
8
8
  profilesQueries: {
9
- data: any[];
9
+ data: ({
10
+ userId: string;
11
+ profile: "Student" | "Teacher" | "Relative" | "Personnel" | "Guest";
12
+ } | undefined)[];
10
13
  isLoading: boolean;
11
14
  };
12
15
  content: string;
@@ -24,6 +27,6 @@ export declare const useComments: ({ defaultComments, options, type, callbacks,
24
27
  handleDeleteComment: (id: string) => void;
25
28
  handleCreateComment: (content: string) => void;
26
29
  handleModifyComment: (commentId: string) => void;
27
- handleUpdateComment: (comment: string) => void;
30
+ handleUpdateComment: (comment: string) => Promise<void>;
28
31
  handleReset: () => void;
29
32
  };
@@ -50,7 +50,7 @@ const useComments = ({
50
50
  handleModifyComment: (commentId) => {
51
51
  setEditCommentId(commentId);
52
52
  },
53
- handleUpdateComment: (comment) => {
53
+ handleUpdateComment: async (comment) => {
54
54
  editCommentId && (type === "edit" && (callbacks == null || callbacks.put({
55
55
  comment,
56
56
  commentId: editCommentId
@@ -5,6 +5,7 @@ export declare const useCommentsContext: () => {
5
5
  profiles: (import('../types').UserProfileResult | undefined)[];
6
6
  options: Partial<import('../types').CommentOptions>;
7
7
  type: import('../types').CommentType;
8
+ userRights?: Record<import('@edifice.io/client').RightRole, boolean>;
8
9
  setEditCommentId: (value: string | null) => void;
9
10
  handleModifyComment: (commentId: string) => void;
10
11
  handleChangeContent: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
@@ -1,4 +1,7 @@
1
1
  export declare const useProfileQueries: (usersIds: string[]) => {
2
- data: any[];
2
+ data: ({
3
+ userId: string;
4
+ profile: "Student" | "Teacher" | "Relative" | "Personnel" | "Guest";
5
+ } | undefined)[];
3
6
  isLoading: boolean;
4
7
  };
@@ -3,7 +3,7 @@ import { useMemo } from "react";
3
3
  import { CommentForm } from "../components/CommentForm.js";
4
4
  import { CommentHeader } from "../components/CommentHeader.js";
5
5
  import { CommentList } from "../components/CommentList.js";
6
- import { DEFAULT_MAX_COMMENT_LENGTH, DEFAULT_MAX_REPLY_LENGTH, DEFAULT_MAX_COMMENTS, DEFAULT_ADD_COMMENTS, DEFAULT_MAX_REPLIES } from "../constants.js";
6
+ import { DEFAULT_MAX_REPLIES, DEFAULT_ADD_COMMENTS, DEFAULT_MAX_COMMENTS, DEFAULT_MAX_REPLY_LENGTH, DEFAULT_MAX_COMMENT_LENGTH } from "../constants.js";
7
7
  import { CommentContext } from "../context/Context.js";
8
8
  import { useComments } from "../hooks/useComments.js";
9
9
  import Button from "../../../components/Button/Button.js";
@@ -46,7 +46,7 @@ const CommentProvider = ({
46
46
  defaultComments,
47
47
  callbacks: type == "edit" ? props.callbacks : null,
48
48
  options
49
- }), values = useMemo(
49
+ }), userRights = type === "edit" ? props.rights : void 0, values = useMemo(
50
50
  () => ({
51
51
  comments,
52
52
  content,
@@ -54,6 +54,7 @@ const CommentProvider = ({
54
54
  editCommentId,
55
55
  options,
56
56
  type,
57
+ userRights,
57
58
  setEditCommentId,
58
59
  handleCreateComment,
59
60
  handleModifyComment,
@@ -1,4 +1,4 @@
1
- import { UserProfile } from '@edifice.io/client';
1
+ import { RightRole, UserProfile } from '@edifice.io/client';
2
2
  export interface CommentProps {
3
3
  /**
4
4
  * Comment Id
@@ -61,6 +61,10 @@ interface EditRootProps extends BaseProps {
61
61
  * Callbacks to perform CRUD on comment
62
62
  */
63
63
  callbacks: CommentCallbacks;
64
+ /**
65
+ * Rights to perform CRUD on comment
66
+ */
67
+ rights?: Record<RightRole, boolean>;
64
68
  }
65
69
  interface ReadRootProps extends BaseProps {
66
70
  type: 'read';
@@ -15,9 +15,9 @@ import { EditorToolbar } from "../EditorToolbar/EditorToolbar.js";
15
15
  import LinkToolbar from "../Toolbar/LinkToolbar.js";
16
16
  import TableToolbar from "../Toolbar/TableToolbar.js";
17
17
  import BubbleMenuEditImage from "../BubbleMenuEditImage/BubbleMenuEditImage.js";
18
- import LoadingScreen from "../../../../components/LoadingScreen/LoadingScreen.js";
19
18
  import MediaLibrary from "../../../multimedia/MediaLibrary/MediaLibrary.js";
20
- const MathsModal = /* @__PURE__ */ lazy(async () => await import("./MathsModal.js")), ImageEditor = /* @__PURE__ */ lazy(async () => await import("../../../multimedia/ImageEditor/components/ImageEditor.js")), Editor = /* @__PURE__ */ forwardRef(({
19
+ import LoadingScreen from "../../../../components/LoadingScreen/LoadingScreen.js";
20
+ const MathsModal = /* @__PURE__ */ lazy(async () => await import("../MathsModal/MathsModal.js")), ImageEditor = /* @__PURE__ */ lazy(async () => await import("../../../multimedia/ImageEditor/components/ImageEditor.js")), Editor = /* @__PURE__ */ forwardRef(({
21
21
  id,
22
22
  content,
23
23
  mode = "read",
@@ -3,5 +3,5 @@ interface ModalProps {
3
3
  onSuccess?: (formulaEditor: string) => void;
4
4
  onCancel?: () => void;
5
5
  }
6
- declare const MathsModal: ({ isOpen, onSuccess, onCancel }: ModalProps) => import('react').ReactPortal;
6
+ declare const MathsModal: ({ isOpen, onSuccess, onCancel }: ModalProps) => import("react/jsx-runtime").JSX.Element;
7
7
  export default MathsModal;
@@ -3,7 +3,6 @@ import { useState, useEffect } from "react";
3
3
  import Mathematics from "@tiptap-pro/extension-mathematics";
4
4
  import { useEditor, EditorContent } from "@tiptap/react";
5
5
  import StarterKit from "@tiptap/starter-kit";
6
- import { createPortal } from "react-dom";
7
6
  import { useTranslation } from "react-i18next";
8
7
  import Modal from "../../../../components/Modal/Modal.js";
9
8
  import Button from "../../../../components/Button/Button.js";
@@ -29,7 +28,7 @@ const MathsModal = ({
29
28
  }, handleOnCancel = () => {
30
29
  onCancel == null || onCancel();
31
30
  };
32
- return /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id: "MathsModal", isOpen, onModalClose: handleOnCancel, children: [
31
+ return /* @__PURE__ */ jsxs(Modal, { id: "MathsModal", isOpen, onModalClose: handleOnCancel, children: [
33
32
  /* @__PURE__ */ jsx(Modal.Header, { onModalClose: handleOnCancel, children: t("tiptap.maths.title") }),
34
33
  /* @__PURE__ */ jsxs(Modal.Subtitle, { children: [
35
34
  t("tiptap.maths.subtitle.1"),
@@ -43,7 +42,7 @@ const MathsModal = ({
43
42
  /* @__PURE__ */ jsx(Button, { color: "tertiary", onClick: onCancel, type: "button", variant: "ghost", children: t("tiptap.maths.cancel") }),
44
43
  /* @__PURE__ */ jsx(Button, { color: "primary", onClick: () => onSuccess == null ? void 0 : onSuccess(formulaEditor), type: "button", variant: "filled", children: t("tiptap.maths.add") })
45
44
  ] })
46
- ] }), document.getElementById("portal"));
45
+ ] });
47
46
  };
48
47
  export {
49
48
  MathsModal as default
@@ -0,0 +1 @@
1
+ export { default as MathsModal } from './MathsModal';
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import { useState, useEffect } from "react";
3
3
  import { NodeViewWrapper } from "@tiptap/react";
4
4
  import { useTranslation } from "react-i18next";
5
5
  import SvgIconDelete from "../../../icons/components/IconDelete.js";
@@ -10,15 +10,20 @@ import { useEditorContext } from "../../hooks/useEditorContext.js";
10
10
  import { Grid } from "../../../../components/Grid/Grid.js";
11
11
  const AttachmentRenderer = (props) => {
12
12
  const {
13
+ node,
14
+ editor
15
+ } = props, [attachmentArrayAttrs, setAttachmentArrayAttrs] = useState(node.attrs.links), {
13
16
  t
14
17
  } = useTranslation(), {
15
- node
16
- } = props, {
17
18
  editable
18
- } = useEditorContext(), [attachmentArrayAttrs, setAttachmentArrayAttrs] = useState(node.attrs.links), handleDelete = (index) => {
19
- setAttachmentArrayAttrs((oldAttachments) => oldAttachments.filter((_, i) => i !== index));
19
+ } = useEditorContext();
20
+ useEffect(() => {
21
+ attachmentArrayAttrs !== node.attrs.links && setAttachmentArrayAttrs(node.attrs.links);
22
+ }, [node.attrs.links, attachmentArrayAttrs]);
23
+ const handleDelete = (index, documentId) => {
24
+ editor.commands.unsetAttachment(documentId), setAttachmentArrayAttrs((oldAttachments) => oldAttachments.filter((_, i) => i !== index));
20
25
  };
21
- return attachmentArrayAttrs.length !== 0 && /* @__PURE__ */ jsx(NodeViewWrapper, { children: /* @__PURE__ */ jsxs("div", { style: {
26
+ return (attachmentArrayAttrs == null ? void 0 : attachmentArrayAttrs.length) !== 0 && /* @__PURE__ */ jsx(NodeViewWrapper, { children: /* @__PURE__ */ jsxs("div", { style: {
22
27
  backgroundColor: "#F2F2F2",
23
28
  borderRadius: ".8rem",
24
29
  padding: "1.2rem"
@@ -26,7 +31,7 @@ const AttachmentRenderer = (props) => {
26
31
  /* @__PURE__ */ jsx("p", { className: "m-12 mt-0", children: t("tiptap.attachments.bloc") }),
27
32
  /* @__PURE__ */ jsx(Grid, { children: attachmentArrayAttrs == null ? void 0 : attachmentArrayAttrs.map((attachment, index) => /* @__PURE__ */ jsx(Grid.Col, { sm: "6", children: /* @__PURE__ */ jsx(Attachment, { name: attachment.name, options: /* @__PURE__ */ jsxs(Fragment, { children: [
28
33
  /* @__PURE__ */ jsx("a", { href: attachment.href, download: !0, children: /* @__PURE__ */ jsx(IconButton, { "aria-label": t("tiptap.attachments.download"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDownload, {}), variant: "ghost" }) }),
29
- editable && /* @__PURE__ */ jsx(IconButton, { "aria-label": t("tiptap.attachments.delete"), color: "danger", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDelete, {}), variant: "ghost", onClick: () => handleDelete(index) })
34
+ editable && /* @__PURE__ */ jsx(IconButton, { "aria-label": t("tiptap.attachments.delete"), color: "danger", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDelete, {}), variant: "ghost", onClick: () => handleDelete(index, attachment.documentId) })
30
35
  ] }) }) }, index)) })
31
36
  ] }) });
32
37
  };
@@ -4,7 +4,10 @@ const AudioRenderer = (props) => {
4
4
  const {
5
5
  node
6
6
  } = props;
7
- return /* @__PURE__ */ jsx(NodeViewWrapper, { children: /* @__PURE__ */ jsx("div", { className: "audio-wrapper", children: /* @__PURE__ */ jsx("audio", { src: node.attrs.src, controls: !0, "data-document-id": node.attrs.src, children: /* @__PURE__ */ jsx("track", { kind: "captions" }) }) }) });
7
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { style: {
8
+ display: "inline-block",
9
+ width: "fit-content"
10
+ }, children: /* @__PURE__ */ jsx("div", { className: "audio-wrapper", "data-drag-handle": !0, children: /* @__PURE__ */ jsx("audio", { src: node.attrs.src, controls: !0, "data-document-id": node.attrs.src, children: /* @__PURE__ */ jsx("track", { kind: "captions" }) }) }) });
8
11
  };
9
12
  export {
10
13
  AudioRenderer as default
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { NodeViewWrapper } from "@tiptap/react";
3
3
  import clsx from "clsx";
4
+ import useEdificeIcons from "../../../../hooks/useEdificeIcons/useEdificeIcons.js";
4
5
  import Badge from "../../../../components/Badge/Badge.js";
5
6
  import AppIcon from "../../../../components/AppIcon/AppIcon.js";
6
- import useEdificeIcons from "../../../../hooks/useEdificeIcons/useEdificeIcons.js";
7
7
  const LinkerRenderer = ({
8
8
  selected,
9
9
  ...props
@@ -1,7 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useEffect } from "react";
3
+ import { odeServices } from "@edifice.io/client";
3
4
  import { NodeViewWrapper } from "@tiptap/react";
4
5
  import { useTranslation } from "react-i18next";
6
+ import useBrowserInfo from "../../../../hooks/useBrowserInfo/useBrowserInfo.js";
5
7
  import { useResizeMedia } from "../../hooks/useResizeMedia.js";
6
8
  import Image from "../../../../components/Image/Image.js";
7
9
  const MediaRenderer = (props) => {
@@ -9,7 +11,10 @@ const MediaRenderer = (props) => {
9
11
  node
10
12
  } = props, {
11
13
  t
12
- } = useTranslation(), resizableMedia = useRef(null), {
14
+ } = useTranslation(), {
15
+ browser,
16
+ device
17
+ } = useBrowserInfo(navigator.userAgent), resizableMedia = useRef(null), {
13
18
  startVerticalResize,
14
19
  stopVerticalResize,
15
20
  isVerticalResizeActive
@@ -36,7 +41,10 @@ const MediaRenderer = (props) => {
36
41
  return {};
37
42
  }
38
43
  }, onVideoPlay = () => {
39
- resizableMedia.current instanceof HTMLVideoElement;
44
+ if (resizableMedia.current instanceof HTMLVideoElement) {
45
+ const videoElement = resizableMedia.current, videoId = videoElement.dataset.documentId, isCaptation = (videoElement.dataset.documentIsCaptation || "false") == "true";
46
+ videoId && odeServices.data().trackVideoRead(videoId, isCaptation, window.location.hostname, `${browser.name} ${browser.version}`, device.type);
47
+ }
40
48
  };
41
49
  return useEffect(() => {
42
50
  if (!resizableMedia.current) return;
@@ -6,7 +6,7 @@ import { Content, HTMLContent } from '@tiptap/react';
6
6
  * @param content default rich content
7
7
  */
8
8
  export declare const useCommentEditor: (editable: boolean, content: Content, maxLength?: number) => {
9
- editor: import('@tiptap/react').Editor | null;
9
+ editor: import('@tiptap/core').Editor | null;
10
10
  commentLength: number;
11
11
  getComment: () => HTMLContent;
12
12
  resetComment: () => void;
@@ -1,9 +1,11 @@
1
1
  import { useState } from "react";
2
+ import { odeServices } from "@edifice.io/client";
2
3
  const useSpeechRecognition = (editor) => {
3
4
  const [isActive, setActive] = useState(!1), toggle = () => {
4
5
  if (isActive)
5
6
  editor == null || editor.commands.stopSpeechRecognition(), setActive(!1);
6
7
  else {
8
+ odeServices.data().trackSpeechAndText("STT");
7
9
  const started = (editor == null ? void 0 : editor.commands.startSpeechRecognition()) || !1;
8
10
  setActive(started);
9
11
  }