@selfcommunity/react-ui 0.10.2-courses.191 → 0.10.2-courses.193

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 (38) hide show
  1. package/lib/cjs/components/CourseForm/CourseForm.js +2 -2
  2. package/lib/cjs/components/EditCourse/Requests.js +3 -3
  3. package/lib/cjs/components/EditCourse/Users.js +14 -4
  4. package/lib/cjs/components/Notification/Course/Course.d.ts +15 -0
  5. package/lib/cjs/components/Notification/Course/Course.js +75 -0
  6. package/lib/cjs/components/Notification/Course/index.d.ts +3 -0
  7. package/lib/cjs/components/Notification/Course/index.js +5 -0
  8. package/lib/cjs/components/Notification/Notification.js +8 -0
  9. package/lib/cjs/components/SnippetNotifications/SnippetNotifications.js +8 -0
  10. package/lib/cjs/components/ToastNotifications/ToastNotifications.js +8 -0
  11. package/lib/cjs/constants/PubSub.d.ts +3 -1
  12. package/lib/cjs/constants/PubSub.js +2 -0
  13. package/lib/cjs/shared/CourseUsersTable/CourseUsersTable.js +24 -3
  14. package/lib/cjs/shared/CourseUsersTable/RemoveButton.d.ts +10 -0
  15. package/lib/cjs/shared/CourseUsersTable/RemoveButton.js +51 -0
  16. package/lib/cjs/shared/CourseUsersTable/RequestButton.d.ts +3 -2
  17. package/lib/cjs/shared/CourseUsersTable/RequestButton.js +14 -10
  18. package/lib/cjs/types/course.d.ts +9 -0
  19. package/lib/esm/components/CourseForm/CourseForm.js +3 -3
  20. package/lib/esm/components/EditCourse/Requests.js +4 -4
  21. package/lib/esm/components/EditCourse/Users.js +15 -5
  22. package/lib/esm/components/Notification/Course/Course.d.ts +15 -0
  23. package/lib/esm/components/Notification/Course/Course.js +72 -0
  24. package/lib/esm/components/Notification/Course/index.d.ts +3 -0
  25. package/lib/esm/components/Notification/Course/index.js +2 -0
  26. package/lib/esm/components/Notification/Notification.js +8 -0
  27. package/lib/esm/components/SnippetNotifications/SnippetNotifications.js +8 -0
  28. package/lib/esm/components/ToastNotifications/ToastNotifications.js +8 -0
  29. package/lib/esm/constants/PubSub.d.ts +3 -1
  30. package/lib/esm/constants/PubSub.js +2 -0
  31. package/lib/esm/shared/CourseUsersTable/CourseUsersTable.js +25 -4
  32. package/lib/esm/shared/CourseUsersTable/RemoveButton.d.ts +10 -0
  33. package/lib/esm/shared/CourseUsersTable/RemoveButton.js +48 -0
  34. package/lib/esm/shared/CourseUsersTable/RequestButton.d.ts +3 -2
  35. package/lib/esm/shared/CourseUsersTable/RequestButton.js +16 -12
  36. package/lib/esm/types/course.d.ts +9 -0
  37. package/lib/umd/react-ui.js +1 -1
  38. package/package.json +8 -8
@@ -254,11 +254,11 @@ function CourseForm(inProps) {
254
254
  /**
255
255
  * Renders root object
256
256
  */
257
- return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: _step === Course_1.SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === Course_1.SCCourseFormStepType.GENERAL && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Object.values(types_1.SCCourseTypologyType).map((option, index) => ((0, jsx_runtime_1.jsx)(material_1.Card, Object.assign({ className: (0, classnames_1.default)(classes.card, { [classes.selected]: option === field.type }, { [classes.disabled]: !courseAdvancedEnabled && option !== types_1.SCCourseTypologyType.SELF }) }, { children: (0, jsx_runtime_1.jsx)(material_1.CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ variant: "subtitle2", className: classes.cardTitle }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }), !courseAdvancedEnabled && option !== types_1.SCCourseTypologyType.SELF && ((0, jsx_runtime_1.jsx)(material_1.Chip, { variant: "outlined", color: "warning", size: "small", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.comingSoon.chip", defaultMessage: "ui.courseForm.comingSoon.chip" }) }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [course && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", className: classes.contrastColor }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), (0, jsx_runtime_1.jsxs)(material_1.FormGroup, Object.assign({ className: (0, classnames_1.default)(classes.form, _step === Course_1.SCCourseFormStepType.CUSTOMIZATION ? classes.stepCustomization : undefined) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: (0, jsx_runtime_1.jsx)(UploadCourseCover_1.default, { isUploading: field.isSubmitting, onChange: handleChangeCover }) })), (0, jsx_runtime_1.jsx)(material_1.TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
257
+ return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: _step === Course_1.SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === Course_1.SCCourseFormStepType.GENERAL && ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: Object.values(types_1.SCCourseTypologyType).map((option, index) => ((0, jsx_runtime_1.jsx)(material_1.Card, Object.assign({ className: (0, classnames_1.default)(classes.card, { [classes.selected]: option === field.type }, { [classes.disabled]: !courseAdvancedEnabled && option !== types_1.SCCourseTypologyType.SELF }) }, { children: (0, jsx_runtime_1.jsx)(material_1.CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ variant: "subtitle2", className: classes.cardTitle }, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }), !courseAdvancedEnabled && option !== types_1.SCCourseTypologyType.SELF && ((0, jsx_runtime_1.jsx)(material_1.Chip, { variant: "outlined", color: "warning", size: "small", label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.comingSoon.chip", defaultMessage: "ui.courseForm.comingSoon.chip" }) }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [course && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", className: classes.contrastColor }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), (0, jsx_runtime_1.jsxs)(material_1.FormGroup, Object.assign({ className: (0, classnames_1.default)(classes.form, _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && course ? classes.stepCustomization : undefined) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: (0, jsx_runtime_1.jsx)(UploadCourseCover_1.default, { isUploading: field.isSubmitting, onChange: handleChangeCover }) })), (0, jsx_runtime_1.jsx)(material_1.TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
258
258
  endAdornment: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: Course_1.COURSE_TITLE_MAX_LENGTH - field.name.length }))
259
259
  }, error: Boolean(field.name.length > Course_1.COURSE_TITLE_MAX_LENGTH) || Boolean(error['nameError']), helperText: field.name.length > Course_1.COURSE_TITLE_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.name.error.maxLength", defaultMessage: "ui.courseForm.name.error.maxLength" })) : error['nameError'] ? (error['nameError']) : null }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
260
260
  endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_a = field.description) === null || _a === void 0 ? void 0 : _a.length) ? Course_1.COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : Course_1.COURSE_DESCRIPTION_MAX_LENGTH })))
261
- }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && (0, jsx_runtime_1.jsx)(Edit_1.default, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))] })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: (0, classnames_1.default)(classes.actions, _step === Course_1.SCCourseFormStepType.CUSTOMIZATION ? classes.stepCustomization : undefined) }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === Course_1.SCCourseFormStepType.GENERAL
261
+ }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > Course_1.COURSE_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && (0, jsx_runtime_1.jsx)(Edit_1.default, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))] })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: (0, classnames_1.default)(classes.actions, _step === Course_1.SCCourseFormStepType.CUSTOMIZATION && course ? classes.stepCustomization : undefined) }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === Course_1.SCCourseFormStepType.GENERAL
262
262
  ? !field.type || Object.keys(error).length !== 0
263
263
  : _step === Course_1.SCCourseFormStepType.CUSTOMIZATION &&
264
264
  (!field.name ||
@@ -67,7 +67,7 @@ function Requests(props) {
67
67
  }
68
68
  }, [state.isLoadingNext, state.initialized, course, dispatch, endpointQueryParams]);
69
69
  // HANDLERS
70
- const handleRemoveUser = (0, react_1.useCallback)((_msg, user) => {
70
+ const handleRejectUser = (0, react_1.useCallback)((_msg, user) => {
71
71
  dispatch({
72
72
  type: widget_1.actionWidgetTypes.SET_RESULTS,
73
73
  payload: { count: state.results.length - 1, results: state.results.filter((result) => result.id !== user.id) }
@@ -84,11 +84,11 @@ function Requests(props) {
84
84
  }
85
85
  }, [scUserContext.user, _init]);
86
86
  (0, react_1.useEffect)(() => {
87
- updatedUsers.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCGroupEventType.REMOVE_MEMBER}`, handleRemoveUser);
87
+ updatedUsers.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.REJECT_MEMBER}`, handleRejectUser);
88
88
  return () => {
89
89
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
90
90
  };
91
- }, [handleRemoveUser]);
91
+ }, [handleRejectUser]);
92
92
  return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.contrastColor }, { 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, handleTabChange: handleTabChange }) })), (0, jsx_runtime_1.jsx)(CourseUsersTable_1.default, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: course_1.SCCourseUsersTableModeType.REQUESTS, emptyStatusTitle: "ui.courseUsersTable.empty.requests.title" })] }));
93
93
  }
94
94
  exports.default = (0, react_1.memo)(Requests);
@@ -35,7 +35,8 @@ const headerCells = [
35
35
  },
36
36
  {
37
37
  id: 'ui.editCourse.tab.users.table.header.latestActivity'
38
- }
38
+ },
39
+ {}
39
40
  ];
40
41
  function Users(props) {
41
42
  // PROPS
@@ -58,6 +59,7 @@ function Users(props) {
58
59
  const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
59
60
  // REFS
60
61
  const updatedUsers = (0, react_1.useRef)(null);
62
+ const removedUsers = (0, react_1.useRef)(null);
61
63
  // CALLBACKS
62
64
  const _init = (0, react_1.useCallback)(() => {
63
65
  if (!state.initialized && !state.isLoadingNext) {
@@ -76,6 +78,12 @@ function Users(props) {
76
78
  const handleAddUser = (0, react_1.useCallback)((_msg, user) => {
77
79
  dispatch({ type: widget_1.actionWidgetTypes.LOAD_PREVIOUS_SUCCESS, payload: { count: state.count + 1, results: [user], initialized: true } });
78
80
  }, [state.count, dispatch]);
81
+ const handleRemoveUser = (0, react_1.useCallback)((_msg, user) => {
82
+ dispatch({
83
+ type: widget_1.actionWidgetTypes.SET_RESULTS,
84
+ payload: { count: state.count - 1, results: state.results.filter((result) => result.id !== user.id), initialized: true }
85
+ });
86
+ }, [state.count, state.results, dispatch]);
79
87
  // EFFECTS
80
88
  (0, react_1.useEffect)(() => {
81
89
  let _t;
@@ -87,11 +95,13 @@ function Users(props) {
87
95
  }
88
96
  }, [scUserContext.user, _init]);
89
97
  (0, react_1.useEffect)(() => {
90
- updatedUsers.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCGroupEventType.ADD_MEMBER}`, handleAddUser);
98
+ updatedUsers.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.ADD_MEMBER}`, handleAddUser);
99
+ removedUsers.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.REMOVE_MEMBER}`, handleRemoveUser);
91
100
  return () => {
92
101
  updatedUsers.current && pubsub_js_1.default.unsubscribe(updatedUsers.current);
102
+ removedUsers.current && pubsub_js_1.default.unsubscribe(removedUsers.current);
93
103
  };
94
- }, [handleAddUser]);
104
+ }, [handleAddUser, handleRemoveUser]);
95
105
  const handleConfirm = (0, react_1.useCallback)((newUsers) => {
96
106
  const data = {
97
107
  joined: newUsers.map((user) => user.id)
@@ -116,7 +126,7 @@ function Users(props) {
116
126
  });
117
127
  });
118
128
  }, [course, dispatch]);
119
- return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.contrastColor }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.users.title", defaultMessage: "ui.editCourse.tab.users.title", values: { usersNumber: state.results.length } }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: [(0, jsx_runtime_1.jsx)(Status_1.default, { course: course, handleTabChange: handleTabChange }), (0, jsx_runtime_1.jsx)(AddUsersButton_1.default, { label: "ui.editCourse.tab.users.addUsersButton.label", endpoint: {
129
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", className: classes.contrastColor }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.users.title", defaultMessage: "ui.editCourse.tab.users.title", values: { usersNumber: state.count } }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.usersStatusWrapper }, { children: [(0, jsx_runtime_1.jsx)(Status_1.default, { course: course, handleTabChange: handleTabChange }), (0, jsx_runtime_1.jsx)(AddUsersButton_1.default, { label: "ui.editCourse.tab.users.addUsersButton.label", endpoint: {
120
130
  url: () => api_services_1.Endpoints.GetCourseSuggestedUsers.url({ id: course.id }),
121
131
  method: api_services_1.Endpoints.GetCourseSuggestedUsers.method
122
132
  }, onConfirm: handleConfirm })] })), (0, jsx_runtime_1.jsx)(CourseUsersTable_1.default, { course: course, state: state, dispatch: dispatch, headerCells: headerCells, mode: course_1.SCCourseUsersTableModeType.EDIT, emptyStatusTitle: "ui.courseUsersTable.empty.users.title", emptyStatusDescription: "ui.courseUsersTable.empty.users.description" })] }));
@@ -0,0 +1,15 @@
1
+ import { SCNotificationCourseActivityType } from '@selfcommunity/types';
2
+ import { NotificationItemProps } from '../../../shared/NotificationItem';
3
+ export interface NotificationCourseProps extends Pick<NotificationItemProps, Exclude<keyof NotificationItemProps, 'image' | 'disableTypography' | 'primary' | 'primaryTypographyProps' | 'secondary' | 'secondaryTypographyProps' | 'actions' | 'footer' | 'isNew'>> {
4
+ /**
5
+ * Notification obj
6
+ * @default null
7
+ */
8
+ notificationObject: SCNotificationCourseActivityType;
9
+ }
10
+ /**
11
+ * This component render the content of the notification of type course
12
+ * @constructor
13
+ * @param props
14
+ */
15
+ export default function CourseNotification(props: NotificationCourseProps): JSX.Element;
@@ -0,0 +1,75 @@
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 react_1 = require("react");
6
+ const styles_1 = require("@mui/material/styles");
7
+ const material_1 = require("@mui/material");
8
+ const react_core_1 = require("@selfcommunity/react-core");
9
+ const react_intl_1 = require("react-intl");
10
+ const DateTimeAgo_1 = tslib_1.__importDefault(require("../../../shared/DateTimeAgo"));
11
+ const classnames_1 = tslib_1.__importDefault(require("classnames"));
12
+ const types_1 = require("../../../types");
13
+ const NotificationItem_1 = tslib_1.__importDefault(require("../../../shared/NotificationItem"));
14
+ const lab_1 = require("@mui/lab");
15
+ const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../../shared/UserDeletedSnackBar"));
16
+ const UserAvatar_1 = tslib_1.__importDefault(require("../../../shared/UserAvatar"));
17
+ const constants_1 = require("../constants");
18
+ const Course_1 = tslib_1.__importDefault(require("../../Course"));
19
+ const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../../shared/HiddenPlaceholder"));
20
+ const classes = {
21
+ root: `${constants_1.PREFIX}-course-root`,
22
+ avatar: `${constants_1.PREFIX}-avatar`,
23
+ actions: `${constants_1.PREFIX}-actions`,
24
+ seeButton: `${constants_1.PREFIX}see-button`,
25
+ activeAt: `${constants_1.PREFIX}-active-at`,
26
+ snippetTime: `${constants_1.PREFIX}-snippet-time`,
27
+ username: `${constants_1.PREFIX}-username`
28
+ };
29
+ const Root = (0, styles_1.styled)(NotificationItem_1.default, {
30
+ name: constants_1.PREFIX,
31
+ slot: 'CourseRoot'
32
+ })(() => ({}));
33
+ /**
34
+ * This component render the content of the notification of type course
35
+ * @constructor
36
+ * @param props
37
+ */
38
+ function CourseNotification(props) {
39
+ // PROPS
40
+ const { notificationObject, id = `n_${props.notificationObject['sid']}`, className, template = types_1.SCNotificationObjectTemplateType.DETAIL } = props, rest = tslib_1.__rest(props, ["notificationObject", "id", "className", "template"]);
41
+ // CONTEXT
42
+ const scRoutingContext = (0, react_core_1.useSCRouting)();
43
+ // STATE
44
+ const [openAlert, setOpenAlert] = (0, react_1.useState)(false);
45
+ // CONST
46
+ const isSnippetTemplate = template === types_1.SCNotificationObjectTemplateType.SNIPPET;
47
+ const isToastTemplate = template === types_1.SCNotificationObjectTemplateType.TOAST;
48
+ if (!notificationObject.course) {
49
+ return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {});
50
+ }
51
+ // RENDER
52
+ if (isSnippetTemplate || isToastTemplate) {
53
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.course.created_by.deleted && {
54
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.course.created_by)
55
+ }), { onClick: notificationObject.course.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.course.created_by.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: notificationObject.course.created_by.username, variant: "circular", src: notificationObject.course.created_by.avatar, classes: { root: classes.avatar } }) })) })), primary: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.course.created_by.deleted && {
56
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.course.created_by)
57
+ }), { onClick: notificationObject.course.created_by.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.course.created_by.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.course.${notificationObject.type}`, defaultMessage: `ui.notification.course.${notificationObject.type}`, values: {
58
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
59
+ // @ts-ignore
60
+ course: notificationObject.course.name,
61
+ link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, notificationObject.course) }, { children: chunks }))
62
+ } })] }), footer: isToastTemplate ? ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [(0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ color: "primary" }, { children: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, notificationObject.course) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.notification.course.button.see", defaultMessage: "ui.notification.course.button.see" }) })) }))] }))) : ((0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.snippetTime })) }, rest)));
63
+ }
64
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className, `${constants_1.PREFIX}-${template}`), template: template, isNew: notificationObject.is_new, disableTypography: true, image: (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.course.created_by.deleted && {
65
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.course.created_by)
66
+ }), { onClick: notificationObject.course.created_by.deleted ? () => setOpenAlert(true) : null }, { children: (0, jsx_runtime_1.jsx)(UserAvatar_1.default, Object.assign({ hide: !notificationObject.course.created_by.community_badge, smaller: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { className: classes.avatar, alt: notificationObject.course.created_by.username, variant: "circular", src: notificationObject.course.created_by.avatar }) })) })), primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({}, (!notificationObject.course.created_by.deleted && {
67
+ to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, notificationObject.course.created_by)
68
+ }), { onClick: notificationObject.course.created_by.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: notificationObject.course.created_by.username })), ' ', (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.notification.course.${notificationObject.type}`, defaultMessage: `ui.notification.course.${notificationObject.type}`, values: {
69
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
70
+ // @ts-ignore
71
+ course: notificationObject.course.name,
72
+ link: (...chunks) => (0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, notificationObject.course) }, { children: chunks }))
73
+ } }), (0, jsx_runtime_1.jsx)(Course_1.default, { course: notificationObject.course, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), template: types_1.SCCourseTemplateType.SNIPPET, elevation: 0 })] }), actions: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [(0, jsx_runtime_1.jsx)(DateTimeAgo_1.default, { date: notificationObject.active_at, className: classes.activeAt }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ color: 'primary', variant: "outlined", size: "small", classes: { root: classes.seeButton }, component: react_core_1.Link, to: scRoutingContext.url(react_core_1.SCRoutes.COURSE_ROUTE_NAME, notificationObject.course) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.notification.course.button.see", defaultMessage: "ui.notification.course.button.see" }) }))] })) }, rest)), openAlert && (0, jsx_runtime_1.jsx)(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
74
+ }
75
+ exports.default = CourseNotification;
@@ -0,0 +1,3 @@
1
+ import CourseNotification, { NotificationCourseProps } from './Course';
2
+ export default CourseNotification;
3
+ export { NotificationCourseProps };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const Course_1 = tslib_1.__importDefault(require("./Course"));
5
+ exports.default = Course_1.default;
@@ -39,6 +39,7 @@ const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../shared/User
39
39
  const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
40
40
  const constants_1 = require("./constants");
41
41
  const Group_1 = tslib_1.__importDefault(require("./Group"));
42
+ const Course_1 = tslib_1.__importDefault(require("./Course"));
42
43
  const messages = (0, react_intl_1.defineMessages)({
43
44
  receivePrivateMessage: {
44
45
  id: 'ui.notification.receivePrivateMessage',
@@ -309,6 +310,13 @@ function UserNotification(inProps) {
309
310
  n.type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
310
311
  return (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n }, i);
311
312
  }
313
+ else if (n.type === types_1.SCNotificationTypologyType.USER_ADDED_TO_COURSE ||
314
+ n.type === types_1.SCNotificationTypologyType.USER_COMMENTED_A_COURSE_LESSON ||
315
+ n.type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_COURSE ||
316
+ n.type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_COURSE ||
317
+ n.type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_COURSE) {
318
+ return (0, jsx_runtime_1.jsx)(Course_1.default, { notificationObject: n }, i);
319
+ }
312
320
  else if (n.type === types_1.SCNotificationTypologyType.LIVE_STREAM_STARTED) {
313
321
  return (0, jsx_runtime_1.jsx)(LiveStream_1.default, { notificationObject: n }, i);
314
322
  }
@@ -37,6 +37,7 @@ const constants_1 = require("./constants");
37
37
  const Group_1 = tslib_1.__importDefault(require("../Notification/Group"));
38
38
  const Event_1 = tslib_1.__importDefault(require("../Notification/Event/Event"));
39
39
  const LiveStream_1 = tslib_1.__importDefault(require("../Notification/LiveStream"));
40
+ const Course_1 = tslib_1.__importDefault(require("../Notification/Course"));
40
41
  const classes = {
41
42
  root: `${constants_1.PREFIX}-root`,
42
43
  notificationsWrap: `${constants_1.PREFIX}-notifications-wrap`,
@@ -270,6 +271,13 @@ function SnippetNotifications(inProps) {
270
271
  n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
271
272
  return (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
272
273
  }
274
+ else if (n.type === types_2.SCNotificationTypologyType.USER_ADDED_TO_COURSE ||
275
+ n.type === types_2.SCNotificationTypologyType.USER_COMMENTED_A_COURSE_LESSON ||
276
+ n.type === types_2.SCNotificationTypologyType.USER_INVITED_TO_JOIN_COURSE ||
277
+ n.type === types_2.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_COURSE ||
278
+ n.type === types_2.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_COURSE) {
279
+ return (0, jsx_runtime_1.jsx)(Course_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
280
+ }
273
281
  else if (type === types_2.SCNotificationTypologyType.LIVE_STREAM_STARTED) {
274
282
  content = (0, jsx_runtime_1.jsx)(LiveStream_1.default, { notificationObject: n, template: types_1.SCNotificationObjectTemplateType.SNIPPET }, i);
275
283
  }
@@ -28,6 +28,7 @@ const Contribution_1 = tslib_1.__importDefault(require("../Notification/Contribu
28
28
  const Group_1 = tslib_1.__importDefault(require("../Notification/Group"));
29
29
  const Event_1 = tslib_1.__importDefault(require("../Notification/Event/Event"));
30
30
  const LiveStream_1 = tslib_1.__importDefault(require("../Notification/LiveStream"));
31
+ const Course_1 = tslib_1.__importDefault(require("../Notification/Course"));
31
32
  const Root = (0, styles_1.styled)(material_1.Box, {
32
33
  name: constants_1.PREFIX,
33
34
  slot: 'Root'
@@ -127,6 +128,13 @@ function UserToastNotifications(inProps) {
127
128
  type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_EVENT) {
128
129
  content = (0, jsx_runtime_1.jsx)(Event_1.default, { notificationObject: n.notification_obj, template: types_2.SCNotificationObjectTemplateType.TOAST });
129
130
  }
131
+ else if (type === types_1.SCNotificationTypologyType.USER_ADDED_TO_COURSE ||
132
+ n.type === types_1.SCNotificationTypologyType.USER_COMMENTED_A_COURSE_LESSON ||
133
+ type === types_1.SCNotificationTypologyType.USER_INVITED_TO_JOIN_COURSE ||
134
+ type === types_1.SCNotificationTypologyType.USER_ACCEPTED_TO_JOIN_COURSE ||
135
+ type === types_1.SCNotificationTypologyType.USER_REQUESTED_TO_JOIN_COURSE) {
136
+ content = (0, jsx_runtime_1.jsx)(Course_1.default, { notificationObject: n.notification_obj, template: types_2.SCNotificationObjectTemplateType.TOAST });
137
+ }
130
138
  else if (type === types_1.SCNotificationTypologyType.LIVE_STREAM_STARTED) {
131
139
  content = (0, jsx_runtime_1.jsx)(LiveStream_1.default, { notificationObject: n.notification_obj, template: types_2.SCNotificationObjectTemplateType.TOAST });
132
140
  }
@@ -29,7 +29,9 @@ export declare enum SCCourseEventType {
29
29
  EDIT = "edit",
30
30
  DELETE = "delete",
31
31
  ADD_MEMBER = "members.add_member",
32
- INVITE_MEMBER = "members.invite_member"
32
+ INVITE_MEMBER = "members.invite_member",
33
+ REMOVE_MEMBER = "members.remove_member",
34
+ REJECT_MEMBER = "members.reject_member"
33
35
  }
34
36
  /**
35
37
  * Category event types
@@ -35,6 +35,8 @@ var SCCourseEventType;
35
35
  SCCourseEventType["DELETE"] = "delete";
36
36
  SCCourseEventType["ADD_MEMBER"] = "members.add_member";
37
37
  SCCourseEventType["INVITE_MEMBER"] = "members.invite_member";
38
+ SCCourseEventType["REMOVE_MEMBER"] = "members.remove_member";
39
+ SCCourseEventType["REJECT_MEMBER"] = "members.reject_member";
38
40
  })(SCCourseEventType = exports.SCCourseEventType || (exports.SCCourseEventType = {}));
39
41
  /**
40
42
  * Category event types
@@ -20,6 +20,9 @@ const ChangeUsersStatus_1 = tslib_1.__importDefault(require("./ChangeUsersStatus
20
20
  const react_core_1 = require("@selfcommunity/react-core");
21
21
  const RequestButton_1 = tslib_1.__importDefault(require("./RequestButton"));
22
22
  const course_1 = require("../../types/course");
23
+ const RemoveButton_1 = tslib_1.__importDefault(require("./RemoveButton"));
24
+ const ConfirmDialog_1 = tslib_1.__importDefault(require("../ConfirmDialog/ConfirmDialog"));
25
+ const course_2 = require("../../types/course");
23
26
  const classes = {
24
27
  root: `${constants_1.PREFIX}-root`,
25
28
  search: `${constants_1.PREFIX}-search`,
@@ -34,7 +37,7 @@ const Root = (0, material_1.styled)(material_1.Box, {
34
37
  overridesResolver: (_props, styles) => styles.root
35
38
  })(() => ({}));
36
39
  function filteredUsers(users, value) {
37
- return users.filter((user) => (user.username || user.real_name).includes(value));
40
+ return users.filter((user) => (user.username || user.real_name).toLowerCase().includes(value.toLowerCase()));
38
41
  }
39
42
  function CourseUsersTable(inProps) {
40
43
  // PROPS
@@ -47,6 +50,9 @@ function CourseUsersTable(inProps) {
47
50
  const [users, setUsers] = (0, react_1.useState)(null);
48
51
  const [tempUsers, setTempUsers] = (0, react_1.useState)(null);
49
52
  const [value, setValue] = (0, react_1.useState)('');
53
+ const [dialog, setDialog] = (0, react_1.useState)(null);
54
+ // REFS
55
+ const ref = (0, react_1.useRef)(null);
50
56
  // CONTEXTS
51
57
  const scUserContext = (0, react_core_1.useSCUser)();
52
58
  // HOOKS
@@ -88,6 +94,19 @@ function CourseUsersTable(inProps) {
88
94
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
89
95
  });
90
96
  }, [state.next, dispatch]);
97
+ const handleOpenDialog = (0, react_1.useCallback)((tab) => {
98
+ setDialog(tab);
99
+ }, [setDialog]);
100
+ const handleConfirm = (0, react_1.useCallback)(() => {
101
+ switch (dialog.tab) {
102
+ case course_2.SCCourseEditTabType.USERS:
103
+ ref.current.handleManageUser(dialog.user);
104
+ break;
105
+ case course_2.SCCourseEditTabType.REQUESTS:
106
+ ref.current.handleManageUser(dialog.request);
107
+ }
108
+ handleOpenDialog(null);
109
+ }, [dialog, handleOpenDialog]);
91
110
  if (!users) {
92
111
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
93
112
  }
@@ -97,11 +116,13 @@ function CourseUsersTable(inProps) {
97
116
  }), InputProps: {
98
117
  startAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "start" }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "search" }) })))
99
118
  }, value: value, onChange: handleChange, disabled: users.length === 0 && value.length === 0, fullWidth: true, className: classes.search }), (0, jsx_runtime_1.jsx)(material_1.TableContainer, { children: (0, jsx_runtime_1.jsxs)(material_1.Table, { children: [(0, jsx_runtime_1.jsx)(material_1.TableHead, { children: (0, jsx_runtime_1.jsx)(material_1.TableRow, { children: headerCells.map((cell, i, array) => {
100
- if (mode !== course_1.SCCourseUsersTableModeType.EDIT && i === array.length - 1) {
119
+ if (i === array.length - 1) {
101
120
  return (0, jsx_runtime_1.jsx)(material_1.TableCell, { width: "14%" }, i);
102
121
  }
103
122
  return ((0, jsx_runtime_1.jsx)(material_1.TableCell, Object.assign({ width: mode === course_1.SCCourseUsersTableModeType.DASHBOARD ? '20%' : '25%' }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: cell.id, defaultMessage: cell.id }) })) }), i));
104
123
  }) }) }), (0, jsx_runtime_1.jsxs)(material_1.TableBody, { children: [users.length > 0 &&
105
- users.map((user, i) => ((0, jsx_runtime_1.jsxs)(material_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.avatarWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: user.username, src: user.avatar }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === course_1.SCCourseUsersTableModeType.DASHBOARD && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.progressWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === course_1.SCCourseUsersTableModeType.EDIT && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: user.join_status !== types_1.SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(ChangeUsersStatus_1.default, { course: course, user: user })) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.joined_at || new Date()).toLocaleDateString() })) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.last_active_at || new Date()).toLocaleDateString() })) }), mode === course_1.SCCourseUsersTableModeType.DASHBOARD && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(SeeProgressButton_1.default, { course: course, user: user }) })), mode === course_1.SCCourseUsersTableModeType.REQUESTS && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RequestButton_1.default, { course: course, user: user }) }))] }, i))), state.isLoadingNext && (0, jsx_runtime_1.jsx)(RowSkeleton_1.default, { editMode: mode !== course_1.SCCourseUsersTableModeType.DASHBOARD })] })] }) }), users.length > 0 && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && (0, jsx_runtime_1.jsx)(EmptyStatus_1.default, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription })] })));
124
+ users.map((user, i) => ((0, jsx_runtime_1.jsxs)(material_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.avatarWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.Avatar, { alt: user.username, src: user.avatar }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: user.username }))] })) }), mode === course_1.SCCourseUsersTableModeType.DASHBOARD && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.progressWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.LinearProgress, { className: classes.progress, variant: "determinate", value: user.user_completion_rate }), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: `${Math.round(user.user_completion_rate)}%` }))] })) })), mode === course_1.SCCourseUsersTableModeType.EDIT && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: user.join_status !== types_1.SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(ChangeUsersStatus_1.default, { course: course, user: user })) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.editCourse.tab.users.table.select.${user.join_status}`, defaultMessage: `ui.editCourse.tab.users.table.select.${user.join_status}` }) }))) })), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.joined_at || new Date()).toLocaleDateString() })) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: new Date(mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.last_active_at || new Date()).toLocaleDateString() })) }), mode === course_1.SCCourseUsersTableModeType.EDIT &&
125
+ user.join_status !== types_1.SCCourseJoinStatusType.CREATOR &&
126
+ scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RemoveButton_1.default, { ref: ref, course: course, user: user, handleOpenDialog: handleOpenDialog }) })) : (mode === course_1.SCCourseUsersTableModeType.EDIT && (0, jsx_runtime_1.jsx)(material_1.TableCell, {})), mode === course_1.SCCourseUsersTableModeType.DASHBOARD && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(SeeProgressButton_1.default, { course: course, user: user }) })), mode === course_1.SCCourseUsersTableModeType.REQUESTS && ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RequestButton_1.default, { ref: ref, course: course, user: user, handleOpenDialog: handleOpenDialog }) }))] }, i))), state.isLoadingNext && (0, jsx_runtime_1.jsx)(RowSkeleton_1.default, { editMode: mode !== course_1.SCCourseUsersTableModeType.DASHBOARD })] })] }) }), users.length > 0 && ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", variant: "outlined", color: "inherit", loading: state.isLoadingNext, disabled: !state.next, className: classes.loadingButton, onClick: handleNext }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.courseUsersTable.btn.label", defaultMessage: "ui.courseUsersTable.btn.label" }) })) }))), users.length === 0 && value.length === 0 && (0, jsx_runtime_1.jsx)(EmptyStatus_1.default, { icon: "face", title: emptyStatusTitle, description: emptyStatusDescription }), dialog && (0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, { open: true, onClose: () => handleOpenDialog(null), onConfirm: handleConfirm })] })));
106
127
  }
107
128
  exports.default = (0, react_1.memo)(CourseUsersTable);
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { SCCourseType, SCUserType } from '@selfcommunity/types';
3
+ import { SCCourseEditManageUserProps, SCCourseEditManageUserRef } from '../../types/course';
4
+ interface RemoveButtonProps {
5
+ course: SCCourseType;
6
+ user: SCUserType;
7
+ handleOpenDialog: (tab: SCCourseEditManageUserProps) => void;
8
+ }
9
+ declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<RemoveButtonProps & import("react").RefAttributes<SCCourseEditManageUserRef>>>;
10
+ export default _default;
@@ -0,0 +1,51 @@
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 lab_1 = require("@mui/lab");
6
+ const material_1 = require("@mui/material");
7
+ const api_services_1 = require("@selfcommunity/api-services");
8
+ const react_1 = require("react");
9
+ const Errors_1 = require("../../constants/Errors");
10
+ const utils_1 = require("@selfcommunity/utils");
11
+ const react_intl_1 = require("react-intl");
12
+ const notistack_1 = require("notistack");
13
+ const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
14
+ const PubSub_1 = require("../../constants/PubSub");
15
+ const course_1 = require("../../types/course");
16
+ function RemoveButton(props, ref) {
17
+ // PROPS
18
+ const { course, user, handleOpenDialog } = props;
19
+ // STATES
20
+ const [loading, setLoading] = (0, react_1.useState)(false);
21
+ // HOOKS
22
+ const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
23
+ // HANDLERS
24
+ const handleSubmit = (0, react_1.useCallback)((userToRemove) => {
25
+ setLoading(true);
26
+ const params = {
27
+ user: userToRemove.id
28
+ };
29
+ api_services_1.CourseService.leaveOrRemoveCourseRequest(course.id, params)
30
+ .then(() => {
31
+ setLoading(false);
32
+ pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.REMOVE_MEMBER}`, userToRemove);
33
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.users.table.snackbar.removed", defaultMessage: "ui.editCourse.tab.users.table.snackbar.removed" }), {
34
+ variant: 'success',
35
+ autoHideDuration: 3000
36
+ });
37
+ })
38
+ .catch((error) => {
39
+ utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
40
+ enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
41
+ variant: 'error',
42
+ autoHideDuration: 3000
43
+ });
44
+ });
45
+ }, [course, setLoading]);
46
+ (0, react_1.useImperativeHandle)(ref, () => ({
47
+ handleManageUser: (userToRemove) => handleSubmit(userToRemove)
48
+ }), [handleSubmit]);
49
+ return ((0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", color: "inherit", variant: "outlined", onClick: () => handleOpenDialog({ tab: course_1.SCCourseEditTabType.USERS, user }), loading: loading, disabled: loading }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) })));
50
+ }
51
+ exports.default = (0, react_1.memo)((0, react_1.forwardRef)(RemoveButton));
@@ -1,9 +1,10 @@
1
1
  /// <reference types="react" />
2
2
  import { SCCourseType, SCUserType } from '@selfcommunity/types';
3
+ import { SCCourseEditManageUserProps, SCCourseEditManageUserRef } from '../../types/course';
3
4
  interface RequestButtonProps {
4
5
  course: SCCourseType;
5
6
  user: SCUserType;
7
+ handleOpenDialog: (tab: SCCourseEditManageUserProps) => void;
6
8
  }
7
- declare function RequestButton(props: RequestButtonProps): JSX.Element;
8
- declare const _default: import("react").MemoExoticComponent<typeof RequestButton>;
9
+ declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<RequestButtonProps & import("react").RefAttributes<SCCourseEditManageUserRef>>>;
9
10
  export default _default;
@@ -13,12 +13,13 @@ const notistack_1 = require("notistack");
13
13
  const constants_1 = require("./constants");
14
14
  const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
15
15
  const PubSub_1 = require("../../constants/PubSub");
16
+ const course_1 = require("../../types/course");
16
17
  const classes = {
17
18
  requestButtonWrapper: `${constants_1.PREFIX}-request-button-wrapper`
18
19
  };
19
- function RequestButton(props) {
20
+ function RequestButton(props, ref) {
20
21
  // PROPS
21
- const { course, user } = props;
22
+ const { course, user, handleOpenDialog } = props;
22
23
  // STATES
23
24
  const [acceptLoading, setAcceptLoading] = (0, react_1.useState)(false);
24
25
  const [rejectLoading, setRejectLoading] = (0, react_1.useState)(false);
@@ -33,8 +34,8 @@ function RequestButton(props) {
33
34
  api_services_1.CourseService.inviteOrAcceptUsersToCourse(course.id, data)
34
35
  .then(() => {
35
36
  setAcceptLoading(false);
36
- pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCGroupEventType.ADD_MEMBER}`, user);
37
- pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCGroupEventType.REMOVE_MEMBER}`, user);
37
+ pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.ADD_MEMBER}`, user);
38
+ pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.REJECT_MEMBER}`, user);
38
39
  enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.requests.table.snackbar.accepted", defaultMessage: "ui.editCourse.tab.requests.table.snackbar.accepted" }), {
39
40
  variant: 'success',
40
41
  autoHideDuration: 3000
@@ -48,15 +49,15 @@ function RequestButton(props) {
48
49
  });
49
50
  });
50
51
  }, [course, user, setAcceptLoading]);
51
- const handleReject = (0, react_1.useCallback)(() => {
52
+ const handleReject = (0, react_1.useCallback)((userToReject) => {
52
53
  setRejectLoading(true);
53
54
  const params = {
54
- user: user.id
55
+ user: userToReject.id
55
56
  };
56
57
  api_services_1.CourseService.leaveOrRemoveCourseRequest(course.id, params)
57
58
  .then(() => {
58
59
  setRejectLoading(false);
59
- pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCGroupEventType.REMOVE_MEMBER}`, user);
60
+ pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.COURSE}.${PubSub_1.SCCourseEventType.REJECT_MEMBER}`, userToReject);
60
61
  enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.editCourse.tab.requests.table.snackbar.rejected", defaultMessage: "ui.editCourse.tab.requests.table.snackbar.rejected" }), {
61
62
  variant: 'success',
62
63
  autoHideDuration: 3000
@@ -69,7 +70,10 @@ function RequestButton(props) {
69
70
  autoHideDuration: 3000
70
71
  });
71
72
  });
72
- }, [course, user, setRejectLoading]);
73
- return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.requestButtonWrapper }, { children: [(0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", color: "primary", variant: "outlined", onClick: handleAccept, loading: acceptLoading, disabled: acceptLoading }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "check" }) })), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", color: "inherit", variant: "outlined", onClick: handleReject, loading: rejectLoading, disabled: rejectLoading }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) }))] })));
73
+ }, [course, setRejectLoading]);
74
+ (0, react_1.useImperativeHandle)(ref, () => ({
75
+ handleManageUser: (userToReject) => handleReject(userToReject)
76
+ }), [handleReject]);
77
+ return ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.requestButtonWrapper }, { children: [(0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", color: "primary", variant: "outlined", onClick: handleAccept, loading: acceptLoading, disabled: acceptLoading }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "check" }) })), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ size: "small", color: "inherit", variant: "outlined", onClick: () => handleOpenDialog({ tab: course_1.SCCourseEditTabType.REQUESTS, request: user }), loading: rejectLoading, disabled: rejectLoading }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) }))] })));
74
78
  }
75
- exports.default = (0, react_1.memo)(RequestButton);
79
+ exports.default = (0, react_1.memo)((0, react_1.forwardRef)(RequestButton));
@@ -1,3 +1,4 @@
1
+ import { SCUserType } from '@selfcommunity/types';
1
2
  export declare enum SCCourseTemplateType {
2
3
  SNIPPET = "snippet",
3
4
  PREVIEW = "preview"
@@ -23,3 +24,11 @@ export declare enum SCCourseUsersTableModeType {
23
24
  EDIT = "edit",
24
25
  REQUESTS = "requests"
25
26
  }
27
+ export interface SCCourseEditManageUserProps {
28
+ tab: SCCourseEditTabType;
29
+ user?: SCUserType;
30
+ request?: SCUserType;
31
+ }
32
+ export interface SCCourseEditManageUserRef {
33
+ handleManageUser: (user: SCUserType) => void;
34
+ }
@@ -1,5 +1,5 @@
1
1
  import { __rest } from "tslib";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { LoadingButton } from '@mui/lab';
4
4
  import { Box, CardActionArea, Card, CardContent, FormGroup, Paper, TextField, Typography, Chip } from '@mui/material';
5
5
  import { styled } from '@mui/material/styles';
@@ -252,11 +252,11 @@ export default function CourseForm(inProps) {
252
252
  /**
253
253
  * Renders root object
254
254
  */
255
- return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(Box, Object.assign({ className: _step === SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === SCCourseFormStepType.GENERAL && (_jsx(_Fragment, { children: Object.values(SCCourseTypologyType).map((option, index) => (_jsx(Card, Object.assign({ className: classNames(classes.card, { [classes.selected]: option === field.type }, { [classes.disabled]: !courseAdvancedEnabled && option !== SCCourseTypologyType.SELF }) }, { children: _jsx(CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: _jsxs(CardContent, { children: [_jsxs(Typography, Object.assign({ variant: "subtitle2", className: classes.cardTitle }, { children: [_jsx(FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }), !courseAdvancedEnabled && option !== SCCourseTypologyType.SELF && (_jsx(Chip, { variant: "outlined", color: "warning", size: "small", label: _jsx(FormattedMessage, { id: "ui.courseForm.comingSoon.chip", defaultMessage: "ui.courseForm.comingSoon.chip" }) }))] })), _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === SCCourseFormStepType.CUSTOMIZATION && (_jsxs(Fragment, { children: [course && (_jsx(Typography, Object.assign({ variant: "h5", className: classes.contrastColor }, { children: _jsx(FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), _jsxs(FormGroup, Object.assign({ className: classNames(classes.form, _step === SCCourseFormStepType.CUSTOMIZATION ? classes.stepCustomization : undefined) }, { children: [_jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadCourseCover, { isUploading: field.isSubmitting, onChange: handleChangeCover }) })), _jsx(TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
255
+ return (_jsxs(Fragment, { children: [_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(Box, Object.assign({ className: _step === SCCourseFormStepType.GENERAL ? classes.stepOne : classes.stepTwo }, { children: [_step === SCCourseFormStepType.GENERAL && (_jsx(Fragment, { children: Object.values(SCCourseTypologyType).map((option, index) => (_jsx(Card, Object.assign({ className: classNames(classes.card, { [classes.selected]: option === field.type }, { [classes.disabled]: !courseAdvancedEnabled && option !== SCCourseTypologyType.SELF }) }, { children: _jsx(CardActionArea, Object.assign({ onClick: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['type']: option }))) }, { children: _jsxs(CardContent, { children: [_jsxs(Typography, Object.assign({ variant: "subtitle2", className: classes.cardTitle }, { children: [_jsx(FormattedMessage, { id: `ui.courseForm.${option}.title`, defaultMessage: `ui.courseForm.${option}.title` }), !courseAdvancedEnabled && option !== SCCourseTypologyType.SELF && (_jsx(Chip, { variant: "outlined", color: "warning", size: "small", label: _jsx(FormattedMessage, { id: "ui.courseForm.comingSoon.chip", defaultMessage: "ui.courseForm.comingSoon.chip" }) }))] })), _jsx(Typography, Object.assign({ variant: "body2" }, { children: _jsx(FormattedMessage, { id: `ui.courseForm.${option}.info`, defaultMessage: `ui.courseForm.${option}.info` }) }))] }) })) }), index))) })), _step === SCCourseFormStepType.CUSTOMIZATION && (_jsxs(Fragment, { children: [course && (_jsx(Typography, Object.assign({ variant: "h5", className: classes.contrastColor }, { children: _jsx(FormattedMessage, { id: "ui.courseForm.edit.title.general", defaultMessage: "ui.courseForm.edit.title.general" }) }))), _jsxs(FormGroup, Object.assign({ className: classNames(classes.form, _step === SCCourseFormStepType.CUSTOMIZATION && course ? classes.stepCustomization : undefined) }, { children: [_jsx(Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: _jsx(UploadCourseCover, { isUploading: field.isSubmitting, onChange: handleChangeCover }) })), _jsx(TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
256
256
  endAdornment: _jsx(Typography, Object.assign({ variant: "body2" }, { children: COURSE_TITLE_MAX_LENGTH - field.name.length }))
257
257
  }, error: Boolean(field.name.length > COURSE_TITLE_MAX_LENGTH) || Boolean(error['nameError']), helperText: field.name.length > COURSE_TITLE_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.name.error.maxLength", defaultMessage: "ui.courseForm.name.error.maxLength" })) : error['nameError'] ? (error['nameError']) : null }), _jsx(TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
258
258
  endAdornment: (_jsx(Typography, Object.assign({ variant: "body2" }, { children: ((_a = field.description) === null || _a === void 0 ? void 0 : _a.length) ? COURSE_DESCRIPTION_MAX_LENGTH - field.description.length : COURSE_DESCRIPTION_MAX_LENGTH })))
259
- }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > COURSE_DESCRIPTION_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), _jsx(CategoryAutocomplete, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && _jsx(CourseEdit, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))] })), _jsx(Box, Object.assign({ className: classNames(classes.actions, _step === SCCourseFormStepType.CUSTOMIZATION ? classes.stepCustomization : undefined) }, { children: _jsx(LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === SCCourseFormStepType.GENERAL
259
+ }, error: Boolean(((_b = field.description) === null || _b === void 0 ? void 0 : _b.length) > COURSE_DESCRIPTION_MAX_LENGTH), helperText: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) > COURSE_DESCRIPTION_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.courseForm.description.error.maxLength", defaultMessage: "ui.courseForm.description.error.maxLength" })) : null }), _jsx(CategoryAutocomplete, { defaultValue: field.categories, TextFieldProps: { label: intl.formatMessage(Object.keys(field.categories).length ? messages.category : messages.categoryEmpty) }, multiple: true, onChange: handleOnChangeCategory }), course && _jsx(CourseEdit, { course: course, onPrivacyChange: (privacy) => setField((prev) => (Object.assign(Object.assign({}, prev), { ['privacy']: privacy }))) })] }))] })), _jsx(Box, Object.assign({ className: classNames(classes.actions, _step === SCCourseFormStepType.CUSTOMIZATION && course ? classes.stepCustomization : undefined) }, { children: _jsx(LoadingButton, Object.assign({ size: "small", loading: field.isSubmitting, disabled: _step === SCCourseFormStepType.GENERAL
260
260
  ? !field.type || Object.keys(error).length !== 0
261
261
  : _step === SCCourseFormStepType.CUSTOMIZATION &&
262
262
  (!field.name ||