@selfcommunity/react-ui 0.10.2-courses.162 → 0.10.2-courses.164

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/lib/cjs/components/Course/Course.d.ts +5 -4
  2. package/lib/cjs/components/Course/Course.js +13 -17
  3. package/lib/cjs/components/Course/Skeleton.d.ts +5 -0
  4. package/lib/cjs/components/Course/Skeleton.js +4 -4
  5. package/lib/cjs/components/CourseDashboard/Student.js +27 -11
  6. package/lib/cjs/components/EditCourse/Lessons/FieldName.js +3 -3
  7. package/lib/cjs/components/EditCourse/Lessons/SectionRow.js +8 -2
  8. package/lib/cjs/components/EditCourse/Lessons.js +8 -2
  9. package/lib/cjs/components/EditCourse/Requests.js +9 -9
  10. package/lib/cjs/components/EditCourse/Users.js +10 -7
  11. package/lib/cjs/components/UserCreatedCoursesWidget/Skeleton.d.ts +21 -0
  12. package/lib/cjs/components/UserCreatedCoursesWidget/Skeleton.js +43 -0
  13. package/lib/cjs/components/UserCreatedCoursesWidget/UserCreatedCoursesWidget.d.ts +68 -0
  14. package/lib/cjs/components/UserCreatedCoursesWidget/UserCreatedCoursesWidget.js +154 -0
  15. package/lib/cjs/components/UserCreatedCoursesWidget/constants.d.ts +1 -0
  16. package/lib/cjs/components/UserCreatedCoursesWidget/constants.js +4 -0
  17. package/lib/cjs/components/UserCreatedCoursesWidget/index.d.ts +4 -0
  18. package/lib/cjs/components/UserCreatedCoursesWidget/index.js +8 -0
  19. package/lib/cjs/index.d.ts +2 -1
  20. package/lib/cjs/index.js +5 -2
  21. package/lib/cjs/shared/AddUsersButton/AddUsersButton.js +1 -1
  22. package/lib/cjs/shared/CourseUsersTable/ChangeUsersStatus.js +1 -1
  23. package/lib/cjs/shared/CourseUsersTable/CourseUsersTable.js +2 -2
  24. package/lib/esm/components/Course/Course.d.ts +5 -4
  25. package/lib/esm/components/Course/Course.js +13 -17
  26. package/lib/esm/components/Course/Skeleton.d.ts +5 -0
  27. package/lib/esm/components/Course/Skeleton.js +4 -4
  28. package/lib/esm/components/CourseDashboard/Student.js +27 -11
  29. package/lib/esm/components/EditCourse/Lessons/FieldName.js +3 -3
  30. package/lib/esm/components/EditCourse/Lessons/SectionRow.js +8 -2
  31. package/lib/esm/components/EditCourse/Lessons.js +8 -2
  32. package/lib/esm/components/EditCourse/Requests.js +9 -9
  33. package/lib/esm/components/EditCourse/Users.js +10 -7
  34. package/lib/esm/components/UserCreatedCoursesWidget/Skeleton.d.ts +21 -0
  35. package/lib/esm/components/UserCreatedCoursesWidget/Skeleton.js +39 -0
  36. package/lib/esm/components/UserCreatedCoursesWidget/UserCreatedCoursesWidget.d.ts +68 -0
  37. package/lib/esm/components/UserCreatedCoursesWidget/UserCreatedCoursesWidget.js +151 -0
  38. package/lib/esm/components/UserCreatedCoursesWidget/constants.d.ts +1 -0
  39. package/lib/esm/components/UserCreatedCoursesWidget/constants.js +1 -0
  40. package/lib/esm/components/UserCreatedCoursesWidget/index.d.ts +4 -0
  41. package/lib/esm/components/UserCreatedCoursesWidget/index.js +4 -0
  42. package/lib/esm/index.d.ts +2 -1
  43. package/lib/esm/index.js +2 -1
  44. package/lib/esm/shared/AddUsersButton/AddUsersButton.js +1 -1
  45. package/lib/esm/shared/CourseUsersTable/ChangeUsersStatus.js +1 -1
  46. package/lib/esm/shared/CourseUsersTable/CourseUsersTable.js +2 -2
  47. package/lib/umd/react-ui.js +1 -1
  48. package/package.json +8 -8
@@ -20,6 +20,10 @@ export interface CourseProps extends WidgetProps {
20
20
  * @default 'preview'
21
21
  */
22
22
  template?: SCCourseTemplateType;
23
+ /**
24
+ * It shows a different snippet type
25
+ */
26
+ userProfileSnippet?: boolean;
23
27
  /**
24
28
  * Actions
25
29
  * @default null
@@ -79,12 +83,9 @@ export interface CourseProps extends WidgetProps {
79
83
  |previewProgress|.SCCourses-preview-progress|Styles applied to indicate the progress section in the preview template.|
80
84
  |previewProgressBar|.SCCourses-preview-progress-bar|Styles applied to the progress bar in the preview template.|
81
85
  |snippetRoot|.SCCourses-snippet-root|Styles applied to the root element in the snippet template.|
82
- |snippetActions|.SCCourses-snippet-actions|Styles applied to the actions section in the snippet template.|
83
86
  |snippetAvatar|.SCCourses-snippet-avatar|Styles applied to the avatar element in the snippet template.|
84
87
  |snippetImage|.SCCourses-snippet-image|Styles applied to the image element in the snippet template.|
85
- |snippetPrimary|.SCCourses-snippet-primary|Styles applied to the primary section in the snippet template.|
86
- |snippetSecondary|.SCCourses-snippet-secondary|Styles applied to the secondary section in the snippet template.|
87
-
88
+
88
89
  *
89
90
  * @param inProps
90
91
  */
@@ -15,9 +15,9 @@ const CourseParticipantsButton_1 = tslib_1.__importDefault(require("../CoursePar
15
15
  const Widget_1 = tslib_1.__importDefault(require("../Widget"));
16
16
  const constants_1 = require("./constants");
17
17
  const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
18
- const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
19
18
  const course_2 = require("../../utils/course");
20
19
  const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
20
+ const BaseItemButton_1 = tslib_1.__importDefault(require("../../shared/BaseItemButton"));
21
21
  const classes = {
22
22
  root: `${constants_1.PREFIX}-root`,
23
23
  chip: `${constants_1.PREFIX}-chip`,
@@ -36,11 +36,9 @@ const classes = {
36
36
  previewProgress: `${constants_1.PREFIX}-preview-progress`,
37
37
  previewProgressBar: `${constants_1.PREFIX}-preview-progress-bar`,
38
38
  snippetRoot: `${constants_1.PREFIX}-snippet-root`,
39
- snippetActions: `${constants_1.PREFIX}-snippet-actions`,
40
39
  snippetAvatar: `${constants_1.PREFIX}-snippet-avatar`,
41
- snippetImage: `${constants_1.PREFIX}-snippet-image`,
42
- snippetPrimary: `${constants_1.PREFIX}-snippet-primary`,
43
- snippetSecondary: `${constants_1.PREFIX}-snippet-secondary`
40
+ snippetAvatarUserProfile: `${constants_1.PREFIX}-snippet-avatar-user-profile-view`,
41
+ snippetImage: `${constants_1.PREFIX}-snippet-image`
44
42
  };
45
43
  const Root = (0, styles_1.styled)(Widget_1.default, {
46
44
  name: constants_1.PREFIX,
@@ -52,7 +50,7 @@ const PreviewRoot = (0, styles_1.styled)(material_1.Box, {
52
50
  slot: 'PreviewRoot',
53
51
  overridesResolver: (_props, styles) => styles.previewRoot
54
52
  })(() => ({}));
55
- const SnippetRoot = (0, styles_1.styled)(BaseItem_1.default, {
53
+ const SnippetRoot = (0, styles_1.styled)(BaseItemButton_1.default, {
56
54
  name: constants_1.PREFIX,
57
55
  slot: 'SnippetRoot',
58
56
  overridesResolver: (_props, styles) => styles.snippetRoot
@@ -96,22 +94,20 @@ const SnippetRoot = (0, styles_1.styled)(BaseItem_1.default, {
96
94
  |previewProgress|.SCCourses-preview-progress|Styles applied to indicate the progress section in the preview template.|
97
95
  |previewProgressBar|.SCCourses-preview-progress-bar|Styles applied to the progress bar in the preview template.|
98
96
  |snippetRoot|.SCCourses-snippet-root|Styles applied to the root element in the snippet template.|
99
- |snippetActions|.SCCourses-snippet-actions|Styles applied to the actions section in the snippet template.|
100
97
  |snippetAvatar|.SCCourses-snippet-avatar|Styles applied to the avatar element in the snippet template.|
101
98
  |snippetImage|.SCCourses-snippet-image|Styles applied to the image element in the snippet template.|
102
- |snippetPrimary|.SCCourses-snippet-primary|Styles applied to the primary section in the snippet template.|
103
- |snippetSecondary|.SCCourses-snippet-secondary|Styles applied to the secondary section in the snippet template.|
104
-
99
+
105
100
  *
106
101
  * @param inProps
107
102
  */
108
103
  function Course(inProps) {
104
+ var _a, _b, _c, _d, _e, _f, _g;
109
105
  // PROPS
110
106
  const props = (0, system_1.useThemeProps)({
111
107
  props: inProps,
112
108
  name: constants_1.PREFIX
113
109
  });
114
- const { id = `course_object_${props.courseId ? props.courseId : props.course ? props.course.id : ''}`, courseId = null, course = null, className = null, template = course_1.SCCourseTemplateType.PREVIEW, actions, CourseParticipantsButtonComponentProps = {}, CourseSkeletonComponentProps = {} } = props, rest = tslib_1.__rest(props, ["id", "courseId", "course", "className", "template", "actions", "CourseParticipantsButtonComponentProps", "CourseSkeletonComponentProps"]);
110
+ const { id = `course_object_${props.courseId ? props.courseId : props.course ? props.course.id : ''}`, courseId = null, course = null, className = null, template = course_1.SCCourseTemplateType.PREVIEW, actions, CourseParticipantsButtonComponentProps = {}, CourseSkeletonComponentProps = {}, userProfileSnippet } = props, rest = tslib_1.__rest(props, ["id", "courseId", "course", "className", "template", "actions", "CourseParticipantsButtonComponentProps", "CourseSkeletonComponentProps", "userProfileSnippet"]);
115
111
  // STATE
116
112
  const { scCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course });
117
113
  // CONTEXT
@@ -155,20 +151,20 @@ function Course(inProps) {
155
151
  ? 'primary'
156
152
  : isCourseAdmin && !scCourse.privacy
157
153
  ? 'default'
158
- : 'secondary', label: chipLabel, className: classes.chip })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!scCourse.created_by.deleted && {
154
+ : 'secondary', label: chipLabel, className: classes.chip })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!((_a = scCourse.created_by) === null || _a === void 0 ? void 0 : _a.deleted) && {
159
155
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
160
- }), { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !scCourse.created_by.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scCourse.name, src: scCourse.created_by.avatar, className: classes.previewAvatar }) })) }))] })), (0, jsx_runtime_1.jsxs)(material_1.CardContent, Object.assign({ className: classes.previewContent }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ className: classes.previewCreator }, (!scCourse.created_by.deleted && {
156
+ }), { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !((_b = scCourse.created_by) === null || _b === void 0 ? void 0 : _b.community_badge), smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: scCourse.name, src: (_c = scCourse.created_by) === null || _c === void 0 ? void 0 : _c.avatar, className: classes.previewAvatar }) })) }))] })), (0, jsx_runtime_1.jsxs)(material_1.CardContent, Object.assign({ className: classes.previewContent }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ className: classes.previewCreator }, (!((_d = scCourse.created_by) === null || _d === void 0 ? void 0 : _d.deleted) && {
161
157
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
162
- }), { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: scCourse.created_by.username })) })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse), className: classes.previewNameWrapper }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.previewName }, { children: scCourse.name })) })), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.previewInfo }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), "-", (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.previewCategory }, { children: scCourse.categories.map((category) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", label: category.name }, category.id))) })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.previewProgress }, { children: renderProgress() }))] })), actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.previewActions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "outlined", size: "small", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see.preview", id: "ui.course.see.preview" }) })) })))] })));
158
+ }), { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (_e = scCourse.created_by) === null || _e === void 0 ? void 0 : _e.username })) })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse), className: classes.previewNameWrapper }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.previewName }, { children: scCourse.name })) })), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.previewInfo }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), "-", (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.previewCategory }, { children: scCourse.categories.map((category) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", label: category.name }, category.id))) })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.previewProgress }, { children: renderProgress() }))] })), actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.previewActions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "outlined", size: "small", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see", id: "ui.course.see" }) })) })))] })));
163
159
  }
164
160
  else {
165
- contentObj = ((0, jsx_runtime_1.jsx)(SnippetRoot, { elevation: 0, className: classes.snippetRoot, image: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.snippetImage }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { variant: "square", alt: scCourse.name, src: scCourse.image_medium, className: classes.snippetAvatar }), (isCourseAdmin || (0, course_2.isCourseCompleted)(scCourse) || (0, course_2.isCourseNew)(scCourse)) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", component: "div", color: (0, course_2.isCourseCompleted)(scCourse) || (isCourseAdmin && scCourse.privacy)
161
+ contentObj = ((0, jsx_runtime_1.jsx)(SnippetRoot, { elevation: 0, className: classes.snippetRoot, image: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.snippetImage }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { variant: "square", alt: scCourse.name, src: scCourse.image_medium, className: userProfileSnippet ? classes.snippetAvatarUserProfile : classes.snippetAvatar }), !userProfileSnippet && (isCourseAdmin || (0, course_2.isCourseCompleted)(scCourse) || (0, course_2.isCourseNew)(scCourse)) && ((0, jsx_runtime_1.jsx)(material_1.Chip, { size: "small", component: "div", color: (0, course_2.isCourseCompleted)(scCourse) || (isCourseAdmin && scCourse.privacy)
166
162
  ? 'primary'
167
163
  : isCourseAdmin && !scCourse.privacy
168
164
  ? 'default'
169
- : 'secondary', label: chipLabel, className: classes.chip }))] })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!scCourse.created_by.deleted && {
165
+ : 'secondary', label: chipLabel, className: classes.chip }))] })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!userProfileSnippet && ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!((_f = scCourse.created_by) === null || _f === void 0 ? void 0 : _f.deleted) && {
170
166
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
171
- }), { className: classes.snippetPrimary }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span" }, { children: scCourse.created_by.username })) })), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse), className: classes.snippetPrimary }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.name })) }))] }), secondary: (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ component: "p", variant: "body2", className: classes.snippetSecondary }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), "-", (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })), actions: actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.snippetActions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "outlined", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see", id: "ui.course.see" }) })) }))) }));
167
+ }), { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span" }, { children: (_g = scCourse.created_by) === null || _g === void 0 ? void 0 : _g.username })) }))), (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.name })) }))] }), secondary: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: userProfileSnippet ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !scCourse.hide_member_count && ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.userProfileSnippet.students", defaultMessage: "ui.course.userProfileSnippet.students", values: { students: scCourse.member_count } })) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft', defaultMessage: scCourse.privacy ? `ui.course.privacy.${scCourse.privacy}` : 'ui.course.privacy.draft' }), "-", (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.type.${scCourse.type}`, defaultMessage: `ui.course.type.${scCourse.type}` })] })) }), actions: actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "outlined", component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, scCourse) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.course.see", id: "ui.course.see" }) }))) }));
172
168
  }
173
169
  /**
174
170
  * Renders root object
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { SCCourseTemplateType } from '../../types/course';
3
3
  import { WidgetProps } from '../Widget';
4
+ import { CourseProps } from './Course';
4
5
  export interface CourseSkeletonProps extends WidgetProps {
5
6
  /**
6
7
  * Overrides or extends the styles applied to the component.
@@ -20,6 +21,10 @@ export interface CourseSkeletonProps extends WidgetProps {
20
21
  * Prop to pass an action to be rendered next to the skeleton
21
22
  */
22
23
  actions?: React.ReactNode;
24
+ /**
25
+ * CourseProps
26
+ */
27
+ CourseProps?: CourseProps;
23
28
  }
24
29
  /**
25
30
  * > API documentation for the Community-JS Course Skeleton component. Learn about the available props and the CSS API.
@@ -7,10 +7,10 @@ const Skeleton_1 = tslib_1.__importDefault(require("@mui/material/Skeleton"));
7
7
  const styles_1 = require("@mui/material/styles");
8
8
  const system_1 = require("@mui/system");
9
9
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
10
- const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
11
10
  const course_1 = require("../../types/course");
12
11
  const Widget_1 = tslib_1.__importDefault(require("../Widget"));
13
12
  const constants_1 = require("./constants");
13
+ const BaseItemButton_1 = tslib_1.__importDefault(require("../../shared/BaseItemButton"));
14
14
  const classes = {
15
15
  root: `${constants_1.PREFIX}-skeleton-root`,
16
16
  skeletonPreviewRoot: `${constants_1.PREFIX}-skeleton-preview-root`,
@@ -29,7 +29,7 @@ const SkeletonPreviewRoot = (0, styles_1.styled)(material_1.Box, {
29
29
  name: constants_1.PREFIX,
30
30
  slot: 'SkeletonPreviewRoot'
31
31
  })(() => ({}));
32
- const SkeletonSnippetRoot = (0, styles_1.styled)(BaseItem_1.default, {
32
+ const SkeletonSnippetRoot = (0, styles_1.styled)(BaseItemButton_1.default, {
33
33
  name: constants_1.PREFIX,
34
34
  slot: 'SkeletonSnippetRoot'
35
35
  })(() => ({}));
@@ -61,7 +61,7 @@ function CourseSkeleton(inProps) {
61
61
  props: inProps,
62
62
  name: constants_1.PREFIX
63
63
  });
64
- const { className, template, skeletonsAnimation = 'wave', actions } = props, rest = tslib_1.__rest(props, ["className", "template", "skeletonsAnimation", "actions"]);
64
+ const { className, template, skeletonsAnimation = 'wave', actions, CourseProps } = props, rest = tslib_1.__rest(props, ["className", "template", "skeletonsAnimation", "actions", "CourseProps"]);
65
65
  /**
66
66
  * Renders course object
67
67
  */
@@ -70,7 +70,7 @@ function CourseSkeleton(inProps) {
70
70
  contentObj = ((0, jsx_runtime_1.jsxs)(SkeletonPreviewRoot, Object.assign({ className: classes.skeletonPreviewRoot }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ position: "relative" }, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { variant: "rectangular", animation: skeletonsAnimation, width: "100%", height: "110px" }), (0, jsx_runtime_1.jsx)(Skeleton_1.default, { className: classes.skeletonPreviewAvatar, variant: "rounded", animation: skeletonsAnimation })] })), (0, jsx_runtime_1.jsxs)(material_1.CardContent, Object.assign({ className: classes.skeletonPreviewContent }, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, width: "20%", height: 14, sx: { marginTop: 1 }, variant: "rectangular" }), (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, width: "40%", height: 14, sx: { marginTop: 1.5 }, variant: "rectangular" }), (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, width: "60%", height: 14, sx: { marginTop: 4.5 }, variant: "rectangular" })] })), (0, jsx_runtime_1.jsx)(material_1.CardActions, Object.assign({ className: classes.skeletonPreviewActions }, { children: actions !== undefined ? actions : (0, jsx_runtime_1.jsx)(Skeleton_1.default, { variant: "rounded", width: 100, height: 30 }) }))] })));
71
71
  }
72
72
  else {
73
- contentObj = ((0, jsx_runtime_1.jsx)(SkeletonSnippetRoot, { elevation: 0, square: true, disableTypography: true, className: classes.skeletonSnippetRoot, image: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.skeletonSnippetImage }, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", width: 100, height: 60 }), " ", (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "large" }, { children: "courses" }))] })), primary: (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: "40%", style: { marginBottom: 12 } }), secondary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: "60%", style: { marginBottom: 10, marginRight: 5 } }), (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: "35%" })] }), actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: actions !== undefined ? (actions) : ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "outlined", disabled: true }, { children: (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, height: 10, width: 30, style: { marginTop: 5, marginBottom: 5 } }) }))) }) }));
73
+ contentObj = ((0, jsx_runtime_1.jsx)(SkeletonSnippetRoot, { elevation: 0, square: true, disableTypography: true, className: classes.skeletonSnippetRoot, image: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.skeletonSnippetImage }, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", width: (CourseProps === null || CourseProps === void 0 ? void 0 : CourseProps.userProfileSnippet) ? 60 : 100, height: 60 }), (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "large" }, { children: "courses" }))] })), primary: (CourseProps === null || CourseProps === void 0 ? void 0 : CourseProps.userProfileSnippet) ? ((0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: 120, style: { marginBottom: 10 } })) : ((0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: 40, style: { marginBottom: 12 } })), secondary: (CourseProps === null || CourseProps === void 0 ? void 0 : CourseProps.userProfileSnippet) ? ((0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: 60 })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: 120, style: { marginBottom: 10 } }), (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, variant: "rectangular", height: 10, width: 60 })] })), actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: actions !== undefined ? (actions) : ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "outlined", disabled: true }, { children: (0, jsx_runtime_1.jsx)(Skeleton_1.default, { animation: skeletonsAnimation, height: 15, width: 60 }) }))) }) }));
74
74
  }
75
75
  return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-skeleton-${template}`) }, rest, { children: contentObj })));
76
76
  }
@@ -19,14 +19,20 @@ const Errors_1 = require("../../constants/Errors");
19
19
  const notistack_1 = require("notistack");
20
20
  const Skeleton_1 = tslib_1.__importDefault(require("./Student/Skeleton"));
21
21
  const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
22
- const messages = {
22
+ const BUTTON_MESSAGES = {
23
23
  dashboard: 'ui.course.dashboard.student.button.dashboard',
24
24
  request: 'ui.course.dashboard.student.button.request',
25
+ signUp: 'ui.course.dashboard.student.button.signUp',
25
26
  review: 'ui.course.dashboard.student.button.review',
26
27
  cancel: 'ui.course.dashboard.student.button.cancel',
27
28
  start: 'ui.course.dashboard.student.button.start',
28
29
  continue: 'ui.course.dashboard.student.button.continue'
29
30
  };
31
+ const SNACKBAR_MESSAGES = {
32
+ cancel: 'ui.course.dashboard.student.snackbar.success.cancel',
33
+ enroll: 'ui.course.dashboard.student.snackbar.success.enroll',
34
+ request: 'ui.course.dashboard.student.snackbar.success.request'
35
+ };
30
36
  const classes = {
31
37
  root: `${constants_1.PREFIX}-root`,
32
38
  studentContainer: `${constants_1.PREFIX}-student-container`,
@@ -92,7 +98,7 @@ function Student(inProps) {
92
98
  // CONTEXTS
93
99
  const scRoutingContext = (0, react_core_1.useSCRouting)();
94
100
  // HOOKS
95
- const { scCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course });
101
+ const { scCourse, setSCCourse } = (0, react_core_1.useSCFetchCourse)({ id: courseId, course });
96
102
  const intl = (0, react_intl_1.useIntl)();
97
103
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
98
104
  // EFFETCS
@@ -105,20 +111,24 @@ function Student(inProps) {
105
111
  const handleRequest = (0, react_1.useCallback)(() => {
106
112
  setLoadingRequest(true);
107
113
  let request;
114
+ let updatedCourse;
108
115
  if (sentRequest) {
109
116
  request = api_services_1.CourseService.leaveOrRemoveCourseRequest(scCourse.id);
117
+ updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: null });
110
118
  }
111
119
  else {
112
120
  request = api_services_1.CourseService.joinOrAcceptInviteToCourse(scCourse.id);
121
+ updatedCourse = Object.assign(Object.assign({}, scCourse), { join_status: scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE ? types_1.SCCourseJoinStatusType.REQUESTED : types_1.SCCourseJoinStatusType.JOINED });
113
122
  }
114
123
  request
115
124
  .then(() => {
116
- enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.course.dashboard.student.snackbar.success.${sentRequest ? 'cancel' : 'request'}`, defaultMessage: `ui.course.dashboard.student.snackbar.success.${sentRequest ? 'cancel' : 'request'}` }), {
125
+ setSCCourse(updatedCourse);
126
+ setSentRequest((prev) => !prev);
127
+ setLoadingRequest(false);
128
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel, defaultMessage: sentRequest ? SNACKBAR_MESSAGES.request : scCourse.join_status === null ? SNACKBAR_MESSAGES.enroll : SNACKBAR_MESSAGES.cancel }), {
117
129
  variant: 'success',
118
130
  autoHideDuration: 3000
119
131
  });
120
- setSentRequest((prev) => !prev);
121
- setLoadingRequest(false);
122
132
  })
123
133
  .catch((error) => {
124
134
  enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
@@ -133,10 +143,16 @@ function Student(inProps) {
133
143
  if (!scCourse) {
134
144
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
135
145
  }
136
- return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [(scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR || scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: messages.dashboard, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse), color: "inherit", variant: "outlined" })), ((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
137
- (scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || (scCourse === null || scCourse === void 0 ? void 0 : scCourse.join_status) === types_1.SCCourseJoinStatusType.JOINED)) ||
138
- (scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: scCourse.user_completion_rate === 0 ? messages.start : scCourse.user_completion_rate === 100 ? messages.review : messages.continue, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)), disabled: getIsNextLessonLocked(scCourse), color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
139
- (scCourse.join_status === null || scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: sentRequest ? messages.cancel : messages.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
146
+ return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.actionsWrapper }, { children: [(scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR || scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: BUTTON_MESSAGES.dashboard, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_DASHBOARD_ROUTE_NAME, scCourse), color: "inherit", variant: "outlined" })), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
147
+ (scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
148
+ (scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: scCourse.join_status === null
149
+ ? BUTTON_MESSAGES.signUp
150
+ : scCourse.user_completion_rate === 0
151
+ ? BUTTON_MESSAGES.start
152
+ : scCourse.user_completion_rate === 100
153
+ ? BUTTON_MESSAGES.review
154
+ : BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: scCourse.join_status === null ? handleRequest : undefined })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
155
+ (scCourse.join_status === null || scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: sentRequest ? BUTTON_MESSAGES.cancel : BUTTON_MESSAGES.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
140
156
  }, [scCourse, sentRequest, loadingRequest, handleRequest]);
141
157
  if (!scCourse) {
142
158
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
@@ -145,12 +161,12 @@ function Student(inProps) {
145
161
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
146
162
  }), { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !scCourse.created_by.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, src: scCourse.created_by.avatar, alt: scCourse.created_by.username }) })) })), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!scCourse.created_by.deleted && {
147
163
  to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, scCourse.created_by)
148
- }), { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })) })), (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.header.user.creator", defaultMessage: "ui.course.dashboard.header.user.creator" }) }))] })] })), actionButton] })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), ((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
164
+ }), { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.created_by.username })) })), (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.header.user.creator", defaultMessage: "ui.course.dashboard.header.user.creator" }) }))] })] })), actionButton] })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
149
165
  (scCourse.join_status === types_1.SCCourseJoinStatusType.CREATOR ||
150
166
  scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER ||
151
167
  scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
152
168
  scCourse.privacy === types_1.SCCoursePrivacyType.OPEN ||
153
- scCourse.privacy === types_1.SCCoursePrivacyType.DRAFT) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.box }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), ((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
169
+ scCourse.privacy === types_1.SCCoursePrivacyType.DRAFT) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.description", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.box }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: scCourse.description })) }))] })), (((scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE || scCourse.privacy === types_1.SCCoursePrivacyType.SECRET) &&
154
170
  (scCourse.join_status === types_1.SCCourseJoinStatusType.MANAGER || scCourse.join_status === types_1.SCCourseJoinStatusType.JOINED)) ||
155
171
  (scCourse.privacy === types_1.SCCoursePrivacyType.OPEN && scCourse.join_status !== types_1.SCCourseJoinStatusType.CREATOR)) && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.progress", defaultMessage: "ui.course.dashboard.student.description" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.box }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.percentageWrapper }, { 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.student.progress.described", defaultMessage: "ui.course.dashboard.student.progress.described", values: { progress: scCourse.num_lessons_completed, end: scCourse.num_lessons } }) })), (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.student.progress.percentage", defaultMessage: "ui.course.dashboard.student.progress.percentage", values: { percentage: scCourse.user_completion_rate } }) }))] })), (0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: scCourse === null || scCourse === void 0 ? void 0 : scCourse.user_completion_rate })] })), scCourse.user_completion_rate === 100 && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: (0, classnames_1.default)(classes.completedWrapper, classes.margin) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h3" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.completed", defaultMessage: "ui.course.dashboard.student.completed" }) })), (0, jsx_runtime_1.jsx)("img", { src: clapping_1.CLAPPING, alt: intl.formatMessage({ id: 'ui.course.dashboard.student.completed', defaultMessage: 'ui.course.dashboard.student.completed' }), width: 32, height: 32 })] }))), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.margin }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.dashboard.student.contents", defaultMessage: "ui.course.dashboard.student.contents" }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.lessonsSections }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.course.table.sections.title", defaultMessage: "ui.course.table.sections.title", values: {
156
172
  sectionsNumber: scCourse.num_sections
@@ -25,12 +25,12 @@ function FieldName(props) {
25
25
  const { endpoint, row, isNewRow, handleManageRow, editMode, handleDisableEditMode } = props;
26
26
  // STATES
27
27
  const [loading, setLoading] = (0, react_1.useState)(false);
28
- const [name, setName] = (0, react_1.useState)(null);
28
+ const [name, setName] = (0, react_1.useState)(row.name);
29
29
  // HOOKS
30
30
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
31
31
  // DEBOUNCE
32
- const debounceSetData = (0, material_1.debounce)((name) => {
33
- setName(name);
32
+ const debounceSetData = (0, material_1.debounce)((newName) => {
33
+ setName(newName);
34
34
  }, 300);
35
35
  // HANDLERS
36
36
  const handleChange = (0, react_1.useCallback)((e) => {
@@ -60,7 +60,7 @@ function SectionRow(props) {
60
60
  // HANDLERS
61
61
  const handleExpandAccordion = (0, react_1.useCallback)(() => setOpen((prev) => !prev), [setOpen]);
62
62
  const handleDragEnd = (0, react_1.useCallback)((e) => {
63
- if (!e.destination) {
63
+ if (!e.destination || e.destination.index === e.source.index) {
64
64
  return;
65
65
  }
66
66
  const tempLessons = Array.from(section.lessons);
@@ -71,7 +71,13 @@ function SectionRow(props) {
71
71
  lessons_order: tempLessons.map((tempLesson) => tempLesson.id)
72
72
  };
73
73
  api_services_1.CourseService.patchCourseSection(course.id, section.id, data)
74
- .then(() => handleManageSection(tempSection, types_2.ActionLessonType.UPDATE))
74
+ .then(() => {
75
+ handleManageSection(tempSection, types_2.ActionLessonType.UPDATE);
76
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.save", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.save" }), {
77
+ variant: 'success',
78
+ autoHideDuration: 3000
79
+ });
80
+ })
75
81
  .catch((error) => {
76
82
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
77
83
  enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
@@ -75,7 +75,7 @@ function Lessons(props) {
75
75
  }, []);
76
76
  // HANDLERS
77
77
  const handleDragEnd = (0, react_1.useCallback)((e) => {
78
- if (!e.destination) {
78
+ if (!e.destination || e.destination.index === e.source.index) {
79
79
  return;
80
80
  }
81
81
  const tempSections = Array.from(course.sections);
@@ -85,7 +85,13 @@ function Lessons(props) {
85
85
  sections_order: tempSections.map((tempSection) => tempSection.id)
86
86
  };
87
87
  api_services_1.CourseService.patchCourse(course.id, data)
88
- .then(() => setCourse(Object.assign(Object.assign({}, course), { sections: tempSections })))
88
+ .then(() => {
89
+ setCourse(Object.assign(Object.assign({}, course), { sections: tempSections }));
90
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.save", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.save" }), {
91
+ variant: 'success',
92
+ autoHideDuration: 3000
93
+ });
94
+ })
89
95
  .catch((error) => {
90
96
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
91
97
  enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
@@ -63,7 +63,14 @@ function Requests(props) {
63
63
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
64
64
  });
65
65
  }
66
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
66
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
67
+ // HANDLERS
68
+ const handleRemoveUser = (0, react_1.useCallback)((_msg, user) => {
69
+ dispatch({
70
+ type: widget_1.actionWidgetTypes.SET_RESULTS,
71
+ payload: { count: state.results.length - 1, results: state.results.filter((result) => result.id !== user.id) }
72
+ });
73
+ }, [state.count, state.results, dispatch]);
67
74
  // EFFECTS
68
75
  (0, react_1.useEffect)(() => {
69
76
  let _t;
@@ -79,14 +86,7 @@ function Requests(props) {
79
86
  return () => {
80
87
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
81
88
  };
82
- }, []);
83
- // HANDLERS
84
- const handleRemoveUser = (0, react_1.useCallback)((user) => {
85
- dispatch({
86
- type: widget_1.actionWidgetTypes.SET_RESULTS,
87
- payload: { count: state.count - 1, results: state.results.filter((result) => result.id !== user.id) }
88
- });
89
- }, [dispatch]);
89
+ }, [handleRemoveUser]);
90
90
  return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.requests.title", defaultMessage: "ui.editCourse.tab.requests.title", values: { requestsNumber: state.results.length } }) })), (0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: (0, jsx_runtime_1.jsx)(Status_1.default, { course: course }) })), (0, jsx_runtime_1.jsx)(CourseUsersTable_1.default, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: "requests", emptyStatusTitle: "ui.courseUsersTable.empty.requests.title" })] }));
91
91
  }
92
92
  exports.default = (0, react_1.memo)(Requests);
@@ -70,7 +70,11 @@ function Users(props) {
70
70
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
71
71
  });
72
72
  }
73
- }, [state.isLoadingNext, state.initialized, course, dispatch]);
73
+ }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
74
+ // HANDLERS
75
+ const handleAddUser = (0, react_1.useCallback)((_msg, user) => {
76
+ dispatch({ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
77
+ }, [state.count, dispatch]);
74
78
  // EFFECTS
75
79
  (0, react_1.useEffect)(() => {
76
80
  let _t;
@@ -86,18 +90,17 @@ function Users(props) {
86
90
  return () => {
87
91
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
88
92
  };
89
- }, []);
90
- // HANDLERS
91
- const handleAddUser = (0, react_1.useCallback)((user) => {
92
- dispatch({ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
93
- }, [dispatch]);
93
+ }, [handleAddUser]);
94
94
  const handleConfirm = (0, react_1.useCallback)((newUsers) => {
95
95
  const data = {
96
96
  joined: newUsers.map((user) => user.id)
97
97
  };
98
98
  api_services_1.CourseService.changeCourseUserRole(course.id, data)
99
99
  .then(() => {
100
- dispatch({ type: widget_1.actionWidgetTypes.RESET });
100
+ dispatch({
101
+ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS,
102
+ payload: { count: state.count + newUsers.length, results: newUsers, initialized: true }
103
+ });
101
104
  })
102
105
  .catch((error) => {
103
106
  dispatch({ type: widget_1.actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * > API documentation for the Community-JS User Profile Categories Followed Widget Skeleton component. Learn about the available props and the CSS API.
3
+
4
+ #### Import
5
+
6
+ ```jsx
7
+ import {UserCreatedCoursesWidgetSkeleton} from '@selfcommunity/react-ui';
8
+ ```
9
+
10
+ #### Component Name
11
+
12
+ The name `SCUserCategoriesFollowedWidget-skeleton-root` can be used when providing style overrides in the theme.
13
+
14
+ #### CSS
15
+
16
+ |Rule Name|Global class|Description|
17
+ |---|---|---|
18
+ |root|.SCUserCreatedCoursesWidget-skeleton-root|Styles applied to the root element.|
19
+ *
20
+ */
21
+ export default function UserCreatedCoursesWidgetSkeleton(props: any): JSX.Element;
@@ -0,0 +1,43 @@
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 Widget_1 = tslib_1.__importDefault(require("../Widget"));
6
+ const styles_1 = require("@mui/material/styles");
7
+ const material_1 = require("@mui/material");
8
+ const List_1 = tslib_1.__importDefault(require("@mui/material/List"));
9
+ const Skeleton_1 = tslib_1.__importDefault(require("../Course/Skeleton"));
10
+ const course_1 = require("../../types/course");
11
+ const PREFIX = 'SCUserCreatedCoursesWidgetSkeleton';
12
+ const classes = {
13
+ root: `${PREFIX}-skeleton-root`,
14
+ list: `${PREFIX}-list`
15
+ };
16
+ const Root = (0, styles_1.styled)(Widget_1.default, {
17
+ name: PREFIX,
18
+ slot: 'SkeletonRoot'
19
+ })(() => ({}));
20
+ /**
21
+ * > API documentation for the Community-JS User Profile Categories Followed Widget Skeleton component. Learn about the available props and the CSS API.
22
+
23
+ #### Import
24
+
25
+ ```jsx
26
+ import {UserCreatedCoursesWidgetSkeleton} from '@selfcommunity/react-ui';
27
+ ```
28
+
29
+ #### Component Name
30
+
31
+ The name `SCUserCategoriesFollowedWidget-skeleton-root` can be used when providing style overrides in the theme.
32
+
33
+ #### CSS
34
+
35
+ |Rule Name|Global class|Description|
36
+ |---|---|---|
37
+ |root|.SCUserCreatedCoursesWidget-skeleton-root|Styles applied to the root element.|
38
+ *
39
+ */
40
+ function UserCreatedCoursesWidgetSkeleton(props) {
41
+ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, props, { children: [(0, jsx_runtime_1.jsx)(material_1.CardContent, { children: (0, jsx_runtime_1.jsx)(List_1.default, Object.assign({ className: classes.list }, { children: [...Array(3)].map((category, index) => ((0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(Skeleton_1.default, { template: course_1.SCCourseTemplateType.SNIPPET, CourseProps: { userProfileSnippet: true }, elevation: 0 }) }, index))) })) }), ");"] })));
42
+ }
43
+ exports.default = UserCreatedCoursesWidgetSkeleton;
@@ -0,0 +1,68 @@
1
+ import { CacheStrategies } from '@selfcommunity/utils';
2
+ import { BaseDialogProps } from '../../shared/BaseDialog';
3
+ import { WidgetProps } from '../Widget';
4
+ import { VirtualScrollerItemProps } from '../../types/virtualScroller';
5
+ import { CourseProps } from '../Course';
6
+ export interface UserCreatedCoursesWidgetProps extends VirtualScrollerItemProps, WidgetProps {
7
+ /**
8
+ * The user id
9
+ * @default null
10
+ */
11
+ userId: number;
12
+ /**
13
+ * Hides this component
14
+ * @default false
15
+ */
16
+ autoHide?: boolean;
17
+ /**
18
+ * Limit the number of courses to show
19
+ * @default false
20
+ */
21
+ limit?: number;
22
+ /**
23
+ * Props to spread to single course object
24
+ * @default empty object
25
+ */
26
+ CourseProps?: CourseProps;
27
+ /**
28
+ * Caching strategies
29
+ * @default CacheStrategies.CACHE_FIRST
30
+ */
31
+ cacheStrategy?: CacheStrategies;
32
+ /**
33
+ * Props to spread to subscribed courses dialog
34
+ * @default {}
35
+ */
36
+ DialogProps?: BaseDialogProps;
37
+ /**
38
+ * Other props
39
+ */
40
+ [p: string]: any;
41
+ }
42
+ /**
43
+ * > API documentation for the Community-JS User Profile Courses Created Widget component. Learn about the available props and the CSS API.
44
+ *
45
+ *
46
+ * This component renders the list of the courses that the given user follows.
47
+ * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/UserCreatedCourses)
48
+
49
+ #### Import
50
+ ```jsx
51
+ import {UserCreatedCoursesWidget} from '@selfcommunity/react-ui';
52
+ ```
53
+ #### Component Name
54
+ The name `SCUserCreatedCoursesWidget` can be used when providing style overrides in the theme.
55
+
56
+ #### CSS
57
+
58
+ |Rule Name|Global class|Description|
59
+ |---|---|---|
60
+ |root|.SCUserCreatedCoursesWidget-root|Styles applied to the root element.|
61
+ |title|.SCUserCreatedCoursesWidget-title|Styles applied to the title element.|
62
+ |noResults|.SCUserCreatedCoursesWidget-no-results|Styles applied to no results section.|
63
+ |showMore|.SCUserCreatedCoursesWidget-show-more|Styles applied to show more button element.|
64
+ |dialogRoot|.SCUserCreatedCoursesWidget-dialog-root|Styles applied to the root dialog element.|
65
+ |endMessage|.SCUserCreatedCoursesWidget-end-message|Styles applied to the end message element.|
66
+ * @param inProps
67
+ */
68
+ export default function UserCreatedCoursesWidget(inProps: UserCreatedCoursesWidgetProps): JSX.Element;