Merge pull request #7780 from hsm-lv/chore-eventaction

chore:确认弹窗动作取消后阻止组件默认行为 Close #6115
This commit is contained in:
hsm-lv 2023-08-11 10:23:09 +08:00 committed by GitHub
commit 0641153ce9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 248 additions and 0 deletions

View File

@ -156,6 +156,102 @@ IconSchema 配置
| -------- | ------------------------------------ | ---------------- |
| change | `[name]: string \| boolean` 组件的值 | 开关值变化时触发 |
### change
switch 值更新时弹出确认提示,确认后发送请求。
```schema: scope="body"
{
"type": "crud",
"syncLocation": false,
"api": "/api/mock2/sample",
"columns": [
{
"name": "id",
"label": "ID",
"id": "u:daa79afa2e53"
},
{
"name": "engine",
"label": "Rendering engine",
"id": "u:3343cf518656"
},
{
"name": "browser",
"label": "Browser",
"id": "u:fbdc85e45e2f"
},
{
"name": "platform",
"label": "Platform(s)",
"id": "u:ccdb48cc1804"
},
{
"name": "switch",
"label": "开关",
"id": "u:30a36768acce",
"type": "switch",
"inline": true,
"onEvent": {
"change": {
"weight": 0,
"actions": [
{
"actionType": "confirmDialog",
"dialog": {
"type": "dialog",
"title": "弹框标题",
"body": [
{
"type": "tpl",
"tpl": "确定要修改${id}吗?",
"wrapperComponent": "",
"inline": false,
"id": "u:1965506c7599"
}
],
"showCloseButton": true,
"showErrorMsg": true,
"showLoading": true,
"className": "app-popover",
"id": "u:d9783223df98",
"actions": [
{
"type": "button",
"actionType": "cancel",
"label": "取消",
"id": "u:302efee8613b"
},
{
"type": "button",
"actionType": "confirm",
"label": "确定",
"primary": true,
"id": "u:4a4d63cf35e1"
}
]
}
},
{
"actionType": "ajax",
"outputVar": "responseResult",
"options": {
},
"api": {
"method": "get",
"url": "/api/mock2/form/saveForm"
}
}
]
}
},
"value": false
}
],
"id": "u:6c781a765f97"
}
```
## 动作表
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
@ -163,3 +259,52 @@ IconSchema 配置
| 动作名称 | 动作配置 | 说明 |
| -------- | ------------------------------------- | -------- |
| setValue | `value: string \| boolean` 更新的数据 | 更新数据 |
### setValue
```schema: scope="body"
[
{
"type": "button",
"label": "修改开关的值",
"className": "mb-2",
"onEvent": {
"click": {
"actions": [
{
"componentId": "u:6613bfa3a18e",
"actionType": "setValue",
"args": {
"value": true
}
}
]
}
},
"id": "u:9d7d695145bb"
},
{
"type": "form",
"title": "表单",
"debug": true,
"body": [
{
"label": "开启",
"type": "switch",
"name": "switch",
"id": "u:6613bfa3a18e",
"value": false,
"mode": "inline"
}
],
"id": "u:82d44e407eb0",
"actions": [
{
"type": "submit",
"label": "提交",
"primary": true
}
]
}
]
```

View File

@ -318,6 +318,7 @@ export const runAction = async (
// 二次确认弹窗如果取消,则终止后续动作
if (action?.actionType === 'confirmDialog' && !actionResult) {
stopped = true;
preventDefault = true; // 这种对表单项change比较有意义例如switch切换时弹确认弹窗如果取消后不能把switch修改了
}
let stopPropagation = false;

View File

@ -0,0 +1,102 @@
import {fireEvent, render, waitFor} from '@testing-library/react';
import '../../../../src';
import {render as amisRender} from '../../../../src';
import {makeEnv, wait} from '../../../helper';
test('EventAction:switch', async () => {
const fetcher = jest.fn().mockImplementation(() =>
Promise.resolve({
data: {
status: 0,
msg: 'ok',
data: {
id: 1
}
}
})
);
const {container, getByText} = render(
amisRender(
{
type: 'page',
body: [
{
type: 'button',
label: '修改开关的值',
className: 'mb-2',
onEvent: {
click: {
actions: [
{
componentId: 'u:6613bfa3a18e',
actionType: 'setValue',
args: {
value: true
}
}
]
}
},
id: 'u:9d7d695145bb'
},
{
type: 'form',
title: '表单',
debug: true,
body: [
{
label: '开启',
type: 'switch',
name: 'switch',
id: 'u:6613bfa3a18e',
value: false,
mode: 'inline',
onEvent: {
change: {
actions: [
{
actionType: 'ajax',
api: '/api/mock2/form/saveForm?switch=${switch}'
}
]
}
}
}
],
id: 'u:82d44e407eb0',
actions: [
{
type: 'submit',
label: '提交',
primary: true
}
]
}
]
},
{},
makeEnv({
fetcher
})
)
);
await waitFor(() => {
expect(getByText('修改开关的值')).toBeInTheDocument();
});
fireEvent.click(getByText(/修改开关的值/));
await waitFor(() => {
expect(container.querySelector('.is-checked')).toBeInTheDocument();
});
fireEvent.click(container.querySelector('.is-checked')!);
await waitFor(() => {
expect(fetcher).toHaveBeenCalled();
expect(fetcher.mock.calls[0][0].url).toEqual(
'/api/mock2/form/saveForm?switch=false'
);
});
});