feat: CRUD2 head 操作支持testid

This commit is contained in:
yupeng12 2024-04-24 14:56:20 +08:00
parent 4012e9c08f
commit ffe15c5735
8 changed files with 72 additions and 12 deletions

View File

@ -110,6 +110,7 @@ import ScaleOrigin from '../icons/scale-origin.svg';
import If from '../icons/if.svg'; import If from '../icons/if.svg';
import isObject from 'lodash/isObject'; import isObject from 'lodash/isObject';
import type {TestIdBuilder} from 'amis-core';
// 兼容原来的用法,后续不直接试用。 // 兼容原来的用法,后续不直接试用。
@ -284,10 +285,12 @@ export function Icon({
onTouchMove, onTouchMove,
onTouchEnd, onTouchEnd,
onTouchCancel, onTouchCancel,
style style,
testIdBuilder
}: { }: {
icon: string; icon: string;
iconContent?: string; iconContent?: string;
testIdBuilder?: TestIdBuilder;
} & React.ComponentProps<any>) { } & React.ComponentProps<any>) {
let cx = iconCx || cxClass; let cx = iconCx || cxClass;
@ -356,6 +359,7 @@ export function Icon({
className={cx(iconContent, className, classNameProp)} className={cx(iconContent, className, classNameProp)}
ref={refFn} ref={refFn}
style={style} style={style}
{...testIdBuilder?.getTestId()}
></div> ></div>
); );
} }
@ -370,6 +374,7 @@ export function Icon({
// @ts-ignore // @ts-ignore
icon={icon} icon={icon}
style={style} style={style}
{...testIdBuilder?.getTestId()}
/> />
); );
} }

View File

@ -23,6 +23,7 @@ import Cell from './Cell';
import HeadCellSort from './HeadCellSort'; import HeadCellSort from './HeadCellSort';
import HeadCellFilter from './HeadCellFilter'; import HeadCellFilter from './HeadCellFilter';
import HeadCellSelect from './HeadCellSelect'; import HeadCellSelect from './HeadCellSelect';
import type {TestIdBuilder} from 'amis-core';
export interface Props extends ThemeProps { export interface Props extends ThemeProps {
draggable: boolean; draggable: boolean;
@ -48,6 +49,7 @@ export interface Props extends ThemeProps {
onSelectAll: Function; onSelectAll: Function;
onFilter?: Function; onFilter?: Function;
onResizeMouseDown: Function; onResizeMouseDown: Function;
testIdBuilder?: TestIdBuilder;
} }
export default class Head extends React.PureComponent<Props> { export default class Head extends React.PureComponent<Props> {
@ -121,7 +123,8 @@ export default class Head extends React.PureComponent<Props> {
onSort, onSort,
onSelectAll, onSelectAll,
onFilter, onFilter,
onResizeMouseDown onResizeMouseDown,
testIdBuilder
} = this.props; } = this.props;
const {thColumns, tdColumns} = getBuildColumns(columns); const {thColumns, tdColumns} = getBuildColumns(columns);
@ -177,6 +180,7 @@ export default class Head extends React.PureComponent<Props> {
col="drag" col="drag"
classnames={cx} classnames={cx}
classPrefix={classPrefix} classPrefix={classPrefix}
testIdBuilder={testIdBuilder?.getChild(`drag-${index}`)}
></Cell> ></Cell>
) : null} ) : null}
{!draggable && selectable && index === 0 ? ( {!draggable && selectable && index === 0 ? (
@ -189,6 +193,7 @@ export default class Head extends React.PureComponent<Props> {
col="select" col="select"
classnames={cx} classnames={cx}
classPrefix={classPrefix} classPrefix={classPrefix}
testIdBuilder={testIdBuilder?.getChild(`select-${index}`)}
> >
{rowSelectionType !== 'radio' {rowSelectionType !== 'radio'
? [ ? [
@ -234,6 +239,9 @@ export default class Head extends React.PureComponent<Props> {
onSort={(payload: SortProps) => { onSort={(payload: SortProps) => {
onSort && onSort(payload, item); onSort && onSort(payload, item);
}} }}
testIdBuilder={testIdBuilder?.getChild(
`sort-${colIndex}`
)}
></HeadCellSort> ></HeadCellSort>
); );
} }
@ -247,6 +255,9 @@ export default class Head extends React.PureComponent<Props> {
column={item} column={item}
popOverContainer={popOverContainer} popOverContainer={popOverContainer}
onFilter={onFilter} onFilter={onFilter}
testIdBuilder={testIdBuilder?.getChild(
`filter-${colIndex}`
)}
></HeadCellFilter> ></HeadCellFilter>
); );
} }
@ -301,6 +312,7 @@ export default class Head extends React.PureComponent<Props> {
})} })}
depth={item.depth} depth={item.depth}
col={String(colIndex)} col={String(colIndex)}
testIdBuilder={testIdBuilder?.getChild(`cell-${colIndex}`)}
> >
{typeof item.title === 'function' {typeof item.title === 'function'
? item.title(children) ? item.title(children)

View File

@ -16,6 +16,8 @@ import {
PopOver PopOver
} from 'amis-core'; } from 'amis-core';
import type {TestIdBuilder} from 'amis-core';
export interface FilterPayload { export interface FilterPayload {
closeDropdown?: boolean; closeDropdown?: boolean;
} }
@ -38,6 +40,7 @@ export interface Props extends ThemeProps, LocaleProps {
setSelectedKeys?: (keys: Array<string | number> | string) => void; setSelectedKeys?: (keys: Array<string | number> | string) => void;
classnames: ClassNamesFn; classnames: ClassNamesFn;
classPrefix: string; classPrefix: string;
testIdBuilder?: TestIdBuilder;
} }
export interface State { export interface State {

View File

@ -21,6 +21,7 @@ import HeadCellDropDown, {
import CheckBox from '../Checkbox'; import CheckBox from '../Checkbox';
import Button from '../Button'; import Button from '../Button';
import {Icon} from '../icons'; import {Icon} from '../icons';
import type {TestIdBuilder} from 'amis-core';
export interface Props extends ThemeProps, LocaleProps { export interface Props extends ThemeProps, LocaleProps {
column: any; column: any;
@ -30,6 +31,7 @@ export interface Props extends ThemeProps, LocaleProps {
popOverContainer?: () => HTMLElement; popOverContainer?: () => HTMLElement;
classnames: ClassNamesFn; classnames: ClassNamesFn;
classPrefix: string; classPrefix: string;
testIdBuilder?: TestIdBuilder;
} }
export interface OptionProps { export interface OptionProps {
@ -92,7 +94,8 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
column, column,
popOverContainer, popOverContainer,
classnames: cx, classnames: cx,
classPrefix: ns classPrefix: ns,
testIdBuilder
} = this.props; } = this.props;
const filterProps = { const filterProps = {
@ -110,6 +113,7 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
onClick={() => onClick={() =>
this.handleClick(confirm, setSelectedKeys, [option.value]) this.handleClick(confirm, setSelectedKeys, [option.value])
} }
{...testIdBuilder?.getChild(`${index}`).getTestId()}
> >
{option.text} {option.text}
</li> </li>
@ -126,6 +130,7 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
) )
} }
checked={option.selected} checked={option.selected}
testIdBuilder={testIdBuilder?.getChild(`ckbx-${index}`)}
> >
{option.text} {option.text}
</CheckBox> </CheckBox>
@ -140,6 +145,7 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
size={'xs'} size={'xs'}
level={'primary'} level={'primary'}
onClick={() => this.handleConfirmClick(confirm)} onClick={() => this.handleConfirmClick(confirm)}
testIdBuilder={testIdBuilder?.getChild(`btn-confirm`)}
> >
</Button> </Button>
@ -148,6 +154,7 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
onClick={() => onClick={() =>
this.handleCancelClick(confirm, setSelectedKeys) this.handleCancelClick(confirm, setSelectedKeys)
} }
testIdBuilder={testIdBuilder?.getChild(`btn-cancel`)}
> >
</Button> </Button>
@ -169,6 +176,7 @@ export class HeadCellFilter extends React.PureComponent<Props, State> {
icon="column-filter" icon="column-filter"
className="icon" className="icon"
iconContent="table-filter-icon" iconContent="table-filter-icon"
testIdBuilder={testIdBuilder?.getChild(`icon`)}
/> />
} }
active={ active={

View File

@ -14,12 +14,14 @@ import {
} from 'amis-core'; } from 'amis-core';
import {Icon} from '../icons'; import {Icon} from '../icons';
import {ColumnProps} from './index'; import {ColumnProps} from './index';
import type {TestIdBuilder} from 'amis-core';
export interface Props extends ThemeProps, LocaleProps { export interface Props extends ThemeProps, LocaleProps {
column: ColumnProps; column: ColumnProps;
onSort?: (payload: {orderBy: string; orderDir: string}) => any; onSort?: (payload: {orderBy: string; orderDir: string}) => any;
active?: boolean; active?: boolean;
classnames: ClassNamesFn; classnames: ClassNamesFn;
testIdBuilder?: TestIdBuilder;
} }
export interface State { export interface State {
@ -50,11 +52,12 @@ export class HeadCellSort extends React.PureComponent<Props, State> {
} }
render() { render() {
const {active, column, onSort, classnames: cx} = this.props; const {active, column, onSort, classnames: cx, testIdBuilder} = this.props;
return ( return (
<span <span
className={cx('TableCell-sortBtn', 'aaa')} className={cx('TableCell-sortBtn', 'aaa')}
{...testIdBuilder?.getTestId()}
onClick={async () => { onClick={async () => {
let sortPayload: State = { let sortPayload: State = {
orderBy: '', orderBy: '',
@ -97,6 +100,7 @@ export class HeadCellSort extends React.PureComponent<Props, State> {
icon="sort-desc" icon="sort-desc"
className="icon" className="icon"
iconContent="table-sort-down" iconContent="table-sort-down"
testIdBuilder={testIdBuilder?.getChild('desc')}
/> />
</i> </i>
<i <i
@ -105,7 +109,12 @@ export class HeadCellSort extends React.PureComponent<Props, State> {
active && this.state.orderDir === 'asc' ? 'is-active' : '' active && this.state.orderDir === 'asc' ? 'is-active' : ''
)} )}
> >
<Icon icon="sort-asc" className="icon" iconContent="table-sort-up" /> <Icon
icon="sort-asc"
className="icon"
iconContent="table-sort-up"
testIdBuilder={testIdBuilder?.getChild('asc')}
/>
</i> </i>
<i <i
className={cx( className={cx(
@ -117,6 +126,7 @@ export class HeadCellSort extends React.PureComponent<Props, State> {
icon="sort-default" icon="sort-default"
className="icon" className="icon"
iconContent="table-sort-default" iconContent="table-sort-default"
testIdBuilder={testIdBuilder?.getChild('default')}
/> />
</i> </i>
</span> </span>

View File

@ -685,9 +685,11 @@ export class Table extends React.PureComponent<TableProps, TableState> {
dataSource, dataSource,
onSort, onSort,
onSelectAll, onSelectAll,
onFilter onFilter,
testIdBuilder
} = this.props; } = this.props;
console.log(testIdBuilder);
const rowSelectionKeyField = this.getRowSelectionKeyField(); const rowSelectionKeyField = this.getRowSelectionKeyField();
const dataList = const dataList =
rowSelection && rowSelection.getCheckboxProps rowSelection && rowSelection.getCheckboxProps
@ -754,6 +756,7 @@ export class Table extends React.PureComponent<TableProps, TableState> {
}} }}
onFilter={onFilter} onFilter={onFilter}
onResizeMouseDown={this.onResizeMouseDown.bind(this)} onResizeMouseDown={this.onResizeMouseDown.bind(this)}
testIdBuilder={testIdBuilder?.getChild('head')}
></Head> ></Head>
); );
} }

View File

@ -46,7 +46,14 @@ export class HeadCellSearchDropDown extends React.Component<
} }
buildSchema() { buildSchema() {
const {searchable, sortable, name, label, translate: __} = this.props; const {
searchable,
sortable,
name,
label,
translate: __,
testIdBuilder
} = this.props;
let schema: any; let schema: any;
@ -58,7 +65,8 @@ export class HeadCellSearchDropDown extends React.Component<
type: 'text', type: 'text',
name, name,
placeholder: label, placeholder: label,
clearable: true clearable: true,
testid: testIdBuilder?.getChild(name)?.getTestIdValue()
} }
] ]
}; };
@ -81,6 +89,9 @@ export class HeadCellSearchDropDown extends React.Component<
{ {
type: searchable.type || 'text', type: searchable.type || 'text',
name: searchable.name || name, name: searchable.name || name,
testid: testIdBuilder
?.getChild(searchable.name || name)
?.getTestIdValue(),
placeholder: label, placeholder: label,
...searchable ...searchable
} }
@ -132,23 +143,27 @@ export class HeadCellSearchDropDown extends React.Component<
wrapperComponent: 'div', wrapperComponent: 'div',
wrapWithPanel: true, wrapWithPanel: true,
title: false, title: false,
testid: testIdBuilder?.getChild('form')?.getTestIdValue(),
actions: [ actions: [
{ {
type: 'button', type: 'button',
label: __('reset'), label: __('reset'),
actionType: 'clear-and-submit' actionType: 'clear-and-submit',
testid: testIdBuilder?.getChild('btn-reset')?.getTestIdValue()
}, },
{ {
type: 'button', type: 'button',
label: __('cancel'), label: __('cancel'),
actionType: 'cancel' actionType: 'cancel',
testid: testIdBuilder?.getChild('btn-cancel')?.getTestIdValue()
}, },
{ {
label: __('search'), label: __('search'),
type: 'submit', type: 'submit',
primary: true primary: true,
testid: testIdBuilder?.getChild('btn-search')?.getTestIdValue()
} }
] ]
}; };
@ -242,7 +257,8 @@ export class HeadCellSearchDropDown extends React.Component<
orderBy, orderBy,
popOverContainer, popOverContainer,
classPrefix: ns, classPrefix: ns,
classnames: cx classnames: cx,
testIdBuilder
} = this.props; } = this.props;
const formSchema = this.buildSchema(); const formSchema = this.buildSchema();
@ -261,6 +277,7 @@ export class HeadCellSearchDropDown extends React.Component<
icon="search" icon="search"
className="icon" className="icon"
iconContent="table-search-icon" iconContent="table-search-icon"
testIdBuilder={testIdBuilder?.getChild('search-icon')}
/> />
} }
popOverContainer={ popOverContainer={
@ -284,6 +301,7 @@ export class HeadCellSearchDropDown extends React.Component<
} }
}) as JSX.Element; }) as JSX.Element;
}} }}
testIdBuilder={testIdBuilder}
></HeadCellDropDown> ></HeadCellDropDown>
); );
} }

View File

@ -1054,6 +1054,7 @@ export default class Table2 extends React.Component<Table2Props, object> {
searchable={column.searchable} searchable={column.searchable}
onSearch={this.handleSearch} onSearch={this.handleSearch}
key={'th-search-' + col} key={'th-search-' + col}
testIdBuilder={testIdBuilder?.getChild(`head-search-${col}`)}
/> />
); );
} }