chore: 调整 inputTable 的 addItem 动作,不指定 index 时从后插入 (#7898)

This commit is contained in:
liaoxuezhi 2023-08-22 12:38:59 +08:00 committed by GitHub
parent d66a7cd7c7
commit 71bfc3f730
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 143 additions and 19 deletions

View File

@ -679,7 +679,7 @@ export class TableControlPlugin extends BasePlugin {
},
label: '插入位置',
size: 'lg',
placeholder: '请输入行号,为空则在部插入'
placeholder: '请输入行号,为空则在部插入'
},
{
type: 'combo',

View File

@ -5,6 +5,7 @@ import Drawer from './Drawer';
import {localeable, LocaleProps, themeable, ThemeProps} from 'amis-core';
import Spinner from './Spinner';
import PopUp from './PopUp';
import {findDOMNode} from 'react-dom';
export interface ConfirmBoxProps extends LocaleProps, ThemeProps {
show?: boolean;
@ -25,6 +26,7 @@ export interface ConfirmBoxProps extends LocaleProps, ThemeProps {
}
| undefined
>;
popOverContainer: () => HTMLElement | null | undefined;
}) => JSX.Element);
popOverContainer?: any;
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
@ -65,6 +67,14 @@ export function ConfirmBox({
const bodyRef = React.useRef<
{submit: () => Promise<Record<string, any>>} | undefined
>();
const bodyDomRef = React.useRef<HTMLElement | null>();
const getPopOverContainer = React.useCallback(() => {
const dom =
bodyDomRef.current && !(bodyDomRef.current as HTMLElement).nodeType
? findDOMNode(bodyDomRef.current)
: null;
return dom?.parentElement;
}, []);
const handleConfirm = React.useCallback(async () => {
setError('');
setLoading(true);
@ -103,7 +113,8 @@ export function ConfirmBox({
{typeof children === 'function'
? children({
bodyRef: bodyRef,
loading
loading,
popOverContainer: getPopOverContainer
})
: children}
</PopUp>
@ -121,11 +132,12 @@ export function ConfirmBox({
{title}
</Modal.Header>
) : null}
<Modal.Body className={bodyClassName}>
<Modal.Body ref={bodyDomRef as any} className={bodyClassName}>
{typeof children === 'function'
? children({
bodyRef: bodyRef,
loading
loading,
popOverContainer: getPopOverContainer
})
: children}
</Modal.Body>
@ -169,10 +181,15 @@ export function ConfirmBox({
<div className={cx('Drawer-title')}>{title}</div>
</div>
) : null}
<div className={cx('Drawer-body', bodyClassName)}>
<div
ref={bodyDomRef as any}
className={cx('Drawer-body', bodyClassName)}
>
{typeof children === 'function'
? children({
bodyRef: bodyRef
bodyRef: bodyRef,
loading,
popOverContainer: getPopOverContainer
})
: children}
</div>

View File

@ -25,6 +25,7 @@ export interface PickerContainerProps
value: any;
onChange: (value: any) => void;
setState: (state: any) => void;
loading?: boolean;
[propName: string]: any;
}) => JSX.Element | null;
value?: any;
@ -63,6 +64,7 @@ export class PickerContainer extends React.Component<
@autobind
async handleClick() {
const state = {
value: this.props.value,
...(await this.props.onPickerOpen?.(this.props)),
isOpened: true
};
@ -159,7 +161,7 @@ export class PickerContainer extends React.Component<
popOverContainer={popOverContainer}
mobileUI={mobileUI}
>
{() =>
{({popOverContainer, loading}) =>
popOverRender({
...(this.state as any),
ref: this.bodyRef,
@ -167,7 +169,8 @@ export class PickerContainer extends React.Component<
onClose: this.close,
onChange: this.handleChange,
onConfirm: this.confirm,
popOverContainer
popOverContainer,
loading
})!
}
</ConfirmBox>

View File

@ -445,3 +445,103 @@ test('Renderer:input-table cell selects delete', async () => {
replaceReactAriaIds(container);
expect(container).toMatchSnapshot();
});
test('Renderer:input-table doaction:additem', async () => {
const onSubmit = jest.fn();
const {container, findByRole, findByText} = render(
amisRender(
{
type: 'form',
data: {
table: [{a: 2}]
},
body: [
{
label: 'addItem1',
type: 'button',
onEvent: {
click: {
actions: [
{
actionType: 'addItem',
componentId: 'inputtable',
args: {
item: {
a: 3
}
}
}
]
}
}
},
{
label: 'addItem2',
type: 'button',
onEvent: {
click: {
actions: [
{
actionType: 'addItem',
componentId: 'inputtable',
args: {
index: 0,
item: {
a: 1
}
}
}
]
}
}
},
{
type: 'input-table',
id: 'inputtable',
name: 'table',
label: 'Table',
needConfirm: false,
columns: [
{
type: 'text',
name: 'a',
quickEdit: false
}
]
},
{
type: 'submit',
label: 'submitBtn'
}
]
},
{onSubmit},
makeEnv({})
)
);
const addItem1 = await findByText('addItem1');
fireEvent.click(addItem1);
const addItem2 = await findByText('addItem2');
fireEvent.click(addItem2);
const submitBtn = await findByText('submitBtn');
fireEvent.click(submitBtn);
await wait(200);
expect(onSubmit).toBeCalled();
expect(onSubmit.mock.calls[0][0]).toEqual({
table: [
{
a: 1
},
{
a: 2
},
{
a: 3
}
]
});
});

View File

@ -1681,21 +1681,25 @@ export class TableControlRenderer extends FormTable {
toAdd = args.item;
}
toAdd = Array.isArray(toAdd) ? toAdd : [toAdd];
// 如果没指定插入的位置args.index则默认在头部插入
const pushIndex = args.index || 0;
// 从右往左插入
for (let i = toAdd.length; i >= 1; i--) {
if (
toAdd = (Array.isArray(toAdd) ? toAdd : [toAdd]).filter(
a =>
!valueField ||
!find(
items,
item =>
item[valueField as string] == toAdd[i - 1][valueField as string]
item => item[valueField as string] == a[valueField as string]
)
) {
items.splice(pushIndex, 0, toAdd[i - 1]);
}
);
let index = args.index;
if (typeof index === 'string' && /^\d+$/.test(index)) {
index = parseInt(index, 10);
}
if (typeof index === 'number') {
items.splice(index, 0, ...toAdd);
} else {
// 没有指定默认插入在最后
items.push(...toAdd);
}
this.setState(