mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: crud、crud2支持行移入、行移出事件
This commit is contained in:
parent
2a79bd18f2
commit
230823daa7
@ -1872,7 +1872,9 @@ popOver 的其它配置请参考 [popover](./popover)
|
||||
| columnSearch | `searchName: string` 列搜索列名<br/>`searchValue: string` 列搜索数据 | 点击列搜索时触发 |
|
||||
| orderChange | `movedItems: item[]` 已排序数据 | 手动拖拽行排序时触发 |
|
||||
| columnToggled | `columns: item[]` 当前显示的列配置数据 | 点击自定义列时触发 |
|
||||
| rowClick | `rowItem: object` 行点击数据 | 点击整行时触发 |
|
||||
| rowClick | `item: object` 行点击数据<br/>`index: number` 行索引 | 点击整行时触发 |
|
||||
| rowMouseEnter | `item: object` 行移入数据<br/>`index: number` 行索引 | 移入整行时触发 |
|
||||
| rowMouseLeave | `item: object` 行移出数据<br/>`index: number` 行索引 | 移出整行时触发 |
|
||||
|
||||
### 列配置事件表
|
||||
|
||||
|
@ -256,7 +256,7 @@ export default {
|
||||
actionType: 'toast',
|
||||
args: {
|
||||
msgType: 'info',
|
||||
msg: '行单击数据:${rowItem|json}'
|
||||
msg: '行单击数据:${item|json};行索引:${index}'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -287,7 +287,7 @@ export class TablePlugin extends BasePlugin {
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
'event.data.rowItem': {
|
||||
'event.data.item': {
|
||||
type: 'object',
|
||||
title: '行点击数据'
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ export class Table2Plugin extends BasePlugin {
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
'event.data.rowItem': {
|
||||
'event.data.item': {
|
||||
type: 'object',
|
||||
title: '行点击数据'
|
||||
}
|
||||
|
@ -1166,13 +1166,20 @@ export class Table extends React.PureComponent<TableProps, TableState> {
|
||||
}
|
||||
}
|
||||
|
||||
onRowMouseEnter(
|
||||
async onRowMouseEnter(
|
||||
event: React.ChangeEvent<any>,
|
||||
record?: any,
|
||||
rowIndex?: number
|
||||
) {
|
||||
const {classnames: cx, onRow} = this.props;
|
||||
|
||||
if (onRow && onRow.onRowMouseEnter) {
|
||||
const prevented = await onRow.onRowMouseEnter(event, record, rowIndex);
|
||||
if (prevented) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let parent = event.target;
|
||||
while (parent && parent.tagName !== 'TR') {
|
||||
parent = parent.parentElement;
|
||||
@ -1191,22 +1198,24 @@ export class Table extends React.PureComponent<TableProps, TableState> {
|
||||
target = target.closest('tr');
|
||||
}
|
||||
|
||||
this.setState({hoverRow: {target, rowIndex, record}}, () => {
|
||||
if (onRow) {
|
||||
onRow.onRowMouseEnter &&
|
||||
onRow.onRowMouseEnter(event, record, rowIndex);
|
||||
}
|
||||
});
|
||||
this.setState({hoverRow: {target, rowIndex, record}});
|
||||
}
|
||||
}
|
||||
|
||||
onRowMouseLeave(
|
||||
async onRowMouseLeave(
|
||||
event: React.ChangeEvent<any>,
|
||||
record?: any,
|
||||
rowIndex?: number
|
||||
) {
|
||||
const {classnames: cx, onRow} = this.props;
|
||||
|
||||
if (onRow && onRow.onRowMouseLeave) {
|
||||
const prevented = await onRow.onRowMouseLeave(event, record, rowIndex);
|
||||
if (prevented) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let parent = event.target;
|
||||
while (parent && parent.tagName !== 'TR') {
|
||||
parent = parent.parentElement;
|
||||
@ -1218,12 +1227,6 @@ export class Table extends React.PureComponent<TableProps, TableState> {
|
||||
td.classList.remove(cx('Table-cell-row-hover'));
|
||||
}
|
||||
}
|
||||
|
||||
if (record) {
|
||||
if (onRow) {
|
||||
onRow.onRowMouseLeave && onRow.onRowMouseLeave(event, record, rowIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMouseLeave() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import pickBy from 'lodash/pickBy';
|
||||
import omitBy from 'lodash/omitBy';
|
||||
import {Renderer, RendererProps} from 'amis-core';
|
||||
import {SchemaNode, Schema, ActionObject, PlainObject} from 'amis-core';
|
||||
import {CRUDStore, ICRUDStore} from 'amis-core';
|
||||
@ -44,6 +45,8 @@ import {ActionSchema} from './Action';
|
||||
import {CardsSchema} from './Cards';
|
||||
import {ListSchema} from './List';
|
||||
import {TableSchema} from './Table';
|
||||
import type {TableRendererEvent} from './Table';
|
||||
import type {CardsRendererEvent} from './Cards';
|
||||
import {isPureVariable, resolveVariableAndFilter, parseQuery} from 'amis-core';
|
||||
|
||||
import type {PaginationProps} from './Pagination';
|
||||
@ -74,6 +77,8 @@ export type CRUDToolbarObject = {
|
||||
align?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export type CRUDRendererEvent = TableRendererEvent | CardsRendererEvent;
|
||||
|
||||
export interface CRUDCommonSchema extends BaseSchema, SpinnerExtraProps {
|
||||
/**
|
||||
* 指定为 CRUD 渲染器。
|
||||
@ -332,6 +337,19 @@ export interface CRUDProps
|
||||
pickerMode?: boolean; // 选择模式,用做表单中的选择操作
|
||||
}
|
||||
|
||||
const INNER_EVENTS: Array<CRUDRendererEvent> = [
|
||||
'selectedChange',
|
||||
'columnSort',
|
||||
'columnFilter',
|
||||
'columnSearch',
|
||||
'columnToggled',
|
||||
'orderChange',
|
||||
'rowClick',
|
||||
'rowMouseEnter',
|
||||
'rowMouseLeave',
|
||||
'selected'
|
||||
];
|
||||
|
||||
export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
static propsList: Array<keyof CRUDProps> = [
|
||||
'bulkActions',
|
||||
@ -2230,6 +2248,12 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
'body',
|
||||
{
|
||||
...rest,
|
||||
// 通用事件 例如cus-event 如果直接透传给table 则会被触发2次
|
||||
// 因此只将下层组件table、cards中自定义事件透传下去 否则通过crud配置了也不会执行
|
||||
onEvent: omitBy(
|
||||
onEvent,
|
||||
(event, key: any) => !INNER_EVENTS.includes(key)
|
||||
),
|
||||
columns: store.columns ?? rest.columns,
|
||||
type: mode || 'table'
|
||||
},
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import omitBy from 'lodash/omitBy';
|
||||
import {Renderer, RendererProps} from 'amis-core';
|
||||
import {Action} from '../types';
|
||||
import {CRUDStore, ICRUDStore} from 'amis-core';
|
||||
import {
|
||||
createObject,
|
||||
@ -22,6 +21,7 @@ import {evalExpression, filter} from 'amis-core';
|
||||
import {isEffectiveApi, isApiOutdated} from 'amis-core';
|
||||
import findIndex from 'lodash/findIndex';
|
||||
import {Html, SpinnerExtraProps} from 'amis-ui';
|
||||
import {Action} from '../types';
|
||||
import {
|
||||
BaseSchema,
|
||||
SchemaApi,
|
||||
@ -33,11 +33,13 @@ import {
|
||||
import {CardsSchema} from './Cards';
|
||||
import {ListSchema} from './List';
|
||||
import {TableSchema2} from './Table2';
|
||||
import type {Table2RendererEvent} from './Table2';
|
||||
import type {CardsRendererEvent} from './Cards';
|
||||
import {isPureVariable, resolveVariableAndFilter} from 'amis-core';
|
||||
import {SchemaCollection} from '../Schema';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
|
||||
export type CRUDRendererEvent = 'search';
|
||||
export type CRUDRendererEvent = Table2RendererEvent | CardsRendererEvent;
|
||||
|
||||
export interface CRUD2CommonSchema extends BaseSchema, SpinnerExtraProps {
|
||||
/**
|
||||
@ -193,6 +195,19 @@ export interface CRUD2Props
|
||||
pickerMode?: boolean; // 选择模式,用做表单中的选择操作
|
||||
}
|
||||
|
||||
const INNER_EVENTS: Array<CRUDRendererEvent> = [
|
||||
'selectedChange',
|
||||
'columnSort',
|
||||
'columnFilter',
|
||||
'columnSearch',
|
||||
'columnToggled',
|
||||
'orderChange',
|
||||
'rowClick',
|
||||
'rowMouseEnter',
|
||||
'rowMouseLeave',
|
||||
'selected'
|
||||
];
|
||||
|
||||
export default class CRUD2 extends React.Component<CRUD2Props, any> {
|
||||
static propsList: Array<keyof CRUD2Props> = [
|
||||
'mode',
|
||||
@ -1135,6 +1150,7 @@ export default class CRUD2 extends React.Component<CRUD2Props, any> {
|
||||
classnames: cx,
|
||||
keepItemSelectionOnPageChange,
|
||||
maxKeepItemSelectionLength,
|
||||
onEvent,
|
||||
onAction,
|
||||
popOverContainer,
|
||||
translate: __,
|
||||
@ -1171,6 +1187,12 @@ export default class CRUD2 extends React.Component<CRUD2Props, any> {
|
||||
'body',
|
||||
{
|
||||
...rest,
|
||||
// 通用事件 例如cus-event 如果直接透传给table 则会被触发2次
|
||||
// 因此只将下层组件table、cards中自定义事件透传下去 否则通过crud配置了也不会执行
|
||||
onEvent: omitBy(
|
||||
onEvent,
|
||||
(event, key: any) => !INNER_EVENTS.includes(key)
|
||||
),
|
||||
type: mode,
|
||||
columns: mode.startsWith('table')
|
||||
? store.columns || columns
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, {Fragment} from 'react';
|
||||
import React from 'react';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import {Renderer, RendererProps} from 'amis-core';
|
||||
import {SchemaNode, Schema, ActionObject} from 'amis-core';
|
||||
@ -10,7 +10,6 @@ import {
|
||||
getScrollParent,
|
||||
difference,
|
||||
ucFirst,
|
||||
noop,
|
||||
autobind,
|
||||
createObject
|
||||
} from 'amis-core';
|
||||
@ -138,9 +137,9 @@ export interface Column {
|
||||
type: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export type CardsRendererEvent = 'change';
|
||||
export type CardsRendererAction = 'check-all';
|
||||
// 如果这里的事件调整,对应CRUD里的事件配置也需要同步修改
|
||||
export type CardsRendererEvent = 'selected';
|
||||
export type CardsRendererAction = 'toggleSelectAll' | 'selectAll' | 'clearAll';
|
||||
|
||||
export interface GridProps
|
||||
extends RendererProps,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {observer} from 'mobx-react';
|
||||
import React from 'react';
|
||||
import uniq from 'lodash/uniq';
|
||||
import type {IColumn, IRow} from 'amis-core/lib/store/table';
|
||||
import {RendererProps} from 'amis-core';
|
||||
import {Action} from '../Action';
|
||||
@ -35,6 +34,31 @@ export class TableRow extends React.Component<TableRowProps> {
|
||||
this.handleQuickChange = this.handleQuickChange.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleItemClick = this.handleItemClick.bind(this);
|
||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
||||
}
|
||||
|
||||
handleMouseEnter(e: React.MouseEvent<HTMLTableRowElement>) {
|
||||
const {item, itemIndex, data, dispatchEvent} = this.props;
|
||||
|
||||
dispatchEvent(
|
||||
'rowMouseEnter',
|
||||
createObject(data, {
|
||||
item: item?.data,
|
||||
index: itemIndex
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
handleMouseLeave(e: React.MouseEvent<HTMLTableRowElement>) {
|
||||
const {item, itemIndex, data, dispatchEvent} = this.props;
|
||||
dispatchEvent(
|
||||
'rowMouseLeave',
|
||||
createObject(data, {
|
||||
item: item?.data,
|
||||
index: itemIndex
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 定义点击一行的行为,通过 itemAction配置
|
||||
@ -43,13 +67,22 @@ export class TableRow extends React.Component<TableRowProps> {
|
||||
return;
|
||||
}
|
||||
|
||||
const {itemAction, onAction, item, data, dispatchEvent, onCheck} =
|
||||
this.props;
|
||||
const {
|
||||
itemAction,
|
||||
onAction,
|
||||
item,
|
||||
itemIndex,
|
||||
data,
|
||||
dispatchEvent,
|
||||
onCheck
|
||||
} = this.props;
|
||||
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'rowClick',
|
||||
createObject(data, {
|
||||
rowItem: item?.data
|
||||
rowItem: item?.data, // 保留rowItem 可能有用户已经在用 兼容之前的版本
|
||||
item: item?.data,
|
||||
index: itemIndex
|
||||
})
|
||||
);
|
||||
|
||||
@ -144,6 +177,8 @@ export class TableRow extends React.Component<TableRowProps> {
|
||||
? this.handleItemClick
|
||||
: undefined
|
||||
}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
className={cx(itemClassName, {
|
||||
'is-hovered': item.isHover,
|
||||
'is-checked': item.checked,
|
||||
@ -210,6 +245,8 @@ export class TableRow extends React.Component<TableRowProps> {
|
||||
? this.handleItemClick
|
||||
: undefined
|
||||
}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
data-index={item.depth === 1 ? item.newIndex : undefined}
|
||||
data-id={item.id}
|
||||
className={cx(
|
||||
|
@ -400,6 +400,7 @@ export type ExportExcelToolbar = SchemaNode & {
|
||||
filename?: string;
|
||||
};
|
||||
|
||||
// 如果这里的事件调整,对应CRUD里的事件配置也需要同步修改
|
||||
export type TableRendererEvent =
|
||||
| 'selectedChange'
|
||||
| 'columnSort'
|
||||
@ -407,7 +408,9 @@ export type TableRendererEvent =
|
||||
| 'columnSearch'
|
||||
| 'columnToggled'
|
||||
| 'orderChange'
|
||||
| 'rowClick';
|
||||
| 'rowClick'
|
||||
| 'rowMouseEnter'
|
||||
| 'rowMouseLeave';
|
||||
|
||||
export type TableRendererAction =
|
||||
| 'selectAll'
|
||||
|
@ -368,13 +368,17 @@ export interface TableSchema2 extends BaseSchema {
|
||||
keepItemSelectionOnPageChange?: boolean;
|
||||
}
|
||||
|
||||
// 事件调整 对应CRUD2里的事件配置也需要同步修改
|
||||
export type Table2RendererEvent =
|
||||
| 'selected'
|
||||
| 'selectedChange'
|
||||
| 'columnSort'
|
||||
| 'columnFilter'
|
||||
| 'columnSearch'
|
||||
| 'columnToggled'
|
||||
| 'dragOver';
|
||||
| 'orderChange'
|
||||
| 'rowClick'
|
||||
| 'rowMouseEnter'
|
||||
| 'rowMouseLeave';
|
||||
|
||||
export type Table2RendererAction =
|
||||
| 'selectAll'
|
||||
@ -1137,11 +1141,11 @@ export default class Table2 extends React.Component<Table2Props, object> {
|
||||
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'rowClick',
|
||||
createObject(data, {rowItem})
|
||||
createObject(data, {item: rowItem, index: rowIndex})
|
||||
);
|
||||
|
||||
if (rendererEvent?.prevented) {
|
||||
return rendererEvent?.prevented;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowItem && onRow) {
|
||||
@ -1149,6 +1153,50 @@ export default class Table2 extends React.Component<Table2Props, object> {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
async handleRowMouseEnter(
|
||||
event: React.MouseEvent<HTMLTableRowElement>,
|
||||
rowItem: any,
|
||||
rowIndex?: number
|
||||
) {
|
||||
const {dispatchEvent, data, onRow} = this.props;
|
||||
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'rowMouseEnter',
|
||||
createObject(data, {item: rowItem, index: rowIndex})
|
||||
);
|
||||
|
||||
if (rendererEvent?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowItem && onRow) {
|
||||
onRow.onRowMouseEnter && onRow.onRowMouseEnter(event, rowItem, rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
async handleRowMouseLeave(
|
||||
event: React.MouseEvent<HTMLTableRowElement>,
|
||||
rowItem: any,
|
||||
rowIndex?: number
|
||||
) {
|
||||
const {dispatchEvent, data, onRow} = this.props;
|
||||
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'rowMouseLeave',
|
||||
createObject(data, {item: rowItem, index: rowIndex})
|
||||
);
|
||||
|
||||
if (rendererEvent?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowItem && onRow) {
|
||||
onRow.onRowMouseLeave && onRow.onRowMouseLeave(event, rowItem, rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
async handleOrderChange(
|
||||
oldIndex: number,
|
||||
@ -1457,7 +1505,9 @@ export default class Table2 extends React.Component<Table2Props, object> {
|
||||
keyField={keyField}
|
||||
onRow={{
|
||||
...onRow,
|
||||
onRowClick: this.handleRowClick
|
||||
onRowClick: this.handleRowClick,
|
||||
onRowMouseEnter: this.handleRowMouseEnter,
|
||||
onRowMouseLeave: this.handleRowMouseLeave
|
||||
}}
|
||||
></Table>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user