/* * Copyright © 2024 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ import { CheckCircle } from "@mui/icons-material"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettingsOutlined"; import DeleteIcon from "@mui/icons-material/DeleteOutlined"; import EditIcon from "@mui/icons-material/EditOutlined"; import ListAltOutlinedIcon from "@mui/icons-material/ListAltOutlined"; import LocalOfferIcon from "@mui/icons-material/LocalOffer"; import ManageAccountsIcon from "@mui/icons-material/ManageAccounts"; import TocOutlinedIcon from "@mui/icons-material/TocOutlined"; import ViewListIcon from "@mui/icons-material/ViewListOutlined"; import { Stack, Tooltip } from "@mui/material"; import { GridActionsCellItem, GridColDef, GridRenderCellParams, GridTreeNodeWithRender, GridValidRowModel, } from "@mui/x-data-grid"; import { useHasPermission } from "@/hooks/useHasPermission"; import { useTranslate } from "@/hooks/useTranslate"; import { TTranslationKeys } from "@/i18n/i18n.types"; import { theme } from "@/layout/themes/theme"; import { EntityType } from "@/services/types"; import { PermissionAction } from "@/types/permission.types"; export enum ActionColumnLabel { Edit = "Edit", Delete = "Delete", Values = "Values", Manage_Roles = "Manage_Roles", Permissions = "Permissions", Content = "Content", Fields = "Fields", Manage_Labels = "Manage_Labels", Toggle = "Toggle", } const ACTION_COLUMN_LABEL_MAP: Record = { [ActionColumnLabel.Edit]: "button.edit", [ActionColumnLabel.Delete]: "button.delete", [ActionColumnLabel.Values]: "button.values", [ActionColumnLabel.Manage_Roles]: "button.manage_roles", [ActionColumnLabel.Permissions]: "button.permissions", [ActionColumnLabel.Content]: "button.content", [ActionColumnLabel.Fields]: "button.fields", [ActionColumnLabel.Manage_Labels]: "title.manage_labels", [ActionColumnLabel.Toggle]: "button.toggle", } as const; export interface ActionColumn { label: ActionColumnLabel; action?: (row: T) => void; requires?: PermissionAction[]; getState?: (row: T) => boolean; helperText?: string; isDisabled?: (row: T) => boolean; } const BUTTON_WIDTH = 60; export const getActionsWidth = (itemsNumber: number) => itemsNumber === 1 ? BUTTON_WIDTH + 60 : BUTTON_WIDTH * itemsNumber; function getIcon(label: ActionColumnLabel) { switch (label) { case ActionColumnLabel.Edit: return ; case ActionColumnLabel.Delete: return ; case ActionColumnLabel.Values: return ; case ActionColumnLabel.Manage_Roles: return ; case ActionColumnLabel.Permissions: return ; case ActionColumnLabel.Content: return ; case ActionColumnLabel.Fields: return ; case ActionColumnLabel.Manage_Labels: return ; case ActionColumnLabel.Toggle: return ; default: return <>; } } function getColor(label: ActionColumnLabel) { switch (label) { case ActionColumnLabel.Edit: return theme.palette.grey[900]; case ActionColumnLabel.Delete: return theme.palette.error.main; default: return theme.palette.primary.main; } } function StackComponent({ actions, params, }: { actions: ActionColumn[]; params: GridRenderCellParams; }) { const { t } = useTranslate(); return ( {actions.map( ({ label, action, requires = [], getState, helperText, isDisabled, }) => ( {getIcon(label)} } label={helperText || t(ACTION_COLUMN_LABEL_MAP[label])} showInMenu={false} sx={{ color: label === ActionColumnLabel.Toggle && getState && getState(params.row) ? getColor(label) : theme.palette.grey[600], "&:hover": { color: getColor(label), }, }} disabled={ (isDisabled && isDisabled(params.row)) || (params.row.builtin && (requires.includes(PermissionAction.UPDATE) || requires.includes(PermissionAction.DELETE))) } onClick={() => { action && action(params.row); }} /> ), )} ); } export const getActionsColumn = ( actions: ActionColumn[], headerName: string, ): GridColDef => { return { maxWidth: getActionsWidth(actions.length), field: "actions", headerName, sortable: false, minWidth: getActionsWidth(actions.length), align: "center", renderCell: (params) => ( ), }; }; export const useActionColumns = ( type: EntityType, actions: ActionColumn[], headerName: string, ) => { const hasPermission = useHasPermission(); return getActionsColumn( actions.filter( ({ requires }) => !requires || requires.every((action) => hasPermission(type, action)), ), headerName, ); };