UNPKG

@selfcommunity/react-ui

Version:

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

156 lines (155 loc) • 11.5 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import { forwardRef, Fragment, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { Collapse, Icon, IconButton, MenuItem, Stack, Table, TableBody, TableCell, TableRow, Typography } from '@mui/material'; import classNames from 'classnames'; import { PREFIX } from '../constants'; import LessonRow from './LessonRow'; import AddButton from './AddButton'; import MenuRow from '../MenuRow'; import { FormattedMessage, useIntl } from 'react-intl'; import FieldName from './FieldName'; import { Logger } from '@selfcommunity/utils'; import { SCOPE_SC_UI } from '../../../constants/Errors'; import { useSnackbar } from 'notistack'; import LessonReleaseMenu from '../../LessonReleaseMenu'; import { SCCourseLessonTypologyType, SCCourseTypologyType } from '@selfcommunity/types'; import { CourseService, Endpoints } from '@selfcommunity/api-services'; import { ActionLessonType, RowType } from '../types'; import { useIsDisabled } from '../hooks'; const classes = { tableBodyIconWrapper: `${PREFIX}-table-body-icon-wrapper`, tableBodyAccordion: `${PREFIX}-table-body-accordion`, actionsWrapper: `${PREFIX}-actions-wrapper`, tableBodyCollapseWrapper: `${PREFIX}-table-body-collapse-wrapper`, cellWidth: `${PREFIX}-cell-width`, cellAlignRight: `${PREFIX}-cell-align-right`, cellAlignCenter: `${PREFIX}-cell-align-center`, cellPadding: `${PREFIX}-cell-padding` }; function SectionRow(props, ref) { // PROPS const { course, provider, section, isNewRow, handleManageSection, handleOpenDialog } = props; // STATES const [expand, setExpand] = useState(true); const [editMode, setEditMode] = useState(false); const [lessons, setLessons] = useState([]); // REFS const innerRef = useRef(null); // HOOKS const { isDisabled } = useIsDisabled(); const intl = useIntl(); const { enqueueSnackbar } = useSnackbar(); // EFFECTS useEffect(() => { if (section.lessons) { setLessons(section.lessons); } }, [section]); // MEMOS const isNewLocalRow = useMemo(() => { var _a; return lessons.length > ((_a = section.lessons) === null || _a === void 0 ? void 0 : _a.length); }, [lessons, section]); // FUNCTIONS const getLesson = useCallback((id, type = SCCourseLessonTypologyType.LESSON) => { return { id, type, name: intl.formatMessage({ id: 'ui.editCourse.tab.lessons.table.newLesson', defaultMessage: 'ui.editCourse.tab.lessons.table.newLesson' }, { num: id }) }; }, []); const handleExpandAccordion = useCallback(() => setExpand((prev) => !prev), [setExpand]); const handleDragEnd = useCallback((e) => { if (!e.destination || e.destination.index === e.source.index) { return; } const tempLessons = Array.from(section.lessons); const [sourceData] = tempLessons.splice(e.source.index, 1); tempLessons.splice(e.destination.index, 0, sourceData); const tempSection = Object.assign(Object.assign({}, section), { lessons: tempLessons }); const data = { lessons_order: tempLessons.map((tempLesson) => tempLesson.id) }; CourseService.patchCourseSection(course.id, section.id, data) .then(() => { handleManageSection(tempSection, ActionLessonType.UPDATE); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.save", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.save" }), { variant: 'success', autoHideDuration: 3000 }); }) .catch((error) => { Logger.error(SCOPE_SC_UI, error); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), { variant: 'error', autoHideDuration: 3000 }); }); }, [course, section, handleManageSection]); const handleAddTempLesson = useCallback(() => { setLessons((prevLessons) => ((prevLessons === null || prevLessons === void 0 ? void 0 : prevLessons.length) > 0 ? [...prevLessons, getLesson(prevLessons.length + 1)] : [getLesson(1)])); }, [setLessons, getLesson]); const handleAbleEditMode = useCallback(() => setTimeout(() => setEditMode(true)), [setEditMode]); const handleDisableEditMode = useCallback(() => setEditMode(false), [setEditMode]); const handleDeleteSection = useCallback((deleteSection) => { CourseService.deleteCourseSection(course.id, deleteSection.id) .then(() => { var _a; const tempSection = Object.assign(Object.assign({}, deleteSection), { num_lessons: ((_a = deleteSection.lessons) === null || _a === void 0 ? void 0 : _a.length) || 0 }); handleManageSection(tempSection, ActionLessonType.DELETE); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.editCourse.tab.lessons.table.snackbar.delete", defaultMessage: "ui.editCourse.tab.lessons.table.snackbar.delete" }), { variant: 'success', autoHideDuration: 3000 }); }) .catch((error) => { Logger.error(SCOPE_SC_UI, error); enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), { variant: 'error', autoHideDuration: 3000 }); }); }, [course, handleManageSection]); const handleManageLesson = useCallback((lesson, type, newRow) => { switch (type) { case ActionLessonType.ADD: { const tempSection = Object.assign(Object.assign({}, section), { lessons: section.lessons ? [...section.lessons, lesson] : [lesson] }); handleManageSection(tempSection, ActionLessonType.ADD_UPDATE); break; } case ActionLessonType.RENAME: { const tempSection = Object.assign(Object.assign({}, section), { lessons: section.lessons.map((prevLesson) => { if (prevLesson.id === lesson.id) { return Object.assign(Object.assign({}, prevLesson), { name: lesson.name }); } return prevLesson; }) }); handleManageSection(tempSection, ActionLessonType.RENAME_UPDATE); break; } case ActionLessonType.DELETE: { const tempSection = Object.assign(Object.assign({}, section), { lessons: section.lessons.filter((prevLesson) => prevLesson.id !== lesson.id) }); handleManageSection(tempSection, ActionLessonType.DELETE_UPDATE, newRow); break; } case ActionLessonType.UPDATE: { const tempSection = Object.assign(Object.assign({}, section), { lessons: section.lessons.map((prevLesson) => { if (prevLesson.id === lesson.id) { return Object.assign(Object.assign({}, prevLesson), { status: lesson.status }); } return prevLesson; }) }); handleManageSection(tempSection, ActionLessonType.UPDATE_UPDATE); } } }, [section, handleManageSection]); useImperativeHandle(ref, () => ({ handleDeleteSection: (deleteSection) => handleDeleteSection(deleteSection), handleDeleteLesson: (deleteSection, deleteLesson) => innerRef.current.handleDeleteLesson(deleteSection, deleteLesson) }), [handleDeleteSection]); 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: { url: () => isNewRow ? Endpoints.CreateCourseSection.url({ id: course.id }) : Endpoints.PatchCourseSection.url({ id: course.id, section_id: section.id }), method: isNewRow ? Endpoints.CreateCourseSection.method : Endpoints.PatchCourseSection.method }, row: section, isNewRow: isNewRow, handleManageRow: handleManageSection, editMode: editMode, handleDisableEditMode: handleDisableEditMode }) }), course.type !== SCCourseTypologyType.SELF && (_jsx(TableCell, Object.assign({ className: classes.cellAlignCenter }, { children: _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({ row: RowType.SECTION, section }) }, { 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: _jsx(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, handleOpenDialog: () => handleOpenDialog({ row: RowType.LESSON, section, lesson }), ref: innerRef }, i)) }), i))), outerProvider.placeholder] }))) })) }) })) })) })) })] })); } export default memo(forwardRef(SectionRow));