/* eslint-disable jsx-a11y/anchor-is-valid */ import React from 'react'; import _isArray from 'lodash/isArray'; import _isFunction from 'lodash/isFunction'; import { Icon, Dropdown, Menu, Popconfirm, Modal } from 'antd'; import { DETAIL_NAME, UPDATE_NAME, DELETE_NAME } from '../../../constants'; import { InternalCurdBox, ActionsConfig } from '../index'; import styles from './index.less'; export type ConfirmKey = (number | [number, (record: T) => string]); function isConfirmKeyAndItem(key: number, confirmKeys: ConfirmKey[] = []): ConfirmKey | null { for (let i = 0; i < confirmKeys.length; i += 1) { if (_isArray(confirmKeys[i]) && confirmKeys[i][0] === key) { return confirmKeys[i]; } if (confirmKeys[i] === key) { return confirmKeys[i]; } } return null; } function setConfirmTitle(confirmKey: ConfirmKey, action: ActionType, record: T) { if (_isArray(confirmKey)) { const [, setTitle] = confirmKey; return setTitle(record); } return `确定${action.title}吗?`; } export interface ActionType { key: number; title: string; handleClick: (record: T) => void; }; export function sortAndFilterActionsAsc(record: T, actions: ActionType[], hideActions: number[] | ((record?: T) => void | number[])) { return [...actions] .filter((item) => { if (_isFunction(hideActions)) { const hideActionKeys = hideActions(record) || []; return !hideActionKeys.includes(item.key); } else { return !hideActions.includes(item.key); } }) .sort((x, y) => { if (x.key > y.key) return 1; if (x.key < y.key) return -1; return 0; }); } export function initialActions(record: T, handleDefaultActionClick: InternalCurdBox['handleDefaultActionClick'], actionsConfig: ActionsConfig) { const { detailActionTitle = '详情', updateActionTitle = '编辑', deleteActionTitle = '删除', showActionsCount = 3, extraActions = [], hideActions = [] } = actionsConfig; const actions = [ { key: 4, title: detailActionTitle, handleClick: () => { handleDefaultActionClick(DETAIL_NAME, record) } }, { key: 8, title: updateActionTitle, handleClick: () => { handleDefaultActionClick(UPDATE_NAME, record) } }, { key: 12, title: deleteActionTitle, handleClick: () => { handleDefaultActionClick(DELETE_NAME, record) } }, ...extraActions ]; const sortedActions = sortAndFilterActionsAsc(record, actions, hideActions); return [sortedActions.slice(0, showActionsCount), sortedActions.slice(showActionsCount)]; } function renderShowActions(record: T) { return ( actions: ActionType[], actionsConfig: ActionsConfig, disabledActionKeys: number[] = [] ) => { const { confirmKeys, confirmProps } = actionsConfig; return actions.map((item) => { if (disabledActionKeys.includes(item.key)) { return ( {item.title} ); } const confirmKey = isConfirmKeyAndItem(item.key, confirmKeys); if (confirmKey) { return ( { if (event) { event.stopPropagation(); } }} > { item.handleClick(record); }} onCancel={(event) => { if (event) { event.stopPropagation(); } }} > {item.title} ); } return ( { event.stopPropagation(); item.handleClick(record); }} > {item.title} ); }); }; } export function renderActions(record: T) { return ( actions: ActionType[], moreActions: ActionType[], actionsConfig: ActionsConfig ) => { const { confirmKeys, disabledActions } = actionsConfig; let disabledActionKeys: number[] = []; if (disabledActions) { disabledActionKeys = disabledActions(record) || []; } if (!moreActions.length) { return renderShowActions(record)(actions, actionsConfig, disabledActionKeys); } return [ ...renderShowActions(record)(actions, actionsConfig, disabledActionKeys), { if (event) { event.stopPropagation(); } }} > { domEvent.stopPropagation(); }} > {moreActions.map((item) => { const confirmKey = isConfirmKeyAndItem(item.key, confirmKeys); const isDisabled = disabledActionKeys.includes(item.key); return ( { if (confirmKey) { Modal.confirm({ title: setConfirmTitle(confirmKey, item, record), onOk() { item.handleClick(record); }, okText: '确定', cancelText: '取消' }); return; } item.handleClick(record); }} > {isDisabled ? item.title : {item.title}} ); })} } > 更多 ]; }; } export function setActions(record: T, handleDefaultActionClick: InternalCurdBox['handleDefaultActionClick'], actionsConfig: ActionsConfig) { const [actions, moreActions] = initialActions(record, handleDefaultActionClick, actionsConfig); return renderActions(record)(actions, moreActions, actionsConfig); }