import * as React from "react"; import { useCallback, useState } from "react"; import { useParams } from "react-router-dom"; import { KeyboardArrowDown as KeyboardArrowDownIcon } from "@mui/icons-material"; import { Button } from "@mui/material"; import Menu from "@mui/material/Menu"; import { enqueueSnackbar } from "notistack"; import { ApiOperation } from "../../api"; import { useApi } from "../../contexts/ApiContext"; import { useI18n } from "../../contexts/I18nContext"; import { useUser } from "../../contexts/UserContext"; import { ContribComponent } from "../../types"; import { hasAccess } from "../../util/has_access"; import { usePage } from "../Page"; import ActionMenuItem from "./ActionMenuItem"; export const ActionMenu: React.FC = () => { const [anchorEl, setAnchorEl] = useState(null); const [renderedComponent, setRenderedComponent] = useState(); const params = useParams(); const page = usePage(); const { user } = useUser(); const api = useApi(); const { t } = useI18n(); const title = useCallback( (operation: ApiOperation) => t(operation.component?.title ?? operation.summary ?? operation.id), [t], ); const open = Boolean(anchorEl); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const handleAction = async (operation: ApiOperation) => { if (operation.component != null) { let component = operation.component.component; setAnchorEl(null); if (component instanceof Promise) { component = await component; } setRenderedComponent(() => component); return; } try { const action = api.operations[operation.id]; const response = await action.call({ params }); if (response.ok) { enqueueSnackbar(t(`Completed successfully: ${title(action)}`), { variant: "success", }); handleClose(); } else { enqueueSnackbar(t(`Action failed: ${title(action)}`), { variant: "error", }); throw response; } } catch (error) { enqueueSnackbar(t("Action failed"), { variant: "error", }); console.error(error); } }; return ( <> {page?.contrib .filter( (operation) => operation.component?.variant === "action" && hasAccess(user, operation.component.permission, operation.component.group), ) .map((operation) => ( ))} {renderedComponent && React.createElement(renderedComponent, { close: () => setRenderedComponent(undefined), data: {}, refresh: () => {}, })} ); }; export default ActionMenu;