@edifice.io/react 2.2.2-develop-b2school.20250409142344 → 2.2.2-develop.20250409145633

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 (124) hide show
  1. package/dist/components/Avatar/Avatar.d.ts +21 -0
  2. package/dist/components/Avatar/Avatar.js +15 -2
  3. package/dist/components/AvatarGroup/AvatarGroup.d.ts +24 -0
  4. package/dist/components/AvatarGroup/AvatarGroup.js +24 -0
  5. package/dist/components/AvatarGroup/index.d.ts +2 -0
  6. package/dist/components/Card/Card.d.ts +3 -1
  7. package/dist/components/Card/CardBody.d.ts +3 -1
  8. package/dist/components/Card/CardBody.js +4 -2
  9. package/dist/components/Combobox/Combobox.d.ts +5 -55
  10. package/dist/components/Combobox/Combobox.js +7 -13
  11. package/dist/components/Combobox/ComboboxTrigger.d.ts +2 -30
  12. package/dist/components/Combobox/ComboboxTrigger.js +8 -28
  13. package/dist/components/Dropdown/Dropdown.d.ts +6 -6
  14. package/dist/components/Dropdown/Dropdown.js +5 -4
  15. package/dist/components/Dropdown/DropdownItem.d.ts +3 -3
  16. package/dist/components/Dropdown/DropdownItem.js +8 -6
  17. package/dist/components/Dropdown/DropdownTrigger.d.ts +31 -2
  18. package/dist/components/Dropdown/DropdownTrigger.js +24 -8
  19. package/dist/components/List/List.d.ts +1 -9
  20. package/dist/components/List/List.js +9 -9
  21. package/dist/components/PreventPropagation/PreventPropagation.d.ts +10 -0
  22. package/dist/components/PreventPropagation/PreventPropagation.js +9 -0
  23. package/dist/components/PreventPropagation/index.d.ts +2 -0
  24. package/dist/components/SearchBar/SearchBar.d.ts +1 -1
  25. package/dist/components/SearchBar/SearchBar.js +1 -3
  26. package/dist/components/StackedGroup/StackedGroup.d.ts +23 -0
  27. package/dist/components/StackedGroup/StackedGroup.js +21 -0
  28. package/dist/components/StackedGroup/index.d.ts +1 -0
  29. package/dist/components/Switch/Switch.d.ts +29 -0
  30. package/dist/components/Switch/Switch.js +27 -0
  31. package/dist/components/Switch/index.d.ts +2 -0
  32. package/dist/components/index.d.ts +4 -0
  33. package/dist/editor.js +22 -22
  34. package/dist/hooks/index.d.ts +0 -1
  35. package/dist/hooks/useCheckable/useCheckable.js +3 -10
  36. package/dist/hooks/useConf/useConf.d.ts +1 -1
  37. package/dist/hooks/useConversation/useConversation.d.ts +1 -1
  38. package/dist/hooks/useConversation/useConversation.js +17 -13
  39. package/dist/hooks/useDropdown/useDropdown.d.ts +1 -1
  40. package/dist/hooks/useDropdown/useDropdown.js +3 -3
  41. package/dist/hooks/useSession/useSession.d.ts +1 -1
  42. package/dist/icons.js +212 -230
  43. package/dist/index.d.ts +0 -1
  44. package/dist/index.js +154 -172
  45. package/dist/modals.js +14 -16
  46. package/dist/modules/comments/components/Comment.js +49 -34
  47. package/dist/modules/comments/components/CommentDeleted.d.ts +1 -0
  48. package/dist/modules/comments/components/CommentDeleted.js +11 -0
  49. package/dist/modules/comments/components/CommentForm.d.ts +2 -1
  50. package/dist/modules/comments/components/CommentForm.js +12 -8
  51. package/dist/modules/comments/components/CommentList.js +3 -3
  52. package/dist/modules/comments/components/CommentReplies.d.ts +4 -0
  53. package/dist/modules/comments/components/CommentReplies.js +33 -0
  54. package/dist/modules/comments/constants.d.ts +4 -0
  55. package/dist/modules/comments/constants.js +2 -1
  56. package/dist/modules/comments/context/Context.d.ts +6 -4
  57. package/dist/modules/comments/hooks/useCommentReplies.d.ts +12 -0
  58. package/dist/modules/comments/hooks/useCommentReplies.js +36 -0
  59. package/dist/modules/comments/hooks/useComments.d.ts +7 -7
  60. package/dist/modules/comments/hooks/useComments.js +24 -19
  61. package/dist/modules/comments/hooks/useCommentsContext.d.ts +6 -4
  62. package/dist/modules/comments/provider/CommentProvider.js +16 -13
  63. package/dist/modules/comments/types.d.ts +14 -1
  64. package/dist/modules/editor/components/BubbleMenuEditInformationPane/BubbleMenuEditInformationPane.d.ts +6 -0
  65. package/dist/modules/editor/components/BubbleMenuEditInformationPane/BubbleMenuEditInformationPane.js +136 -0
  66. package/dist/modules/editor/components/BubbleMenuEditInformationPane/index.d.ts +1 -0
  67. package/dist/modules/editor/components/Editor/Editor.d.ts +1 -3
  68. package/dist/modules/editor/components/Editor/Editor.js +8 -5
  69. package/dist/modules/editor/components/EditorToolbar/EditorToolbar.js +12 -0
  70. package/dist/modules/editor/components/NodeView/InformationPaneNodeView.d.ts +2 -0
  71. package/dist/modules/editor/components/NodeView/InformationPaneNodeView.js +10 -0
  72. package/dist/modules/editor/components/NodeView/index.d.ts +2 -2
  73. package/dist/modules/editor/components/Renderer/InformationPaneRenderer.d.ts +3 -0
  74. package/dist/modules/editor/components/Renderer/InformationPaneRenderer.js +33 -0
  75. package/dist/modules/editor/components/Renderer/index.d.ts +2 -2
  76. package/dist/modules/editor/hooks/useTipTapEditor.d.ts +2 -6
  77. package/dist/modules/editor/hooks/useTipTapEditor.js +4 -2
  78. package/dist/modules/icons/components/IconInfoRectangle.d.ts +7 -0
  79. package/dist/modules/icons/components/IconInfoRectangle.js +13 -0
  80. package/dist/modules/icons/components/index.d.ts +1 -10
  81. package/dist/modules/modals/ResourceModal/ResourceModal.d.ts +1 -1
  82. package/dist/modules/modals/ResourceModal/hooks/useUpdateMutation.d.ts +1 -1
  83. package/dist/modules/modals/ShareModal/ShareModal.d.ts +1 -1
  84. package/dist/modules/modals/ShareModal/apps/ShareBlog.d.ts +1 -1
  85. package/dist/modules/modals/ShareModal/hooks/useShareMutation.d.ts +1 -1
  86. package/dist/modules/modals/index.d.ts +0 -1
  87. package/dist/modules/multimedia/index.d.ts +0 -1
  88. package/dist/multimedia.js +1 -3
  89. package/dist/providers/EdificeClientProvider/EdificeClientProvider.context.d.ts +1 -1
  90. package/dist/types/index.d.ts +1 -0
  91. package/package.json +6 -6
  92. package/dist/hooks/useWorkspaceFolders/index.d.ts +0 -1
  93. package/dist/hooks/useWorkspaceFolders/useWorkspaceFolders.d.ts +0 -14
  94. package/dist/hooks/useWorkspaceFolders/useWorkspaceFolders.js +0 -44
  95. package/dist/modules/editor/components/NodeView/ConversationHistoryNodeView.d.ts +0 -2
  96. package/dist/modules/editor/components/NodeView/ConversationHistoryNodeView.js +0 -10
  97. package/dist/modules/editor/components/Renderer/ConversationHistoryRenderer.d.ts +0 -8
  98. package/dist/modules/editor/components/Renderer/ConversationHistoryRenderer.js +0 -28
  99. package/dist/modules/icons/components/IconFolderAdd.d.ts +0 -7
  100. package/dist/modules/icons/components/IconFolderAdd.js +0 -13
  101. package/dist/modules/icons/components/IconFolderDelete.d.ts +0 -7
  102. package/dist/modules/icons/components/IconFolderDelete.js +0 -12
  103. package/dist/modules/icons/components/IconGlobe2.d.ts +0 -7
  104. package/dist/modules/icons/components/IconGlobe2.js +0 -16
  105. package/dist/modules/icons/components/IconGroupAvatar.d.ts +0 -7
  106. package/dist/modules/icons/components/IconGroupAvatar.js +0 -12
  107. package/dist/modules/icons/components/IconMailRecall.d.ts +0 -7
  108. package/dist/modules/icons/components/IconMailRecall.js +0 -13
  109. package/dist/modules/icons/components/IconQuestionMark.d.ts +0 -7
  110. package/dist/modules/icons/components/IconQuestionMark.js +0 -13
  111. package/dist/modules/icons/components/IconReadMail.d.ts +0 -7
  112. package/dist/modules/icons/components/IconReadMail.js +0 -16
  113. package/dist/modules/icons/components/IconSignature.d.ts +0 -7
  114. package/dist/modules/icons/components/IconSignature.js +0 -13
  115. package/dist/modules/icons/components/IconUndoAll.d.ts +0 -7
  116. package/dist/modules/icons/components/IconUndoAll.js +0 -14
  117. package/dist/modules/icons/components/IconUnreadMail.d.ts +0 -7
  118. package/dist/modules/icons/components/IconUnreadMail.js +0 -16
  119. package/dist/modules/modals/ConfirmModal/ConfirmModal.d.ts +0 -42
  120. package/dist/modules/modals/ConfirmModal/ConfirmModal.js +0 -36
  121. package/dist/modules/modals/ConfirmModal/index.d.ts +0 -1
  122. package/dist/modules/multimedia/WorkspaceFolders/WorkspaceFolders.d.ts +0 -8
  123. package/dist/modules/multimedia/WorkspaceFolders/WorkspaceFolders.js +0 -28
  124. package/dist/modules/multimedia/WorkspaceFolders/index.d.ts +0 -1
@@ -6,15 +6,15 @@ function CommentList() {
6
6
  const {
7
7
  user
8
8
  } = useEdificeClient(), {
9
- comments,
9
+ displayedComments,
10
10
  profiles
11
11
  } = useCommentsContext();
12
- return comments == null ? void 0 : comments.map((comment) => {
12
+ return displayedComments == null ? void 0 : displayedComments.map((comment) => {
13
13
  var _a;
14
14
  const {
15
15
  authorId
16
16
  } = comment, profile = ((_a = profiles == null ? void 0 : profiles.find((user2) => (user2 == null ? void 0 : user2.userId) === authorId)) == null ? void 0 : _a.profile) ?? "Guest";
17
- return /* @__PURE__ */ jsx(Comment, { comment, profile, userId: user == null ? void 0 : user.userId }, comment.id);
17
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Comment, { comment, profile, userId: user == null ? void 0 : user.userId }) }, comment.id);
18
18
  });
19
19
  }
20
20
  export {
@@ -0,0 +1,4 @@
1
+ import { CommentProps } from '../types';
2
+ export declare const CommentReplies: ({ parentComment, }: {
3
+ parentComment: CommentProps;
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Comment } from "./Comment.js";
3
+ import { CommentForm } from "./CommentForm.js";
4
+ import { useCommentReplies } from "../hooks/useCommentReplies.js";
5
+ import Button from "../../../components/Button/Button.js";
6
+ const CommentReplies = ({
7
+ parentComment
8
+ }) => {
9
+ const {
10
+ t,
11
+ profiles,
12
+ user,
13
+ displayedReplies,
14
+ showCommentForm,
15
+ showMoreReplies,
16
+ handleMoreReplies
17
+ } = useCommentReplies({
18
+ parentComment
19
+ });
20
+ return /* @__PURE__ */ jsxs("div", { className: "comments-replies-container", children: [
21
+ showCommentForm && /* @__PURE__ */ jsx("div", { className: "comments-replies-form", children: /* @__PURE__ */ jsx(CommentForm, { userId: user == null ? void 0 : user.userId, replyTo: parentComment.id }) }),
22
+ /* @__PURE__ */ jsx("div", { className: "comments-replies-list", children: displayedReplies.map((reply) => {
23
+ var _a;
24
+ const profile = ((_a = profiles == null ? void 0 : profiles.find((user2) => (user2 == null ? void 0 : user2.userId) === reply.authorId)) == null ? void 0 : _a.profile) ?? "Guest";
25
+ if (!reply.deleted)
26
+ return /* @__PURE__ */ jsx("div", { className: "comments-replies-reply", children: /* @__PURE__ */ jsx(Comment, { comment: reply, profile, userId: user == null ? void 0 : user.userId }) }, reply.id);
27
+ }) }),
28
+ showMoreReplies && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", onClick: handleMoreReplies, className: "ms-24", children: t("comment.more.replies") })
29
+ ] });
30
+ };
31
+ export {
32
+ CommentReplies
33
+ };
@@ -18,3 +18,7 @@ export declare const DEFAULT_ADD_COMMENTS = 5;
18
18
  * Limit to display replies of a comment
19
19
  */
20
20
  export declare const DEFAULT_MAX_REPLIES = 5;
21
+ /**
22
+ * Number of comments to add when adding more comment in the limited list
23
+ */
24
+ export declare const DEFAULT_ADD_REPLIES = 5;
@@ -1,6 +1,7 @@
1
- const DEFAULT_MAX_COMMENT_LENGTH = 200, DEFAULT_MAX_REPLY_LENGTH = 200, DEFAULT_MAX_COMMENTS = 4, DEFAULT_ADD_COMMENTS = 5, DEFAULT_MAX_REPLIES = 5;
1
+ const DEFAULT_MAX_COMMENT_LENGTH = 200, DEFAULT_MAX_REPLY_LENGTH = 200, DEFAULT_MAX_COMMENTS = 4, DEFAULT_ADD_COMMENTS = 5, DEFAULT_MAX_REPLIES = 5, DEFAULT_ADD_REPLIES = 5;
2
2
  export {
3
3
  DEFAULT_ADD_COMMENTS,
4
+ DEFAULT_ADD_REPLIES,
4
5
  DEFAULT_MAX_COMMENTS,
5
6
  DEFAULT_MAX_COMMENT_LENGTH,
6
7
  DEFAULT_MAX_REPLIES,
@@ -1,18 +1,20 @@
1
1
  import { RightRole } from '@edifice.io/client';
2
2
  import { CommentOptions, CommentProps, CommentType, UserProfileResult } from '../types';
3
3
  export declare const CommentContext: import('react').Context<{
4
- comments: CommentProps[] | undefined;
5
- content: string;
4
+ displayedComments: CommentProps[] | undefined;
5
+ defaultComments: CommentProps[] | undefined;
6
6
  editCommentId: string | null;
7
+ replyToCommentId: string | null;
7
8
  profiles: (UserProfileResult | undefined)[];
8
9
  options: Partial<CommentOptions>;
9
10
  type: CommentType;
10
11
  userRights?: Record<RightRole, boolean>;
11
12
  setEditCommentId: (value: string | null) => void;
13
+ setReplyToCommentId: (value: string | null) => void;
12
14
  handleModifyComment: (commentId: string) => void;
13
- handleChangeContent: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
14
- handleCreateComment: (content: string) => void;
15
+ handleCreateComment: (content: string, replyTo?: string) => void;
15
16
  handleUpdateComment: (comment: string) => void;
16
17
  handleDeleteComment: (id: string) => void;
18
+ handleReplyToComment: (commentId: string) => void;
17
19
  handleReset: () => void;
18
20
  } | null>;
@@ -0,0 +1,12 @@
1
+ import { CommentProps } from '../types';
2
+ export declare const useCommentReplies: ({ parentComment, }: {
3
+ parentComment: CommentProps;
4
+ }) => {
5
+ t: import('i18next').TFunction<"translation", undefined>;
6
+ profiles: (import('../types').UserProfileResult | undefined)[];
7
+ user: import('@edifice.io/client').IUserInfo | undefined;
8
+ showCommentForm: boolean;
9
+ displayedReplies: CommentProps[];
10
+ showMoreReplies: boolean;
11
+ handleMoreReplies: () => void;
12
+ };
@@ -0,0 +1,36 @@
1
+ import { useState } from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { useEdificeClient } from "../../../providers/EdificeClientProvider/EdificeClientProvider.hook.js";
4
+ import { useCommentsContext } from "./useCommentsContext.js";
5
+ const useCommentReplies = ({
6
+ parentComment
7
+ }) => {
8
+ const {
9
+ profiles,
10
+ options,
11
+ replyToCommentId,
12
+ defaultComments
13
+ } = useCommentsContext(), {
14
+ maxReplies,
15
+ additionalReplies
16
+ } = options, [repliesLimit, setRepliesLimit] = useState(maxReplies), {
17
+ user
18
+ } = useEdificeClient(), {
19
+ t
20
+ } = useTranslation(), showCommentForm = replyToCommentId === parentComment.id && !parentComment.deleted, defaultReplies = (defaultComments == null ? void 0 : defaultComments.filter((comment) => comment.replyTo === parentComment.id && !comment.deleted)) ?? [], displayedReplies = (defaultReplies == null ? void 0 : defaultReplies.sort((a, b) => a.createdAt - b.createdAt).slice(0, repliesLimit)) ?? [], showMoreReplies = displayedReplies.length < defaultReplies.length;
21
+ return {
22
+ t,
23
+ profiles,
24
+ user,
25
+ showCommentForm,
26
+ displayedReplies,
27
+ showMoreReplies,
28
+ handleMoreReplies: () => {
29
+ const newLimit = displayedReplies.length + (additionalReplies ?? 2);
30
+ newLimit !== displayedReplies.length && setRepliesLimit(newLimit);
31
+ }
32
+ };
33
+ };
34
+ export {
35
+ useCommentReplies
36
+ };
@@ -5,6 +5,7 @@ export declare const useComments: ({ defaultComments, options, type, callbacks,
5
5
  type: CommentType;
6
6
  callbacks: CommentCallbacks | null;
7
7
  }) => {
8
+ t: import('i18next').TFunction<"translation", undefined>;
8
9
  profilesQueries: {
9
10
  data: ({
10
11
  userId: string;
@@ -12,21 +13,20 @@ export declare const useComments: ({ defaultComments, options, type, callbacks,
12
13
  } | undefined)[];
13
14
  isLoading: boolean;
14
15
  };
15
- content: string;
16
16
  title: string;
17
17
  user: import('@edifice.io/client').IUserInfo | undefined;
18
18
  emptyscreenPath: string;
19
- defaultCommentsCount: number;
20
- comments: CommentProps[];
19
+ displayedComments: CommentProps[];
20
+ showMoreComments: boolean;
21
21
  editCommentId: string | null;
22
22
  setEditCommentId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
23
- commentsCount: number;
24
- t: import('i18next').TFunction<"translation", undefined>;
23
+ replyToCommentId: string | null;
24
+ setReplyToCommentId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
25
25
  handleMoreComments: () => void;
26
- handleChangeContent: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
27
26
  handleDeleteComment: (id: string) => void;
28
- handleCreateComment: (content: string) => void;
27
+ handleCreateComment: (content: string, replyTo?: string) => void;
29
28
  handleModifyComment: (commentId: string) => void;
30
29
  handleUpdateComment: (comment: string) => Promise<void>;
30
+ handleReplyToComment: (commentId: string) => void;
31
31
  handleReset: () => void;
32
32
  };
@@ -9,43 +9,45 @@ const useComments = ({
9
9
  type,
10
10
  callbacks
11
11
  }) => {
12
- const [content, setContent] = useState(""), [editCommentId, setEditCommentId] = useState(null), [commentLimit, setCommentLimit] = useState(options.maxComments), {
12
+ var _a, _b;
13
+ const [editCommentId, setEditCommentId] = useState(null), [replyToCommentId, setReplyToCommentId] = useState(null), [commentLimit, setCommentLimit] = useState(options.maxComments), {
13
14
  t
14
15
  } = useTranslation(), {
15
16
  user
16
- } = useEdificeClient(), usersIds = Array.from(new Set(defaultComments == null ? void 0 : defaultComments.map((comment) => comment.authorId))), profilesQueries = useProfileQueries(usersIds), comments = useMemo(
17
- () => type === "edit" ? (defaultComments == null ? void 0 : defaultComments.sort((a, b) => b.createdAt - a.createdAt).slice(0, commentLimit)) ?? [] : (defaultComments == null ? void 0 : defaultComments.sort((a, b) => b.createdAt - a.createdAt)) ?? [],
17
+ } = useEdificeClient(), usersIds = Array.from(new Set(defaultComments == null ? void 0 : defaultComments.map((comment) => comment.authorId))), profilesQueries = useProfileQueries(usersIds), idsOfDeletedCommentWithNoReply = useMemo(() => (defaultComments == null ? void 0 : defaultComments.filter((comment) => comment.deleted && !defaultComments.some((c) => c.replyTo === comment.id)).map((comment) => comment.id)) ?? [], [defaultComments]), displayedComments = useMemo(
18
+ () => {
19
+ var _a2;
20
+ const result = ((_a2 = defaultComments == null ? void 0 : defaultComments.filter((comment) => !comment.replyTo && !idsOfDeletedCommentWithNoReply.includes(comment.id))) == null ? void 0 : _a2.sort((a, b) => b.createdAt - a.createdAt)) ?? [];
21
+ return type === "edit" ? result.slice(0, commentLimit) ?? [] : result;
22
+ },
18
23
  // eslint-disable-next-line react-hooks/exhaustive-deps
19
24
  [commentLimit, defaultComments]
20
- ), commentsCount = (comments == null ? void 0 : comments.length) ?? 0, defaultCommentsCount = (defaultComments == null ? void 0 : defaultComments.length) ?? 0, title = defaultCommentsCount && defaultCommentsCount > 1 ? t("comment.several", {
21
- number: defaultCommentsCount
25
+ ), showMoreComments = (displayedComments == null ? void 0 : displayedComments.length) < (((_a = defaultComments == null ? void 0 : defaultComments.filter((comment) => !comment.replyTo && !idsOfDeletedCommentWithNoReply.includes(comment.id))) == null ? void 0 : _a.length) ?? 0), titleCommentsCount = ((_b = defaultComments == null ? void 0 : defaultComments.filter((comment) => !comment.deleted)) == null ? void 0 : _b.length) ?? 0, title = titleCommentsCount > 1 ? t("comment.several", {
26
+ number: titleCommentsCount
22
27
  }) : t("comment.little", {
23
- number: defaultCommentsCount
28
+ number: titleCommentsCount
24
29
  });
25
30
  return {
31
+ t,
26
32
  profilesQueries,
27
- content,
28
33
  title,
29
34
  user,
30
35
  emptyscreenPath: illuPad,
31
- defaultCommentsCount,
32
- comments,
36
+ displayedComments,
37
+ showMoreComments,
33
38
  editCommentId,
34
39
  setEditCommentId,
35
- commentsCount,
36
- t,
40
+ replyToCommentId,
41
+ setReplyToCommentId,
37
42
  handleMoreComments: () => {
38
- const newLimit = (comments == null ? void 0 : comments.length) + (options.additionalComments ?? 5);
39
- newLimit !== comments.length && setCommentLimit(newLimit);
40
- },
41
- handleChangeContent: (event) => {
42
- setContent(event.target.value);
43
+ const newLimit = displayedComments.length + (options.additionalComments ?? 5);
44
+ newLimit !== displayedComments.length && setCommentLimit(newLimit);
43
45
  },
44
46
  handleDeleteComment: (id) => {
45
47
  type === "edit" && (callbacks == null || callbacks.delete(id));
46
48
  },
47
- handleCreateComment: (content2) => {
48
- type === "edit" && (callbacks == null || callbacks.post(content2)), setContent("");
49
+ handleCreateComment: (content, replyTo) => {
50
+ type === "edit" && (callbacks == null || callbacks.post(content, replyTo)), replyTo && setReplyToCommentId(null);
49
51
  },
50
52
  handleModifyComment: (commentId) => {
51
53
  setEditCommentId(commentId);
@@ -56,8 +58,11 @@ const useComments = ({
56
58
  commentId: editCommentId
57
59
  })), setEditCommentId(null));
58
60
  },
61
+ handleReplyToComment: (commentId) => {
62
+ setReplyToCommentId(commentId);
63
+ },
59
64
  handleReset: () => {
60
- setContent(""), editCommentId && setEditCommentId(null);
65
+ editCommentId && setEditCommentId(null);
61
66
  }
62
67
  };
63
68
  };
@@ -1,16 +1,18 @@
1
1
  export declare const useCommentsContext: () => {
2
- comments: import('../types').CommentProps[] | undefined;
3
- content: string;
2
+ displayedComments: import('../types').CommentProps[] | undefined;
3
+ defaultComments: import('../types').CommentProps[] | undefined;
4
4
  editCommentId: string | null;
5
+ replyToCommentId: string | null;
5
6
  profiles: (import('../types').UserProfileResult | undefined)[];
6
7
  options: Partial<import('../types').CommentOptions>;
7
8
  type: import('../types').CommentType;
8
9
  userRights?: Record<import('@edifice.io/client').RightRole, boolean>;
9
10
  setEditCommentId: (value: string | null) => void;
11
+ setReplyToCommentId: (value: string | null) => void;
10
12
  handleModifyComment: (commentId: string) => void;
11
- handleChangeContent: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
12
- handleCreateComment: (content: string) => void;
13
+ handleCreateComment: (content: string, replyTo?: string) => void;
13
14
  handleUpdateComment: (comment: string) => void;
14
15
  handleDeleteComment: (id: string) => void;
16
+ handleReplyToComment: (commentId: string) => void;
15
17
  handleReset: () => void;
16
18
  };
@@ -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_REPLIES, DEFAULT_ADD_COMMENTS, DEFAULT_MAX_COMMENTS, DEFAULT_MAX_REPLY_LENGTH, DEFAULT_MAX_COMMENT_LENGTH } from "../constants.js";
6
+ import { DEFAULT_ADD_REPLIES, 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";
@@ -19,27 +19,28 @@ const CommentProvider = ({
19
19
  maxComments: DEFAULT_MAX_COMMENTS,
20
20
  additionalComments: DEFAULT_ADD_COMMENTS,
21
21
  maxReplies: DEFAULT_MAX_REPLIES,
22
+ additionalReplies: DEFAULT_ADD_REPLIES,
22
23
  ...commentOptions
23
24
  }, {
24
25
  type
25
26
  } = props, {
26
27
  profilesQueries,
27
- content,
28
28
  title,
29
29
  user,
30
30
  emptyscreenPath,
31
- defaultCommentsCount,
32
- comments,
31
+ displayedComments,
32
+ showMoreComments,
33
33
  editCommentId,
34
34
  setEditCommentId,
35
- commentsCount,
35
+ replyToCommentId,
36
+ setReplyToCommentId,
36
37
  t,
37
38
  handleMoreComments,
38
- handleChangeContent,
39
39
  handleDeleteComment,
40
40
  handleCreateComment,
41
41
  handleModifyComment,
42
42
  handleUpdateComment,
43
+ handleReplyToComment,
43
44
  handleReset
44
45
  } = useComments({
45
46
  type,
@@ -48,23 +49,25 @@ const CommentProvider = ({
48
49
  options
49
50
  }), userRights = type === "edit" ? props.rights : void 0, values = useMemo(
50
51
  () => ({
51
- comments,
52
- content,
52
+ displayedComments,
53
+ defaultComments,
53
54
  profiles: profilesQueries.data,
54
55
  editCommentId,
56
+ replyToCommentId,
55
57
  options,
56
58
  type,
57
59
  userRights,
58
60
  setEditCommentId,
61
+ setReplyToCommentId,
59
62
  handleCreateComment,
60
63
  handleModifyComment,
61
64
  handleUpdateComment,
62
65
  handleDeleteComment,
63
- handleReset,
64
- handleChangeContent
66
+ handleReplyToComment,
67
+ handleReset
65
68
  }),
66
69
  // eslint-disable-next-line react-hooks/exhaustive-deps
67
- [comments, content, editCommentId, profilesQueries, options]
70
+ [displayedComments, editCommentId, profilesQueries, options]
68
71
  );
69
72
  return /* @__PURE__ */ jsx(CommentContext.Provider, { value: values, children: /* @__PURE__ */ jsxs("div", { className: "my-24", children: [
70
73
  /* @__PURE__ */ jsx(CommentHeader, { title }),
@@ -72,10 +75,10 @@ const CommentProvider = ({
72
75
  user && /* @__PURE__ */ jsx(CommentForm, { userId: user.userId }),
73
76
  profilesQueries.isLoading ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
74
77
  /* @__PURE__ */ jsx(CommentList, {}),
75
- commentsCount !== defaultCommentsCount && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", onClick: handleMoreComments, className: "my-16", children: t("comment.more") })
78
+ showMoreComments && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", onClick: handleMoreComments, className: "my-16", children: t("comment.more") })
76
79
  ] })
77
80
  ] }),
78
- !commentsCount && type === "edit" && /* @__PURE__ */ jsxs("div", { className: "comments-emptyscreen", children: [
81
+ !displayedComments.length && type === "edit" && /* @__PURE__ */ jsxs("div", { className: "comments-emptyscreen", children: [
79
82
  /* @__PURE__ */ jsx("div", { className: "comments-emptyscreen-wrapper", children: /* @__PURE__ */ jsx(EmptyScreen, { imageSrc: emptyscreenPath, size: 150 }) }),
80
83
  /* @__PURE__ */ jsx("p", { children: t("comment.emptyscreen") })
81
84
  ] })
@@ -24,13 +24,22 @@ export interface CommentProps {
24
24
  * Date when comment was updated
25
25
  */
26
26
  updatedAt?: number;
27
+ /**
28
+ * The comment parent ID.
29
+ */
30
+ replyTo?: string;
31
+ /**
32
+ * If the comment is deleted.
33
+ */
34
+ deleted?: boolean;
27
35
  }
28
36
  export interface CommentCallbacks {
29
37
  /**
30
38
  * Method to create a new comment
31
39
  * Get the new comment in the callback function
40
+ * If replyTo is provided, it is a reply to a comment
32
41
  */
33
- post: (comment: string) => Promise<void>;
42
+ post: (comment: string, replyTo?: string) => Promise<void>;
34
43
  /**
35
44
  * Method to update a comment
36
45
  * Get the comment and commentId in the callback function
@@ -91,6 +100,10 @@ export type CommentOptions = {
91
100
  * Limit on displaying replies to a comment
92
101
  */
93
102
  maxReplies: number;
103
+ /**
104
+ * Number of replies to load additionally in the limited list
105
+ */
106
+ additionalReplies: number;
94
107
  };
95
108
  export interface UserProfileResult {
96
109
  /**
@@ -0,0 +1,6 @@
1
+ import { Editor } from '@tiptap/react';
2
+ declare const BubbleMenuEditInformationPane: ({ editor, editable, }: {
3
+ editor: Editor;
4
+ editable: boolean;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export default BubbleMenuEditInformationPane;
@@ -0,0 +1,136 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { BubbleMenu } from "@tiptap/react";
4
+ import { useTranslation } from "react-i18next";
5
+ import { Toolbar } from "../../../../components/Toolbar/Toolbar.js";
6
+ import SvgIconAlertTriangle from "../../../icons/components/IconAlertTriangle.js";
7
+ import SvgIconDelete from "../../../icons/components/IconDelete.js";
8
+ import SvgIconInfoCircle from "../../../icons/components/IconInfoCircle.js";
9
+ import SvgIconQuestion from "../../../icons/components/IconQuestion.js";
10
+ import SvgIconSuccessOutline from "../../../icons/components/IconSuccessOutline.js";
11
+ const BubbleMenuEditInformationPane = ({
12
+ editor,
13
+ editable
14
+ }) => {
15
+ const {
16
+ t
17
+ } = useTranslation(), {
18
+ selection
19
+ } = editor.view.state, selectedNode = selection.$from.node(1), InformationPaneTypeItems = useMemo(() => {
20
+ var _a, _b, _c, _d;
21
+ return [{
22
+ type: "icon",
23
+ name: "info",
24
+ props: {
25
+ size: "lg",
26
+ leftIcon: /* @__PURE__ */ jsx(SvgIconInfoCircle, {}),
27
+ "aria-label": t("tiptap.tooltip.bubblemenu.information.pane.info"),
28
+ className: ((_a = selectedNode == null ? void 0 : selectedNode.attrs) == null ? void 0 : _a.type) === "info" ? "is-selected" : "",
29
+ onClick: () => editor.chain().focus().updateAttributes("information-pane", {
30
+ type: "info"
31
+ }).run()
32
+ },
33
+ tooltip: {
34
+ message: t("tiptap.tooltip.bubblemenu.information.pane.info"),
35
+ position: "top"
36
+ }
37
+ }, {
38
+ type: "icon",
39
+ name: "success",
40
+ props: {
41
+ size: "lg",
42
+ leftIcon: /* @__PURE__ */ jsx(SvgIconSuccessOutline, {}),
43
+ "aria-label": t("tiptap.tooltip.bubblemenu.information.pane.success"),
44
+ className: ((_b = selectedNode == null ? void 0 : selectedNode.attrs) == null ? void 0 : _b.type) === "success" ? "is-selected" : "",
45
+ onClick: () => editor.chain().focus().updateAttributes("information-pane", {
46
+ type: "success"
47
+ }).run()
48
+ },
49
+ tooltip: {
50
+ message: t("tiptap.tooltip.bubblemenu.information.pane.success"),
51
+ position: "top"
52
+ }
53
+ }, {
54
+ type: "icon",
55
+ name: "warning",
56
+ props: {
57
+ size: "lg",
58
+ leftIcon: /* @__PURE__ */ jsx(SvgIconAlertTriangle, {}),
59
+ "aria-label": t("tiptap.tooltip.bubblemenu.information.pane.warning"),
60
+ className: ((_c = selectedNode == null ? void 0 : selectedNode.attrs) == null ? void 0 : _c.type) === "warning" ? "is-selected" : "",
61
+ onClick: () => editor.chain().focus().updateAttributes("information-pane", {
62
+ type: "warning"
63
+ }).run()
64
+ },
65
+ tooltip: {
66
+ message: t("tiptap.tooltip.bubblemenu.information.pane.warning"),
67
+ position: "top"
68
+ }
69
+ }, {
70
+ type: "icon",
71
+ name: "question",
72
+ props: {
73
+ size: "lg",
74
+ leftIcon: /* @__PURE__ */ jsx(SvgIconQuestion, {}),
75
+ "aria-label": t("tiptap.tooltip.bubblemenu.information.pane.question"),
76
+ className: ((_d = selectedNode == null ? void 0 : selectedNode.attrs) == null ? void 0 : _d.type) === "question" ? "is-selected" : "",
77
+ onClick: () => editor.chain().focus().updateAttributes("information-pane", {
78
+ type: "question"
79
+ }).run()
80
+ },
81
+ tooltip: {
82
+ message: t("tiptap.tooltip.bubblemenu.information.pane.question"),
83
+ position: "top"
84
+ }
85
+ }, {
86
+ type: "divider",
87
+ name: "div-4"
88
+ }, {
89
+ type: "button",
90
+ name: "delete",
91
+ props: {
92
+ size: "lg",
93
+ leftIcon: /* @__PURE__ */ jsx(SvgIconDelete, {}),
94
+ "aria-label": t("tiptap.bubblemenu.delete"),
95
+ children: t("tiptap.bubblemenu.delete"),
96
+ onClick: () => editor.chain().focus().deleteNode("information-pane").run()
97
+ },
98
+ tooltip: {
99
+ message: t("tiptap.bubblemenu.delete"),
100
+ position: "top"
101
+ }
102
+ }];
103
+ }, [t, selectedNode]), tippyOptions = useMemo(() => ({
104
+ placement: "bottom",
105
+ offset: [0, 0],
106
+ zIndex: 999,
107
+ duration: 100,
108
+ getReferenceClientRect: () => {
109
+ const {
110
+ state
111
+ } = editor, {
112
+ $anchor
113
+ } = state.selection;
114
+ let informationPanePos = null;
115
+ for (let depth = $anchor.depth; depth >= 0; depth--)
116
+ if ($anchor.node(depth).type.name === "information-pane") {
117
+ informationPanePos = $anchor.before(depth);
118
+ break;
119
+ }
120
+ if (informationPanePos !== null) {
121
+ let domNode = editor.view.nodeDOM(informationPanePos);
122
+ for (; domNode && domNode instanceof HTMLElement && !domNode.classList.contains("information-pane"); )
123
+ domNode = domNode.children[0];
124
+ if (domNode instanceof HTMLElement)
125
+ return domNode.getBoundingClientRect();
126
+ }
127
+ return new DOMRect(0, 0, 0, 0);
128
+ }
129
+ }), [editor]);
130
+ return /* @__PURE__ */ jsx(BubbleMenu, { shouldShow: ({
131
+ editor: editor2
132
+ }) => editor2.isActive("information-pane"), editor, tippyOptions, children: editable && /* @__PURE__ */ jsx(Toolbar, { className: "p-8", items: InformationPaneTypeItems }) });
133
+ };
134
+ export {
135
+ BubbleMenuEditInformationPane as default
136
+ };
@@ -0,0 +1 @@
1
+ export { default as BubbleMenuEditInformationPane } from './BubbleMenuEditInformationPane';
@@ -1,5 +1,5 @@
1
1
  import { WorkspaceVisibility } from '@edifice.io/client';
2
- import { Content, Extensions, FocusPosition, JSONContent } from '@tiptap/react';
2
+ import { Content, FocusPosition, JSONContent } from '@tiptap/react';
3
3
  export interface EditorRef {
4
4
  /** Get the current content. */
5
5
  getContent: (as: 'html' | 'json' | 'plain') => undefined | string | JSONContent;
@@ -40,8 +40,6 @@ export interface EditorProps {
40
40
  onContentChange?: ({ editor }: {
41
41
  editor: any;
42
42
  }) => void;
43
- /** Extensions to add to the editor */
44
- extensions?: Extensions;
45
43
  }
46
44
  declare const Editor: import('react').ForwardRefExoticComponent<EditorProps & import('react').RefAttributes<EditorRef>>;
47
45
  export default Editor;
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { forwardRef, useId, useImperativeHandle, Suspense, lazy } from "react";
3
3
  import { EditorContent } from "@tiptap/react";
4
4
  import clsx from "clsx";
@@ -16,6 +16,7 @@ import { EditorToolbar } from "../EditorToolbar/EditorToolbar.js";
16
16
  import LinkToolbar from "../Toolbar/LinkToolbar.js";
17
17
  import TableToolbar from "../Toolbar/TableToolbar.js";
18
18
  import BubbleMenuEditImage from "../BubbleMenuEditImage/BubbleMenuEditImage.js";
19
+ import BubbleMenuEditInformationPane from "../BubbleMenuEditInformationPane/BubbleMenuEditInformationPane.js";
19
20
  import MediaLibrary from "../../../multimedia/MediaLibrary/MediaLibrary.js";
20
21
  import LoadingScreen from "../../../../components/LoadingScreen/LoadingScreen.js";
21
22
  const MathsModal = /* @__PURE__ */ lazy(async () => await import("../MathsModal/MathsModal.js")), ImageEditor = /* @__PURE__ */ lazy(async () => await import("../../../multimedia/ImageEditor/components/ImageEditor.js")), Editor = /* @__PURE__ */ forwardRef(({
@@ -27,15 +28,14 @@ const MathsModal = /* @__PURE__ */ lazy(async () => await import("../MathsModal/
27
28
  focus = "start",
28
29
  placeholder = "",
29
30
  visibility = "protected",
30
- onContentChange,
31
- extensions
31
+ onContentChange
32
32
  }, ref) => {
33
33
  const editorId = useId(), {
34
34
  appCode
35
35
  } = useEdificeClient(), {
36
36
  editor,
37
37
  editable
38
- } = useTipTapEditor(mode === "edit", content, focus, placeholder, onContentChange, visibility, extensions), {
38
+ } = useTipTapEditor(mode === "edit", content, focus, placeholder, onContentChange, visibility), {
39
39
  ref: mediaLibraryModalRef,
40
40
  ...mediaLibraryModalHandlers
41
41
  } = useMediaLibraryEditor(editor), {
@@ -71,7 +71,10 @@ const MathsModal = /* @__PURE__ */ lazy(async () => await import("../MathsModal/
71
71
  ] }),
72
72
  /* @__PURE__ */ jsx(LinkToolbar, { editor, ...linkToolbarHandlers }),
73
73
  /* @__PURE__ */ jsx(TableToolbar, { editor }),
74
- editor && /* @__PURE__ */ jsx(BubbleMenuEditImage, { editor, onEditImage: imageModal.handleEdit, openEditImage: imageModal.isOpen, editable }),
74
+ editor && /* @__PURE__ */ jsxs(Fragment, { children: [
75
+ /* @__PURE__ */ jsx(BubbleMenuEditImage, { editor, onEditImage: imageModal.handleEdit, openEditImage: imageModal.isOpen, editable }),
76
+ /* @__PURE__ */ jsx(BubbleMenuEditInformationPane, { editor, editable })
77
+ ] }),
75
78
  /* @__PURE__ */ jsxs(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingScreen, {}), children: [
76
79
  editable && /* @__PURE__ */ jsx(MediaLibrary, { appCode, visibility, multiple: !0, ref: mediaLibraryModalRef, ...mediaLibraryModalHandlers }),
77
80
  editable && mathsModalHandlers.isOpen && /* @__PURE__ */ jsx(MathsModal, { ...mathsModalHandlers }),
@@ -5,6 +5,7 @@ import "@tiptap/react";
5
5
  import "@tiptap/starter-kit";
6
6
  import SvgIconAlignLeft from "../../../icons/components/IconAlignLeft.js";
7
7
  import SvgIconBulletList from "../../../icons/components/IconBulletList.js";
8
+ import SvgIconInfoRectangle from "../../../icons/components/IconInfoRectangle.js";
8
9
  import SvgIconLandscape from "../../../icons/components/IconLandscape.js";
9
10
  import SvgIconLink from "../../../icons/components/IconLink.js";
10
11
  import SvgIconMic from "../../../icons/components/IconMic.js";
@@ -213,6 +214,17 @@ const EditorToolbar = ({
213
214
  visibility: showIf(hasMark("customHighlight", editor)),
214
215
  tooltip: t("tiptap.toolbar.highlight.back")
215
216
  },
217
+ //--------------- INFORMATION PANE ---------------//
218
+ {
219
+ type: "icon",
220
+ props: {
221
+ icon: /* @__PURE__ */ jsx(SvgIconInfoRectangle, {}),
222
+ "aria-label": t("tiptap.toolbar.information.pane"),
223
+ onClick: () => editor == null ? void 0 : editor.chain().focus().setInformationPane("info").run()
224
+ },
225
+ name: "information-pane",
226
+ tooltip: t("tiptap.toolbar.information.pane")
227
+ },
216
228
  //-------------------------------------//
217
229
  {
218
230
  type: "divider",