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