UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

156 lines (155 loc) • 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const material_1 = require("@mui/material"); const react_1 = require("react"); const react_intl_1 = require("react-intl"); const RowSkeleton_1 = tslib_1.__importDefault(require("./RowSkeleton")); const lab_1 = require("@mui/lab"); const types_1 = require("@selfcommunity/types"); const constants_1 = require("./constants"); const EmptyStatus_1 = tslib_1.__importDefault(require("../EmptyStatus")); const SeeProgressButton_1 = tslib_1.__importDefault(require("./SeeProgressButton")); const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton")); const widget_1 = require("../../utils/widget"); const api_services_1 = require("@selfcommunity/api-services"); const utils_1 = require("@selfcommunity/utils"); const Errors_1 = require("../../constants/Errors"); const ChangeUsersStatus_1 = tslib_1.__importDefault(require("./ChangeUsersStatus")); const react_core_1 = require("@selfcommunity/react-core"); const RequestButton_1 = tslib_1.__importDefault(require("./RequestButton")); const course_1 = require("../../types/course"); const RemoveButton_1 = tslib_1.__importDefault(require("./RemoveButton")); const ConfirmDialog_1 = tslib_1.__importDefault(require("../ConfirmDialog/ConfirmDialog")); const course_2 = require("../../types/course"); const classes = { root: `${constants_1.PREFIX}-root`, search: `${constants_1.PREFIX}-search`, endAdornmentWrapper: `${constants_1.PREFIX}-end-adornment-wrapper`, searchButton: `${constants_1.PREFIX}-search-button`, avatarWrapper: `${constants_1.PREFIX}-avatar-wrapper`, progressWrapper: `${constants_1.PREFIX}-progress-wrapper`, progress: `${constants_1.PREFIX}-progress`, loadingButton: `${constants_1.PREFIX}-loading-button` }; const Root = (0, material_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'Root', overridesResolver: (_props, styles) => styles.root })(() => ({})); function CourseUsersTable(inProps) { // PROPS const props = (0, material_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { state, dispatch, course, endpointSearch, endpointQueryParamsSearch = { statuses: JSON.stringify([types_1.SCCourseJoinStatusType.JOINED, types_1.SCCourseJoinStatusType.MANAGER]) }, headerCells, mode, emptyStatusTitle, emptyStatusDescription } = props; // STATES const [users, setUsers] = (0, react_1.useState)(null); const [loadingSearch, setLoadingSearch] = (0, react_1.useState)(false); const [value, setValue] = (0, react_1.useState)(''); const [dialog, setDialog] = (0, react_1.useState)(null); // REFS const buttonRef = (0, react_1.useRef)(null); const inputRef = (0, react_1.useRef)(null); // CONTEXTS const scUserContext = (0, react_core_1.useSCUser)(); // INTL const intl = (0, react_intl_1.useIntl)(); // HANDLERS const handleNext = (0, react_1.useCallback)(() => { dispatch({ type: widget_1.actionWidgetTypes.LOADING_NEXT }); api_services_1.http .request({ url: state.next, method: 'GET' }) .then((res) => { dispatch({ type: widget_1.actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: res.data }); }) .catch((error) => { dispatch({ type: widget_1.actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } }); utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); }, [state.next, dispatch]); const handleOpenDialog = (0, react_1.useCallback)((tab) => { setDialog(tab); }, [setDialog]); const handleConfirm = (0, react_1.useCallback)(() => { switch (dialog.tab) { case course_2.SCCourseEditTabType.USERS: buttonRef.current.handleManageUser(dialog.user); break; case course_2.SCCourseEditTabType.REQUESTS: buttonRef.current.handleManageUser(dialog.request); } handleOpenDialog(null); }, [dialog, handleOpenDialog]); const handleSearchClear = (0, react_1.useCallback)(() => { setUsers(state.results); setValue(''); }, [setValue, setUsers, state.results]); const handleChange = (0, react_1.useCallback)((e) => { const _value = e.target.value; if (_value.length === 0) { handleSearchClear(); } else { setValue(_value); } }, [setValue, handleSearchClear]); const handleSearchStart = (0, react_1.useCallback)(() => { setLoadingSearch(true); api_services_1.http .request({ url: endpointSearch.url(), method: endpointSearch.method, params: Object.assign(Object.assign({}, endpointQueryParamsSearch), { search: value }) }) .then((res) => { setUsers(res.data.results); setLoadingSearch(false); }) .catch((error) => { dispatch({ type: widget_1.actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } }); utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); }, [value, endpointSearch, setUsers, setLoadingSearch, dispatch]); const handleKeyUp = (0, react_1.useCallback)((e) => { if (value.length > 0 && e.key === 'Enter') { handleSearchStart(); } }, [value, handleSearchStart]); // EFFECTS (0, react_1.useEffect)(() => { setUsers(state.results); }, [state.results, setUsers]); (0, react_1.useEffect)(() => { var _a; (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('keyup', handleKeyUp); return () => { var _a; (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('keyup', handleKeyUp); }; }, [handleKeyUp]); if (!users) { return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {}); } return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: classes.root }, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { ref: inputRef, placeholder: intl.formatMessage({ id: 'ui.courseUsersTable.searchBar.placeholder', defaultMessage: 'ui.courseUsersTable.searchBar.placeholder' }), InputProps: { startAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "start" }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "search" }) }))), endAdornment: value.length > 0 ? ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.endAdornmentWrapper }, { children: [(0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "start" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ color: "inherit", onClick: handleSearchClear }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) })) })), (0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ color: "primary", variant: "contained", onClick: handleSearchStart, loading: loadingSearch, disabled: loadingSearch, className: classes.searchButton }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "search" }) })) }))] }))) : undefined }, 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) => { if (i === array.length - 1) { return (0, jsx_runtime_1.jsx)(material_1.TableCell, { width: "14%" }, i); } 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)); }) }) }), (0, jsx_runtime_1.jsxs)(material_1.TableBody, { children: [users.length > 0 && 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: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedDate, { value: mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.joined_at || new Date() }) })) }), (0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedDate, { value: mode === course_1.SCCourseUsersTableModeType.REQUESTS ? user.date_joined : user.last_active_at || new Date() }) })) }), mode === course_1.SCCourseUsersTableModeType.EDIT && user.join_status !== types_1.SCCourseJoinStatusType.CREATOR && scUserContext.user.id !== user.id ? ((0, jsx_runtime_1.jsx)(material_1.TableCell, { children: (0, jsx_runtime_1.jsx)(RemoveButton_1.default, { ref: buttonRef, 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: buttonRef, 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: value.length > 0 || !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 && ((0, jsx_runtime_1.jsx)(EmptyStatus_1.default, { icon: "face", title: value.length > 0 ? 'ui.courseUsersTable.empty.search.title' : emptyStatusTitle, description: value.length > 0 ? 'ui.courseUsersTable.empty.search.description' : emptyStatusDescription })), dialog && (0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, { open: true, onClose: () => handleOpenDialog(null), onConfirm: handleConfirm })] }))); } exports.default = (0, react_1.memo)(CourseUsersTable);