@edifice.io/react 2.2.2 → 2.2.3
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.
- package/dist/components/Avatar/Avatar.d.ts +21 -0
- package/dist/components/Avatar/Avatar.js +15 -2
- package/dist/components/AvatarGroup/AvatarGroup.d.ts +24 -0
- package/dist/components/AvatarGroup/AvatarGroup.js +24 -0
- package/dist/components/AvatarGroup/index.d.ts +2 -0
- package/dist/components/Card/Card.d.ts +3 -1
- package/dist/components/Card/CardBody.d.ts +3 -1
- package/dist/components/Card/CardBody.js +4 -2
- package/dist/components/Dropdown/Dropdown.d.ts +6 -2
- package/dist/components/Dropdown/Dropdown.js +2 -0
- package/dist/components/Dropdown/DropdownItem.d.ts +5 -1
- package/dist/components/Dropdown/DropdownItem.js +7 -2
- package/dist/components/Dropdown/DropdownTrigger.d.ts +31 -2
- package/dist/components/Dropdown/DropdownTrigger.js +23 -3
- package/dist/components/PreventPropagation/PreventPropagation.d.ts +10 -0
- package/dist/components/PreventPropagation/PreventPropagation.js +9 -0
- package/dist/components/PreventPropagation/index.d.ts +2 -0
- package/dist/components/StackedGroup/StackedGroup.d.ts +23 -0
- package/dist/components/StackedGroup/StackedGroup.js +21 -0
- package/dist/components/StackedGroup/index.d.ts +1 -0
- package/dist/components/Switch/Switch.d.ts +29 -0
- package/dist/components/Switch/Switch.js +27 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/editor.js +16 -12
- package/dist/hooks/useConf/useConf.d.ts +1 -1
- package/dist/hooks/useSession/useSession.d.ts +1 -1
- package/dist/icons.js +178 -176
- package/dist/index.js +154 -146
- package/dist/modules/comments/components/Comment.js +49 -34
- package/dist/modules/comments/components/CommentDeleted.d.ts +1 -0
- package/dist/modules/comments/components/CommentDeleted.js +11 -0
- package/dist/modules/comments/components/CommentForm.d.ts +2 -1
- package/dist/modules/comments/components/CommentForm.js +12 -8
- package/dist/modules/comments/components/CommentList.js +3 -3
- package/dist/modules/comments/components/CommentReplies.d.ts +4 -0
- package/dist/modules/comments/components/CommentReplies.js +33 -0
- package/dist/modules/comments/constants.d.ts +4 -0
- package/dist/modules/comments/constants.js +2 -1
- package/dist/modules/comments/context/Context.d.ts +6 -4
- package/dist/modules/comments/hooks/useCommentReplies.d.ts +12 -0
- package/dist/modules/comments/hooks/useCommentReplies.js +36 -0
- package/dist/modules/comments/hooks/useComments.d.ts +7 -7
- package/dist/modules/comments/hooks/useComments.js +24 -19
- package/dist/modules/comments/hooks/useCommentsContext.d.ts +6 -4
- package/dist/modules/comments/provider/CommentProvider.js +16 -13
- package/dist/modules/comments/types.d.ts +14 -1
- package/dist/modules/editor/components/BubbleMenuEditInformationPane/BubbleMenuEditInformationPane.d.ts +6 -0
- package/dist/modules/editor/components/BubbleMenuEditInformationPane/BubbleMenuEditInformationPane.js +136 -0
- package/dist/modules/editor/components/BubbleMenuEditInformationPane/index.d.ts +1 -0
- package/dist/modules/editor/components/Editor/Editor.js +6 -2
- package/dist/modules/editor/components/EditorToolbar/EditorToolbar.js +12 -0
- package/dist/modules/editor/components/NodeView/InformationPaneNodeView.d.ts +2 -0
- package/dist/modules/editor/components/NodeView/InformationPaneNodeView.js +10 -0
- package/dist/modules/editor/components/NodeView/index.d.ts +1 -0
- package/dist/modules/editor/components/Renderer/InformationPaneRenderer.d.ts +3 -0
- package/dist/modules/editor/components/Renderer/InformationPaneRenderer.js +33 -0
- package/dist/modules/editor/components/Renderer/index.d.ts +1 -0
- package/dist/modules/editor/hooks/useTipTapEditor.js +3 -1
- package/dist/modules/icons/components/IconInfoRectangle.d.ts +7 -0
- package/dist/modules/icons/components/IconInfoRectangle.js +13 -0
- package/dist/modules/icons/components/index.d.ts +1 -0
- package/dist/modules/modals/ResourceModal/ResourceModal.d.ts +1 -1
- package/dist/modules/modals/ResourceModal/hooks/useUpdateMutation.d.ts +1 -1
- package/dist/modules/modals/ShareModal/ShareModal.d.ts +1 -1
- package/dist/modules/modals/ShareModal/apps/ShareBlog.d.ts +1 -1
- package/dist/modules/modals/ShareModal/hooks/useShareMutation.d.ts +1 -1
- package/dist/providers/EdificeClientProvider/EdificeClientProvider.context.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/package.json +6 -6
|
@@ -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
|
-
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
19
|
+
displayedComments: CommentProps[];
|
|
20
|
+
showMoreComments: boolean;
|
|
21
21
|
editCommentId: string | null;
|
|
22
22
|
setEditCommentId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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),
|
|
17
|
-
() =>
|
|
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
|
-
),
|
|
21
|
-
number:
|
|
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:
|
|
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
|
-
|
|
32
|
-
|
|
36
|
+
displayedComments,
|
|
37
|
+
showMoreComments,
|
|
33
38
|
editCommentId,
|
|
34
39
|
setEditCommentId,
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
replyToCommentId,
|
|
41
|
+
setReplyToCommentId,
|
|
37
42
|
handleMoreComments: () => {
|
|
38
|
-
const newLimit =
|
|
39
|
-
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: (
|
|
48
|
-
type === "edit" && (callbacks == null || callbacks.post(
|
|
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
|
-
|
|
65
|
+
editCommentId && setEditCommentId(null);
|
|
61
66
|
}
|
|
62
67
|
};
|
|
63
68
|
};
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
export declare const useCommentsContext: () => {
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
31
|
+
displayedComments,
|
|
32
|
+
showMoreComments,
|
|
33
33
|
editCommentId,
|
|
34
34
|
setEditCommentId,
|
|
35
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
|
|
64
|
-
|
|
66
|
+
handleReplyToComment,
|
|
67
|
+
handleReset
|
|
65
68
|
}),
|
|
66
69
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
-
[
|
|
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
|
-
|
|
78
|
+
showMoreComments && /* @__PURE__ */ jsx(Button, { variant: "ghost", color: "tertiary", onClick: handleMoreComments, className: "my-16", children: t("comment.more") })
|
|
76
79
|
] })
|
|
77
80
|
] }),
|
|
78
|
-
!
|
|
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,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,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(({
|
|
@@ -70,7 +71,10 @@ const MathsModal = /* @__PURE__ */ lazy(async () => await import("../MathsModal/
|
|
|
70
71
|
] }),
|
|
71
72
|
/* @__PURE__ */ jsx(LinkToolbar, { editor, ...linkToolbarHandlers }),
|
|
72
73
|
/* @__PURE__ */ jsx(TableToolbar, { editor }),
|
|
73
|
-
editor && /* @__PURE__ */
|
|
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
|
+
] }),
|
|
74
78
|
/* @__PURE__ */ jsxs(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingScreen, {}), children: [
|
|
75
79
|
editable && /* @__PURE__ */ jsx(MediaLibrary, { appCode, visibility, multiple: !0, ref: mediaLibraryModalRef, ...mediaLibraryModalHandlers }),
|
|
76
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",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InformationPane } from "@edifice.io/tiptap-extensions/information-pane";
|
|
2
|
+
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
3
|
+
const InformationPaneNodeView = (Component) => InformationPane.extend({
|
|
4
|
+
addNodeView() {
|
|
5
|
+
return ReactNodeViewRenderer(Component);
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
export {
|
|
9
|
+
InformationPaneNodeView as default
|
|
10
|
+
};
|
|
@@ -3,3 +3,4 @@ export { default as AttachmentNodeView } from './AttachmentNodeView';
|
|
|
3
3
|
export { default as ImageNodeView } from './ImageNodeView';
|
|
4
4
|
export { default as LinkerNodeView } from './LinkerNodeView';
|
|
5
5
|
export { default as VideoNodeView } from './VideoNodeView';
|
|
6
|
+
export { default as InformationPaneNodeView } from './InformationPaneNodeView';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import SvgIconAlertTriangle from "../../../icons/components/IconAlertTriangle.js";
|
|
3
|
+
import SvgIconInfoCircle from "../../../icons/components/IconInfoCircle.js";
|
|
4
|
+
import SvgIconQuestion from "../../../icons/components/IconQuestion.js";
|
|
5
|
+
import SvgIconSuccessOutline from "../../../icons/components/IconSuccessOutline.js";
|
|
6
|
+
import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
|
|
7
|
+
const InformationPaneRenderer = (props) => {
|
|
8
|
+
const {
|
|
9
|
+
node
|
|
10
|
+
} = props, getIconByType = (type) => {
|
|
11
|
+
switch (type) {
|
|
12
|
+
case "warning":
|
|
13
|
+
return /* @__PURE__ */ jsx(SvgIconAlertTriangle, { color: "#F59700" });
|
|
14
|
+
case "success":
|
|
15
|
+
return /* @__PURE__ */ jsx(SvgIconSuccessOutline, { color: "#7DBF85" });
|
|
16
|
+
case "info":
|
|
17
|
+
return /* @__PURE__ */ jsx(SvgIconInfoCircle, { color: "#2A9CC8" });
|
|
18
|
+
case "question":
|
|
19
|
+
return /* @__PURE__ */ jsx(SvgIconQuestion, { color: "#823AA1" });
|
|
20
|
+
default:
|
|
21
|
+
return /* @__PURE__ */ jsx(SvgIconInfoCircle, { color: "#2A9CC8" });
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return /* @__PURE__ */ jsx(NodeViewWrapper, { node, className: "react-component", children: /* @__PURE__ */ jsxs("div", { className: `information-pane information-pane-${node.attrs.type}`, "data-information-pane": !0, "data-type": node.attrs.type, children: [
|
|
25
|
+
/* @__PURE__ */ jsx("span", { className: "information-pane-icon", children: getIconByType(node.attrs.type) }),
|
|
26
|
+
/* @__PURE__ */ jsx(NodeViewContent, { style: {
|
|
27
|
+
width: "100%"
|
|
28
|
+
} })
|
|
29
|
+
] }) });
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
InformationPaneRenderer as default
|
|
33
|
+
};
|
|
@@ -2,3 +2,4 @@ export { default as AudioRenderer } from './AudioRenderer';
|
|
|
2
2
|
export { default as AttachmentRenderer } from './AttachmentRenderer';
|
|
3
3
|
export { default as LinkerRenderer } from './LinkerRenderer';
|
|
4
4
|
export { default as MediaRenderer } from './MediaRenderer';
|
|
5
|
+
export { default as InformationPaneRenderer } from './InformationPaneRenderer';
|
|
@@ -32,10 +32,12 @@ import AudioNodeView from "../components/NodeView/AudioNodeView.js";
|
|
|
32
32
|
import LinkerNodeView from "../components/NodeView/LinkerNodeView.js";
|
|
33
33
|
import ImageNodeView from "../components/NodeView/ImageNodeView.js";
|
|
34
34
|
import AttachmentNodeView from "../components/NodeView/AttachmentNodeView.js";
|
|
35
|
+
import InformationPaneNodeView from "../components/NodeView/InformationPaneNodeView.js";
|
|
35
36
|
import MediaRenderer from "../components/Renderer/MediaRenderer.js";
|
|
36
37
|
import AudioRenderer from "../components/Renderer/AudioRenderer.js";
|
|
37
38
|
import LinkerRenderer from "../components/Renderer/LinkerRenderer.js";
|
|
38
39
|
import AttachmentRenderer from "../components/Renderer/AttachmentRenderer.js";
|
|
40
|
+
import InformationPaneRenderer from "../components/Renderer/InformationPaneRenderer.js";
|
|
39
41
|
const useTipTapEditor = (editable, content, focus, placeholder, onContentChange, visibility = "protected") => {
|
|
40
42
|
const {
|
|
41
43
|
currentLanguage
|
|
@@ -63,7 +65,7 @@ const useTipTapEditor = (editable, content, focus, placeholder, onContentChange,
|
|
|
63
65
|
levels: [1, 2]
|
|
64
66
|
}), Typography, FontSize, SpeechRecognition, SpeechSynthesis.configure({
|
|
65
67
|
lang: (currentLanguage == null ? void 0 : currentLanguage.length) === 2 ? `${currentLanguage}-${currentLanguage.toUpperCase()}` : "fr-FR"
|
|
66
|
-
}), Iframe, Hyperlink, FontFamily, Mathematics, Alert, VideoNodeView(MediaRenderer), AudioNodeView(AudioRenderer), LinkerNodeView(LinkerRenderer), ImageNodeView(MediaRenderer, uploadFile), AttachmentNodeView(AttachmentRenderer)],
|
|
68
|
+
}), Iframe, Hyperlink, FontFamily, Mathematics, Alert, VideoNodeView(MediaRenderer), AudioNodeView(AudioRenderer), LinkerNodeView(LinkerRenderer), ImageNodeView(MediaRenderer, uploadFile), AttachmentNodeView(AttachmentRenderer), InformationPaneNodeView(InformationPaneRenderer)],
|
|
67
69
|
content,
|
|
68
70
|
// If the onContentChange callback is provided, we call it on every content change.
|
|
69
71
|
...onContentChange ? {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface SVGRProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleId?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIconInfoRectangle: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIconInfoRectangle;
|