// Copyright 2021 99cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React, { Component } from 'react';
import { inject } from 'mobx-react';
import { Menu, Dropdown, Button, Divider } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { isArray, isEqual } from 'lodash';
import classnames from 'classnames';
import { getAllowedResults, getAction } from '../Action';
import ActionButton from '../ActionButton';
import styles from './index.less';
const { SubMenu } = Menu;
function getActionConf(action) {
const { id, title, actionType, buttonText, isDanger = false } = action;
return {
id,
title,
name: buttonText || title,
actionType,
action,
isDanger,
};
}
function getIsAllowedValue(alloweds, index) {
const result = alloweds[index];
if (isArray(result)) {
return result.every((value) => !!value);
}
return result;
}
// 第一个action一定保留, action | 更多
function DropdownActionButton({
firstAction = null,
moreActions = [],
alloweds = [],
item,
onFinishAction,
routing,
containerProps,
firstActionClassName,
onClickAction,
onCancelAction,
isWide,
}) {
if (alloweds.length === 0) {
return null;
}
if (!firstAction && moreActions.length === 0) {
return null;
}
let firstElement = null;
let dividerElement = null;
let moreElement = null;
if (firstAction) {
const isAllowed = getIsAllowedValue(alloweds, 0);
const config = getActionConf(firstAction.action, item);
firstElement = (
);
}
let allowedFatherCount = 0;
let allowedAll = 0;
let actionButton = null;
if (moreActions.length > 0) {
const buttonClassName =
isWide || moreActions.length > 1 ? styles['more-action-btn'] : '';
const menuContent = moreActions.map((it, index) => {
if (!it.actions) {
const isAllowed = getIsAllowedValue(alloweds, it.allowedIndex);
const key = it.key || `key-more-${index}`;
const config = getActionConf(it.action, item);
if (!isAllowed) {
return null;
}
allowedFatherCount += 1;
allowedAll += 1;
actionButton = (
);
return
{actionButton};
}
let allowedCount = 0;
const menuItems = it.actions.map((action, actionIndex) => {
const isAllowed = getIsAllowedValue(alloweds, action.allowedIndex);
const key = action.key || `key-more-${index}-${actionIndex}`;
if (isAllowed) {
allowedCount += 1;
allowedFatherCount += 1;
allowedAll += 1;
}
const config = getActionConf(action.action, item);
return (
);
});
const menuKey = `sub-menu-${index}`;
return (
{menuItems}
);
});
const menu = ;
if (firstAction && moreActions.length > 0 && allowedFatherCount > 0) {
dividerElement = ;
}
if (allowedFatherCount === 1 && allowedAll === 1 && actionButton) {
const className = isWide ? '' : styles['single-more-action'];
moreElement = {actionButton};
} else if (allowedFatherCount > 0) {
moreElement = (
);
}
}
return (
<>
{firstElement}
{dividerElement}
{moreElement}
>
);
}
function getActionList(actions, item, containerProps) {
const { firstAction = null, moreActions = [] } = actions;
const actionList = [];
const newFirst = firstAction
? {
action: getAction(firstAction, item, containerProps),
allowedIndex: 0,
}
: null;
const newMoreActions = [];
if (firstAction) {
actionList.push(newFirst);
}
moreActions.forEach((it) => {
if (it.actions) {
const newActions = [];
it.actions.forEach((action) => {
const newAction = {
action: getAction(action, item, containerProps),
allowedIndex: actionList.length,
};
newActions.push(newAction);
actionList.push(newAction);
});
newMoreActions.push({
...it,
actions: newActions,
});
} else if (it.action) {
const newAction = {
action: getAction(it.action, item, containerProps),
allowedIndex: actionList.length,
};
newMoreActions.push(newAction);
actionList.push(newAction);
}
});
return {
actionList,
firstAction: newFirst,
moreActions: newMoreActions,
};
}
export class ItemActionButtons extends Component {
constructor(props) {
super(props);
this.actionList = [];
this.firstAction = null;
this.moreActions = [];
this.state = {
results: [],
};
}
async componentDidMount() {
const { item, containerProps } = this.props;
this.updateResult(item, containerProps);
}
shouldComponentUpdate(nextProps, nextState) {
const { item, containerProps } = this.props;
const { results } = this.state;
if (!isEqual(nextProps.item, item)) {
this.updateResult(nextProps.item, containerProps);
return true;
}
if (!isEqual(results, nextState.results)) {
return true;
}
return false;
}
static getDerivedStateFromProps(nextProps, prevState) {
if (!isEqual(nextProps.item, prevState.item)) {
const { item } = nextProps;
return {
item,
};
}
return null;
}
get routing() {
return this.props.rootStore.routing;
}
async updateResult(item, containerProps) {
const { actions, isAdminPage } = this.props;
const { actionList, firstAction, moreActions } = getActionList(
actions,
item,
containerProps
);
this.actionList = actionList;
this.firstAction = firstAction;
this.moreActions = moreActions;
const results = await getAllowedResults({
actions: this.actionList,
data: item,
key: 'action',
containerProps,
isAdminPage,
});
this.setState({
results,
});
}
render() {
const {
item,
onFinishAction,
containerProps,
firstActionClassName,
onClickAction,
onCancelAction,
isWide,
} = this.props;
const { results } = this.state;
return (
);
}
}
export default inject('rootStore')(ItemActionButtons);