UNPKG

@selfcommunity/react-ui

Version:

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

740 lines (739 loc) • 46.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const styles_1 = require("@mui/material/styles"); const react_intl_1 = require("react-intl"); const Popper_1 = tslib_1.__importDefault(require("@mui/material/Popper")); const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon")); const CentralProgress_1 = tslib_1.__importDefault(require("../CentralProgress")); const Errors_1 = require("../../constants/Errors"); const utils_1 = require("@selfcommunity/utils"); const notistack_1 = require("notistack"); const contribution_1 = require("../../utils/contribution"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const ConfirmDialog_1 = tslib_1.__importDefault(require("../ConfirmDialog/ConfirmDialog")); const material_1 = require("@mui/material"); const Flagging_1 = require("../../constants/Flagging"); const api_services_1 = require("@selfcommunity/api-services"); const react_core_1 = require("@selfcommunity/react-core"); const types_1 = require("@selfcommunity/types"); const ContributionsActionsMenu_1 = require("../../constants/ContributionsActionsMenu"); const PREFIX = 'SCContributionActionsMenu'; const classes = { root: `${PREFIX}-root`, button: `${PREFIX}-button`, popperRoot: `${PREFIX}-popper-root`, paper: `${PREFIX}-paper`, item: `${PREFIX}-item`, itemText: `${PREFIX}-item-text`, subItem: `${PREFIX}-sub-item`, subItemText: `${PREFIX}-sub-item-text`, footerSubItems: `${PREFIX}-footer-sub-items`, selectedIcon: `${PREFIX}-selected-icon`, sectionBadge: `${PREFIX}-section-badge`, sectionWithSelectionIcon: `${PREFIX}-section-with-selection-icon`, visibilityIcons: `${PREFIX}-visibility-icons` }; const PopperRoot = (0, styles_1.styled)(Popper_1.default, { name: PREFIX, slot: 'Root', overridesResolver: (props, styles) => styles.popperRoot })(() => ({})); const Root = (0, styles_1.styled)(material_1.Box, { name: PREFIX, slot: 'Root', overridesResolver: (props, styles) => styles.root })(() => ({})); const messages = (0, react_intl_1.defineMessages)({ title: { id: 'ui.contributionActionMenu.title', defaultMessage: 'ui.contributionActionMenu.title' }, spam: { id: 'ui.contributionActionMenu.spam', defaultMessage: 'ui.contributionActionMenu.spam' }, aggressive: { id: 'ui.contributionActionMenu.aggressive', defaultMessage: 'ui.contributionActionMenu.aggressive' }, vulgar: { id: 'ui.contributionActionMenu.vulgar', defaultMessage: 'ui.contributionActionMenu.vulgar' }, poorContent: { id: 'ui.contributionActionMenu.poorContent', defaultMessage: 'ui.contributionActionMenu.poorContent' }, offtopic: { id: 'ui.contributionActionMenu.offtopic', defaultMessage: 'ui.contributionActionMenu.offtopic' }, footer: { id: 'ui.contributionActionMenu.footer', defaultMessage: 'ui.contributionActionMenu.footer' } }); function ContributionActionsMenu(props) { // PROPS const { className, feedObjectId, feedObject, feedObjectType = types_1.SCContributionType.POST, commentObjectId, commentObject, onFlagContribution, onEditContribution, onHideContribution, onDeleteContribution, onRestoreContribution, onSuspendNotificationContribution, onSuspendNotificationEvent, PopperProps = {} } = props, rest = tslib_1.__rest(props, ["className", "feedObjectId", "feedObject", "feedObjectType", "commentObjectId", "commentObject", "onFlagContribution", "onEditContribution", "onHideContribution", "onDeleteContribution", "onRestoreContribution", "onSuspendNotificationContribution", "onSuspendNotificationEvent", "PopperProps"]); // INTL const intl = (0, react_intl_1.useIntl)(); // CONTEXT const theme = (0, material_1.useTheme)(); const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md')); const scContext = (0, react_1.useContext)(react_core_1.SCContext); const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext); const scUserId = scUserContext.user ? scUserContext.user.id : null; const scRoutingContext = (0, react_core_1.useSCRouting)(); const { enqueueSnackbar } = (0, notistack_1.useSnackbar)(); // CONTRIBUTION STATE const { obj: feedObj, setObj: setFeedObj } = (0, react_core_1.useSCFetchFeedObject)({ id: feedObjectId, feedObject, feedObjectType }); const { obj: commentObj, setObj: setCommentObj } = (0, react_core_1.useSCFetchCommentObject)({ id: commentObjectId, commentObject }); // GENERAL POPPER STATE const [open, setOpen] = (0, react_1.useState)(false); const [openSection, setOpenSection] = (0, react_1.useState)(null); const [isLoading, setIsLoading] = (0, react_1.useState)(false); // MODERATION FLAGS STATE const [flagType, setFlagType] = (0, react_1.useState)(null); const [isFlagging, setIsFlagging] = (0, react_1.useState)(false); // MODERATION HIDE STATE const [hideType, setHideType] = (0, react_1.useState)(null); const [hideFlagType, setHideFlagType] = (0, react_1.useState)(null); // MODERATION DELETE STATE const [deleteType, setDeleteType] = (0, react_1.useState)(null); const [deleteFlagType, setDeleteFlagType] = (0, react_1.useState)(null); // CONFIRM ACTION DIALOG STATE const [openConfirmDialog, setOpenConfirmDialog] = (0, react_1.useState)(false); const [currentAction, setCurrentAction] = (0, react_1.useState)(null); const [currentActionLoading, setCurrentActionLoading] = (0, react_1.useState)(null); // CONST const contributionObj = commentObj ? commentObj : feedObj; let popperRef = (0, react_1.useRef)(null); /** * Intial extra sections to render, in addition to the GENERAL_SECTION * @return {array} */ const getExtraSections = (0, react_1.useMemo)(() => () => { let _extra = []; if (scUserContext.user && Boolean(contributionObj) && scUserId !== contributionObj.author.id && !contributionObj.deleted && !contributionObj.collapsed) { _extra.push(ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION); } // Enable when backend is ready if (react_core_1.UserUtils.isStaff(scUserContext.user)) { // admin or moderator _extra.push(ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION); _extra.push(ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION); } return _extra; }, [contributionObj, scUserId]); /** * Extra sections to render in the popup */ const extraSections = getExtraSections(); /** * Define renders for extra section */ const extraSectionsRenders = { [ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION]: renderFlagContributionSection, [ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION]: renderHideContributionSection, [ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION]: renderDeleteContributionSection }; /** * Handles open popup */ function handleOpen() { if (scUserContext.user) { setIsLoading(true); Promise.all([fetchFlagStatus(), fetchModerationStatus()]).then(() => { setIsLoading(false); }); setOpen(true); } else { scContext.settings.handleAnonymousAction(); } } /** * Closes popup */ function handleClose() { if (popperRef.current && popperRef.current.contains(event.target)) { return; } setOpen(false); if (rest.onClose) { rest.onClose(); } } /** * Performs notification suspension */ const performSuspendNotification = (0, react_1.useMemo)(() => () => { return api_services_1.http .request({ url: api_services_1.Endpoints.UserSuspendContributionNotification.url({ type: contributionObj.type, id: contributionObj.id }), method: api_services_1.Endpoints.UserSuspendContributionNotification.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Performs notification suspension of event embedded */ const performSuspendNotificationEvent = (0, react_1.useMemo)(() => () => { const _endpoint = contributionObj.event.show_on_feed ? api_services_1.Endpoints.HideEvent : api_services_1.Endpoints.ShowEvent; return api_services_1.http .request({ url: _endpoint.url({ id: contributionObj.event.id }), method: _endpoint.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Handles stop notification for contributionObj */ function handleSuspendContentNotification() { setCurrentActionLoading(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION); performSuspendNotification() .then(() => { const _feedObj = Object.assign({}, feedObj, { suspended: !feedObj.suspended }); setFeedObj(_feedObj); onSuspendNotificationContribution && onSuspendNotificationContribution(_feedObj); setCurrentActionLoading(null); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); setCurrentAction(null); setCurrentActionLoading(null); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionError", defaultMessage: "ui.contributionActionMenu.actionError" }), { variant: 'error', autoHideDuration: 3000 }); }); } /** * Handles stop notification for event embedded in contributionObj */ function handleSuspendEventNotification() { setCurrentActionLoading(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT); performSuspendNotificationEvent() .then(() => { const _eventObj = Object.assign({}, feedObj.event, { show_on_feed: !feedObj.event.show_on_feed }); const _feedObj = Object.assign({}, feedObj, { event: _eventObj }); setFeedObj(_feedObj); onSuspendNotificationEvent && onSuspendNotificationEvent(_feedObj); setCurrentActionLoading(null); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); setCurrentAction(null); setCurrentActionLoading(null); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionError", defaultMessage: "ui.contributionActionMenu.actionError" }), { variant: 'error', autoHideDuration: 3000 }); }); } /** * Get Status Flag */ const performFetchFlagStatus = (0, react_1.useMemo)(() => () => { return api_services_1.http .request({ url: api_services_1.Endpoints.FlagStatus.url({ type: contributionObj.type, id: contributionObj.id }), method: api_services_1.Endpoints.FlagStatus.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Perform Flag */ const performFlag = (0, react_1.useMemo)(() => (type) => { return api_services_1.http .request({ url: api_services_1.Endpoints.Flag.url({ type: contributionObj.type, id: contributionObj.id }), method: api_services_1.Endpoints.Flag.method, data: { flag_type: type } }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Get Status Flag */ const performFetchModerationStatus = (0, react_1.useMemo)(() => () => { return api_services_1.http .request({ url: api_services_1.Endpoints.ModerateContributionStatus.url({ contribution_type: contributionObj.type, id: contributionObj.id }), method: api_services_1.Endpoints.ModerateContributionStatus.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Perform delete contribution */ const performDeleteContribution = (0, react_1.useMemo)(() => () => { const contributionType = contributionObj.type; return api_services_1.http .request({ url: contributionType === types_1.SCContributionType.COMMENT ? api_services_1.Endpoints.DeleteComment.url({ id: contributionObj.id }) : api_services_1.Endpoints.DeleteFeedObject.url({ type: contributionType, id: contributionObj.id }), method: contributionType === types_1.SCContributionType.COMMENT ? api_services_1.Endpoints.DeleteComment.method : api_services_1.Endpoints.DeleteFeedObject.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Perform restore contribution */ const performRestoreContribution = (0, react_1.useMemo)(() => () => { const contributionType = contributionObj.type; return api_services_1.http .request({ url: contributionType === types_1.SCContributionType.COMMENT ? api_services_1.Endpoints.RestoreComment.url({ id: contributionObj.id }) : api_services_1.Endpoints.RestoreFeedObject.url({ type: contributionType, id: contributionObj.id }), method: contributionType === types_1.SCContributionType.COMMENT ? api_services_1.Endpoints.RestoreComment.method : api_services_1.Endpoints.RestoreFeedObject.method }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Fetch initial flag status */ function fetchFlagStatus() { if (contributionObj && extraSections.includes(ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION)) { return performFetchFlagStatus() .then((data) => { // It could also be spam (=0) if (data['flag_type'] !== undefined && data['flag_type'] !== null) { setFlagType(data['flag_type']); } }) .catch((error) => { console.dir(error); utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); } return Promise.resolve(); } /** * Fetch initial moderation status */ function fetchModerationStatus() { if (contributionObj && (extraSections.includes(ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION) || extraSections.includes(ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION))) { return performFetchModerationStatus() .then((data) => { // It could also be spam (=0) if (data['flag_type'] !== undefined && data['flag_type'] !== null) { if (data.status === Flagging_1.MODERATION_CONTRIBUTION_STATE_DELETED) { setDeleteType(data['flag_type']); } else if (data.status === Flagging_1.MODERATION_CONTRIBUTION_STATE_HIDDEN) { setHideType(data['flag_type']); } } }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); } return Promise.resolve(); } /** * Perform contribute flagging by authenticated user * If the user authenticated is blocked, deny this action * @param type */ function handleFlagContribution(type) { if (react_core_1.UserUtils.isBlocked(scUserContext.user)) { enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.userBlocked", defaultMessage: "ui.common.userBlocked" }), { variant: 'warning', autoHideDuration: 3000 }); } else if (contributionObj && !isLoading && !isFlagging && type !== 'undefined') { setIsFlagging(true); performFlag(type) .then(() => { setFlagType(flagType === type ? null : type); setIsFlagging(false); onFlagContribution && onFlagContribution(contributionObj, type, flagType !== type); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionError", defaultMessage: "ui.contributionActionMenu.actionError" }), { variant: 'error', autoHideDuration: 3000 }); }); } } /** * Perform moderation */ const performModerationContribution = (0, react_1.useMemo)(() => (action, type) => { return api_services_1.http .request({ url: api_services_1.Endpoints.ModerateContribution.url({ id: contributionObj.id }), method: api_services_1.Endpoints.ModerateContribution.method, data: Object.assign(Object.assign({ contribution_type: contributionObj.type }, (type !== null ? { moderation_type: type } : {})), { action: action }) }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [contributionObj]); /** * Perform contribute moderation hide * @param type */ function handleHideContribution(type) { setHideFlagType(type); handleAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN); } /** * Perform contribute moderation delete * @param type */ function handleDeleteContribution(type) { setDeleteFlagType(type); handleAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED); } /** * handle action */ function handleAction(action) { if (react_core_1.UserUtils.isBlocked(scUserContext.user) && [ContributionsActionsMenu_1.EDIT_CONTRIBUTION, ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN, ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED].includes(action)) { // if user is blocked, deny edit and moderate enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.userBlocked", defaultMessage: "ui.common.userBlocked" }), { variant: 'warning', autoHideDuration: 3000 }); return; } if (action === ContributionsActionsMenu_1.GET_CONTRIBUTION_PERMALINK) { (0, utils_1.copyTextToClipboard)(`${location.protocol}//${location.host}${scRoutingContext.url((0, contribution_1.getContributionRouteName)(contributionObj), (0, contribution_1.getRouteData)(contributionObj))}`).then(() => { setOpen(false); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.permanentLinkCopied", defaultMessage: "ui.common.permanentLinkCopied" }), { variant: 'success', autoHideDuration: 3000 }); }); handleClose(); } else if (action === ContributionsActionsMenu_1.EDIT_CONTRIBUTION) { onEditContribution && onEditContribution(contributionObj); handleClose(); } else if (action === ContributionsActionsMenu_1.DELETE_CONTRIBUTION) { setCurrentAction(ContributionsActionsMenu_1.DELETE_CONTRIBUTION); setOpenConfirmDialog(true); handleClose(); } else if (action === ContributionsActionsMenu_1.RESTORE_CONTRIBUTION) { setCurrentAction(ContributionsActionsMenu_1.RESTORE_CONTRIBUTION); setOpenConfirmDialog(true); handleClose(); } else if (action === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION) { setCurrentAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION); handleSuspendContentNotification(); } else if (action === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT) { setCurrentAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT); handleSuspendEventNotification(); } else if (action === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN) { setCurrentAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN); setOpenConfirmDialog(true); handleClose(); } else if (action === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED) { setCurrentAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED); setOpenConfirmDialog(true); handleClose(); } } /** * Perform additional operations at the end of single action */ function performPostConfirmAction(success) { if (success) { if ([ContributionsActionsMenu_1.DELETE_CONTRIBUTION, ContributionsActionsMenu_1.RESTORE_CONTRIBUTION].includes(currentAction)) { commentObj ? setCommentObj(Object.assign(Object.assign({}, commentObj), { deleted: currentAction === ContributionsActionsMenu_1.DELETE_CONTRIBUTION })) : setFeedObj(Object.assign(Object.assign({}, feedObj), { deleted: currentAction === ContributionsActionsMenu_1.DELETE_CONTRIBUTION })); } else if (currentAction === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN) { commentObj ? setCommentObj(Object.assign(Object.assign({}, commentObj), { collapsed: !commentObj.collapsed })) : setFeedObj(Object.assign(Object.assign({}, feedObj), { collapsed: !feedObj.collapsed })); } else if (currentAction === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED) { commentObj ? setCommentObj(Object.assign(Object.assign({}, commentObj), { deleted: !commentObj.deleted })) : setFeedObj(Object.assign(Object.assign({}, feedObj), { deleted: !feedObj.deleted })); } setCurrentActionLoading(null); setCurrentAction(null); setOpenConfirmDialog(false); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionSuccess", defaultMessage: "ui.contributionActionMenu.actionSuccess" }), { variant: 'success', autoHideDuration: 3000 }); } else { setCurrentActionLoading(null); enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionError", defaultMessage: "ui.contributionActionMenu.actionError" }), { variant: 'error', autoHideDuration: 3000 }); } } /** * Delete a contribution */ function handleConfirmedAction() { if (contributionObj && !isLoading && !currentActionLoading) { if (currentAction === ContributionsActionsMenu_1.DELETE_CONTRIBUTION) { setCurrentActionLoading(ContributionsActionsMenu_1.DELETE_CONTRIBUTION); performDeleteContribution() .then(() => { const _contributionObj = Object.assign({}, contributionObj, { deleted: true }); onDeleteContribution && onDeleteContribution(_contributionObj); performPostConfirmAction(true); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); performPostConfirmAction(false); }); } else if (currentAction === ContributionsActionsMenu_1.RESTORE_CONTRIBUTION) { setCurrentActionLoading(ContributionsActionsMenu_1.RESTORE_CONTRIBUTION); performRestoreContribution() .then(() => { const _contributionObj = Object.assign({}, contributionObj, { deleted: false }); onRestoreContribution && onRestoreContribution(_contributionObj); performPostConfirmAction(true); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); performPostConfirmAction(false); }); } else if (currentAction === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN) { setCurrentActionLoading(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN); performModerationContribution(Flagging_1.MODERATION_TYPE_ACTION_HIDE, hideFlagType) .then(() => { const _contributionObj = Object.assign({}, contributionObj, { collapsed: !contributionObj.collapsed }); setHideType(hideType === hideFlagType ? null : hideFlagType); setHideFlagType(null); onHideContribution && onHideContribution(_contributionObj); performPostConfirmAction(true); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); performPostConfirmAction(false); }); } else if (currentAction === ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED) { setCurrentActionLoading(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED); performModerationContribution(Flagging_1.MODERATION_TYPE_ACTION_DELETE, deleteFlagType) .then(() => { const _contributionObj = Object.assign({}, contributionObj, { deleted: !contributionObj.deleted }); setDeleteType(deleteType === deleteFlagType ? null : deleteFlagType); setDeleteFlagType(null); onDeleteContribution && onDeleteContribution(_contributionObj); performPostConfirmAction(true); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); performPostConfirmAction(false); }); } } } /** * Returns flag label based on type * @param flagType * @return {*} */ function getReportName(flagType) { let name; switch (flagType) { case Flagging_1.REPORT_SPAM: name = intl.formatMessage(messages.spam); break; case Flagging_1.REPORT_AGGRESSIVE: name = intl.formatMessage(messages.aggressive); break; case Flagging_1.REPORT_VULGAR: name = intl.formatMessage(messages.vulgar); break; case Flagging_1.REPORT_POORCONTENT: name = intl.formatMessage(messages.poorContent); break; case Flagging_1.REPORT_OFFTOPIC: name = intl.formatMessage(messages.offtopic); break; default: break; } return name; } /** * action * @param sectionId */ function handleOpenSection(sectionId) { if (sectionId) { if (sectionId === openSection) { setOpenSection(null); } else { setOpenSection(sectionId); } } else { setOpenSection(null); } } /** * Renders single flag item * @return {[{REPORTS}]} */ function renderReports(section) { const handlerFunc = section === ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION ? handleFlagContribution : section === ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION ? handleHideContribution : handleDeleteContribution; let value = section === ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION ? flagType : section === ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION ? hideType : deleteType; return Flagging_1.REPORTS.map((report, index) => { return ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, Object.assign({ classes: { root: classes.selectedIcon } }, { children: value === report && (0, jsx_runtime_1.jsx)(Icon_1.default, Object.assign({ color: "secondary" }, { children: "check" })) })), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: getReportName(report), onClick: () => handlerFunc(report), classes: { root: classes.subItemText } })] }), `${section}_${index}`)); }); } /** * Renders section flags actions */ function renderFlagContributionSection() { const open = openSection === ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION; return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: !contributionObj.deleted && !contributionObj.collapsed && ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging, onClick: () => handleOpenSection(ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: flagType !== undefined && flagType !== null ? ((0, jsx_runtime_1.jsx)(material_1.Badge, Object.assign({ classes: { badge: classes.sectionBadge }, badgeContent: (0, jsx_runtime_1.jsx)(Icon_1.default, Object.assign({ className: classes.sectionWithSelectionIcon }, { children: "check" })), color: "primary" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "outlined_flag" }) }))) : ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "outlined_flag" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.flagContributionWithMotivation", defaultMessage: "ui.contributionActionMenu.flagContributionWithMotivation" }) }), open ? (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_less" }) : (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" })] })), (0, jsx_runtime_1.jsxs)(material_1.Collapse, Object.assign({ in: open, timeout: "auto", unmountOnExit: true }, { children: [renderReports(ContributionsActionsMenu_1.FLAG_CONTRIBUTION_SECTION), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: 'caption', component: "div", className: classes.footerSubItems }, { children: intl.formatMessage(messages.footer) }))] }))] })) })); } /** * Renders section hide actions */ function renderHideContributionSection() { const open = openSection === ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION; return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: !contributionObj.deleted && ((0, jsx_runtime_1.jsx)(material_1.Box, { children: hideType !== undefined && hideType !== null ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: Boolean(currentAction), onClick: () => handleAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_HIDDEN) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "restore" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.restoreFromHidden", defaultMessage: "ui.contributionActionMenu.restoreFromHidden" }), ' ', "(", getReportName(hideType), ")"] }) })] })) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: Boolean(currentAction), onClick: () => handleOpenSection(ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "hide_image" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.hideContributionWithMotivation", defaultMessage: "ui.contributionActionMenu.hideContributionWithMotivation" }) }), open ? (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_less" }) : (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" })] })), (0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: open, timeout: "auto", unmountOnExit: true }, { children: renderReports(ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION) }))] })) })) }, ContributionsActionsMenu_1.HIDE_CONTRIBUTION_SECTION)); } /** * Renders section hidden actions */ function renderDeleteContributionSection() { const open = openSection === ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION; return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: !contributionObj.collapsed && !(contributionObj.deleted && !deleteType) && ((0, jsx_runtime_1.jsx)(material_1.Box, { children: deleteType !== undefined && deleteType !== null ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: Boolean(currentAction), onClick: () => handleAction(ContributionsActionsMenu_1.MODERATE_CONTRIBUTION_DELETED) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "restore_from_trash" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.restoreFromDeleted", defaultMessage: "ui.contributionActionMenu.restoreFromDeleted" }), ' ', "(", getReportName(deleteType), ")"] }) })] })) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: Boolean(currentAction), onClick: () => handleOpenSection(ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "delete" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.deleteContributionWithMotivation", defaultMessage: "ui.contributionActionMenu.deleteContributionWithMotivation" }) }), open ? (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_less" }) : (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" })] })), (0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: open, timeout: "auto", unmountOnExit: true }, { children: renderReports(ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION) }))] })) })) }, ContributionsActionsMenu_1.DELETE_CONTRIBUTION_SECTION)); } /** * Can authenticated user modify the contribution */ function canModifyContribution() { return scUserContext.user && scUserContext.user.id === contributionObj.author.id && !contributionObj.deleted; } /** * Can authenticated user delete the contribution */ function canDeleteContribution() { return scUserContext.user && scUserContext.user.id === contributionObj.author.id && !deleteType; } /** * Can authenticated user suspend notification for the contribution */ function canSuspendNotificationContribution() { return (scUserContext.user && scUserContext.user.id !== contributionObj.author.id && contributionObj && contributionObj.type !== types_1.SCContributionType.COMMENT); } /** * Can authenticated user suspend notification for the event related to the contribution */ function canSuspendNotificationEvent() { return (scUserContext.user && scUserContext.user.id !== contributionObj.author.id && contributionObj && contributionObj.type !== types_1.SCContributionType.COMMENT && Boolean(contributionObj.event) && Boolean(contributionObj.event.active)); } /** * Renders section general */ function renderGeneralSection() { return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "link" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.permanentLink", defaultMessage: "ui.contributionActionMenu.permanentLink" }), onClick: () => handleAction(ContributionsActionsMenu_1.GET_CONTRIBUTION_PERMALINK), classes: { root: classes.itemText } })] })), canModifyContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "edit" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.editContribution", defaultMessage: "ui.contributionActionMenu.editContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.EDIT_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canDeleteContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.DELETE_CONTRIBUTION || currentActionLoading === ContributionsActionsMenu_1.RESTORE_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "delete" })) }), contributionObj.deleted ? ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.restoreContribution", defaultMessage: "ui.contributionActionMenu.restoreContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.RESTORE_CONTRIBUTION), classes: { root: classes.itemText } })) : ((0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.deleteContribution", defaultMessage: "ui.contributionActionMenu.deleteContribution" }), onClick: () => handleAction(ContributionsActionsMenu_1.DELETE_CONTRIBUTION), classes: { root: classes.itemText } }))] }))), canSuspendNotificationContribution() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: contributionObj['suspended'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_CONTRIBUTION), classes: { root: classes.itemText } })] }))), canSuspendNotificationEvent() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: isFlagging }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: currentActionLoading === ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT ? ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 20 })) : contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "notifications_active" })) : ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "notifications_off" })) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: !contributionObj.event['show_on_feed'] ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.enableNotificationContribution", defaultMessage: "ui.contributionActionMenu.enableNotificationContribution" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.suspendNotificationContribution", defaultMessage: "ui.contributionActionMenu.suspendNotificationContribution" })), onClick: () => handleAction(ContributionsActionsMenu_1.SUSPEND_NOTIFICATION_EVENT), classes: { root: classes.itemText } })] })))] }, ContributionsActionsMenu_1.GENERAL_SECTION)); } /** * Renders contribution menu content */ function renderContent() { return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: isLoading || (!feedObj && !commentObj) ? ((0, jsx_runtime_1.jsx)(CentralProgress_1.default, { size: 30 })) : ((0, jsx_runtime_1.jsxs)(material_1.MenuList, { children: [renderGeneralSection(), Boolean(extraSections.length) && (0, jsx_runtime_1.jsx)(material_1.Divider, {}), extraSections.map((s, i) => ((0, jsx_runtime_1.jsx)(material_1.Box, { children: extraSectionsRenders[s]() }, `es_${i}`)))] })) })); } /** * Renders component */ return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore , Object.assign({ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore ref: (ref) => { popperRef.current = ref; }, "aria-haspopup": "true", onClick: handleOpen, className: classes.button, size: "small" }, { children: contributionObj && (contributionObj.collapsed || contributionObj.deleted) ? ((0, jsx_runtime_1.jsxs)("span", Object.assign({ className: classes.visibilityIcons }, { children: [contributionObj.collapsed ? (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "visibility_off" }) : (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "delete" }), (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" })] }))) : ((0, jsx_runtime_1.jsx)(Icon_1.default, { children: "more_vert" })) })), open && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isMobile ? ((0, jsx_runtime_1.jsx)(material_1.SwipeableDrawer, Object.assign({ open: true, onClose: handleClose, onOpen: handleOpen, anchor: "bottom", disableSwipeToOpen: true }, { children: renderContent() }))) : ((0, jsx_runtime_1.jsx)(PopperRoot, Object.assign({ open: true, anchorEl: popperRef.current, role: undefined, transition: true, className: classes.popperRoot }, PopperProps, { placement: "bottom-end" }, { children: ({ TransitionProps, placement }) => ((0, jsx_runtime_1.jsx)(material_1.Grow, Object.assign({}, TransitionProps, { style: { transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' } }, { children: (0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ variant: 'outlined', className: classes.paper }, { children: (0, jsx_runtime_1.jsx)(material_1.ClickAwayListener, Object.assign({ onClickAway: handleClose }, { children: renderContent() })) })) }))) }))) })), openConfirmDialog && ((0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, Object.assign({ open: openConfirmDialog }, (currentAction === ContributionsActionsMenu_1.DELETE_CONTRIBUTION ? { content: ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.deleteContributionInfo", defaultMessage: "ui.contributionActionMenu.deleteContributionInfo" })) } : {}), { onConfirm: handleConfirmedAction, isUpdating: Boolean(currentActionLoading), onClose: () => setOpenConfirmDialog(false) })))] }))); } exports.default = ContributionActionsMenu;