@selfcommunity/react-ui 0.10.2-courses.172 → 0.10.2-courses.174

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 (28) hide show
  1. package/lib/cjs/components/CourseDashboard/Student.js +10 -3
  2. package/lib/cjs/components/CourseParticipantsButton/CourseParticipantsButton.js +9 -7
  3. package/lib/cjs/components/EditCourse/Lessons/LessonRow.js +1 -1
  4. package/lib/cjs/components/EditCourse/Lessons/SectionRow.js +7 -6
  5. package/lib/cjs/components/EditCourse/Lessons.js +4 -2
  6. package/lib/cjs/components/EditCourse/Users.js +5 -2
  7. package/lib/cjs/components/LessonCommentObject/LessonCommentObject.js +1 -6
  8. package/lib/cjs/components/LessonCommentObjects/LessonCommentObjects.js +1 -2
  9. package/lib/cjs/shared/AccordionLessons/AccordionLessons.d.ts +2 -1
  10. package/lib/cjs/shared/AccordionLessons/AccordionLessons.js +16 -3
  11. package/lib/cjs/shared/AddUsersButton/AddUsersButton.d.ts +0 -5
  12. package/lib/cjs/shared/AddUsersButton/AddUsersButton.js +6 -7
  13. package/lib/cjs/shared/CourseUsersTable/SeeProgressButton.js +4 -1
  14. package/lib/esm/components/CourseDashboard/Student.js +11 -4
  15. package/lib/esm/components/CourseParticipantsButton/CourseParticipantsButton.js +9 -7
  16. package/lib/esm/components/EditCourse/Lessons/LessonRow.js +1 -1
  17. package/lib/esm/components/EditCourse/Lessons/SectionRow.js +7 -6
  18. package/lib/esm/components/EditCourse/Lessons.js +4 -2
  19. package/lib/esm/components/EditCourse/Users.js +5 -2
  20. package/lib/esm/components/LessonCommentObject/LessonCommentObject.js +1 -6
  21. package/lib/esm/components/LessonCommentObjects/LessonCommentObjects.js +1 -2
  22. package/lib/esm/shared/AccordionLessons/AccordionLessons.d.ts +2 -1
  23. package/lib/esm/shared/AccordionLessons/AccordionLessons.js +18 -5
  24. package/lib/esm/shared/AddUsersButton/AddUsersButton.d.ts +0 -5
  25. package/lib/esm/shared/AddUsersButton/AddUsersButton.js +6 -7
  26. package/lib/esm/shared/CourseUsersTable/SeeProgressButton.js +4 -1
  27. package/lib/umd/react-ui.js +1 -1
  28. package/package.json +8 -8
@@ -57,6 +57,9 @@ function SectionRow(props) {
57
57
  };
58
58
  }, []);
59
59
  // HANDLERS
60
+ const handleOpenDialog = useCallback(() => {
61
+ setOpen((prev) => !prev);
62
+ }, [setOpen]);
60
63
  const handleExpandAccordion = useCallback(() => setExpand((prev) => !prev), [setExpand]);
61
64
  const handleDragEnd = useCallback((e) => {
62
65
  if (!e.destination || e.destination.index === e.source.index) {
@@ -87,7 +90,7 @@ function SectionRow(props) {
87
90
  }, [course, section, handleManageSection]);
88
91
  const handleAddTempLesson = useCallback(() => {
89
92
  setLessons((prevLessons) => ((prevLessons === null || prevLessons === void 0 ? void 0 : prevLessons.length) > 0 ? [...prevLessons, getLesson(prevLessons.length + 1)] : [getLesson(1)]));
90
- }, [setLessons]);
93
+ }, [setLessons, getLesson]);
91
94
  const handleAbleEditMode = useCallback(() => setTimeout(() => setEditMode(true)), [setEditMode]);
92
95
  const handleDisableEditMode = useCallback(() => setEditMode(false), [setEditMode]);
93
96
  const handleDeleteSection = useCallback(() => {
@@ -96,6 +99,7 @@ function SectionRow(props) {
96
99
  var _a;
97
100
  const tempSection = Object.assign(Object.assign({}, section), { num_lessons: ((_a = section.lessons) === null || _a === void 0 ? void 0 : _a.length) || 0 });
98
101
  handleManageSection(tempSection, ActionLessonType.DELETE);
102
+ handleOpenDialog();
99
103
  enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.delete", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.delete" }), {
100
104
  variant: 'success',
101
105
  autoHideDuration: 3000
@@ -108,7 +112,7 @@ function SectionRow(props) {
108
112
  autoHideDuration: 3000
109
113
  });
110
114
  });
111
- }, [course, section, handleManageSection]);
115
+ }, [course, section, handleManageSection, handleOpenDialog]);
112
116
  const handleManageLesson = useCallback((lesson, type, newRow) => {
113
117
  switch (type) {
114
118
  case ActionLessonType.ADD: {
@@ -132,14 +136,11 @@ function SectionRow(props) {
132
136
  }
133
137
  }
134
138
  }, [section, handleManageSection]);
135
- const handleOpenDialog = useCallback(() => {
136
- setOpen((prev) => !prev);
137
- }, [setOpen]);
138
139
  return (_jsxs(Fragment, { children: [_jsxs(TableRow, Object.assign({}, provider.draggableProps, { ref: provider.innerRef, className: classes.tableBodyAccordion }, { children: [_jsx(TableCell, Object.assign({ component: "th", scope: "row" }, provider.dragHandleProps, { className: classNames(classes.cellWidth, classes.cellPadding) }, { children: _jsxs(Stack, Object.assign({ className: classes.tableBodyIconWrapper }, { children: [_jsx(IconButton, Object.assign({ "aria-label": "expand row", size: "small", onClick: handleExpandAccordion }, { children: expand ? _jsx(Icon, { children: "expand_less" }) : _jsx(Icon, { children: "expand_more" }) })), _jsx(Icon, Object.assign({ color: "disabled" }, { children: "drag" }))] })) })), _jsx(TableCell, { children: _jsx(FieldName, { endpoint: {
139
140
  url: () => isNewRow
140
141
  ? Endpoints.CreateCourseSection.url({ id: course.id })
141
142
  : Endpoints.PatchCourseSection.url({ id: course.id, section_id: section.id }),
142
143
  method: isNewRow ? Endpoints.CreateCourseSection.method : Endpoints.PatchCourseSection.method
143
- }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), _jsx(TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: isDisabled ? (_jsx(Skeleton, { animation: false, variant: "rectangular", width: "250px", height: "53px", sx: { margin: 'auto', borderRadius: '5px' } })) : (_jsx(LessonReleaseMenu, { course: course, section: section })) })), _jsx(TableCell, Object.assign({ className: classes.cellAlignRight }, { children: _jsxs(Stack, Object.assign({ className: classes.actionsWrapper }, { children: [_jsx(AddButton, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), _jsxs(MenuRow, Object.assign({ disabled: isDisabled }, { children: [_jsx(MenuItem, Object.assign({ onClick: handleAbleEditMode }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), _jsx(MenuItem, Object.assign({ onClick: handleOpenDialog }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), _jsx(TableRow, { children: _jsxs(TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [_jsx(Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: _jsx(DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: _jsx(Table, { children: _jsx(Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => (_jsxs(TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => (_jsx(Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => (_jsx(LessonRow, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && _jsx(ConfirmDialog, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
144
+ }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), _jsx(TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: isDisabled ? (_jsx(Skeleton, { animation: false, variant: "rectangular", width: "250px", height: "38px", sx: { margin: 'auto', borderRadius: '5px' } })) : (_jsx(LessonReleaseMenu, { course: course, section: section })) })), _jsx(TableCell, Object.assign({ className: classes.cellAlignRight }, { children: _jsxs(Stack, Object.assign({ className: classes.actionsWrapper }, { children: [_jsx(AddButton, { label: "ui.editCourse.tab.lessons.table.lesson", handleAddRow: handleAddTempLesson, color: "primary", variant: "outlined", disabled: isDisabled }), _jsxs(MenuRow, Object.assign({ disabled: isDisabled }, { children: [_jsx(MenuItem, Object.assign({ onClick: handleAbleEditMode }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.rename", defaultMessage: "ui.editCourse.tab.lessons.table.menu.rename" }) })) })), _jsx(MenuItem, Object.assign({ onClick: handleOpenDialog }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.menu.delete", defaultMessage: "ui.editCourse.tab.lessons.table.menu.delete" }) })) }))] }))] })) }))] })), _jsx(TableRow, { children: _jsxs(TableCell, Object.assign({ className: classes.tableBodyCollapseWrapper, colSpan: 4 }, { children: [_jsx(Collapse, Object.assign({ in: expand, timeout: "auto", unmountOnExit: true }, { children: _jsx(DragDropContext, Object.assign({ onDragEnd: handleDragEnd }, { children: _jsx(Table, { children: _jsx(Droppable, Object.assign({ droppableId: "droppable-2" }, { children: (outerProvider) => (_jsxs(TableBody, Object.assign({ ref: outerProvider.innerRef }, outerProvider.droppableProps, { children: [lessons.map((lesson, i, array) => (_jsx(Draggable, Object.assign({ draggableId: i.toString(), index: i, isDragDisabled: isDisabled }, { children: (innerProvider) => (_jsx(LessonRow, { provider: innerProvider, course: course, section: section, lesson: lesson, isNewRow: isNewLocalRow && i + 1 === array.length, handleManageLesson: handleManageLesson }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })), open && _jsx(ConfirmDialog, { open: true, onClose: handleOpenDialog, onConfirm: handleDeleteSection })] })) })] }));
144
145
  }
145
146
  export default memo(SectionRow);
@@ -105,9 +105,11 @@ function Lessons(props) {
105
105
  }, [setSections]);
106
106
  const handleManageSection = useCallback((section, type, newRow = false) => {
107
107
  switch (type) {
108
- case ActionLessonType.ADD:
109
- setCourse(Object.assign(Object.assign({}, course), { num_sections: course.num_sections + 1, sections: [...course.sections, section] }));
108
+ case ActionLessonType.ADD: {
109
+ const newSection = Object.assign(Object.assign({}, section), { lessons: [] });
110
+ setCourse(Object.assign(Object.assign({}, course), { num_sections: course.num_sections + 1, sections: [...course.sections, newSection] }));
110
111
  break;
112
+ }
111
113
  case ActionLessonType.RENAME:
112
114
  setCourse(Object.assign(Object.assign({}, course), { sections: course.sections.map((prevSection) => {
113
115
  if (prevSection.id === section.id) {
@@ -43,7 +43,6 @@ function Users(props) {
43
43
  } } = props;
44
44
  // STATES
45
45
  const [state, dispatch] = useReducer(dataWidgetReducer, {
46
- isLoadingPrevious: false,
47
46
  isLoadingNext: false,
48
47
  next: null,
49
48
  cacheKey: SCCache.getWidgetStateCacheKey(SCCache.USER_PARTECIPANTS_COURSES_STATE_CACHE_PREFIX_KEY, course.id),
@@ -100,6 +99,10 @@ function Users(props) {
100
99
  type: actionWidgetTypes.LOAD_PREVIOUS_SUCCESS,
101
100
  payload: { count: state.count + newUsers.length, results: newUsers, initialized: true }
102
101
  });
102
+ enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.editCourse.tab.users.table.snackbar.success", defaultMessage: "ui.editCourse.tab.users.table.snackbar.success" }), {
103
+ variant: 'success',
104
+ autoHideDuration: 3000
105
+ });
103
106
  })
104
107
  .catch((error) => {
105
108
  dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
@@ -113,6 +116,6 @@ function Users(props) {
113
116
  return (_jsxs(Box, { children: [_jsx(Typography, Object.assign({ variant: "h6", className: classes.contrastColor }, { children: _jsx(FormattedMessage, { id: "ui.editCourse.tab.users.title", defaultMessage: "ui.editCourse.tab.users.title", values: { usersNumber: state.results.length } }) })), _jsxs(Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: [_jsx(Status, { course: course }), _jsx(AddUsersButton, { label: "ui.editCourse.tab.users.addUsersButton.label", endpoint: {
114
117
  url: () => Endpoints.GetCourseSuggestedUsers.url({ id: course.id }),
115
118
  method: Endpoints.GetCourseSuggestedUsers.method
116
- }, onConfirm: handleConfirm, isUpdating: state.isLoadingPrevious, className: classes.contrastBgColor })] })), _jsx(CourseUsersTable, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: "edit", emptyStatusTitle: "ui.courseUsersTable.empty.users.title", emptyStatusDescription: "ui.courseUsersTable.empty.users.description" })] }));
119
+ }, onConfirm: handleConfirm, className: classes.contrastBgColor })] })), _jsx(CourseUsersTable, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: "edit", emptyStatusTitle: "ui.courseUsersTable.empty.users.title", emptyStatusDescription: "ui.courseUsersTable.empty.users.description" })] }));
117
120
  }
118
121
  export default memo(Users);
@@ -177,15 +177,10 @@ export default function LessonCommentObject(inProps) {
177
177
  * @param comment
178
178
  */
179
179
  function renderComment(comment) {
180
- if (!scUserContext.user || (scUserContext.user && !UserUtils.isStaff(scUserContext.user) && scUserContext.user.id !== comment.created_by.id)) {
181
- // render the comment if user is logged and is staff (admin, moderator)
182
- // or the comment author is the logged user
183
- return null;
184
- }
185
180
  const summaryHtml = getCommentContributionHtml(comment.html, scRoutingContext.url);
186
181
  return (_jsx(React.Fragment, { children: editComment && editComment.id === comment.id ? (_jsx(Box, Object.assign({ className: classes.comment }, { children: _jsx(CommentObjectReply, 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)) }))) : (_jsx(BaseItem, { elevation: 0, className: classes.comment, image: _jsx(Link, Object.assign({}, (!comment.created_by.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(UserAvatar, Object.assign({ hide: !obj.created_by.community_badge }, { children: _jsx(Avatar, { alt: obj.created_by.username, variant: "circular", src: comment.created_by.avatar, className: classes.avatar }) })) })), disableTypography: true, primary: _jsx(_Fragment, { children: _jsxs(Widget, Object.assign({ className: classes.content, elevation: elevation }, rest, { children: [_jsxs(CardContent, { children: [_jsx(Link, Object.assign({ className: classes.author }, (!comment.created_by.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, comment.created_by) }), { onClick: comment.created_by.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(Typography, Object.assign({ component: "span" }, { children: comment.created_by.username })) })), _jsxs(_Fragment, { children: [_jsx(Bullet, {}), _jsx(DateTimeAgo, { date: comment.created_at, showStartIcon: false })] }), _jsx(Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: summaryHtml } }), obj.medias && obj.medias.length > 0 && (_jsx(_Fragment, { children: obj.medias.map((media) => {
187
182
  return _jsx(LessonFilePreview, { className: classes.mediaContent, media: media }, media.id);
188
- }) }))] }), scUserContext.user && (_jsx(Box, Object.assign({ className: classes.commentActionsMenu }, { children: _jsx(LessonCommentActionsMenu, { lesson: lessonObject, commentObject: comment, onDelete: handleDelete, onEdit: handleEdit }) })))] })) }) })) }, comment.id));
183
+ }) }))] }), scUserContext.user && scUserContext.user.id === comment.created_by.id && (_jsx(Box, Object.assign({ className: classes.commentActionsMenu }, { children: _jsx(LessonCommentActionsMenu, { lesson: lessonObject, commentObject: comment, onDelete: handleDelete, onEdit: handleEdit }) })))] })) }) })) }, comment.id));
189
184
  }
190
185
  /**
191
186
  * Render comments
@@ -86,7 +86,7 @@ export default function LessonCommentObjects(inProps) {
86
86
  id: lessonObject.id,
87
87
  lessonObject: lessonObject,
88
88
  pageSize: 8,
89
- orderBy: SCCommentsOrderBy.CONNECTION_ASC,
89
+ orderBy: SCCommentsOrderBy.ADDED_AT_ASC,
90
90
  cacheStrategy
91
91
  });
92
92
  // EFFECTS
@@ -163,7 +163,6 @@ export default function LessonCommentObjects(inProps) {
163
163
  }
164
164
  commentsObject.updateLessonComments([...updated]);
165
165
  };
166
- console.log(commentsObject.isLoadingNext);
167
166
  /**
168
167
  * Renders root object(if obj)
169
168
  */
@@ -1,7 +1,8 @@
1
1
  import { HTMLAttributes } from 'react';
2
- import { SCCourseType } from '@selfcommunity/types';
2
+ import { SCCourseJoinStatusType, SCCourseType } from '@selfcommunity/types';
3
3
  export interface AccordionLessonsProps {
4
4
  course: SCCourseType | null;
5
+ viewerJoinStatus?: SCCourseJoinStatusType;
5
6
  className?: HTMLAttributes<HTMLDivElement>['className'];
6
7
  }
7
8
  export default function AccordionLessons(inProps: AccordionLessonsProps): JSX.Element;
@@ -1,19 +1,30 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Accordion, AccordionDetails, AccordionSummary, Box, Icon, styled, Typography, useMediaQuery, useTheme, useThemeProps } from '@mui/material';
2
+ import { Accordion, AccordionDetails, AccordionSummary, Box, Button, Icon, styled, Typography, useMediaQuery, useTheme, useThemeProps } from '@mui/material';
3
3
  import { FormattedMessage } from 'react-intl';
4
4
  import classNames from 'classnames';
5
5
  import { useCallback, useState } from 'react';
6
- import { SCCourseLessonCompletionStatusType } from '@selfcommunity/types';
6
+ import { SCCourseJoinStatusType, SCCourseLessonCompletionStatusType } from '@selfcommunity/types';
7
+ import { SCRoutes, useSCRouting } from '@selfcommunity/react-core';
7
8
  import { PREFIX } from './constants';
8
9
  import AccordionLessonSkeleton from './Skeleton';
10
+ import { Link } from '@selfcommunity/react-core';
9
11
  const classes = {
10
12
  root: `${PREFIX}-root`,
11
13
  empty: `${PREFIX}-empty`,
12
14
  accordion: `${PREFIX}-accordion`,
13
15
  summary: `${PREFIX}-summary`,
14
16
  details: `${PREFIX}-details`,
15
- circle: `${PREFIX}-circle`
17
+ circle: `${PREFIX}-circle`,
18
+ link: `${PREFIX}-link`
16
19
  };
20
+ function getUrlLesson(course, section, lesson) {
21
+ return {
22
+ id: course.id,
23
+ slug: course.slug,
24
+ section_id: section.id,
25
+ lesson_id: lesson.id
26
+ };
27
+ }
17
28
  const Root = styled(Box, {
18
29
  name: PREFIX,
19
30
  slot: 'Root',
@@ -26,12 +37,14 @@ export default function AccordionLessons(inProps) {
26
37
  props: inProps,
27
38
  name: PREFIX
28
39
  });
29
- const { course, className } = props;
40
+ const { course, viewerJoinStatus, className } = props;
30
41
  //STATES
31
42
  const [expanded, setExpanded] = useState(false);
32
43
  // HOOKS
33
44
  const theme = useTheme();
34
45
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
46
+ // CONTEXTS
47
+ const scRoutingContext = useSCRouting();
35
48
  // HANDLERS
36
49
  const handleChange = useCallback((panel) => (_, newExpanded) => {
37
50
  setExpanded(newExpanded ? panel : false);
@@ -41,5 +54,5 @@ export default function AccordionLessons(inProps) {
41
54
  }
42
55
  return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, { children: ((_a = course.sections) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (course.sections.map((section) => (_jsxs(Accordion, Object.assign({ className: classes.accordion, expanded: expanded === section.id, onChange: handleChange(section.id), disableGutters: true, elevation: 0, square: true }, { children: [_jsxs(AccordionSummary, Object.assign({ className: classes.summary, expandIcon: _jsx(Icon, { children: "expand_less" }) }, { children: [_jsx(Typography, Object.assign({ component: "span", variant: "body1" }, { children: section.name })), !isMobile && (_jsx(Typography, Object.assign({ component: "span", variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.course.table.lessons.title", defaultMessage: "ui.course.table.lessons.title", values: {
43
56
  lessonsNumber: section.lessons.length
44
- } }) })))] })), section.lessons.map((lesson) => (_jsxs(AccordionDetails, Object.assign({ className: classes.details }, { children: [lesson.completion_status === SCCourseLessonCompletionStatusType.COMPLETED ? (_jsx(Icon, Object.assign({ fontSize: "small", color: "primary" }, { children: "circle_checked" }))) : lesson.locked ? (_jsx(Icon, { children: "private" })) : (_jsx(Box, { className: classes.circle })), _jsx(Typography, { children: lesson.name })] }), lesson.id)))] }), section.id)))) : (_jsx(Typography, Object.assign({ variant: "body1", className: classes.empty }, { children: _jsx(FormattedMessage, { id: "ui.course.accordionLessons.empty", defaultMessage: "ui.course.accordionLessons.empty" }) }))) })));
57
+ } }) })))] })), section.lessons.map((lesson) => (_jsxs(AccordionDetails, Object.assign({ className: classes.details }, { children: [lesson.completion_status === SCCourseLessonCompletionStatusType.COMPLETED ? (_jsx(Icon, Object.assign({ fontSize: "small", color: "primary" }, { children: "circle_checked" }))) : lesson.locked ? (_jsx(Icon, { children: "private" })) : (_jsx(Box, { className: classes.circle })), course.join_status === null || viewerJoinStatus === SCCourseJoinStatusType.CREATOR || lesson.locked ? (_jsx(Typography, { children: lesson.name })) : (_jsx(Button, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlLesson(course, section, lesson)), variant: "text", color: "inherit", className: classes.link }, { children: _jsx(Typography, { children: lesson.name }) })))] }), lesson.id)))] }), section.id)))) : (_jsx(Typography, Object.assign({ variant: "body1", className: classes.empty }, { children: _jsx(FormattedMessage, { id: "ui.course.accordionLessons.empty", defaultMessage: "ui.course.accordionLessons.empty" }) }))) })));
45
58
  }
@@ -4,11 +4,6 @@ import { SCUserType } from '@selfcommunity/types';
4
4
  import { EndpointType } from '@selfcommunity/api-services';
5
5
  export interface AddUsersButtonProps extends ButtonProps {
6
6
  label: string;
7
- /**
8
- * Handles component update
9
- * @default false
10
- */
11
- isUpdating?: boolean;
12
7
  /**
13
8
  * Event API Endpoint
14
9
  * @default Endpoints.GetCourseSuggestedUsers
@@ -41,7 +41,7 @@ function AddUsersButton(inProps) {
41
41
  props: inProps,
42
42
  name: PREFIX
43
43
  });
44
- const { label, variant = 'outlined', color = 'inherit', size = 'small', isUpdating = false, endpoint = Endpoints.GetCourseSuggestedUsers, endpointQueryParams = { limit: DEFAULT_PAGINATION_LIMIT, offset: DEFAULT_PAGINATION_OFFSET, search: '' }, onConfirm, className } = props, rest = __rest(props, ["label", "variant", "color", "size", "isUpdating", "endpoint", "endpointQueryParams", "onConfirm", "className"]);
44
+ const { label, variant = 'outlined', color = 'inherit', size = 'small', endpoint = Endpoints.GetCourseSuggestedUsers, endpointQueryParams = { limit: DEFAULT_PAGINATION_LIMIT, offset: DEFAULT_PAGINATION_OFFSET, search: '' }, onConfirm, className } = props, rest = __rest(props, ["label", "variant", "color", "size", "endpoint", "endpointQueryParams", "onConfirm", "className"]);
45
45
  // STATES
46
46
  const [openDialog, setOpenDialog] = useState(false);
47
47
  const [invited, setInvited] = useState([]);
@@ -84,17 +84,16 @@ function AddUsersButton(inProps) {
84
84
  * @param reason
85
85
  */
86
86
  const handleToggleDialogOpen = useCallback(() => {
87
- if (!isUpdating) {
88
- setOpenDialog((prev) => !prev);
89
- }
90
- }, [isUpdating, setOpenDialog]);
87
+ setOpenDialog((prev) => !prev);
88
+ }, [setOpenDialog]);
91
89
  /**
92
90
  * Handles action confirm
93
91
  */
94
92
  const handleConfirm = useCallback(() => {
95
93
  onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(invited);
96
94
  setInvited([]);
97
- }, [invited, onConfirm]);
95
+ handleToggleDialogOpen();
96
+ }, [invited, onConfirm, handleToggleDialogOpen]);
98
97
  // HANDLERS AUTOCOMPLETE
99
98
  const handleInputChange = useCallback((_, newValue, reason) => {
100
99
  switch (reason) {
@@ -127,7 +126,7 @@ function AddUsersButton(inProps) {
127
126
  const handleDelete = useCallback((userToDelete) => {
128
127
  setInvited((prev) => prev.filter((user) => user.id !== userToDelete.id));
129
128
  }, [setInvited]);
130
- return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ onClick: handleToggleDialogOpen, variant: variant, color: color, size: size, className: classNames(classes.root, className) }, rest, { children: _jsx(FormattedMessage, { id: label, defaultMessage: label }) })), openDialog && (_jsx(DialogRoot, Object.assign({ DialogContentProps: { dividers: false }, open: true, onClose: handleToggleDialogOpen, title: _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.addUserButton.dialog.title", defaultMessage: "ui.addUserButton.dialog.title" }) })), actions: _jsx(LoadingButton, Object.assign({ onClick: handleConfirm, size: "medium", variant: "contained", autoFocus: true, disabled: !invited.length, loading: isUpdating }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.addUserButton.dialog.confirm", defaultMessage: "ui.addUserButton.dialog.confirm" }) })) })), className: classes.dialogRoot }, { children: _jsxs(Stack, Object.assign({ className: classes.dialogAutocompleteWrapper }, { children: [_jsx(Autocomplete, { loading: loading, size: "small", multiple: true, options: suggested, onChange: handleChange, onInputChange: handleInputChange, inputValue: value, filterOptions: filterOptions, value: invited, getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.username) || '...', isOptionEqualToValue: (option, value) => (option === null || option === void 0 ? void 0 : option.id) === value.id, loadingText: _jsx(FormattedMessage, { id: "ui.addUserButton.autocomplete.loading", defaultMessage: "ui.addUserButton.autocomplete.loading" }), noOptionsText: _jsx(FormattedMessage, { id: "ui.addUserButton.autocomplete.noResults", defaultMessage: "ui.addUserButton.autocomplete.noResults" }), renderTags: () => null, popupIcon: null, disableClearable: true, renderOption: (props, option) => (_jsxs(Stack, Object.assign({ component: "li", flexDirection: "row", gap: "5px" }, props, { children: [_jsx(Avatar, { alt: option.username, src: option.avatar }), _jsx(Typography, { children: option.username })] }))), renderInput: (params) => (_jsx(TextField, Object.assign({}, params, { variant: "outlined", placeholder: `${intl.formatMessage(messages.placeholder)}`, InputProps: Object.assign({}, params.InputProps) }))) }), _jsx(Stack, Object.assign({ className: classes.dialogChipWrapper }, { children: invited.map((option, index) => (_jsx(Chip, { avatar: _jsx(Avatar, { alt: option.username, src: option.avatar }), label: option.username, onDelete: () => {
129
+ return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ onClick: handleToggleDialogOpen, variant: variant, color: color, size: size, className: classNames(classes.root, className) }, rest, { children: _jsx(FormattedMessage, { id: label, defaultMessage: label }) })), openDialog && (_jsx(DialogRoot, Object.assign({ DialogContentProps: { dividers: false }, open: true, onClose: handleToggleDialogOpen, title: _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.addUserButton.dialog.title", defaultMessage: "ui.addUserButton.dialog.title" }) })), actions: _jsx(LoadingButton, Object.assign({ onClick: handleConfirm, size: "medium", variant: "contained", autoFocus: true, disabled: !invited.length }, { children: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.addUserButton.dialog.confirm", defaultMessage: "ui.addUserButton.dialog.confirm" }) })) })), className: classes.dialogRoot }, { children: _jsxs(Stack, Object.assign({ className: classes.dialogAutocompleteWrapper }, { children: [_jsx(Autocomplete, { loading: loading, size: "small", multiple: true, options: suggested, onChange: handleChange, onInputChange: handleInputChange, inputValue: value, filterOptions: filterOptions, value: invited, getOptionLabel: (option) => (option === null || option === void 0 ? void 0 : option.username) || '...', isOptionEqualToValue: (option, value) => (option === null || option === void 0 ? void 0 : option.id) === value.id, loadingText: _jsx(FormattedMessage, { id: "ui.addUserButton.autocomplete.loading", defaultMessage: "ui.addUserButton.autocomplete.loading" }), noOptionsText: _jsx(FormattedMessage, { id: "ui.addUserButton.autocomplete.noResults", defaultMessage: "ui.addUserButton.autocomplete.noResults" }), renderTags: () => null, popupIcon: null, disableClearable: true, renderOption: (props, option) => (_jsxs(Stack, Object.assign({ component: "li", flexDirection: "row", gap: "5px" }, props, { children: [_jsx(Avatar, { alt: option.username, src: option.avatar }), _jsx(Typography, { children: option.username })] }))), renderInput: (params) => (_jsx(TextField, Object.assign({}, params, { variant: "outlined", placeholder: `${intl.formatMessage(messages.placeholder)}`, InputProps: Object.assign({}, params.InputProps) }))) }), _jsx(Stack, Object.assign({ className: classes.dialogChipWrapper }, { children: invited.map((option, index) => (_jsx(Chip, { avatar: _jsx(Avatar, { alt: option.username, src: option.avatar }), label: option.username, onDelete: () => {
131
130
  handleDelete(option);
132
131
  } }, index))) }))] })) })))] }));
133
132
  }
@@ -9,6 +9,7 @@ import AccordionLessons from '../AccordionLessons';
9
9
  import { CourseService } from '@selfcommunity/api-services';
10
10
  import { Logger } from '@selfcommunity/utils';
11
11
  import { SCOPE_SC_UI } from '../../constants/Errors';
12
+ import UserAvatar from '../UserAvatar';
12
13
  const classes = {
13
14
  dialogRoot: `${PREFIX}-dialog-root`,
14
15
  contentWrapper: `${PREFIX}-content-wrapper`,
@@ -45,6 +46,8 @@ function SeeProgressButton(props) {
45
46
  const handleToggleOpen = useCallback(() => {
46
47
  setOpen((prev) => !prev);
47
48
  }, [setOpen]);
48
- return (_jsxs(Fragment, { children: [isMobile ? (_jsx(IconButton, Object.assign({ size: "small", color: "inherit", onClick: handleToggleOpen }, { children: _jsx(Icon, { children: "chevron_right" }) }))) : (_jsx(Button, Object.assign({ variant: "outlined", size: "small", color: "inherit", onClick: handleToggleOpen }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.action.btn.label", defaultMessage: "ui.courseUsersTable.action.btn.label" }) })) }))), open && (_jsx(DialogRoot, Object.assign({ DialogContentProps: { dividers: isMobile }, open: true, scroll: "paper", onClose: handleToggleOpen, title: _jsx(Typography, Object.assign({ variant: "h3" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.title", defaultMessage: "ui.courseUsersTable.dialog.title" }) })), className: classes.dialogRoot }, { children: _jsxs(Stack, Object.assign({ className: classes.contentWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.infoOuterWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.infoInnerWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.avatarWrapper }, { children: [_jsx(Avatar, { className: classes.avatar, src: user.avatar, alt: user.username }), _jsx(Typography, Object.assign({ variant: "body1" }, { children: user.username }))] })), _jsx(Button, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user), variant: "outlined", size: "small", color: "inherit" }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.btn.label", defaultMessage: "ui.courseUsersTable.dialog.btn.label" }) })) }))] })), student ? (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.info.text1", defaultMessage: "ui.courseUsersTable.dialog.info.text1", values: { lessonsCompleted: student.num_lessons_completed } }) }))) : (_jsx(Skeleton, { animation: "wave", variant: "text", width: "100px", height: "21px" })), student ? (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.info.text2", defaultMessage: "ui.courseUsersTable.dialog.info.text2", values: { courseCompleted: student.user_completion_rate } }) }))) : (_jsx(Skeleton, { animation: "wave", variant: "text", width: "100px", height: "21px" }))] })), _jsx(AccordionLessons, { course: student })] })) })))] }));
49
+ return (_jsxs(Fragment, { children: [isMobile ? (_jsx(IconButton, Object.assign({ size: "small", color: "inherit", onClick: handleToggleOpen }, { children: _jsx(Icon, { children: "chevron_right" }) }))) : (_jsx(Button, Object.assign({ variant: "outlined", size: "small", color: "inherit", onClick: handleToggleOpen }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.action.btn.label", defaultMessage: "ui.courseUsersTable.action.btn.label" }) })) }))), open && (_jsx(DialogRoot, Object.assign({ DialogContentProps: { dividers: isMobile }, open: true, scroll: "paper", onClose: handleToggleOpen, title: _jsx(Typography, Object.assign({ variant: "h3" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.title", defaultMessage: "ui.courseUsersTable.dialog.title" }) })), className: classes.dialogRoot }, { children: _jsxs(Stack, Object.assign({ className: classes.contentWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.infoOuterWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.infoInnerWrapper }, { children: [_jsxs(Stack, Object.assign({ className: classes.avatarWrapper }, { children: [_jsx(Link, Object.assign({}, (!course.created_by.deleted && {
50
+ to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, course.created_by)
51
+ }), { children: _jsx(UserAvatar, Object.assign({ hide: !course.created_by.community_badge, smaller: true }, { children: _jsx(Avatar, { className: classes.avatar, src: user.avatar, alt: user.username }) })) })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: user.username }))] })), _jsx(Button, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, user), variant: "outlined", size: "small", color: "inherit" }, { children: _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.btn.label", defaultMessage: "ui.courseUsersTable.dialog.btn.label" }) })) }))] })), student ? (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.info.text1", defaultMessage: "ui.courseUsersTable.dialog.info.text1", values: { lessonsCompleted: student.num_lessons_completed } }) }))) : (_jsx(Skeleton, { animation: "wave", variant: "text", width: "100px", height: "21px" })), student ? (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.courseUsersTable.dialog.info.text2", defaultMessage: "ui.courseUsersTable.dialog.info.text2", values: { courseCompleted: student.user_completion_rate } }) }))) : (_jsx(Skeleton, { animation: "wave", variant: "text", width: "100px", height: "21px" }))] })), _jsx(AccordionLessons, { course: student, viewerJoinStatus: course.join_status })] })) })))] }));
49
52
  }
50
53
  export default memo(SeeProgressButton);