@selfcommunity/react-ui 0.10.2-courses.159 → 0.10.2-courses.160
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/lib/cjs/components/CommentObjectReply/CommentObjectReply.js +11 -5
- package/lib/cjs/components/Composer/Content/ContentLesson/ContentLesson.js +35 -4
- package/lib/cjs/components/CourseDashboard/Teacher/Comments.js +2 -2
- package/lib/cjs/components/CourseParticipantsButton/CourseParticipantsButton.js +1 -1
- package/lib/cjs/components/Editor/Editor.d.ts +13 -1
- package/lib/cjs/components/Editor/Editor.js +3 -4
- package/lib/cjs/components/Editor/nodes/index.d.ts +1 -2
- package/lib/cjs/components/Editor/nodes/index.js +1 -3
- package/lib/cjs/components/Editor/plugins/MediaPlugin.d.ts +2 -1
- package/lib/cjs/components/Editor/plugins/MediaPlugin.js +5 -27
- package/lib/cjs/components/Editor/plugins/ToolbarPlugin.d.ts +2 -0
- package/lib/cjs/components/Editor/plugins/ToolbarPlugin.js +2 -2
- package/lib/cjs/components/LessonCommentObject/LessonCommentObject.d.ts +1 -0
- package/lib/cjs/components/LessonCommentObject/LessonCommentObject.js +8 -2
- package/lib/cjs/components/LessonCommentObjects/LessonCommentObjects.js +5 -1
- package/lib/cjs/components/LessonObject/LessonObject.js +7 -3
- package/lib/cjs/shared/AccordionLessons/AccordionLessons.js +5 -4
- package/lib/cjs/shared/LessonFilePreview/index.d.ts +12 -0
- package/lib/cjs/shared/LessonFilePreview/index.js +29 -0
- package/lib/cjs/shared/Media/Link/UrlTextField/index.js +2 -3
- package/lib/esm/components/CommentObjectReply/CommentObjectReply.js +11 -5
- package/lib/esm/components/Composer/Content/ContentLesson/ContentLesson.js +37 -6
- package/lib/esm/components/CourseDashboard/Teacher/Comments.js +3 -3
- package/lib/esm/components/CourseParticipantsButton/CourseParticipantsButton.js +1 -1
- package/lib/esm/components/Editor/Editor.d.ts +13 -1
- package/lib/esm/components/Editor/Editor.js +3 -4
- package/lib/esm/components/Editor/nodes/index.d.ts +1 -2
- package/lib/esm/components/Editor/nodes/index.js +1 -3
- package/lib/esm/components/Editor/plugins/MediaPlugin.d.ts +2 -1
- package/lib/esm/components/Editor/plugins/MediaPlugin.js +5 -27
- package/lib/esm/components/Editor/plugins/ToolbarPlugin.d.ts +2 -0
- package/lib/esm/components/Editor/plugins/ToolbarPlugin.js +2 -2
- package/lib/esm/components/LessonCommentObject/LessonCommentObject.d.ts +1 -0
- package/lib/esm/components/LessonCommentObject/LessonCommentObject.js +8 -2
- package/lib/esm/components/LessonCommentObjects/LessonCommentObjects.js +5 -1
- package/lib/esm/components/LessonObject/LessonObject.js +8 -4
- package/lib/esm/shared/AccordionLessons/AccordionLessons.js +6 -5
- package/lib/esm/shared/LessonFilePreview/index.d.ts +12 -0
- package/lib/esm/shared/LessonFilePreview/index.js +25 -0
- package/lib/esm/shared/Media/Link/UrlTextField/index.js +3 -4
- package/lib/umd/react-ui.js +1 -1
- package/package.json +8 -8
- package/lib/cjs/components/Editor/nodes/DocNode.d.ts +0 -39
- package/lib/cjs/components/Editor/nodes/DocNode.js +0 -181
- package/lib/esm/components/Editor/nodes/DocNode.d.ts +0 -39
- package/lib/esm/components/Editor/nodes/DocNode.js +0 -175
|
@@ -14,10 +14,12 @@ const lab_1 = require("@mui/lab");
|
|
|
14
14
|
const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
|
|
15
15
|
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
|
|
16
16
|
const system_1 = require("@mui/system");
|
|
17
|
+
const PreviewComponent_1 = tslib_1.__importDefault(require("../../shared/Media/File/PreviewComponent"));
|
|
17
18
|
const PREFIX = 'SCCommentObjectReply';
|
|
18
19
|
const classes = {
|
|
19
20
|
root: `${PREFIX}-root`,
|
|
20
21
|
comment: `${PREFIX}-comment`,
|
|
22
|
+
media: `${PREFIX}-media`,
|
|
21
23
|
hasValue: `${PREFIX}-has-value`,
|
|
22
24
|
avatar: `${PREFIX}-avatar`,
|
|
23
25
|
actions: `${PREFIX}-actions`,
|
|
@@ -70,7 +72,8 @@ function CommentObjectReply(inProps) {
|
|
|
70
72
|
const scUserContext = (0, react_core_1.useSCUser)();
|
|
71
73
|
// RETRIEVE OBJECTS
|
|
72
74
|
const [html, setHtml] = (0, react_1.useState)(text);
|
|
73
|
-
const [media, setMedia] = (0, react_1.useState)(medias);
|
|
75
|
+
const [media, setMedia] = (0, react_1.useState)(medias !== null && medias !== void 0 ? medias : []);
|
|
76
|
+
const [uploadingMedia, setUploadingMedia] = (0, react_1.useState)(false);
|
|
74
77
|
// HOOKS
|
|
75
78
|
const theme = (0, material_1.useTheme)();
|
|
76
79
|
const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'));
|
|
@@ -115,8 +118,11 @@ function CommentObjectReply(inProps) {
|
|
|
115
118
|
const handleChangeText = (value) => {
|
|
116
119
|
setHtml(value);
|
|
117
120
|
};
|
|
118
|
-
const handleChangeMedia = (
|
|
119
|
-
setMedia(
|
|
121
|
+
const handleChangeMedia = (value) => {
|
|
122
|
+
setMedia((prev) => [...prev, value]);
|
|
123
|
+
};
|
|
124
|
+
const handleChangeMedias = (value) => {
|
|
125
|
+
setMedia([...value]);
|
|
120
126
|
};
|
|
121
127
|
/**
|
|
122
128
|
* Check if editor is empty
|
|
@@ -127,7 +133,7 @@ function CommentObjectReply(inProps) {
|
|
|
127
133
|
}, [html]);
|
|
128
134
|
// RENDER
|
|
129
135
|
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id }, rest, { disableTypography: true, onClick: handleEditorFocus, elevation: elevation, className: (0, classnames_1.default)(classes.root, className), image: showAvatar &&
|
|
130
|
-
(!scUserContext.user ? ((0, jsx_runtime_1.jsx)(material_1.Avatar, { variant: "circular", className: classes.avatar })) : ((0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !scUserContext.user.community_badge }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scUserContext.user.username, variant: "circular", src: scUserContext.user.avatar, classes: { root: classes.avatar } }) })))), secondary: (0, jsx_runtime_1.jsxs)(Widget_1.default, Object.assign({ className: (0, classnames_1.default)(classes.comment, { [classes.hasValue]: !isEditorEmpty }) }, WidgetProps, { children: [(0, jsx_runtime_1.jsx)(Editor_1.default, Object.assign({ ref: editor, onChange: handleChangeText,
|
|
131
|
-
onReply && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleReply, className: classes.iconReply }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "send" }) }))) }, EditorProps)), !isEditorEmpty && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", spacing: 2, className: classes.actions }, { children: [onReply && !replyIcon && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: "outlined", size: "small", onClick: handleReply, loading: !editable, className: classes.buttonReply }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.reply", defaultMessage: "ui.commentObject.replyComment.reply" }) }))), onSave && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [onCancel && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: 'text', size: "small", onClick: handleCancel, disabled: !editable, color: "inherit", className: classes.buttonCancel }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.cancel", defaultMessage: "ui.commentObject.replyComment.cancel" }) }))), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: "outlined", size: "small", onClick: handleSave, loading: !editable, className: classes.buttonSave }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.save", defaultMessage: "ui.commentObject.replyComment.save" }) }))] }))] })))] })) })));
|
|
136
|
+
(!scUserContext.user ? ((0, jsx_runtime_1.jsx)(material_1.Avatar, { variant: "circular", className: classes.avatar })) : ((0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !scUserContext.user.community_badge }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scUserContext.user.username, variant: "circular", src: scUserContext.user.avatar, classes: { root: classes.avatar } }) })))), secondary: (0, jsx_runtime_1.jsxs)(Widget_1.default, Object.assign({ className: (0, classnames_1.default)(classes.comment, { [classes.hasValue]: !isEditorEmpty }) }, WidgetProps, { children: [media && media.length > 0 && (0, jsx_runtime_1.jsx)(PreviewComponent_1.default, { value: media, onChange: handleChangeMedias, className: classes.media }), (0, jsx_runtime_1.jsx)(Editor_1.default, Object.assign({ ref: editor, onChange: handleChangeText, defaultValue: html, editable: editable, uploadImage: true, action: replyIcon &&
|
|
137
|
+
onReply && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleReply, className: classes.iconReply, disabled: uploadingMedia }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "send" }) }))) }, EditorProps, { MediaPluginProps: { isUploading: setUploadingMedia, onMediaAdd: handleChangeMedia } })), !isEditorEmpty && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", spacing: 2, className: classes.actions }, { children: [onReply && !replyIcon && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: "outlined", size: "small", onClick: handleReply, loading: !editable, className: classes.buttonReply }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.reply", defaultMessage: "ui.commentObject.replyComment.reply" }) }))), onSave && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [onCancel && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: 'text', size: "small", onClick: handleCancel, disabled: !editable, color: "inherit", className: classes.buttonCancel }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.cancel", defaultMessage: "ui.commentObject.replyComment.cancel" }) }))), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ variant: "outlined", size: "small", onClick: handleSave, loading: !editable, className: classes.buttonSave }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.commentObject.replyComment.save", defaultMessage: "ui.commentObject.replyComment.save" }) }))] }))] })))] })) })));
|
|
132
138
|
}
|
|
133
139
|
exports.default = CommentObjectReply;
|
|
@@ -9,12 +9,15 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
|
9
9
|
const Editor_1 = tslib_1.__importDefault(require("../../../Editor"));
|
|
10
10
|
const react_intl_1 = require("react-intl");
|
|
11
11
|
const constants_1 = require("../../constants");
|
|
12
|
+
const Media_1 = require("../../../../shared/Media");
|
|
13
|
+
const UrlTextField_1 = tslib_1.__importDefault(require("../../../../shared/Media/Link/UrlTextField"));
|
|
12
14
|
const classes = {
|
|
13
15
|
root: `${constants_1.PREFIX}-content-lesson-root`,
|
|
14
16
|
generalError: `${constants_1.PREFIX}-general-error`,
|
|
15
17
|
title: `${constants_1.PREFIX}-content-lesson-title`,
|
|
16
18
|
medias: `${constants_1.PREFIX}-content-lesson-medias`,
|
|
17
|
-
editor: `${constants_1.PREFIX}-content-lesson-editor
|
|
19
|
+
editor: `${constants_1.PREFIX}-content-lesson-editor`,
|
|
20
|
+
link: `${constants_1.PREFIX}-content-lesson-link`
|
|
18
21
|
};
|
|
19
22
|
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
20
23
|
name: constants_1.PREFIX,
|
|
@@ -24,13 +27,41 @@ exports.default = (props) => {
|
|
|
24
27
|
// PROPS
|
|
25
28
|
const { className = null, value, error = {}, disabled = false, onChange, onMediaChange, EditorProps = {} } = props;
|
|
26
29
|
const { error: generalError = null } = Object.assign({}, error);
|
|
30
|
+
const mediaObjectTypes = [Media_1.File, Media_1.Link];
|
|
31
|
+
const [medias, setMedias] = (0, react_1.useState)((value === null || value === void 0 ? void 0 : value.medias) || []);
|
|
32
|
+
const [openLink, setOpenLink] = (0, react_1.useState)();
|
|
33
|
+
const linkInputRef = (0, react_1.useRef)(null);
|
|
27
34
|
// HANDLERS
|
|
28
35
|
const handleChangeHtml = (0, react_1.useCallback)((html) => {
|
|
29
36
|
onChange(html);
|
|
30
37
|
}, [value]);
|
|
31
|
-
const
|
|
32
|
-
|
|
38
|
+
const handleChangeMedias = (0, react_1.useCallback)((value) => {
|
|
39
|
+
setMedias([...value]);
|
|
40
|
+
onMediaChange([...value]);
|
|
33
41
|
}, []);
|
|
42
|
+
const handleChangeMedia = (value) => {
|
|
43
|
+
setMedias((prev) => [...prev, value]);
|
|
44
|
+
onMediaChange([...medias, value]);
|
|
45
|
+
};
|
|
46
|
+
const handleLinkAdd = (0, react_1.useCallback)((media) => {
|
|
47
|
+
setMedias([...medias, media]);
|
|
48
|
+
setOpenLink(false);
|
|
49
|
+
}, [medias]);
|
|
50
|
+
(0, react_1.useEffect)(() => {
|
|
51
|
+
if (openLink && linkInputRef.current) {
|
|
52
|
+
linkInputRef.current.scrollIntoView({ behavior: 'smooth' });
|
|
53
|
+
}
|
|
54
|
+
}, [openLink]);
|
|
34
55
|
// RENDER
|
|
35
|
-
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [generalError && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.generalError }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.composer.error.${generalError}`, defaultMessage: `ui.composer.error.${generalError}` }) }))), (0, jsx_runtime_1.jsx)(Editor_1.default, Object.assign({}, EditorProps, { editable: !disabled, className: classes.editor, onChange: handleChangeHtml, onMediaChange: handleChangeMedia, defaultValue: value.html
|
|
56
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [generalError && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.generalError }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.composer.error.${generalError}`, defaultMessage: `ui.composer.error.${generalError}` }) }))), (0, jsx_runtime_1.jsx)(Editor_1.default, Object.assign({}, EditorProps, { editable: !disabled, className: classes.editor, onChange: handleChangeHtml, onMediaChange: handleChangeMedia, defaultValue: value.html, ToolBarProps: {
|
|
57
|
+
customLink: (0, jsx_runtime_1.jsx)(Media_1.Link.triggerButton, { color: "default", onClick: () => setOpenLink(true) }, Media_1.Link.name),
|
|
58
|
+
uploadImage: false,
|
|
59
|
+
uploadFile: true
|
|
60
|
+
} })), openLink && ((0, jsx_runtime_1.jsx)(UrlTextField_1.default, { inputRef: linkInputRef, className: classes.link, id: "page", name: "page", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.media.link.add.label", defaultMessage: "ui.composer.media.link.add.label" }), fullWidth: true, variant: "outlined", placeholder: "https://", onSuccess: handleLinkAdd, InputProps: {
|
|
61
|
+
endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: () => setOpenLink(false) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) })) })))
|
|
62
|
+
} })), medias && medias.length > 0 && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.medias }, { children: mediaObjectTypes.map((mediaObjectType) => {
|
|
63
|
+
if (mediaObjectType.previewComponent) {
|
|
64
|
+
return (0, jsx_runtime_1.jsx)(mediaObjectType.previewComponent, { value: medias, onChange: handleChangeMedias }, mediaObjectType.name);
|
|
65
|
+
}
|
|
66
|
+
}) })))] })));
|
|
36
67
|
};
|
|
@@ -96,11 +96,11 @@ function Comments(props) {
|
|
|
96
96
|
map.set(name, [...map.get(name), comment]);
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
|
-
return Array.from(map.entries()).map(([name, comments]) => ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.outerWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: name })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.innerWrapper }, { children: [comments.map((comment) => ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { src: comment.created_by.avatar, alt: comment.created_by.username, className: classes.avatar }), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userInfo }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: comment.created_by.username })), (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.circle }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(comment.created_at).toLocaleDateString() }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography,
|
|
99
|
+
return Array.from(map.entries()).map(([name, comments]) => ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.outerWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: name })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.innerWrapper }, { children: [comments.map((comment) => ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { src: comment.created_by.avatar, alt: comment.created_by.username, className: classes.avatar }), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.userInfo }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: comment.created_by.username })), (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.circle }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(comment.created_at).toLocaleDateString() }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body1", component: "div", dangerouslySetInnerHTML: { __html: comment.html } })] })] }), comment.id))), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, course), size: "small", variant: "outlined", color: "inherit", className: classes.button }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.teacher.tab.comments.lessons.btn.label", defaultMessage: "ui.course.dashboard.teacher.tab.comments.lessons.btn.label" }) })) }))] }))] }), name)));
|
|
100
100
|
}, [state.results]);
|
|
101
101
|
if (!state.initialized) {
|
|
102
102
|
return (0, jsx_runtime_1.jsx)(CommentsSkeleton, {});
|
|
103
103
|
}
|
|
104
|
-
return ((0, jsx_runtime_1.
|
|
104
|
+
return ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.container }, { children: state.count > 0 ? ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.teacher.tab.comments.number", defaultMessage: "ui.course.dashboard.teacher.tab.comments.number", values: { commentsNumber: state.count } }) })), renderComments, isLoadingComments && (0, jsx_runtime_1.jsx)(CommentSkeleton, { id: 1 }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: isLoadingComments, disabled: !state.next, onClick: handleNext }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.teacher.tab.comments.btn.label", defaultMessage: "ui.course.dashboard.teacher.tab.comments.btn.label" }) })) }))] })) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.teacher.tab.comments.empty", defaultMessage: "ui.course.dashboard.teacher.tab.comments.empty" }) }))) })));
|
|
105
105
|
}
|
|
106
106
|
exports.default = (0, react_1.memo)(Comments);
|
|
@@ -138,7 +138,7 @@ function CourseParticipantsButton(inProps) {
|
|
|
138
138
|
/**
|
|
139
139
|
* Rendering
|
|
140
140
|
*/
|
|
141
|
-
if (!participantsAvailable
|
|
141
|
+
if (!participantsAvailable) {
|
|
142
142
|
return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
|
|
143
143
|
}
|
|
144
144
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), onClick: handleToggleDialogOpen, disabled: loading || !scCourse || enrolled.length === 0,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { MediaPluginProps } from './plugins';
|
|
3
|
+
import { ToolbarPluginProps } from './plugins/ToolbarPlugin';
|
|
2
4
|
import { SCMediaType } from '@selfcommunity/types';
|
|
3
5
|
export declare type EditorRef = {
|
|
4
6
|
focus: () => void;
|
|
@@ -48,7 +50,17 @@ export interface EditorProps {
|
|
|
48
50
|
* Handler for change media in the editor
|
|
49
51
|
* @default null
|
|
50
52
|
* */
|
|
51
|
-
onMediaChange?: (
|
|
53
|
+
onMediaChange?: (media: SCMediaType) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Props to spread to ToolBar.
|
|
56
|
+
* @default {}
|
|
57
|
+
*/
|
|
58
|
+
ToolBarProps?: ToolbarPluginProps;
|
|
59
|
+
/**
|
|
60
|
+
* Props to spread to MediaPlugin.
|
|
61
|
+
* @default {}
|
|
62
|
+
*/
|
|
63
|
+
MediaPluginProps?: MediaPluginProps;
|
|
52
64
|
/**
|
|
53
65
|
* Handler for blur event of the editor
|
|
54
66
|
* @default null
|
|
@@ -70,8 +70,7 @@ const editorTheme = {
|
|
|
70
70
|
superscript: `${constants_1.PREFIX}-textSuperscript`,
|
|
71
71
|
underline: `${constants_1.PREFIX}-textUnderline`,
|
|
72
72
|
underlineStrikethrough: `${constants_1.PREFIX}-textUnderlineStrikethrough`
|
|
73
|
-
}
|
|
74
|
-
document: `${constants_1.PREFIX}-document`
|
|
73
|
+
}
|
|
75
74
|
};
|
|
76
75
|
/**
|
|
77
76
|
* > API documentation for the Community-JS Editor component. Learn about the available props and the CSS API.
|
|
@@ -108,7 +107,7 @@ const Editor = (inProps, ref) => {
|
|
|
108
107
|
props: inProps,
|
|
109
108
|
name: constants_1.PREFIX
|
|
110
109
|
});
|
|
111
|
-
const { id = 'editor', className = null, defaultValue = '', toolbar = false, uploadImage = false, uploadFile = false, editable = true, onChange = null, onMediaChange = null, onFocus = null, onBlur = null, action = null, placeholder = (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.placeholder", defaultMessage: "ui.editor.placeholder" }) } = props;
|
|
110
|
+
const { id = 'editor', className = null, defaultValue = '', toolbar = false, uploadImage = false, uploadFile = false, editable = true, onChange = null, onMediaChange = null, onFocus = null, onBlur = null, action = null, ToolBarProps = {}, MediaPluginProps = {}, placeholder = (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.placeholder", defaultMessage: "ui.editor.placeholder" }) } = props;
|
|
112
111
|
const apiRef = (0, react_1.useRef)();
|
|
113
112
|
// STATE
|
|
114
113
|
const [focused, setFocused] = (0, react_1.useState)(false);
|
|
@@ -149,6 +148,6 @@ const Editor = (inProps, ref) => {
|
|
|
149
148
|
nodes: [...nodes_1.default],
|
|
150
149
|
theme: editorTheme
|
|
151
150
|
}), [editable]);
|
|
152
|
-
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, { [classes.toolbar]: toolbar, [classes.focused]: focused }) }, { children: (0, jsx_runtime_1.jsxs)(LexicalComposer_1.LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [toolbar ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ToolbarPlugin_1.default, { uploadImage: uploadImage, uploadFile: uploadFile, MediaPluginProps: { onMediaAdd: handleMediaChange } }), (0, jsx_runtime_1.jsx)(LexicalListPlugin_1.ListPlugin, {}), (0, jsx_runtime_1.jsx)(LexicalHorizontalRulePlugin_1.HorizontalRulePlugin, {})] })) : ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actions, direction: "row" }, { children: [uploadImage && (0, jsx_runtime_1.jsx)(plugins_1.ImagePlugin, {}), uploadFile && (0, jsx_runtime_1.jsx)(plugins_1.MediaPlugin, {
|
|
151
|
+
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, { [classes.toolbar]: toolbar, [classes.focused]: focused }) }, { children: (0, jsx_runtime_1.jsxs)(LexicalComposer_1.LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [toolbar ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ToolbarPlugin_1.default, Object.assign({ uploadImage: uploadImage, uploadFile: uploadFile, MediaPluginProps: { onMediaAdd: handleMediaChange } }, ToolBarProps)), (0, jsx_runtime_1.jsx)(LexicalListPlugin_1.ListPlugin, {}), (0, jsx_runtime_1.jsx)(LexicalHorizontalRulePlugin_1.HorizontalRulePlugin, {})] })) : ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actions, direction: "row" }, { children: [uploadImage && (0, jsx_runtime_1.jsx)(plugins_1.ImagePlugin, {}), uploadFile && (0, jsx_runtime_1.jsx)(plugins_1.MediaPlugin, Object.assign({}, MediaPluginProps)), (0, jsx_runtime_1.jsx)(plugins_1.EmojiPlugin, {}), action && action] }))), (0, jsx_runtime_1.jsx)(LexicalRichTextPlugin_1.RichTextPlugin, { contentEditable: (0, jsx_runtime_1.jsx)(LexicalContentEditable_1.ContentEditable, { className: classes.content }), placeholder: (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.placeholder, onClick: handleFocus }, { children: placeholder })), ErrorBoundary: LexicalErrorBoundary_1.default }), (0, jsx_runtime_1.jsx)(plugins_1.DefaultHtmlValuePlugin, { defaultValue: defaultValue }), (0, jsx_runtime_1.jsx)(LexicalHistoryPlugin_1.HistoryPlugin, {}), (0, jsx_runtime_1.jsx)(plugins_1.OnChangePlugin, { onChange: handleChange }), (0, jsx_runtime_1.jsx)(OnBlurPlugin_1.default, { onBlur: handleHasBlur }), (0, jsx_runtime_1.jsx)(OnFocusPlugin_1.default, { onFocus: handleHasFocus }), (0, jsx_runtime_1.jsx)(plugins_1.AutoLinkPlugin, {}), (0, jsx_runtime_1.jsx)(plugins_1.MentionsPlugin, {}), (0, jsx_runtime_1.jsx)(LexicalLinkPlugin_1.LinkPlugin, {}), (0, jsx_runtime_1.jsx)(FloatingLinkPlugin_1.default, {}), (0, jsx_runtime_1.jsx)(ApiPlugin_1.default, { ref: apiRef })] })) })));
|
|
153
152
|
};
|
|
154
153
|
exports.default = (0, react_1.forwardRef)(Editor);
|
|
@@ -5,6 +5,5 @@ import { ImageNode } from './ImageNode';
|
|
|
5
5
|
import { MentionNode } from './MentionNode';
|
|
6
6
|
import { TextNode } from 'lexical';
|
|
7
7
|
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
8
|
-
|
|
9
|
-
declare const nodes: (typeof ImageNode | typeof TextNode | typeof MentionNode | typeof DocNode | typeof HorizontalRuleNode | typeof HeadingNode | typeof ListNode | typeof ListItemNode | typeof QuoteNode | typeof LinkNode)[];
|
|
8
|
+
declare const nodes: (typeof ImageNode | typeof TextNode | typeof MentionNode | typeof HorizontalRuleNode | typeof HeadingNode | typeof ListNode | typeof ListItemNode | typeof QuoteNode | typeof LinkNode)[];
|
|
10
9
|
export default nodes;
|
|
@@ -7,7 +7,6 @@ const ImageNode_1 = require("./ImageNode");
|
|
|
7
7
|
const MentionNode_1 = require("./MentionNode");
|
|
8
8
|
const lexical_1 = require("lexical");
|
|
9
9
|
const LexicalHorizontalRuleNode_1 = require("@lexical/react/LexicalHorizontalRuleNode");
|
|
10
|
-
const DocNode_1 = require("./DocNode");
|
|
11
10
|
const nodes = [
|
|
12
11
|
LexicalHorizontalRuleNode_1.HorizontalRuleNode,
|
|
13
12
|
rich_text_1.HeadingNode,
|
|
@@ -19,7 +18,6 @@ const nodes = [
|
|
|
19
18
|
link_1.AutoLinkNode,
|
|
20
19
|
link_1.LinkNode,
|
|
21
20
|
ImageNode_1.ImageNode,
|
|
22
|
-
MentionNode_1.MentionNode
|
|
23
|
-
DocNode_1.DocNode
|
|
21
|
+
MentionNode_1.MentionNode
|
|
24
22
|
];
|
|
25
23
|
exports.default = nodes;
|
|
@@ -8,6 +8,7 @@ export interface InsertDocPayload {
|
|
|
8
8
|
export declare const INSERT_DOC_COMMAND: LexicalCommand<InsertDocPayload>;
|
|
9
9
|
export interface MediaPluginProps {
|
|
10
10
|
className?: string;
|
|
11
|
-
onMediaAdd?: (
|
|
11
|
+
onMediaAdd?: (media: SCMediaType) => void | null;
|
|
12
|
+
isUploading?: (boolean: any) => void;
|
|
12
13
|
}
|
|
13
14
|
export default function MediaPlugin(props: MediaPluginProps): JSX.Element;
|
|
@@ -17,7 +17,6 @@ const upload_button_1 = require("@rpldy/upload-button");
|
|
|
17
17
|
const notistack_1 = require("notistack");
|
|
18
18
|
const ImageNode_1 = require("../nodes/ImageNode");
|
|
19
19
|
const constants_1 = require("../constants");
|
|
20
|
-
const DocNode_1 = require("../nodes/DocNode");
|
|
21
20
|
const ImagePlugin_1 = require("./ImagePlugin");
|
|
22
21
|
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
23
22
|
exports.INSERT_DOC_COMMAND = (0, lexical_1.createCommand)();
|
|
@@ -34,11 +33,10 @@ const Root = (0, styles_1.styled)(material_1.Box, {
|
|
|
34
33
|
})(() => ({}));
|
|
35
34
|
function MediaPlugin(props) {
|
|
36
35
|
var _a;
|
|
37
|
-
const { className = '', onMediaAdd = null } = props;
|
|
36
|
+
const { className = '', onMediaAdd = null, isUploading } = props;
|
|
38
37
|
// STATE
|
|
39
38
|
const [uploading, setUploading] = (0, react_1.useState)({});
|
|
40
39
|
const [mediaType, setMediaType] = (0, react_1.useState)('');
|
|
41
|
-
const [uploadedMedia, setUploadedMedia] = (0, react_1.useState)([]);
|
|
42
40
|
const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
|
|
43
41
|
// CONTEXT
|
|
44
42
|
const scContext = (0, react_core_1.useSCContext)();
|
|
@@ -64,27 +62,6 @@ function MediaPlugin(props) {
|
|
|
64
62
|
return true;
|
|
65
63
|
}, lexical_1.COMMAND_PRIORITY_EDITOR);
|
|
66
64
|
}, [editor]);
|
|
67
|
-
(0, react_1.useEffect)(() => {
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
69
|
-
// @ts-ignore
|
|
70
|
-
if (!editor.hasNodes([DocNode_1.DocNode])) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
editor.registerCommand(exports.INSERT_DOC_COMMAND, (payload) => {
|
|
74
|
-
const docNode = (0, DocNode_1.$createDocNode)({
|
|
75
|
-
src: payload.src,
|
|
76
|
-
name: payload.name,
|
|
77
|
-
type: payload.type
|
|
78
|
-
});
|
|
79
|
-
(0, utils_1.$insertNodeToNearestRoot)(docNode);
|
|
80
|
-
return true;
|
|
81
|
-
}, lexical_1.COMMAND_PRIORITY_EDITOR);
|
|
82
|
-
}, [editor]);
|
|
83
|
-
(0, react_1.useEffect)(() => {
|
|
84
|
-
if (uploadedMedia.length > 0) {
|
|
85
|
-
onMediaAdd && onMediaAdd(uploadedMedia);
|
|
86
|
-
}
|
|
87
|
-
}, [uploadedMedia, onMediaAdd]);
|
|
88
65
|
// HANDLERS
|
|
89
66
|
const handleFileUploadFilter = (file) => {
|
|
90
67
|
if (file.type.startsWith('image/')) {
|
|
@@ -114,11 +91,12 @@ function MediaPlugin(props) {
|
|
|
114
91
|
};
|
|
115
92
|
editor.focus();
|
|
116
93
|
editor.dispatchCommand(exports.INSERT_DOC_COMMAND, data);
|
|
117
|
-
|
|
94
|
+
onMediaAdd && onMediaAdd(media);
|
|
118
95
|
}
|
|
119
96
|
};
|
|
120
97
|
const handleUploadProgress = (chunks) => {
|
|
121
98
|
setUploading(Object.assign({}, chunks));
|
|
99
|
+
isUploading && isUploading(Object.keys(chunks).length !== 0);
|
|
122
100
|
};
|
|
123
101
|
const handleUploadError = (chunk, error) => {
|
|
124
102
|
enqueueSnackbar(error, {
|
|
@@ -128,14 +106,14 @@ function MediaPlugin(props) {
|
|
|
128
106
|
};
|
|
129
107
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
130
108
|
// @ts-ignore
|
|
131
|
-
if (!scUserContext.user || !editor.hasNodes([ImageNode_1.ImageNode
|
|
109
|
+
if (!scUserContext.user || !editor.hasNodes([ImageNode_1.ImageNode])) {
|
|
132
110
|
return null;
|
|
133
111
|
}
|
|
134
112
|
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: (0, jsx_runtime_1.jsxs)(chunked_uploady_1.default, Object.assign({ destination: {
|
|
135
113
|
url: `${scContext.settings.portal}${api_services_1.Endpoints.ComposerChunkUploadMedia.url()}`,
|
|
136
114
|
headers: ((_a = scContext.settings.session) === null || _a === void 0 ? void 0 : _a.authToken) ? { Authorization: `Bearer ${scContext.settings.session.authToken.accessToken}` } : {},
|
|
137
115
|
method: api_services_1.Endpoints.ComposerChunkUploadMedia.method
|
|
138
|
-
}, chunkSize: 204800, accept: "image/*,application/*", fileFilter: handleFileUploadFilter }, { children: [(0, jsx_runtime_1.jsx)(MediaChunkUploader_1.default, { type: mediaType, onSuccess: handleUploadSuccess, onProgress: handleUploadProgress, onError: handleUploadError }), (0, jsx_runtime_1.jsx)(UploadButton, { className: className, extraProps: {
|
|
116
|
+
}, chunkSize: 204800, accept: "image/*,application/*", fileFilter: handleFileUploadFilter, multiple: true }, { children: [(0, jsx_runtime_1.jsx)(MediaChunkUploader_1.default, { type: mediaType, onSuccess: handleUploadSuccess, onProgress: handleUploadProgress, onError: handleUploadError }), (0, jsx_runtime_1.jsx)(UploadButton, { className: className, extraProps: {
|
|
139
117
|
disabled: Object.keys(uploading).length !== 0,
|
|
140
118
|
progress: Object.keys(uploading).length !== 0 ? Object.values(uploading)[0].completed : null
|
|
141
119
|
} })] })) })));
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
import * as React from 'react';
|
|
8
9
|
import { MediaPluginProps } from './MediaPlugin';
|
|
9
10
|
export interface ToolbarPluginProps {
|
|
10
11
|
uploadImage: boolean;
|
|
11
12
|
uploadFile?: boolean;
|
|
12
13
|
MediaPluginProps?: MediaPluginProps;
|
|
14
|
+
customLink?: React.ReactNode;
|
|
13
15
|
}
|
|
14
16
|
export default function ToolbarPlugin(inProps: ToolbarPluginProps): JSX.Element;
|
|
@@ -129,7 +129,7 @@ function ToolbarPlugin(inProps) {
|
|
|
129
129
|
props: inProps,
|
|
130
130
|
name: constants_1.PREFIX
|
|
131
131
|
});
|
|
132
|
-
const { uploadImage = false, uploadFile = false, MediaPluginProps = {} } = props;
|
|
132
|
+
const { uploadImage = false, uploadFile = false, MediaPluginProps = {}, customLink = null } = props;
|
|
133
133
|
// STATE
|
|
134
134
|
const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
|
|
135
135
|
const [activeEditor, setActiveEditor] = (0, react_1.useState)(editor);
|
|
@@ -272,6 +272,6 @@ function ToolbarPlugin(inProps) {
|
|
|
272
272
|
activeEditor.dispatchCommand(lexical_1.FORMAT_TEXT_COMMAND, format);
|
|
273
273
|
} }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.editor.toolbarPlugin.${format}`, defaultMessage: `ui.editor.toolbarPlugin.${format}` }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: `format_${format}` }) })) }), format))) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: !isEditable, onClick: clearFormatting }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.toolbarPlugin.clear", defaultMessage: "ui.editor.toolbarPlugin.clear" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "format_clear" }) })) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: !isEditable, onClick: () => {
|
|
274
274
|
activeEditor.dispatchCommand(LexicalHorizontalRuleNode_1.INSERT_HORIZONTAL_RULE_COMMAND, undefined);
|
|
275
|
-
} }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.toolbarPlugin.horizontalRule", defaultMessage: "ui.editor.toolbarPlugin.horizontalRule" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "format_horizontal_rule" }) })) })), uploadImage && (0, jsx_runtime_1.jsx)(ImagePlugin_1.default, {}), uploadFile && (0, jsx_runtime_1.jsx)(MediaPlugin_1.default, Object.assign({}, MediaPluginProps)), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: !isEditable, onClick: insertLink }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.toolbarPlugin.link", defaultMessage: "ui.editor.toolbarPlugin.link" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "format_link" }) })) })), (0, jsx_runtime_1.jsx)(EmojiPlugin_1.default, {})] })));
|
|
275
|
+
} }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.toolbarPlugin.horizontalRule", defaultMessage: "ui.editor.toolbarPlugin.horizontalRule" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "format_horizontal_rule" }) })) })), uploadImage && (0, jsx_runtime_1.jsx)(ImagePlugin_1.default, {}), uploadFile && (0, jsx_runtime_1.jsx)(MediaPlugin_1.default, Object.assign({}, MediaPluginProps)), customLink !== null && customLink !== void 0 ? customLink : ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: !isEditable, onClick: insertLink }, { children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editor.toolbarPlugin.link", defaultMessage: "ui.editor.toolbarPlugin.link" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "format_link" }) })) }))), (0, jsx_runtime_1.jsx)(EmojiPlugin_1.default, {})] })));
|
|
276
276
|
}
|
|
277
277
|
exports.default = ToolbarPlugin;
|
|
@@ -85,6 +85,7 @@ export interface LessonCommentObjectProps {
|
|
|
85
85
|
|author|.SCCommentObject-author|Styles applied to the author section.|
|
|
86
86
|
|content|.SCCommentObject-content|Styles applied to content section.|
|
|
87
87
|
|textContent|.SCCommentObject-text-content|Styles applied to text content section.|
|
|
88
|
+
|mediaContent|.SCCommentObject-media-content|Styles applied to media content section.|
|
|
88
89
|
|commentActionsMenu|.SCCommentObject-comment-actions-menu|Styles applied to comment action menu element.|
|
|
89
90
|
|
|
90
91
|
|
|
@@ -24,6 +24,7 @@ const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../shared/User
|
|
|
24
24
|
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
|
|
25
25
|
const constants_1 = require("./constants");
|
|
26
26
|
const LessonCommentActionsMenu_1 = tslib_1.__importDefault(require("../../shared/LessonCommentActionsMenu"));
|
|
27
|
+
const LessonFilePreview_1 = tslib_1.__importDefault(require("../../shared/LessonFilePreview"));
|
|
27
28
|
const classes = {
|
|
28
29
|
root: `${constants_1.PREFIX}-root`,
|
|
29
30
|
comment: `${constants_1.PREFIX}-comment`,
|
|
@@ -31,6 +32,7 @@ const classes = {
|
|
|
31
32
|
content: `${constants_1.PREFIX}-content`,
|
|
32
33
|
author: `${constants_1.PREFIX}-author`,
|
|
33
34
|
textContent: `${constants_1.PREFIX}-text-content`,
|
|
35
|
+
mediaContent: `${constants_1.PREFIX}-media-content`,
|
|
34
36
|
commentActionsMenu: `${constants_1.PREFIX}-comment-actions-menu`
|
|
35
37
|
};
|
|
36
38
|
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
@@ -65,6 +67,7 @@ const Root = (0, styles_1.styled)(material_1.Box, {
|
|
|
65
67
|
|author|.SCCommentObject-author|Styles applied to the author section.|
|
|
66
68
|
|content|.SCCommentObject-content|Styles applied to content section.|
|
|
67
69
|
|textContent|.SCCommentObject-text-content|Styles applied to text content section.|
|
|
70
|
+
|mediaContent|.SCCommentObject-media-content|Styles applied to media content section.|
|
|
68
71
|
|commentActionsMenu|.SCCommentObject-comment-actions-menu|Styles applied to comment action menu element.|
|
|
69
72
|
|
|
70
73
|
|
|
@@ -154,7 +157,8 @@ function LessonCommentObject(inProps) {
|
|
|
154
157
|
const newObj = Object.assign({}, obj, {
|
|
155
158
|
text: data.text,
|
|
156
159
|
html: data.html,
|
|
157
|
-
created_at: data.created_at
|
|
160
|
+
created_at: data.created_at,
|
|
161
|
+
medias: medias
|
|
158
162
|
});
|
|
159
163
|
updateObject(newObj);
|
|
160
164
|
setEditComment(null);
|
|
@@ -181,7 +185,9 @@ function LessonCommentObject(inProps) {
|
|
|
181
185
|
return null;
|
|
182
186
|
}
|
|
183
187
|
const summaryHtml = (0, contribution_1.getCommentContributionHtml)(comment.html, scRoutingContext.url);
|
|
184
|
-
return ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: editComment && editComment.id === comment.id ? ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.comment }, { children: (0, jsx_runtime_1.jsx)(CommentObjectReply_1.default, Object.assign({ text: comment.html, medias: comment.medias, autoFocus: true, id: `edit-${comment.id}`, onSave: handleUpdate, onCancel: handleCancel, editable: !isSavingComment, EditorProps: { uploadFile: true, uploadImage: false } }, CommentObjectReplyProps)) }))) : ((0, jsx_runtime_1.jsx)(BaseItem_1.default, { elevation: 0, className: classes.comment, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!comment.created_by.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !obj.created_by.community_badge }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: obj.created_by.username, variant: "circular", src: comment.created_by.avatar, className: classes.avatar }) })) })), disableTypography: true, primary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(Widget_1.default, Object.assign({ className: classes.content, elevation: elevation }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ className: classes.author }, (!comment.created_by.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span" }, { children: comment.created_by.username })) })), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Bullet_1.default, {}), (0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: comment.created_at, showStartIcon: false })] }), (0, jsx_runtime_1.jsx)(material_1.Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: summaryHtml } })
|
|
188
|
+
return ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: editComment && editComment.id === comment.id ? ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.comment }, { children: (0, jsx_runtime_1.jsx)(CommentObjectReply_1.default, Object.assign({ text: comment.html, medias: comment.medias, autoFocus: true, id: `edit-${comment.id}`, onSave: handleUpdate, onCancel: handleCancel, editable: !isSavingComment, EditorProps: { uploadFile: true, uploadImage: false } }, CommentObjectReplyProps)) }))) : ((0, jsx_runtime_1.jsx)(BaseItem_1.default, { elevation: 0, className: classes.comment, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!comment.created_by.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !obj.created_by.community_badge }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: obj.created_by.username, variant: "circular", src: comment.created_by.avatar, className: classes.avatar }) })) })), disableTypography: true, primary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(Widget_1.default, Object.assign({ className: classes.content, elevation: elevation }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ className: classes.author }, (!comment.created_by.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span" }, { children: comment.created_by.username })) })), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Bullet_1.default, {}), (0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: comment.created_at, showStartIcon: false })] }), (0, jsx_runtime_1.jsx)(material_1.Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: summaryHtml } }), obj.medias && obj.medias.length > 0 && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: obj.medias.map((media) => {
|
|
189
|
+
return (0, jsx_runtime_1.jsx)(LessonFilePreview_1.default, { className: classes.mediaContent, media: media }, media.id);
|
|
190
|
+
}) }))] }), scUserContext.user && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.commentActionsMenu }, { children: (0, jsx_runtime_1.jsx)(LessonCommentActionsMenu_1.default, { lesson: lessonObject, commentObject: comment, onDelete: handleDelete, onEdit: handleEdit }) })))] })) }) })) }, comment.id));
|
|
185
191
|
}
|
|
186
192
|
/**
|
|
187
193
|
* Render comments
|
|
@@ -105,6 +105,11 @@ function LessonCommentObjects(inProps) {
|
|
|
105
105
|
var _a;
|
|
106
106
|
(_a = commentsEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'end', behavior: 'instant' });
|
|
107
107
|
};
|
|
108
|
+
(0, react_1.useEffect)(() => {
|
|
109
|
+
if (commentsObject.comments.length > 0) {
|
|
110
|
+
scrollToBottom();
|
|
111
|
+
}
|
|
112
|
+
}, [commentsObject.comments]);
|
|
108
113
|
/**
|
|
109
114
|
* Perform save/update comment
|
|
110
115
|
*/
|
|
@@ -140,7 +145,6 @@ function LessonCommentObjects(inProps) {
|
|
|
140
145
|
handleCommentsUpdate(data);
|
|
141
146
|
setReplyKey(comment.id);
|
|
142
147
|
setIsCommenting(false);
|
|
143
|
-
scrollToBottom();
|
|
144
148
|
})
|
|
145
149
|
.catch((error) => {
|
|
146
150
|
utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
|
|
@@ -14,12 +14,16 @@ const contribution_1 = require("../../utils/contribution");
|
|
|
14
14
|
const Widget_1 = tslib_1.__importDefault(require("../Widget"));
|
|
15
15
|
const ContentLesson_1 = tslib_1.__importDefault(require("../Composer/Content/ContentLesson"));
|
|
16
16
|
const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder"));
|
|
17
|
+
const DisplayComponent_1 = tslib_1.__importDefault(require("../../shared/Media/Link/DisplayComponent"));
|
|
18
|
+
const LessonFilePreview_1 = tslib_1.__importDefault(require("../../shared/LessonFilePreview"));
|
|
19
|
+
const api_services_1 = require("@selfcommunity/api-services");
|
|
17
20
|
const classes = {
|
|
18
21
|
root: `${constants_1.PREFIX}-root`,
|
|
19
22
|
content: `${constants_1.PREFIX}-content`,
|
|
20
23
|
contentEdit: `${constants_1.PREFIX}-content-edit`,
|
|
21
24
|
title: `${constants_1.PREFIX}-title`,
|
|
22
25
|
text: `${constants_1.PREFIX}-text`,
|
|
26
|
+
mediasSection: `${constants_1.PREFIX}-medias-section`,
|
|
23
27
|
navigation: `${constants_1.PREFIX}-navigation`,
|
|
24
28
|
editor: `${constants_1.PREFIX}-editor`
|
|
25
29
|
};
|
|
@@ -54,8 +58,8 @@ function LessonObject(inProps) {
|
|
|
54
58
|
}
|
|
55
59
|
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(className, classes.root) }, rest, { children: (0, jsx_runtime_1.jsx)(Widget_1.default, { children: (0, jsx_runtime_1.jsx)(CardContent_1.default, Object.assign({ classes: { root: editMode ? classes.contentEdit : classes.content } }, { children: editMode ? ((0, jsx_runtime_1.jsx)(ContentLesson_1.default, { value: lesson,
|
|
56
60
|
//error={{error}}
|
|
57
|
-
onChange: handleChangeLesson, onMediaChange: handleChangeMedia, disabled: isSubmitting, EditorProps: Object.assign({ toolbar: true
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
onChange: handleChangeLesson, onMediaChange: handleChangeMedia, disabled: isSubmitting, EditorProps: Object.assign({ toolbar: true }, EditorProps) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { component: "div", gutterBottom: true, className: classes.text, dangerouslySetInnerHTML: {
|
|
62
|
+
__html: (0, contribution_1.getContributionHtml)(lesson.html, scRoutingContext.url)
|
|
63
|
+
} }), lesson.medias && lesson.medias.length > 0 && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.mediasSection }, { children: lesson.medias.map((media) => media.type === api_services_1.MediaTypes.URL ? ((0, jsx_runtime_1.jsx)(DisplayComponent_1.default, { medias: [media] }, media.id)) : ((0, jsx_runtime_1.jsx)(LessonFilePreview_1.default, { media: media }, media.id))) })))] })) })) }) })));
|
|
60
64
|
}
|
|
61
65
|
exports.default = LessonObject;
|
|
@@ -10,7 +10,8 @@ const types_1 = require("@selfcommunity/types");
|
|
|
10
10
|
const constants_1 = require("./constants");
|
|
11
11
|
const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
|
|
12
12
|
const classes = {
|
|
13
|
-
root: `${constants_1.PREFIX}-
|
|
13
|
+
root: `${constants_1.PREFIX}-root`,
|
|
14
|
+
empty: `${constants_1.PREFIX}-empty`,
|
|
14
15
|
accordion: `${constants_1.PREFIX}-accordion`,
|
|
15
16
|
summary: `${constants_1.PREFIX}-summary`,
|
|
16
17
|
details: `${constants_1.PREFIX}-details`,
|
|
@@ -41,8 +42,8 @@ function AccordionLessons(inProps) {
|
|
|
41
42
|
if (!course) {
|
|
42
43
|
return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
|
|
43
44
|
}
|
|
44
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: ((_a = course.sections) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (course.sections.map((section) => ((0, jsx_runtime_1.jsxs)(material_1.Accordion, Object.assign({ className: classes.accordion, expanded: expanded === section.id, onChange: handleChange(section.id), disableGutters: true, elevation: 0, square: true }, { children: [(0, jsx_runtime_1.jsxs)(material_1.AccordionSummary, Object.assign({ className: classes.summary, expandIcon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "expand_less" }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span", variant: "body1" }, { children: section.name })), !isMobile && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span", variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.table.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: {
|
|
46
|
+
lessonsNumber: section.lessons.length
|
|
47
|
+
} }) })))] })), section.lessons.map((lesson) => ((0, jsx_runtime_1.jsxs)(material_1.AccordionDetails, Object.assign({ className: classes.details }, { children: [lesson.completion_status === types_1.SCCourseLessonCompletionStatusType.COMPLETED ? ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small", color: "primary" }, { children: "circle_checked" }))) : lesson.locked ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "private" })) : ((0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.circle })), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: lesson.name })] }), lesson.id)))] }), section.id)))) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.empty }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.accordionLessons.empty", defaultMessage: "ui.course.accordionLessons.empty" }) }))) })));
|
|
47
48
|
}
|
|
48
49
|
exports.default = AccordionLessons;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LessonFilePreviewProps {
|
|
2
|
+
/**
|
|
3
|
+
* Overrides or extends the styles applied to the component.
|
|
4
|
+
* @default null
|
|
5
|
+
*/
|
|
6
|
+
className?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The media object to show
|
|
9
|
+
*/
|
|
10
|
+
media: any;
|
|
11
|
+
}
|
|
12
|
+
export default function LessonFilePreview(props: LessonFilePreviewProps): JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const styles_1 = require("@mui/material/styles");
|
|
6
|
+
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
7
|
+
const material_1 = require("@mui/material");
|
|
8
|
+
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
9
|
+
const Media_1 = require("../../constants/Media");
|
|
10
|
+
const PREFIX = 'SCLessonFilePreview';
|
|
11
|
+
const classes = {
|
|
12
|
+
root: `${PREFIX}-root`,
|
|
13
|
+
item: `${PREFIX}-item`,
|
|
14
|
+
title: `${PREFIX}-title`
|
|
15
|
+
};
|
|
16
|
+
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
17
|
+
name: PREFIX,
|
|
18
|
+
slot: 'Root',
|
|
19
|
+
overridesResolver: (props, styles) => styles.root
|
|
20
|
+
})(() => ({}));
|
|
21
|
+
function LessonFilePreview(props) {
|
|
22
|
+
// PROPS
|
|
23
|
+
const { className, media } = props;
|
|
24
|
+
/**
|
|
25
|
+
* Renders component
|
|
26
|
+
*/
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), sx: { backgroundImage: `url(${(media === null || media === void 0 ? void 0 : media.image_thumbnail) ? media.image_thumbnail.url : media.image})` } }, { children: media.title && ((0, jsx_runtime_1.jsx)(material_1.Link, Object.assign({ href: media.url, target: "_blank", rel: "noopener noreferrer" }, { children: (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.title }, { children: [media.type === Media_1.MEDIA_TYPE_DOCUMENT && (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "picture_as_pdf" }), media.title] })) }))) }), media.id));
|
|
28
|
+
}
|
|
29
|
+
exports.default = LessonFilePreview;
|
|
@@ -16,6 +16,7 @@ const INITIAL_STATE = {
|
|
|
16
16
|
urlError: null
|
|
17
17
|
};
|
|
18
18
|
exports.default = (props) => {
|
|
19
|
+
var _a, _b;
|
|
19
20
|
// STATE
|
|
20
21
|
const [isCreating, setIsCreating] = (0, react_1.useState)(false);
|
|
21
22
|
const [state, setState] = (0, react_1.useState)(Object.assign({}, INITIAL_STATE));
|
|
@@ -75,7 +76,5 @@ exports.default = (props) => {
|
|
|
75
76
|
* Renders url text field
|
|
76
77
|
*/
|
|
77
78
|
return ((0, jsx_runtime_1.jsx)("form", Object.assign({ method: "post", onSubmit: handleSubmit }, { children: (0, jsx_runtime_1.jsx)(TextField_1.default, Object.assign({ value: url, type: "url", onChange: handleChange, onPaste: handlePaste, error: error || Boolean(urlError), helperText: helperText ||
|
|
78
|
-
(urlError && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.composer.media.link.add.error.${urlError}`, defaultMessage: `ui.composer.media.link.add.error.${urlError}` }))) || (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.media.link.add.help", defaultMessage: "ui.composer.media.link.add.help" }), disabled: isCreating }, rest, { InputProps: {
|
|
79
|
-
endAdornment: ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.Fade, Object.assign({ in: urlError === null && url !== '' }, { children: (0, jsx_runtime_1.jsx)(IconButton_1.default, Object.assign({ size: "small", disabled: isCreating, type: "submit" }, { children: isCreating ? (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { color: "primary", size: 20 }) : (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.media.link.add.submit", defaultMessage: "ui.composer.media.link.add.submit" }) })) })) })))
|
|
80
|
-
} })) })));
|
|
79
|
+
(urlError && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.composer.media.link.add.error.${urlError}`, defaultMessage: `ui.composer.media.link.add.error.${urlError}` }))) || (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.media.link.add.help", defaultMessage: "ui.composer.media.link.add.help" }), disabled: isCreating }, rest, { InputProps: Object.assign(Object.assign({}, rest.InputProps), { endAdornment: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: url === '' && ((_a = rest.InputProps) === null || _a === void 0 ? void 0 : _a.endAdornment) ? ((_b = rest.InputProps) === null || _b === void 0 ? void 0 : _b.endAdornment) : ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.Fade, Object.assign({ in: urlError === null && url !== '' }, { children: (0, jsx_runtime_1.jsx)(IconButton_1.default, Object.assign({ size: "small", disabled: isCreating, type: "submit" }, { children: isCreating ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { color: "primary", size: 20 })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.media.link.add.submit", defaultMessage: "ui.composer.media.link.add.submit" })) })) })) }))) })) }) })) })));
|
|
81
80
|
};
|