mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat(amis): 增加tabs、table cell的testid (#9541)
This commit is contained in:
parent
da01d47b0e
commit
51131b64c0
@ -2325,4 +2325,12 @@ export class TestIdBuilder {
|
||||
[TEST_ID_KEY]: data ? filter(this.testId, data) : this.testId
|
||||
};
|
||||
}
|
||||
|
||||
getTestIdValue(data?: object) {
|
||||
if (this.testId == null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return data ? filter(this.testId, data) : this.testId;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,13 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {ClassName, localeable, LocaleProps, Schema} from 'amis-core';
|
||||
import {
|
||||
ClassName,
|
||||
localeable,
|
||||
LocaleProps,
|
||||
Schema,
|
||||
TestIdBuilder
|
||||
} from 'amis-core';
|
||||
import Transition, {ENTERED, ENTERING} from 'react-transition-group/Transition';
|
||||
import {themeable, ThemeProps, noop} from 'amis-core';
|
||||
import {uncontrollable} from 'amis-core';
|
||||
@ -59,6 +65,7 @@ export interface TabProps extends ThemeProps {
|
||||
children?: React.ReactNode | Array<React.ReactNode>;
|
||||
swipeable?: boolean;
|
||||
onSelect?: (eventKey: string | number) => void;
|
||||
testIdBuilder?: TestIdBuilder;
|
||||
}
|
||||
|
||||
class TabComponent extends React.PureComponent<TabProps> {
|
||||
@ -113,7 +120,8 @@ class TabComponent extends React.PureComponent<TabProps> {
|
||||
children,
|
||||
className,
|
||||
swipeable,
|
||||
mobileUI
|
||||
mobileUI,
|
||||
testIdBuilder
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -140,6 +148,7 @@ class TabComponent extends React.PureComponent<TabProps> {
|
||||
onTouchMove={swipeable && mobileUI ? this.onTouchMove : noop}
|
||||
onTouchEnd={swipeable && mobileUI ? this.onTouchEnd : noop}
|
||||
onTouchCancel={swipeable && mobileUI ? this.onTouchEnd : noop}
|
||||
{...testIdBuilder?.getTestId()}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
@ -181,6 +190,7 @@ export interface TabsProps extends ThemeProps, LocaleProps {
|
||||
collapseBtnLabel?: string;
|
||||
popOverContainer?: any;
|
||||
children?: React.ReactNode | Array<React.ReactNode>;
|
||||
testIdBuilder?: TestIdBuilder;
|
||||
}
|
||||
|
||||
export interface IDragInfo {
|
||||
@ -586,7 +596,8 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
draggable,
|
||||
showTip,
|
||||
showTipClassName,
|
||||
editable
|
||||
editable,
|
||||
testIdBuilder
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@ -646,7 +657,9 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
)}
|
||||
</a>
|
||||
);
|
||||
|
||||
const tabTestIdBuidr = testIdBuilder?.getChild(
|
||||
`tab-${typeof title === 'string' ? title : index}`
|
||||
);
|
||||
return (
|
||||
<li
|
||||
className={cx(
|
||||
@ -662,6 +675,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
typeof title === 'string' &&
|
||||
this.handleStartEdit(index, title);
|
||||
}}
|
||||
{...tabTestIdBuidr?.getChild('link').getTestId()}
|
||||
>
|
||||
{showTip ? (
|
||||
<TooltipWrapper
|
||||
@ -684,6 +698,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
this.props.onClose &&
|
||||
this.props.onClose(index, eventKey ?? index);
|
||||
}}
|
||||
{...tabTestIdBuidr?.getChild('close').getTestId()}
|
||||
>
|
||||
<Icon icon="close" className={cx('Tabs-link-close-icon')} />
|
||||
</span>
|
||||
@ -722,7 +737,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
}
|
||||
|
||||
renderArrow(type: 'left' | 'right') {
|
||||
const {mode: dMode, tabsMode} = this.props;
|
||||
const {mode: dMode, tabsMode, testIdBuilder} = this.props;
|
||||
const mode = tabsMode || dMode;
|
||||
if (['vertical', 'sidebar'].includes(mode)) {
|
||||
return;
|
||||
@ -738,6 +753,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
'Tabs-linksContainer-arrow--' + type,
|
||||
disabled && 'Tabs-linksContainer-arrow--disabled'
|
||||
)}
|
||||
{...testIdBuilder?.getChild(`arrow-${type}`).getTestId()}
|
||||
>
|
||||
<Icon icon="right-arrow-bold" className="icon" />
|
||||
</div>
|
||||
@ -835,7 +851,8 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
draggable,
|
||||
sidePosition,
|
||||
addBtnText,
|
||||
mobileUI
|
||||
mobileUI,
|
||||
testIdBuilder
|
||||
} = this.props;
|
||||
|
||||
const {isOverflow} = this.state;
|
||||
@ -851,6 +868,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
<div
|
||||
className={cx('Tabs-addable')}
|
||||
onClick={() => this.handleAddBtn()}
|
||||
{...testIdBuilder?.getChild('add-tab').getTestId()}
|
||||
>
|
||||
<Icon icon="plus" className={cx('Tabs-addable-icon')} />
|
||||
{addBtnText}
|
||||
@ -871,6 +889,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
{...testIdBuilder?.getTestId()}
|
||||
>
|
||||
{!['vertical', 'sidebar', 'chrome'].includes(mode) ? (
|
||||
<div
|
||||
@ -885,6 +904,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
'Tabs-linksContainer',
|
||||
isOverflow && 'Tabs-linksContainer--overflow'
|
||||
)}
|
||||
{...testIdBuilder?.getChild('links').getTestId()}
|
||||
>
|
||||
{!mobileUI ? this.renderArrow('left') : null}
|
||||
<div className={cx('Tabs-linksContainer-main')}>
|
||||
@ -911,6 +931,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
'is-mobile': mobileUI
|
||||
})}
|
||||
role="tablist"
|
||||
{...testIdBuilder?.getChild('links').getTestId()}
|
||||
>
|
||||
{this.renderNavs()}
|
||||
{additionBtns}
|
||||
@ -925,7 +946,11 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
})}
|
||||
</div>
|
||||
{draggable && (
|
||||
<div className={cx('Tabs-drag-tip')} ref={this.dragTipRef} />
|
||||
<div
|
||||
className={cx('Tabs-drag-tip')}
|
||||
ref={this.dragTipRef}
|
||||
{...testIdBuilder?.getChild('drag').getTestId()}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -7,7 +7,8 @@ import {
|
||||
ThemeProps,
|
||||
resolveVariable,
|
||||
buildTrackExpression,
|
||||
evalTrackExpression
|
||||
evalTrackExpression,
|
||||
TestIdBuilder
|
||||
} from 'amis-core';
|
||||
import {BadgeObject, Checkbox, Icon, Spinner} from 'amis-ui';
|
||||
import React from 'react';
|
||||
@ -33,6 +34,7 @@ export interface CellProps extends ThemeProps {
|
||||
quickEditFormRef: any;
|
||||
onImageEnlarge?: any;
|
||||
translate: (key: string, ...args: Array<any>) => string;
|
||||
testIdBuilder: TestIdBuilder;
|
||||
}
|
||||
|
||||
export default function Cell({
|
||||
@ -53,7 +55,8 @@ export default function Cell({
|
||||
popOverContainer,
|
||||
quickEditFormRef,
|
||||
onImageEnlarge,
|
||||
translate: __
|
||||
translate: __,
|
||||
testIdBuilder
|
||||
}: CellProps) {
|
||||
if (column.name && item.rowSpans[column.name] === 0) {
|
||||
return null;
|
||||
@ -77,6 +80,7 @@ export default function Cell({
|
||||
<td
|
||||
style={style}
|
||||
className={cx(column.pristine.className, stickyClassName)}
|
||||
{...testIdBuilder.getTestId()}
|
||||
>
|
||||
<Checkbox
|
||||
classPrefix={ns}
|
||||
@ -85,6 +89,7 @@ export default function Cell({
|
||||
checked={item.checked || item.partial}
|
||||
disabled={item.checkdisable || !item.checkable}
|
||||
onChange={onCheckboxChange}
|
||||
testIdBuilder={testIdBuilder.getChild('chekbx')}
|
||||
/>
|
||||
</td>
|
||||
);
|
||||
@ -95,6 +100,7 @@ export default function Cell({
|
||||
className={cx(column.pristine.className, stickyClassName, {
|
||||
'is-dragDisabled': !item.draggable
|
||||
})}
|
||||
{...testIdBuilder.getChild('drag').getTestId()}
|
||||
>
|
||||
{item.draggable ? <Icon icon="drag" className="icon" /> : null}
|
||||
</td>
|
||||
@ -111,6 +117,9 @@ export default function Cell({
|
||||
// data-tooltip="展开/收起"
|
||||
// data-position="top"
|
||||
onClick={item.toggleExpanded}
|
||||
{...testIdBuilder
|
||||
.getChild(item.expanded ? 'fold' : 'expand')
|
||||
.getTestId()}
|
||||
>
|
||||
<Icon icon="right-arrow-bold" className="icon" />
|
||||
</a>
|
||||
@ -142,6 +151,7 @@ export default function Cell({
|
||||
key="retryBtn"
|
||||
onClick={item.resetDefered}
|
||||
data-tooltip={__('Options.retry', {reason: item.error})}
|
||||
{...testIdBuilder.getChild('retry').getTestId()}
|
||||
>
|
||||
<Icon icon="retry" className="icon" />
|
||||
</a>
|
||||
@ -152,6 +162,9 @@ export default function Cell({
|
||||
// data-tooltip="展开/收起"
|
||||
// data-position="top"
|
||||
onClick={item.toggleExpanded}
|
||||
{...testIdBuilder
|
||||
.getChild(item.expanded ? 'fold' : 'expand')
|
||||
.getTestId()}
|
||||
>
|
||||
<Icon icon="right-arrow-bold" className="icon" />
|
||||
</a>
|
||||
@ -174,6 +187,7 @@ export default function Cell({
|
||||
draggable
|
||||
onDragStart={onDragStart}
|
||||
className={cx('Table-dragBtn')}
|
||||
{...testIdBuilder.getChild('drag').getTestId()}
|
||||
>
|
||||
<Icon icon="drag" className="icon" />
|
||||
</a>
|
||||
@ -245,7 +259,8 @@ export default function Cell({
|
||||
{
|
||||
...column.pristine,
|
||||
column: column.pristine,
|
||||
type: 'cell'
|
||||
type: 'cell',
|
||||
testid: testIdBuilder.getTestIdValue()
|
||||
},
|
||||
subProps
|
||||
);
|
||||
|
@ -72,7 +72,8 @@ export class TableBody extends React.Component<TableBodyProps> {
|
||||
renderRows(
|
||||
rows: Array<any>,
|
||||
columns = this.props.columns,
|
||||
rowProps: any = {}
|
||||
rowProps: any = {},
|
||||
indexPath?: string
|
||||
): any {
|
||||
const {
|
||||
rowClassName,
|
||||
@ -99,16 +100,20 @@ export class TableBody extends React.Component<TableBodyProps> {
|
||||
|
||||
return rows.map((item: IRow, rowIndex: number) => {
|
||||
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
|
||||
const rowPath = `${indexPath ? indexPath + '/' : ''}${rowIndex}`;
|
||||
const rowTestBuidr = testIdBuilder?.getChild(`row-${rowPath}`);
|
||||
|
||||
const doms = [
|
||||
<TableRow
|
||||
{...itemProps}
|
||||
testIdBuilder={testIdBuilder?.getChild(`row${rowIndex}`)}
|
||||
testIdBuilder={rowTestBuidr}
|
||||
store={store}
|
||||
itemAction={itemAction}
|
||||
classnames={cx}
|
||||
checkOnItemClick={checkOnItemClick}
|
||||
key={item.id}
|
||||
itemIndex={rowIndex}
|
||||
rowPath={rowPath}
|
||||
item={item}
|
||||
itemClassName={cx(
|
||||
rowClassNameExpr
|
||||
@ -147,6 +152,7 @@ export class TableBody extends React.Component<TableBodyProps> {
|
||||
checkOnItemClick={checkOnItemClick}
|
||||
key={`foot-${item.id}`}
|
||||
itemIndex={rowIndex}
|
||||
rowPath={rowPath}
|
||||
item={item}
|
||||
itemClassName={cx(
|
||||
rowClassNameExpr
|
||||
@ -167,16 +173,22 @@ export class TableBody extends React.Component<TableBodyProps> {
|
||||
onQuickChange={onQuickChange}
|
||||
ignoreFootableContent={ignoreFootableContent}
|
||||
{...rowProps}
|
||||
testIdBuilder={rowTestBuidr}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (item.children.length && item.expanded) {
|
||||
// 嵌套表格
|
||||
doms.push(
|
||||
...this.renderRows(item.children, columns, {
|
||||
...rowProps,
|
||||
parent: item
|
||||
})
|
||||
...this.renderRows(
|
||||
item.children,
|
||||
columns,
|
||||
{
|
||||
...rowProps,
|
||||
parent: item
|
||||
},
|
||||
rowPath
|
||||
)
|
||||
);
|
||||
}
|
||||
return doms;
|
||||
|
@ -45,6 +45,7 @@ interface TableRowProps extends Pick<RendererProps, 'render'> {
|
||||
checkOnItemClick?: boolean;
|
||||
ignoreFootableContent?: boolean;
|
||||
testIdBuilder?: TestIdBuilder;
|
||||
rowPath: string; // 整体行的路径,树形时需要父行序号/当前展开层级下的行序号
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
@ -205,6 +206,7 @@ export class TableRow extends React.PureComponent<
|
||||
trRef,
|
||||
isNested,
|
||||
testIdBuilder,
|
||||
rowPath,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
@ -267,6 +269,7 @@ export class TableRow extends React.PureComponent<
|
||||
width: null,
|
||||
rowIndex: itemIndex,
|
||||
colIndex: column.index,
|
||||
rowPath,
|
||||
key: column.index,
|
||||
onAction: this.handleAction,
|
||||
onQuickChange: this.handleQuickChange,
|
||||
@ -328,11 +331,11 @@ export class TableRow extends React.PureComponent<
|
||||
...rest,
|
||||
rowIndex: itemIndex,
|
||||
colIndex: column.index,
|
||||
rowPath,
|
||||
key: column.id,
|
||||
onAction: this.handleAction,
|
||||
onQuickChange: this.handleQuickChange,
|
||||
onChange: this.handleChange,
|
||||
testIdBuilder: testIdBuilder?.getChild(`col${column.index}`)
|
||||
onChange: this.handleChange
|
||||
})
|
||||
) : column.name && item.rowSpans[column.name] === 0 ? null : (
|
||||
<td key={column.id}>
|
||||
|
@ -2076,7 +2076,8 @@ export default class Table extends React.Component<TableProps, object> {
|
||||
classnames: cx,
|
||||
canAccessSuperData,
|
||||
itemBadge,
|
||||
translate
|
||||
translate,
|
||||
testIdBuilder
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -2100,6 +2101,9 @@ export default class Table extends React.Component<TableProps, object> {
|
||||
quickEditFormRef={this.subFormRef}
|
||||
onImageEnlarge={this.handleImageEnlarge}
|
||||
translate={translate}
|
||||
testIdBuilder={testIdBuilder.getChild(
|
||||
`cell-${props.rowPath}-${column.index}`
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -763,7 +763,8 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
collapseBtnLabel,
|
||||
disabled,
|
||||
mobileUI,
|
||||
swipeable
|
||||
swipeable,
|
||||
testIdBuilder
|
||||
} = this.props;
|
||||
|
||||
const mode = tabsMode || dMode;
|
||||
@ -809,6 +810,9 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
: unmountOnExit
|
||||
}
|
||||
onSelect={this.handleSelect}
|
||||
testIdBuilder={testIdBuilder.getChild(
|
||||
`tab-${typeof tab.title === 'string' ? tab.title : index}`
|
||||
)}
|
||||
>
|
||||
{render(
|
||||
`item/${index}`,
|
||||
@ -850,6 +854,9 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
: unmountOnExit
|
||||
}
|
||||
onSelect={this.handleSelect}
|
||||
testIdBuilder={testIdBuilder.getChild(
|
||||
`tab-${typeof tab.title === 'string' ? tab.title : index}`
|
||||
)}
|
||||
>
|
||||
{this.renderTab
|
||||
? this.renderTab(tab, this.props, index)
|
||||
@ -897,6 +904,7 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
collapseOnExceed={collapseOnExceed}
|
||||
collapseBtnLabel={collapseBtnLabel}
|
||||
mobileUI={mobileUI}
|
||||
testIdBuilder={testIdBuilder}
|
||||
>
|
||||
{children}
|
||||
</CTabs>
|
||||
|
Loading…
Reference in New Issue
Block a user