tree数据操作换成hover显示

This commit is contained in:
catchonme 2019-09-10 19:42:18 +08:00
parent b64188f9dd
commit 310927b73f
9 changed files with 137 additions and 125 deletions

View File

@ -1,7 +1,9 @@
@mixin tree-input { @mixin tree-input {
> i { > svg {
display: inline-block; display: inline-block;
cursor: pointer; cursor: pointer;
position: relative;
top: 2px;
margin-left: px2rem(5px); margin-left: px2rem(5px);
} }
@ -65,16 +67,27 @@
line-height: px2rem(30px); line-height: px2rem(30px);
position: relative; position: relative;
.#{$ns}Tree-item-icons {
visibility: hidden;
transition: visibility .1s ease;
}
> a { > a {
color: inherit; color: inherit;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
> span.#{$ns}Tree-item-icons {
visibility: visible;
}
} }
> span > i { > span > svg {
display: inline-block; display: inline-block;
cursor: pointer; cursor: pointer;
position: relative;
top: 2px;
margin-left: px2rem(5px); margin-left: px2rem(5px);
} }
} }
@ -99,9 +112,15 @@
line-height: px2rem(25px); line-height: px2rem(25px);
cursor: pointer; cursor: pointer;
padding-left: $Tree-indent; padding-left: $Tree-indent;
> p > span { > p {
> svg {
position: relative;
top: 2px;
}
> span {
padding-left: px2rem(5px); padding-left: px2rem(5px);
} }
}
&-input { &-input {
@include tree-input @include tree-input

View File

@ -5,10 +5,11 @@
*/ */
import React from 'react'; import React from 'react';
import {eachTree, isVisible, isObject} from '../utils/helper'; import {eachTree, isVisible, isObject, autobind} from '../utils/helper';
import {Option, Options, value2array} from './Checkboxes'; import {Option, Options, value2array} from './Checkboxes';
import {ClassNamesFn, themeable} from '../theme'; import {ClassNamesFn, themeable} from '../theme';
import {highlight} from '../renderers/Form/Options'; import {highlight} from '../renderers/Form/Options';
import {Icon} from './icons';
interface TreeSelectorProps { interface TreeSelectorProps {
classPrefix: string; classPrefix: string;
@ -53,20 +54,21 @@ interface TreeSelectorProps {
selfDisabledAffectChildren?: boolean; selfDisabledAffectChildren?: boolean;
minLength?: number; minLength?: number;
maxLength?: number; maxLength?: number;
addMode?: string; addMode?: 'dialog' | 'normal';
addItem?: Function; addable?: boolean;
onAdd?: Function;
openAddDialog?: Function; openAddDialog?: Function;
editMode?: string; editMode?: 'dialog' | 'normal';
editItem?: Function; onEdit?: Function;
editable?: boolean;
openEditDialog?: Function; openEditDialog?: Function;
deletable?: boolean; deletable?: boolean;
deleteItem?: Function; onDelete?: Function;
} }
interface TreeSelectorState { interface TreeSelectorState {
value: Array<any>; value: Array<any>;
unfolded: {[propName: string]: string}; unfolded: {[propName: string]: string};
hoverItem: Option | null;
editItem: Option | null; editItem: Option | null;
addItem: Option | null; addItem: Option | null;
addingItem: Option | null; addingItem: Option | null;
@ -101,24 +103,6 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}; };
componentWillMount() { componentWillMount() {
this.renderList = this.renderList.bind(this);
this.handleSelect = this.handleSelect.bind(this);
this.clearSelect = this.clearSelect.bind(this);
this.handleCheck = this.handleCheck.bind(this);
this.toggleUnfolded = this.toggleUnfolded.bind(this);
this.handleEnter = this.handleEnter.bind(this);
this.handleMove = this.handleMove.bind(this);
this.handleLeave = this.handleLeave.bind(this);
this.addItem = this.addItem.bind(this);
this.onChangeAddItem = this.onChangeAddItem.bind(this);
this.confirmAddItem = this.confirmAddItem.bind(this);
this.cancelAddItem = this.cancelAddItem.bind(this);
this.editItem = this.editItem.bind(this);
this.onChangeEditItem = this.onChangeEditItem.bind(this);
this.confirmEditItem = this.confirmEditItem.bind(this);
this.cancelEditItem = this.cancelEditItem.bind(this);
this.deleteItem = this.deleteItem.bind(this);
const props = this.props; const props = this.props;
this.setState({ this.setState({
@ -131,7 +115,6 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
options: props.data options: props.data
}), }),
unfolded: this.syncUnFolded(props), unfolded: this.syncUnFolded(props),
hoverItem: null, // 鼠标覆盖选中的 item
editItem: null, // 点击编辑时的 item editItem: null, // 点击编辑时的 item
addItem: null, // 点击添加时的 item addItem: null, // 点击添加时的 item
addingItem: null, // 添加后的 item addingItem: null, // 添加后的 item
@ -187,6 +170,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
return unfolded; return unfolded;
} }
@autobind
toggleUnfolded(node: any) { toggleUnfolded(node: any) {
this.setState({ this.setState({
addItem: null, addItem: null,
@ -197,6 +181,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}); });
} }
@autobind
clearSelect() { clearSelect() {
this.setState( this.setState(
{ {
@ -210,6 +195,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
); );
} }
@autobind
handleSelect(node: any, value?: any) { handleSelect(node: any, value?: any) {
this.setState( this.setState(
{ {
@ -223,6 +209,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
); );
} }
@autobind
handleCheck(item: any, checked: boolean) { handleCheck(item: any, checked: boolean) {
const props = this.props; const props = this.props;
const value = this.state.value.concat(); const value = this.state.value.concat();
@ -306,36 +293,12 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
); );
} }
handleEnter(item: Option) { @autobind
this.setState({ handleAdd(item: Option | null, isFolder: boolean) {
hoverItem: item
});
}
handleMove(e: MouseEvent, item: Option) {
const target = e.target as HTMLElement;
const tagName = target.tagName;
if (tagName === 'LI') {
const current = target.childNodes[0].textContent;
if (current == item['label'] && (!this.state.hoverItem || current !== (this.state.hoverItem as Option)['label'])) {
this.setState({
hoverItem: item
});
}
}
}
handleLeave() {
this.setState({
hoverItem: null
});
}
addItem(item: Option | null, isFolder: boolean) {
const {addMode, openAddDialog, valueField} = this.props; const {addMode, openAddDialog, valueField} = this.props;
let {hoverItem, unfolded} = this.state; let {unfolded} = this.state;
if (addMode === 'dialog') { if (addMode === 'dialog') {
openAddDialog && openAddDialog(item ? hoverItem : null) openAddDialog && openAddDialog(item ? item : null)
} else if (addMode === 'normal') { } else if (addMode === 'normal') {
// item 为 null 时为添加一级 // item 为 null 时为添加一级
if (item) { if (item) {
@ -362,11 +325,12 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
} }
} }
editItem(item: Option) { @autobind
handleEdit(item: Option) {
const {editMode, openEditDialog} = this.props; const {editMode, openEditDialog} = this.props;
const {hoverItem, addItem} = this.state; const {addItem} = this.state;
if (editMode === 'dialog') { if (editMode === 'dialog') {
openEditDialog && openEditDialog(hoverItem); openEditDialog && openEditDialog(item);
addItem && this.setState({ addItem && this.setState({
addItem: null addItem: null
}); });
@ -378,19 +342,17 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
} }
} }
deleteItem(item: Option) { @autobind
const {deleteItem} = this.props; handleDelete(item: Option) {
deleteItem && deleteItem(item); const {onDelete} = this.props;
onDelete && onDelete(item);
this.setState({
hoverItem: null
});
} }
confirmAddItem() { @autobind
const {addItem} = this.props; handleConfirmOnAdd() {
const {onAdd} = this.props;
const {addItem: parent, addingItem} = this.state; const {addItem: parent, addingItem} = this.state;
addItem && addItem({ onAdd && onAdd({
...addingItem, ...addingItem,
parent: parent parent: parent
}); });
@ -402,17 +364,19 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}) })
} }
cancelAddItem() { @autobind
handleCancelOnAdd() {
this.setState({ this.setState({
addItem: null, addItem: null,
addTop: false addTop: false
}); });
} }
confirmEditItem() { @autobind
const {editItem} = this.props; handleConfirmOnEdit() {
const {onEdit} = this.props;
let {editingItem, editItem: prevItem} = this.state; let {editingItem, editItem: prevItem} = this.state;
editItem && editItem({ onEdit && onEdit({
...editingItem, ...editingItem,
prev: prevItem prev: prevItem
}); });
@ -422,13 +386,15 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}); });
} }
cancelEditItem() { @autobind
handleCancelOnEdit() {
this.setState({ this.setState({
editItem: null editItem: null
}); });
} }
onChangeAddItem(value: string) { @autobind
handleChangeOnAdd(value: string) {
this.setState({ this.setState({
addingItem: { addingItem: {
label: value label: value
@ -436,7 +402,8 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}); });
} }
onChangeEditItem(item: Option, value: string) { @autobind
handleChangeOnEdit(item: Option, value: string) {
let {editItem} = this.state; let {editItem} = this.state;
this.setState({ this.setState({
editingItem: { editingItem: {
@ -446,6 +413,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
}); });
} }
@autobind
renderList( renderList(
list: Options, list: Options,
value: Option[], value: Option[],
@ -469,14 +437,13 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
data, data,
maxLength, maxLength,
minLength, minLength,
addMode, addable,
editMode, editable,
deletable deletable
} = this.props; } = this.props;
const { const {
addItem, addItem,
editItem, editItem,
hoverItem,
unfolded, unfolded,
addTop, addTop,
value: stateValue value: stateValue
@ -553,15 +520,6 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
className={cx(`Tree-item ${itemClassName || ''}`, { className={cx(`Tree-item ${itemClassName || ''}`, {
'Tree-item--isLeaf': isLeaf 'Tree-item--isLeaf': isLeaf
})} })}
onMouseMove={(e) =>
!nodeDisabled && this.handleMove(e, item)
}
onMouseEnter={() =>
!nodeDisabled && this.handleEnter(item)
}
onMouseLeave={() =>
!nodeDisabled && this.handleLeave()
}
> >
{!editItem || isObject(editItem) && (editItem as Option)[valueField] !== item[valueField] ? ( {!editItem || isObject(editItem) && (editItem as Option)[valueField] !== item[valueField] ? (
<a> <a>
@ -598,24 +556,21 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
> >
{highlightTxt ? highlight(item[nameField], highlightTxt) : item[nameField]} {highlightTxt ? highlight(item[nameField], highlightTxt) : item[nameField]}
</span> </span>
{/* 非添加时 && 非编辑时 && 鼠标覆盖时是当前item时显示添加/编辑/删除图标 */}
{!addTop {!addTop
&& !addItem && !addItem
&& !editItem && !editItem ? (
&& isObject(hoverItem) <span className={cx('Tree-item-icons')}>
&& (hoverItem as Option)[valueField as string] === item[valueField] ? ( {addable ? <Icon icon="plus" className="icon" onClick={() => this.handleAdd(item, !isLeaf)}/> : null}
<span> {deletable ? <Icon icon="minus" className="icon" onClick={() => this.handleDelete(item)}/> : null}
{addMode ? <i className="fa fa-plus" onClick={() => this.addItem(item, !isLeaf)}></i> : null} {editable ? <Icon icon="pencil" className="icon" onClick={() => this.handleEdit(item)}/> : null}
{deletable ? <i className="fa fa-minus" onClick={() => this.deleteItem(item)}></i> : null}
{editMode ? <i className="fa fa-pencil" onClick={() => this.editItem(item)}></i> : null}
</span> </span>
) : null} ) : null}
</a> </a>
) : ( ) : (
<div className={cx('Tree-item--isEdit')}> <div className={cx('Tree-item--isEdit')}>
<input defaultValue={item['label']} onChange={(e) => this.onChangeEditItem(item, e.currentTarget.value)}/> <input defaultValue={item['label']} onChange={(e) => this.handleChangeOnEdit(item, e.currentTarget.value)}/>
<i className="fa fa-check" onClick={this.confirmEditItem}></i> <Icon icon="check" className="icon" onClick={this.handleConfirmOnEdit}/>
<i className="fa fa-close" onClick={this.cancelEditItem}></i> <Icon icon="tree-close" className="icon" onClick={this.handleCancelOnEdit}/>
</div> </div>
)} )}
{/* 有children而且为展开状态 或者 添加child时 */} {/* 有children而且为展开状态 或者 添加child时 */}
@ -625,9 +580,9 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
> >
{addItem && addItem[valueField] === item[valueField] ? ( {addItem && addItem[valueField] === item[valueField] ? (
<li> <li>
<input onChange={(e) => this.onChangeAddItem(e.currentTarget.value)}/> <input onChange={(e) => this.handleChangeOnAdd(e.currentTarget.value)}/>
<i className="fa fa-check" onClick={this.confirmAddItem}></i> <Icon icon="check" className="icon" onClick={this.handleConfirmOnAdd}/>
<i className="fa fa-close" onClick={this.cancelAddItem}></i> <Icon icon="tree-close" className="icon" onClick={this.handleCancelOnAdd}/>
</li> </li>
) : null} ) : null}
{childrenItems} {childrenItems}
@ -644,7 +599,7 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
} }
render() { render() {
const {className, placeholder, hideRoot, rootLabel, showIcon, classnames: cx, addMode} = this.props; const {className, placeholder, hideRoot, rootLabel, showIcon, classnames: cx, addable} = this.props;
let data = this.props.data; let data = this.props.data;
const {value, addTop} = this.state; const {value, addTop} = this.state;
@ -669,19 +624,19 @@ export class TreeSelector extends React.Component<TreeSelectorProps, TreeSelecto
</span> </span>
</label> </label>
</a> </a>
{addMode ? ( {addable ? (
<div className={cx('Tree-addTop')}> <div className={cx('Tree-addTop')}>
{!addTop ? ( {!addTop ? (
<p onClick={() => this.addItem(null, false)}> <p onClick={() => this.handleAdd(null, false)}>
<i className="fa fa-plus"></i> <Icon icon="plus" className="icon" />
<span></span> <span></span>
</p> </p>
) : null} ) : null}
{addTop ? ( {addTop ? (
<div className={cx('Tree-addTop-input')}> <div className={cx('Tree-addTop-input')}>
<input onChange={(e) => this.onChangeAddItem(e.currentTarget.value)}/> <input onChange={(e) => this.handleChangeOnAdd(e.currentTarget.value)}/>
<i className="fa fa-check" onClick={this.confirmAddItem}></i> <Icon icon="check" className="icon" onClick={this.handleConfirmOnAdd}/>
<i className="fa fa-close" onClick={this.cancelAddItem}></i> <Icon icon="tree-close" className="icon" onClick={this.handleCancelOnAdd}/>
</div> </div>
) : null} ) : null}
</div> </div>

View File

@ -25,6 +25,16 @@ import PauseIcon from '../icons/pause.svg';
import LeftArrowIcon from '../icons/left-arrow.svg'; import LeftArrowIcon from '../icons/left-arrow.svg';
// @ts-ignore // @ts-ignore
import RightArrowIcon from '../icons/right-arrow.svg'; import RightArrowIcon from '../icons/right-arrow.svg';
// @ts-ignore
import CheckIcon from '../icons/check.svg';
// @ts-ignore
import PlusIcon from '../icons/plus.svg';
// @ts-ignore
import MinusIcon from '../icons/minus.svg';
// @ts-ignore
import PencilIcon from '../icons/pencil.svg';
// @ts-ignore
import TreeClose from '../icons/tree-close.svg';
// 兼容原来的用法,后续不直接试用。 // 兼容原来的用法,后续不直接试用。
// @ts-ignore // @ts-ignore
@ -70,6 +80,11 @@ registerIcon('play', PlayIcon);
registerIcon('pause', PauseIcon); registerIcon('pause', PauseIcon);
registerIcon('left-arrow', LeftArrowIcon); registerIcon('left-arrow', LeftArrowIcon);
registerIcon('right-arrow', RightArrowIcon); registerIcon('right-arrow', RightArrowIcon);
registerIcon('check', CheckIcon);
registerIcon('plus', PlusIcon);
registerIcon('minus', MinusIcon);
registerIcon('pencil', PencilIcon);
registerIcon('tree-close', TreeClose);
export function Icon({ export function Icon({
icon, icon,
@ -91,5 +106,9 @@ export {
PlayIcon, PlayIcon,
PauseIcon, PauseIcon,
LeftArrowIcon, LeftArrowIcon,
RightArrowIcon RightArrowIcon,
CheckIcon,
PlusIcon,
MinusIcon,
PencilIcon
}; };

3
src/icons/check.svg Normal file
View File

@ -0,0 +1,3 @@
<svg t="1568105259329" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" version="1.1" p-id="983" >
<path d="M954.848 323.424q0 22.848-16 38.848l-491.424 491.424q-16 16-38.848 16t-38.848-16l-284.576-284.576q-16-16-16-38.848t16-38.848l77.728-77.728q16-16 38.848-16t38.848 16l168 168.576 374.848-375.424q16-16 38.848-16t38.848 16l77.728 77.728q16 16 16 38.848z" p-id="984" fill="#606670"></path>
</svg>

After

Width:  |  Height:  |  Size: 456 B

3
src/icons/minus.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" version="1.1" p-id="850">
<path d="M911.232 420.565333l0 109.717333q0 22.848-16 38.848t-38.848 16l-694.848 0q-22.848 0-38.848-16t-16-38.848l0-109.717333q0-22.848 16-38.848t38.848-16l694.848 0q22.848 0 38.848 16t16 38.848z" p-id="851" fill="#606670"></path>
</svg>

After

Width:  |  Height:  |  Size: 374 B

3
src/icons/pencil.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" version="1.1" p-id="2332">
<path d="M768 0l-128 128 256 256 128-128-256-256zm-256 256l-512 512 0 256 256 0 512-512-256-256z" p-id="2333" fill="#606670"></path>
</svg>

After

Width:  |  Height:  |  Size: 277 B

3
src/icons/plus.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" version="1.1" p-id="717">
<path d="M914.285714 420.571429v109.714285q0 22.857143-16 38.857143t-38.857143 16h-237.714285v237.714286q0 22.857143-16 38.857143t-38.857143 16H457.142857q-22.857143 0-38.857143-16t-16-38.857143v-237.714286H164.571429q-22.857143 0-38.857143-16t-16-38.857143V420.571429q0-22.857143 16-38.857143t38.857143-16h237.714285V128q0-22.857143 16-38.857143t38.857143-16h109.714286q22.857143 0 38.857143 16t16 38.857143v237.714286h237.714285q22.857143 0 38.857143 16t16 38.857143z" p-id="718" fill="#606670"></path>
</svg>

After

Width:  |  Height:  |  Size: 649 B

3
src/icons/tree-close.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" version="1.1" p-id="1775" >
<path d="M853.728 755.424q0 22.848-16 38.848l-77.728 77.728q-16 16-38.848 16t-38.848-16l-168-168-168 168q-16 16-38.848 16t-38.848-16l-77.728-77.728q-16-16-16-38.848t16-38.848l168-168-168-168q-16-16-16-38.848t16-38.848l77.728-77.728q16-16 38.848-16t38.848 16l168 168 168-168q16-16 38.848-16t38.848 16l77.728 77.728q16 16 16 38.848t-16 38.848l-168 168 168 168q16 16 16 38.848z" p-id="1776" fill="#606670"></path>
</svg>

After

Width:  |  Height:  |  Size: 556 B

View File

@ -18,10 +18,10 @@ export interface TreeProps extends OptionsControlProps {
withChildren?: boolean; // 选父级的时候是否把子节点的值也包含在内。 withChildren?: boolean; // 选父级的时候是否把子节点的值也包含在内。
onlyChildren?: boolean; // 选父级的时候,是否只把子节点的值包含在内 onlyChildren?: boolean; // 选父级的时候,是否只把子节点的值包含在内
addApi?: Api; addApi?: Api;
addMode?: string; addMode?: 'dialog' | 'normal';
addDialog?: Schema; addDialog?: Schema;
editApi?: Api; editApi?: Api;
editMode?: string; editMode?: 'dialog' | 'normal';
editDialog?: Schema; editDialog?: Schema;
deleteApi?: Api; deleteApi?: Api;
deleteConfirmText?: string; deleteConfirmText?: string;
@ -57,7 +57,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
} }
@autobind @autobind
addItem(values: PlainObject) { handleAdd(values: PlainObject) {
this.saveRemote(values, 'add'); this.saveRemote(values, 'add');
} }
@ -71,7 +71,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
} }
@autobind @autobind
editItem(values: PlainObject) { handleEdit(values: PlainObject) {
this.saveRemote(values, 'add'); this.saveRemote(values, 'add');
} }
@ -80,7 +80,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
this.saveRemote({ this.saveRemote({
...values, ...values,
prev: this.state.prev prev: this.state.prev
}, 'add'); }, 'edit');
this.closeEditDialog(); this.closeEditDialog();
} }
@ -109,7 +109,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
} }
@autobind @autobind
async deleteItem(item: any) { async handleDelete(item: any) {
const {deleteConfirmText, deleteApi, data, env} = this.props; const {deleteConfirmText, deleteApi, data, env} = this.props;
const ctx = createObject(data, item); const ctx = createObject(data, item);
if (isEffectiveApi(deleteApi, ctx)) { if (isEffectiveApi(deleteApi, ctx)) {
@ -189,8 +189,10 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
showRadio, showRadio,
render, render,
addMode, addMode,
addApi,
addDialog, addDialog,
editMode, editMode,
editApi,
editDialog, editDialog,
deleteApi deleteApi
} = this.props; } = this.props;
@ -228,17 +230,19 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
nameField="label" nameField="label"
selfDisabledAffectChildren={false} selfDisabledAffectChildren={false}
addMode={addMode} addMode={addMode}
addItem={this.addItem} addable={isEffectiveApi(addApi)}
onAdd={this.handleAdd}
openAddDialog={this.openAddDialog} openAddDialog={this.openAddDialog}
editMode={editMode} editMode={editMode}
editItem={this.editItem} editable={isEffectiveApi(editApi)}
onEdit={this.handleEdit}
openEditDialog={this.openEditDialog} openEditDialog={this.openEditDialog}
deleteItem={this.deleteItem} onDelete={this.handleDelete}
deletable={isEffectiveApi(deleteApi)} deletable={isEffectiveApi(deleteApi)}
/> />
)} )}
{render( {addMode && render(
'modal', 'modal',
{ {
type: 'dialog', type: 'dialog',
@ -252,7 +256,7 @@ export default class TreeControl extends React.Component<TreeProps, TreeState> {
} }
)} )}
{render( {editMode && render(
'modal', 'modal',
{ {
type: 'dialog', type: 'dialog',