mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Mege Feat-X Into Master (#11252)
* feat: Editor 支持插件弹出面板 (#11055) * feat: Editor 支持插件弹出面板 (#11059) * chore: 暴露 RendererThumb * feat: resultBox item项支持点击事件 (#11060) * feat: resultBox item项支持点击事件 * feat: resultBox item项支持点击事件 * feat: resultBox item项点击事件增加testid * feat: resultBox item项点击事件更新jest快照 --------- Co-authored-by: hezhihang <hezhihang@baidu.com> * chore: 调整 Page 渲染器导出方便外部覆盖 * chore: ConfirmBox 支持配置 onEntered 和 onExit 事件 * chore: checkboxes radios 选项 children 必须是数组且有长度才切到分组展示 * feat: 折叠面板,无标题时显示折叠箭头。组件存在于表单中,面板新增切换展示方式按钮 (#11067) * feat: 折叠面板,无标题时显示折叠箭头。组件存在于表单中,面板新增切换展示方式按钮 * feat: 调整面板组件默认值 * feat: 调整无标题时,折叠箭头样式。调整面板配置 * 更新jest快照 * feat: page侧栏支持左右位置 (#11090) Co-authored-by: hezhihang <hezhihang@baidu.com> * chore: checkboxes radios 选项 children 必须是数组且有长度才切到分组展示 * feat: AvailableRenderersPanel 支持外围扩展 * feat: AvailableRenderersPanel 支持外围扩展 * feat: editor 插件 scaffoldForm 支持异步获取 * chore: add cross-env * chore: 避免 Table 数据更新死循环 * chore: 调整 ts 定义 * feat: 给配置面板加些标记方便外围扩充 * chore: checkboxes radios 选项 children 必须是数组且有长度才切到分组展示 * chore: Options 相关逻辑支持外部扩展 * feat: mapping支持接口变量是records,提供外围扩充函数 (#11105) * feat: mapping支持接口变量是records 的情况 * feat: 提供外围扩充函数 * feat: 修改函数名 * feat: 补充props 类型定义 * chore: 调整用例 * feat: 自定义样式扩展 (#11140) Co-authored-by: hezhihang <hezhihang@baidu.com> * feat: tabs支持删除动作,外观样式支持主题 * typo error * chore: 支持更多的场景 * feat: 穿梭选择器增加点击选项事件 * feat: 锚点导航调整为sticky布局 (#11143) * feat: 锚点导航调整为sticky布局 * bugfix * 更新快照 * 更新单测 * 更新单测 * bugfix * 优化样式 --------- Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com> * 动作面板支持外部注册 (#11149) * 动作面板支持外部注册 * 修复someTree报错 * chore: debug 面板调整 (#11152) * feat:事件动作面板支持查看调用链 * feat: 新增autoCheckChildren和onlyChildren属性配置面板,更改穿梭框事件点击位置 * feat: 预留外围扩充函数 * fix: 调整文案和属性名 * 修复初始化弹窗问题 * fix:自定义样式根节点不生效、样式修改时schema更新不正确,tabs动作仅支持hash删除 (#11145) Co-authored-by: hezhihang <hezhihang@baidu.com> * feat: 日期\日期范围组件可配禁止输入 (#11197) * feat:验证器手机和电话号支持国家代号,数字框新增显示上下按钮,修改自定义样式实现。 (#11198) * fix: 穿梭器面板中onlyChildren属性默认开启 * feat: 验证器中手机号和电话号支持国家代号 * feat: 数字框编辑器新增显示上下按钮开关,修改自定义样式实现 * 修复插件重复注册&输入序号支持表达式 * 移除无用代码 * feat: tree支持节点行为配置、点击事件、虚拟列表高度、工具栏、操作栏等功能 * feat: 虚拟列表支持高度自适应 * feat: 虚拟列表支持高度自适应 * feat: 虚拟列表支持高度自适应 * feat: 虚拟列表支持高度自适应 * feat: 表格列新增textOverflow属性 * feat: 新增文本未超出,不呼出功能 * feat: 修改dom计算的位置 * feat: 增加限制条件 * feat: 删除sonTarget属性 * feat: 合并renderTextOver * feat: 留出外围扩充位置 * feat: 步骤条新增iconPositon属性,修复简单模式下箭头布局错乱 (#11250) * feat: 替换按钮配置面板自定义样式 * feat: 步骤条新增iconPositon属性,修复简单模式下箭头布局错乱 --------- Co-authored-by: hzh11012 <43038692+hzh11012@users.noreply.github.com> Co-authored-by: hezhihang <hezhihang@baidu.com> Co-authored-by: F-jianchao <161407305+F-jianchao@users.noreply.github.com> Co-authored-by: hsm-lv <80095014+hsm-lv@users.noreply.github.com> Co-authored-by: fujianchao <fujianchao@baidu.com> Co-authored-by: qkiroc <30946345+qkiroc@users.noreply.github.com> Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com> Co-authored-by: z418577198 <418577198@qq.com> Co-authored-by: lvxiaojiao <lvxiaojiao@baidu.com> Co-authored-by: zhangzhijun03 <zhangzhijun03@baidu.com> Co-authored-by: Allen <yupeng.fe@qq.com>
This commit is contained in:
parent
8eb9a667ee
commit
ad9c8d73b2
@ -3999,6 +3999,7 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,
|
||||
| filterable | `boolean` \| [`QuickFilterConfig`](./crud#quickfilterconfig) | `false` | 是否可快速搜索,`options`属性为静态选项,支持设置`source`属性从接口获取选项 |
|
||||
| quickEdit | `boolean` \| [`QuickEditConfig`](./crud#quickeditconfig) | - | 快速编辑,一般需要配合`quickSaveApi`接口使用 |
|
||||
| quickEditEnabledOn | `SchemaExpression` | - | 开启快速编辑条件[表达式](../../docs/concepts/expression) | |
|
||||
| textOverflow | `string` | `default` | 文本溢出后展示形式,默认换行处理。可选值 `ellipsis` 溢出隐藏展示, `noWrap` 不换行展示(仅在列为静态文本时生效) | `6.9.0` |
|
||||
|
||||
#### QuickFilterConfig
|
||||
|
||||
|
@ -249,6 +249,8 @@ order: 59
|
||||
|
||||
`cascade`默认为 false,子节点禁止反选,值不包含子节点值,配置`"cascade": true`,子节点可以反选,值包含父子节点值(1.9.0 之前的版本 cascade 配置为 true 的效果为:选中父节点不默认选中子节点)
|
||||
|
||||
> 6.9.0 以上版本 autoCancelParent 配置为 true 的效果为:取消子节点,自动去除父节点的值(仅在多选和 cascade 为 true 时生效)
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
@ -326,6 +328,45 @@ order: 59
|
||||
"value": "c"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree3",
|
||||
"label": "子节点可以反选,值包含父子节点值,取消子节点,自动去除父节点的值",
|
||||
"multiple": true,
|
||||
"cascade": true,
|
||||
"autoCancelParent": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "A",
|
||||
"value": "a"
|
||||
},
|
||||
{
|
||||
"label": "B",
|
||||
"value": "b",
|
||||
"children": [
|
||||
{
|
||||
"label": "B-1",
|
||||
"value": "b-1"
|
||||
},
|
||||
{
|
||||
"label": "B-2",
|
||||
"value": "b-2"
|
||||
},
|
||||
{
|
||||
"label": "B-3",
|
||||
"value": "b-3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "C",
|
||||
"value": "c"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1086,6 +1127,338 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
|
||||
适用于需选择的数据/信息源较多时,用户可直观的知道自己所选择的数据/信息的场景。未配置 searchApi 是前端检索,配置之后就只能通过后端检索。
|
||||
|
||||
## 节点行为配置
|
||||
|
||||
> 6.9.0 以上版本
|
||||
|
||||
设置`nodeBehavior`属性,可以更改节点的行为,默认为选中行为,支持配置多个行为。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree1",
|
||||
"label": "选中",
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree2",
|
||||
"label": "展开",
|
||||
"nodeBehavior": ["unfold"],
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 4,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 5,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 6
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree3",
|
||||
"label": "选中+展开",
|
||||
"nodeBehavior": ["check", "unfold"],
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 7,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 8,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 9
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 自定义选项操作
|
||||
|
||||
> 6.9.0 以上版本
|
||||
|
||||
> 使用`itemActions`属性,自定义下拉选项的操作。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree",
|
||||
"label": "Tree",
|
||||
"iconField": "icon",
|
||||
"options": [
|
||||
{
|
||||
"label": "采购单",
|
||||
"value": "order",
|
||||
"tag": "数据模型",
|
||||
"icon": "fa fa-database",
|
||||
"children": [
|
||||
{
|
||||
"label": "ID",
|
||||
"value": "id",
|
||||
"tag": "数字",
|
||||
"icon": "fa fa-check"
|
||||
},
|
||||
{
|
||||
"label": "采购人",
|
||||
"value": "name",
|
||||
"tag": "字符串",
|
||||
"icon": "fa fa-check"
|
||||
},
|
||||
{
|
||||
"label": "采购时间",
|
||||
"value": "time",
|
||||
"tag": "日期时间",
|
||||
"icon": "fa fa-check"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"itemActions": [
|
||||
{
|
||||
"type": "button",
|
||||
"icon": "fa fa-plus",
|
||||
"level": "link",
|
||||
"size": "xs",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"weight": 0,
|
||||
"actions": [
|
||||
{
|
||||
"ignoreError": false,
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msgType": "info",
|
||||
"position": "top-right",
|
||||
"closeButton": true,
|
||||
"showIcon": true,
|
||||
"msg": "自定义操作",
|
||||
"className": "theme-toast-action-scope"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 工具栏区域
|
||||
|
||||
> 6.9.0 以上版本
|
||||
> 使用`toolbar`属性,自定义工具栏区域。(仅开启检索时生效)
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree",
|
||||
"label": "Tree",
|
||||
"searchable": true,
|
||||
"toolbar": [
|
||||
{
|
||||
"type": "button",
|
||||
"label": "弹窗",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "dialog",
|
||||
"dialog": {
|
||||
"type": "dialog",
|
||||
"title": "未命名弹窗",
|
||||
"body": [
|
||||
{
|
||||
"type": "tpl",
|
||||
"tpl": "弹窗内容"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"type": "button",
|
||||
"actionType": "cancel",
|
||||
"label": "取消"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"actionType": "confirm",
|
||||
"label": "确定",
|
||||
"primary": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"collapsed": true,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"label": "file B",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file D",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 虚拟列表
|
||||
|
||||
> 6.9.0 以上版本, 开启 heightAuto 后,虚拟列表将自适应高度
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "page",
|
||||
"aside": [
|
||||
{
|
||||
"type": "flex",
|
||||
"direction": "column",
|
||||
"isFixedHeight": true,
|
||||
"style": {
|
||||
"height": "300px"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"id": "tree",
|
||||
"name": "tree",
|
||||
"label": false,
|
||||
"heightAuto": true,
|
||||
"virtualThreshold": 5,
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"label": "file B",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"label": "file D",
|
||||
"value": 5
|
||||
},
|
||||
{
|
||||
"label": "file E",
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"label": "file F",
|
||||
"value": 7
|
||||
},
|
||||
{
|
||||
"label": "file G",
|
||||
"value": 8
|
||||
},
|
||||
{
|
||||
"label": "file H",
|
||||
"value": 9
|
||||
},
|
||||
{
|
||||
"label": "file I",
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"label": "file J",
|
||||
"value": 11
|
||||
},
|
||||
{
|
||||
"label": "file K",
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"label": "file L",
|
||||
"value": 13
|
||||
}
|
||||
],
|
||||
"wrapperCustomStyle": {
|
||||
"root": {
|
||||
"height": "100%"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"type": "tpl",
|
||||
"tpl": "开启heightAuto后,设置tree的高度,虚拟列表将自适应"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
当做选择器表单项使用时,除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||
@ -1137,6 +1510,11 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
| menuTpl | `string` | | 选项自定义渲染 HTML 片段 | `2.8.0` |
|
||||
| enableDefaultIcon | `boolean` | `true` | 是否为选项添加默认的前缀 Icon,父节点默认为`folder`,叶节点默认为`file` | `2.8.0` |
|
||||
| heightAuto | `boolean` | `false` | 默认高度会有个 maxHeight,即超过一定高度就会内部滚动,如果希望自动增长请设置此属性 | `3.0.0` |
|
||||
| nodeBehavior | `Array<'unfold' \| 'check' \| ''>` | `['check']` | 节点行为配置,支持配置多个行为 | `6.9.0` |
|
||||
| autoCancelParent | `boolean` | `false` | 子节点取消时自动取消父节点的值,仅在多选且 cascade 为 true 时生效 | `6.9.0` |
|
||||
| toolbar | `SchemaNode` | | 工具栏区域,仅开启检索时生效 | `6.9.0` |
|
||||
| toolbarClassName | `string` | | 工具栏区域类名 | `6.9.0` |
|
||||
| itemActions | `SchemaNode` | | 节点操作栏区域 | `6.9.0` |
|
||||
|
||||
## 事件表
|
||||
|
||||
@ -1151,6 +1529,7 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
| editConfirm (3.6.4 及以上版本) | `[name]: object` 组件的值<br/>`item: object` 编辑的节点信息<br/>`items: object[]`选项集合 | 编辑节点提交时触发 |
|
||||
| deleteConfirm (3.6.4 及以上版本) | `[name]: string` 组件的值<br/>`item: object` 删除的节点信息<br/>`items: object[]`选项集合 | 删除节点提交时触发 |
|
||||
| deferLoadFinished (3.6.4 及以上版本) | `[name]: object` 组件的值<br/>`result: object` deferApi 懒加载远程请求成功后返回的数据 <br/>`items: object[]`选项集合 | 懒加载接口远程请求成功时触发 |
|
||||
| itemClick (6.9.0 以上版本) | `value: any`表单项的值,值格式取决于具体配置<br/>`item: object` 点击的节点信息 | 节点点击时触发 |
|
||||
| add(不推荐) | `[name]: object` 新增的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 新增节点提交时触发 |
|
||||
| edit(不推荐) | `[name]: object` 编辑的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 编辑节点提交时触发 |
|
||||
| delete(不推荐) | `[name]: object` 删除的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 删除节点提交时触发 |
|
||||
@ -1440,6 +1819,60 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
}
|
||||
```
|
||||
|
||||
### itemClick
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"debug": true,
|
||||
"body": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree",
|
||||
"label": "Tree",
|
||||
"nodeBehavior": [],
|
||||
"onEvent": {
|
||||
"itemClick": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msg": "${event.data.tree|json}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"label": "file B",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"label": "file D",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 动作表
|
||||
|
||||
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
|
||||
@ -1455,6 +1888,7 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
| clear | - | 清空 |
|
||||
| reset | - | 将值重置为初始值。6.3.0 及以下版本为`resetValue` |
|
||||
| setValue | `value: string` \| `string[]` 更新的值 | 更新数据,开启`multiple`支持设置多项,开启`joinValues`时,多值用`,`分隔,否则多值用数组 |
|
||||
| search | `keyword: string` 检索的值 | 检索数据 |
|
||||
|
||||
### clear
|
||||
|
||||
@ -1589,3 +2023,67 @@ true false false [{label: 'A/B/C', value: 'a/b/c'},{label: 'A
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### search
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"debug": true,
|
||||
"body": [
|
||||
{
|
||||
"type": "search-box",
|
||||
"name": "keyword",
|
||||
"className": "mb-4",
|
||||
"style": {
|
||||
"width": "100%"
|
||||
},
|
||||
"onEvent": {
|
||||
"change": {
|
||||
"actions": [
|
||||
{
|
||||
"componentId": "tree",
|
||||
"groupType": "component",
|
||||
"actionType": "search",
|
||||
"args": {
|
||||
"keyword": "${event.data.value}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "input-tree",
|
||||
"id": "tree",
|
||||
"name": "tree",
|
||||
"label": false,
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"label": "file B",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"label": "file D",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -418,6 +418,7 @@ order: 60
|
||||
| editConfirm (3.6.4 及以上版本) | `[name]: object` 组件的值<br/>`item: object` 编辑的节点信息<br/>`items: object[]`选项集合 | 编辑节点提交时触发 |
|
||||
| deleteConfirm (3.6.4 及以上版本) | `[name]: string` 组件的值<br/>`item: object` 删除的节点信息<br/>`items: object[]`选项集合 | 删除节点提交时触发 |
|
||||
| deferLoadFinished (3.6.4 及以上版本) | `[name]: object` 组件的值<br/>`result: object` deferApi 懒加载远程请求成功后返回的数据 <br/>`items: object[]`选项集合 | 懒加载接口远程请求成功时触发 |
|
||||
| itemClick (6.9.0 以上版本) | `value: any`表单项的值,值格式取决于具体配置<br/>`item: object` 点击的节点信息 | 节点点击时触发 |
|
||||
| add(不推荐) | `[name]: object` 新增的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 新增节点提交时触发 |
|
||||
| edit(不推荐) | `[name]: object` 编辑的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 编辑节点提交时触发 |
|
||||
| delete(不推荐) | `[name]: object` 删除的节点信息<br/>`items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 删除节点提交时触发 |
|
||||
@ -812,6 +813,60 @@ order: 60
|
||||
}
|
||||
```
|
||||
|
||||
### itemClick
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"debug": true,
|
||||
"body": [
|
||||
{
|
||||
"type": "input-tree",
|
||||
"name": "tree",
|
||||
"label": "Tree",
|
||||
"nodeBehavior": [],
|
||||
"onEvent": {
|
||||
"itemClick": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msg": "${event.data.tree|json}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"label": "Folder A",
|
||||
"value": 1,
|
||||
"children": [
|
||||
{
|
||||
"label": "file A",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"label": "file B",
|
||||
"value": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "file C",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"label": "file D",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 动作表
|
||||
|
||||
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
|
||||
|
@ -251,6 +251,30 @@ Page 默认将页面分为几个区域,分别是**内容区(`body`)**、**
|
||||
|
||||
通过配置 `asideSticky` 来开关,默认是开启状态。
|
||||
|
||||
## aside 展示位置
|
||||
|
||||
通过配置 `asidePosition`,可以控制侧边栏的展示位置。
|
||||
|
||||
```schema
|
||||
{
|
||||
"type": "page",
|
||||
"asideResizor": true,
|
||||
"asidePosition": "right",
|
||||
"aside": [
|
||||
{
|
||||
"type": "tpl",
|
||||
"tpl": "这是侧边栏部分"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"type": "tpl",
|
||||
"tpl": "这是内容区"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
@ -264,6 +288,7 @@ Page 默认将页面分为几个区域,分别是**内容区(`body`)**、**
|
||||
| asideMinWidth | `number` | | 页面边栏区域的最小宽度 |
|
||||
| asideMaxWidth | `number` | | 页面边栏区域的最大宽度 |
|
||||
| asideSticky | `boolean` | true | 用来控制边栏固定与否 |
|
||||
| asidePosition | `"left" \| "right"` | `"left"` | 页面边栏区域的位置 |
|
||||
| toolbar | [SchemaNode](../../docs/types/schemanode) | | 往页面的右上角加内容,需要注意的是,当有 title 时,该区域在右上角,没有时该区域在顶部 |
|
||||
| body | [SchemaNode](../../docs/types/schemanode) | | 往页面的内容区域加内容 |
|
||||
| className | `string` | | 外层 dom 类名 |
|
||||
|
@ -881,6 +881,7 @@ order: 68
|
||||
| 事件名称 | 事件参数 | 说明 |
|
||||
| -------- | ------------------------------------ | ---------------- |
|
||||
| change | `value: number \| string` 选项卡索引 | 切换选项卡时触发 |
|
||||
| delete | `value: number \| string` 选项卡索引 | 删除选项卡时触发 |
|
||||
|
||||
### change
|
||||
|
||||
@ -918,6 +919,43 @@ order: 68
|
||||
}
|
||||
```
|
||||
|
||||
### delete
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"closable": true,
|
||||
"mode": "line",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
"body": "选项卡内容1"
|
||||
},
|
||||
{
|
||||
"title": "选项卡2",
|
||||
"body": "选项卡内容2"
|
||||
},
|
||||
{
|
||||
"title": "选项卡3",
|
||||
"body": "选项卡内容3"
|
||||
}
|
||||
],
|
||||
"onEvent": {
|
||||
"delete": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msgType": "info",
|
||||
"msg": "删除选项卡${event.data.value}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 动作表
|
||||
|
||||
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
|
||||
@ -925,6 +963,7 @@ order: 68
|
||||
| 动作名称 | 动作配置 | 说明 |
|
||||
| --------------- | ---------------------------------------- | ---------------- |
|
||||
| changeActiveKey | `activeKey: number \| string` 选项卡索引 | 激活指定的选项卡 |
|
||||
| deleteTab | `deleteHash: string` 选项卡 hash | 删除指定的选项卡 |
|
||||
|
||||
### changeActiveKey
|
||||
|
||||
@ -1007,3 +1046,88 @@ order: 68
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### deleteTab
|
||||
|
||||
可以尝试点击下方按钮,实现选项卡删除。
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "action",
|
||||
"label": "删除选项卡1",
|
||||
"className": "mr-3 mb-3",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "deleteTab",
|
||||
"componentId": "tabs-change-receiver",
|
||||
"args": {
|
||||
"deleteHash": "tab1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "action",
|
||||
"label": "删除选项卡2",
|
||||
"className": "mr-3 mb-3",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "deleteTab",
|
||||
"componentId": "tabs-change-receiver",
|
||||
"args": {
|
||||
"deleteHash": "tab2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "action",
|
||||
"label": "删除选项卡3",
|
||||
"className": "mr-3 mb-3",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "deleteTab",
|
||||
"componentId": "tabs-change-receiver",
|
||||
"args": {
|
||||
"deleteHash": "tab3"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tabs-change-receiver",
|
||||
"type": "tabs",
|
||||
"mode": "line",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
"hash": "tab1",
|
||||
"body": "选项卡内容1"
|
||||
},
|
||||
{
|
||||
"title": "选项卡2",
|
||||
"hash": "tab2",
|
||||
"body": "选项卡内容2"
|
||||
},
|
||||
{
|
||||
"title": "选项卡3",
|
||||
"hash": "tab3",
|
||||
"body": "选项卡内容3"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -28,7 +28,7 @@ describe('constructor', () => {
|
||||
OriginComponent.defaultProps = {
|
||||
name: 'test'
|
||||
};
|
||||
const WrappedComponent = wrapControl(OriginComponent as any);
|
||||
const WrappedComponent = wrapControl({}, OriginComponent as any);
|
||||
|
||||
renderComponent(WrappedComponent, {$schema: {}});
|
||||
expect(screen.getByText('FormItemStore')).toBeInTheDocument();
|
||||
@ -39,7 +39,7 @@ describe('constructor', () => {
|
||||
// 用于断言formItem已被注册
|
||||
return <div>{props.formItem?.storeType}</div>;
|
||||
};
|
||||
const WrappedComponent = wrapControl(OriginComponent as any);
|
||||
const WrappedComponent = wrapControl({}, OriginComponent as any);
|
||||
|
||||
renderComponent(WrappedComponent, {$schema: {name: 'test'}});
|
||||
expect(screen.getByText('FormItemStore')).toBeInTheDocument();
|
||||
@ -50,7 +50,7 @@ describe('constructor', () => {
|
||||
// 用于断言formItem已被注册
|
||||
return <div>{props.formItem?.storeType}</div>;
|
||||
};
|
||||
const WrappedComponent = wrapControl(OriginComponent as any);
|
||||
const WrappedComponent = wrapControl({}, OriginComponent as any);
|
||||
|
||||
renderComponent(WrappedComponent, {$schema: {}});
|
||||
expect(screen.queryByText('FormItemStore')).not.toBeInTheDocument();
|
||||
|
@ -35,8 +35,8 @@
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run clean-dist && NODE_ENV=production rollup -c ",
|
||||
"build-esm": "npm run clean-dist && NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"build": "npm run clean-dist && cross-env NODE_ENV=production rollup -c ",
|
||||
"build-esm": "npm run clean-dist && cross-env NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"dev": "rollup -c -w",
|
||||
"test": "jest",
|
||||
"update-snapshot": "jest --updateSnapshot",
|
||||
@ -49,7 +49,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@rc-component/mini-decimal": "^1.0.1",
|
||||
"amis-formula": "^6.9.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"amis-formula": "*",
|
||||
"classnames": "2.3.2",
|
||||
"file-saver": "^2.0.2",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
|
@ -10,6 +10,7 @@ import {IContinueAction} from './ContinueAction';
|
||||
import {ILoopAction} from './LoopAction';
|
||||
import {IParallelAction} from './ParallelAction';
|
||||
import {ISwitchAction} from './SwitchAction';
|
||||
import {debug} from '../utils/debug';
|
||||
|
||||
// 循环动作执行状态
|
||||
export enum LoopStatus {
|
||||
@ -343,6 +344,9 @@ export const runAction = async (
|
||||
console.group?.(`run action ${action.actionType}`);
|
||||
console.debug(`[${action.actionType}] action args, data`, args, data);
|
||||
|
||||
debug('action', `run action ${action.actionType} with args`, args);
|
||||
debug('action', `run action ${action.actionType} with data`, data);
|
||||
|
||||
let stopped = false;
|
||||
const actionResult = await actionInstrance.run(
|
||||
{
|
||||
|
@ -81,7 +81,11 @@ import type {
|
||||
FormControlProps,
|
||||
FormItemProps
|
||||
} from './renderers/Item';
|
||||
import {OptionsControl, registerOptionsControl} from './renderers/Options';
|
||||
import {
|
||||
OptionsControl,
|
||||
registerOptionsControl,
|
||||
OptionsControlBase
|
||||
} from './renderers/Options';
|
||||
import type {OptionsControlProps} from './renderers/Options';
|
||||
import type {FormOptionsControl} from './renderers/Options';
|
||||
import {Schema} from './types';
|
||||
@ -217,6 +221,7 @@ export {
|
||||
ErrorBoundary,
|
||||
addSchemaFilter,
|
||||
OptionsControlProps,
|
||||
OptionsControlBase,
|
||||
FormOptionsControl,
|
||||
FormControlProps,
|
||||
FormBaseControl,
|
||||
@ -241,6 +246,7 @@ export {
|
||||
envOverwrite,
|
||||
getGlobalOptions,
|
||||
setGlobalOptions,
|
||||
wrapFetcher,
|
||||
SchemaRenderer
|
||||
};
|
||||
|
||||
|
@ -481,6 +481,7 @@ export interface FormItemBasicConfig extends Partial<RendererConfig> {
|
||||
renderDescription?: boolean;
|
||||
test?: RegExp | TestFunc;
|
||||
storeType?: string;
|
||||
formItemStoreType?: string;
|
||||
validations?: string;
|
||||
strictMode?: boolean;
|
||||
|
||||
@ -2205,6 +2206,7 @@ export function asFormItem(config: Omit<FormItemConfig, 'component'>) {
|
||||
}
|
||||
|
||||
return wrapControl(
|
||||
config,
|
||||
hoistNonReactStatic(
|
||||
class extends FormItemWrap {
|
||||
static defaultProps: any = {
|
||||
|
@ -287,34 +287,16 @@ export const detectProps = itemDetectProps.concat([
|
||||
'hideSelected'
|
||||
]);
|
||||
|
||||
export function registerOptionsControl(config: OptionsConfig) {
|
||||
const Control = config.component;
|
||||
|
||||
class FormOptionsItem extends React.Component<OptionsProps, any> {
|
||||
static displayName = `OptionsControl(${config.type})`;
|
||||
static defaultProps = {
|
||||
delimiter: ',',
|
||||
labelField: 'label',
|
||||
valueField: 'value',
|
||||
joinValues: true,
|
||||
extractValue: false,
|
||||
multiple: false,
|
||||
placeholder: 'Select.placeholder',
|
||||
resetValue: '',
|
||||
deleteConfirmText: 'deleteConfirm',
|
||||
...Control.defaultProps
|
||||
};
|
||||
static propsList: any = (Control as any).propsList
|
||||
? [...(Control as any).propsList]
|
||||
: [];
|
||||
static ComposedComponent = Control;
|
||||
|
||||
export class OptionsControlBase<
|
||||
T extends OptionsProps = OptionsProps,
|
||||
S = any
|
||||
> extends React.Component<T, S> {
|
||||
toDispose: Array<() => void> = [];
|
||||
|
||||
input: any;
|
||||
mounted = false;
|
||||
|
||||
constructor(props: OptionsProps) {
|
||||
constructor(props: T, readonly config: OptionsConfig) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
@ -404,7 +386,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: OptionsProps) {
|
||||
if (config.strictMode === false || nextProps.strictMode === false) {
|
||||
if (this.config.strictMode === false || nextProps.strictMode === false) {
|
||||
return true;
|
||||
} else if (nextProps.source || nextProps.autoComplete) {
|
||||
return true;
|
||||
@ -429,7 +411,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
);
|
||||
this.normalizeValue();
|
||||
} else if (
|
||||
config.autoLoadOptionsFromSource !== false &&
|
||||
this.config.autoLoadOptionsFromSource !== false &&
|
||||
(props.formInited || typeof props.formInited === 'undefined') &&
|
||||
props.source &&
|
||||
formItem &&
|
||||
@ -557,7 +539,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
!(
|
||||
(Array.isArray(value) &&
|
||||
value.every(
|
||||
val => typeof val === 'string' || typeof val === 'number'
|
||||
(val: any) => typeof val === 'string' || typeof val === 'number'
|
||||
)) ||
|
||||
typeof value === 'string' ||
|
||||
typeof value === 'number'
|
||||
@ -565,9 +547,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
) {
|
||||
const selectedOptions = formItem
|
||||
.getSelectedOptions(value)
|
||||
.map(
|
||||
(selectedOption: Option) => selectedOption[valueField || 'value']
|
||||
);
|
||||
.map((selectedOption: Option) => selectedOption[valueField || 'value']);
|
||||
onChange?.(multiple ? selectedOptions.concat() : selectedOptions[0]);
|
||||
}
|
||||
}
|
||||
@ -1085,9 +1065,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
if (Array.isArray(idx)) {
|
||||
options = spliceTree(options, idx, 0, {...result});
|
||||
} else {
|
||||
~idx
|
||||
? options.splice(idx, 0, {...result})
|
||||
: options.push({...result});
|
||||
~idx ? options.splice(idx, 0, {...result}) : options.push({...result});
|
||||
}
|
||||
model.setOptions(options, this.changeOptionValue, data);
|
||||
}
|
||||
@ -1282,12 +1260,9 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
}
|
||||
|
||||
// 避免产生breakchange,增加新事件名,用来更正之前的设计问题
|
||||
const delConfirmPrevent = await this.dispatchOptionEvent(
|
||||
'deleteConfirm',
|
||||
{
|
||||
const delConfirmPrevent = await this.dispatchOptionEvent('deleteConfirm', {
|
||||
item: value
|
||||
}
|
||||
);
|
||||
});
|
||||
if (delConfirmPrevent) {
|
||||
return;
|
||||
}
|
||||
@ -1342,7 +1317,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const {
|
||||
value,
|
||||
formItem,
|
||||
@ -1369,6 +1344,8 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
delimiter
|
||||
);
|
||||
|
||||
const Control = this.config.component;
|
||||
|
||||
return (
|
||||
<Control
|
||||
{...this.props}
|
||||
@ -1409,6 +1386,33 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
export function registerOptionsControl(config: OptionsConfig) {
|
||||
const Control = config.component;
|
||||
|
||||
class FormOptionsItem extends OptionsControlBase<OptionsProps> {
|
||||
static displayName = `OptionsControl(${config.type})`;
|
||||
static defaultProps = {
|
||||
delimiter: ',',
|
||||
labelField: 'label',
|
||||
valueField: 'value',
|
||||
joinValues: true,
|
||||
extractValue: false,
|
||||
multiple: false,
|
||||
placeholder: 'Select.placeholder',
|
||||
resetValue: '',
|
||||
deleteConfirmText: 'deleteConfirm',
|
||||
...Control.defaultProps
|
||||
};
|
||||
static propsList: any = (Control as any).propsList
|
||||
? [...(Control as any).propsList]
|
||||
: [];
|
||||
static ComposedComponent = Control;
|
||||
|
||||
constructor(props: OptionsProps) {
|
||||
super(props, config);
|
||||
}
|
||||
}
|
||||
|
||||
return registerFormItem({
|
||||
...(config as FormItemBasicConfig),
|
||||
strictMode: false,
|
||||
|
@ -27,7 +27,7 @@ import {isAlive} from 'mobx-state-tree';
|
||||
import {observer} from 'mobx-react';
|
||||
import hoistNonReactStatic from 'hoist-non-react-statics';
|
||||
import {withRootStore} from '../WithRootStore';
|
||||
import {FormBaseControl, FormItemWrap} from './Item';
|
||||
import {FormBaseControl, FormItemConfig, FormItemWrap} from './Item';
|
||||
import {Api, DataChangeReason} from '../types';
|
||||
import {TableStore} from '../store/table';
|
||||
import pick from 'lodash/pick';
|
||||
@ -94,7 +94,7 @@ export interface ControlProps {
|
||||
|
||||
export function wrapControl<
|
||||
T extends React.ComponentType<React.ComponentProps<T> & ControlProps>
|
||||
>(ComposedComponent: T) {
|
||||
>(config: Omit<FormItemConfig, 'component'>, ComposedComponent: T) {
|
||||
type OuterProps = JSX.LibraryManagedAttributes<
|
||||
T,
|
||||
Omit<React.ComponentProps<T>, keyof ControlProps>
|
||||
@ -194,7 +194,7 @@ export function wrapControl<
|
||||
const model = rootStore.addStore({
|
||||
id: guid(),
|
||||
path: this.props.$path,
|
||||
storeType: FormItemStore.name,
|
||||
storeType: config.formItemStoreType || FormItemStore.name,
|
||||
parentId: store?.id,
|
||||
name,
|
||||
colIndex: colIndex !== undefined ? colIndex : undefined,
|
||||
|
@ -620,7 +620,7 @@ export const FormItemStore = StoreNode.named('FormItemStore')
|
||||
}
|
||||
|
||||
for (let option of options) {
|
||||
if (Array.isArray(option.children)) {
|
||||
if (Array.isArray(option.children) && option.children.length) {
|
||||
const childFirst = getFirstAvaibleOption(option.children);
|
||||
if (childFirst !== undefined) {
|
||||
return childFirst;
|
||||
|
@ -66,10 +66,12 @@ export function removeApiRequestAdaptor(adaptor: RequestAdaptor) {
|
||||
* 添加全局响应适配器
|
||||
* @param adaptor
|
||||
*/
|
||||
export function addApiResponseAdator(adaptor: ResponseAdaptor) {
|
||||
export function addApiResponseAdaptor(adaptor: ResponseAdaptor) {
|
||||
responseAdaptors.push(adaptor);
|
||||
return () => removeApiResponseAdaptor(adaptor);
|
||||
}
|
||||
// :( 之前写错了,这里为了让以前的代码能继续跑,暂时保留
|
||||
export const addApiResponseAdator = addApiResponseAdaptor;
|
||||
|
||||
/**
|
||||
* 删除全局响应适配器
|
||||
|
@ -28,6 +28,8 @@ export function attachmentAdpator(
|
||||
let matches = disposition.match(filenameRegex);
|
||||
if (matches && matches.length) {
|
||||
filename = matches[1].replace(`UTF-8''`, '').replace(/['"]/g, '');
|
||||
} else {
|
||||
filename = disposition?.split(';')[1];
|
||||
}
|
||||
|
||||
// 很可能是中文被 url-encode 了
|
||||
|
@ -6,10 +6,12 @@ import React, {Component, useEffect, useRef, useState, version} from 'react';
|
||||
import cx from 'classnames';
|
||||
import {findDOMNode, render, unmountComponentAtNode} from 'react-dom';
|
||||
// import {createRoot} from 'react-dom/client';
|
||||
import {autorun, observable} from 'mobx';
|
||||
import {autorun, observable, action} from 'mobx';
|
||||
import {observer} from 'mobx-react';
|
||||
import {uuidv4, importLazyComponent} from './helper';
|
||||
import position from './position';
|
||||
import {resolveVariableAndFilter} from './resolveVariableAndFilter';
|
||||
import {callStrFunction} from './api';
|
||||
|
||||
export const JsonView = React.lazy(() =>
|
||||
import('react-json-view').then(importLazyComponent)
|
||||
@ -19,7 +21,7 @@ class Log {
|
||||
@observable cat = '';
|
||||
@observable level = '';
|
||||
@observable msg = '';
|
||||
@observable ext? = '';
|
||||
@observable ext?: any = '';
|
||||
}
|
||||
|
||||
class AMISDebugStore {
|
||||
@ -62,6 +64,25 @@ class AMISDebugStore {
|
||||
* 字段值文本最大展示长度
|
||||
*/
|
||||
@observable ellipsisThreshold: number;
|
||||
|
||||
@action.bound
|
||||
open() {
|
||||
this.isExpanded = true;
|
||||
this.inspectMode = true;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
close() {
|
||||
this.isExpanded = false;
|
||||
this.activeId = '';
|
||||
this.hoverId = '';
|
||||
this.inspectMode = false;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
toggleInspectMode() {
|
||||
this.inspectMode = !this.inspectMode;
|
||||
}
|
||||
}
|
||||
|
||||
const store = new AMISDebugStore();
|
||||
@ -86,12 +107,16 @@ const LogView = observer(({store}: {store: AMISDebugStore}) => {
|
||||
<div className="AMISDebug-logLineMsg">
|
||||
[{log.cat}] {log.msg}
|
||||
</div>
|
||||
{log.ext ? (
|
||||
{(typeof log.ext === 'string' &&
|
||||
(log.ext.startsWith('{') || log.ext.startsWith('['))) ||
|
||||
typeof log.ext === 'object' ? (
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<JsonView
|
||||
name={null}
|
||||
theme="monokai"
|
||||
src={JSON.parse(log.ext)}
|
||||
src={
|
||||
typeof log.ext === 'string' ? parseJson(log.ext) : log.ext
|
||||
}
|
||||
collapsed={true}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
@ -99,7 +124,9 @@ const LogView = observer(({store}: {store: AMISDebugStore}) => {
|
||||
iconStyle="square"
|
||||
/>
|
||||
</React.Suspense>
|
||||
) : null}
|
||||
) : (
|
||||
<pre className="AMISDebug-value">{JSON.stringify(log.ext)}</pre>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@ -188,6 +215,36 @@ const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
};
|
||||
}, [isResizing]);
|
||||
|
||||
const handleInputKeyUp = React.useCallback((e: React.KeyboardEvent<any>) => {
|
||||
if (e.key === 'Enter') {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const expression = input.value;
|
||||
input.value = '';
|
||||
|
||||
try {
|
||||
const activeId = store.activeId;
|
||||
const ctx = ComponentInfo[activeId]?.component.props.data || {};
|
||||
const result = expression.startsWith('${')
|
||||
? resolveVariableAndFilter(expression, ctx, '| raw')
|
||||
: callStrFunction(
|
||||
new Function('data', `with(data) {return ${expression};}`),
|
||||
['data'],
|
||||
ctx
|
||||
);
|
||||
|
||||
debug('debug', `evaluate expression \`${expression}\``, result);
|
||||
} catch (e) {
|
||||
debug(
|
||||
'error',
|
||||
`evaluate expression \`${expression}\``,
|
||||
`Error: ${e.message}`
|
||||
);
|
||||
} finally {
|
||||
store.tab = 'log';
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('AMISDebug', {
|
||||
@ -196,13 +253,7 @@ const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
})}
|
||||
ref={panelRef}
|
||||
>
|
||||
<div
|
||||
className="AMISDebug-toggle"
|
||||
title="open debug"
|
||||
onClick={() => {
|
||||
store.isExpanded = true;
|
||||
}}
|
||||
>
|
||||
<div className="AMISDebug-toggle" title="open debug" onClick={store.open}>
|
||||
{store.isExpanded ? (
|
||||
<i className="fas fa-times"></i>
|
||||
) : (
|
||||
@ -210,15 +261,7 @@ const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
)}
|
||||
</div>
|
||||
<div className={cx('AMISDebug-content')}>
|
||||
<div
|
||||
className="AMISDebug-close"
|
||||
title="Close"
|
||||
onClick={() => {
|
||||
store.isExpanded = false;
|
||||
store.activeId = '';
|
||||
store.hoverId = '';
|
||||
}}
|
||||
>
|
||||
<div className="AMISDebug-close" title="Close" onClick={store.close}>
|
||||
<i className="fas fa-times" />
|
||||
</div>
|
||||
<div
|
||||
@ -285,17 +328,48 @@ const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
) : null}
|
||||
{store.tab === 'inspect' ? (
|
||||
<div className="AMISDebug-inspect">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1024 1024"
|
||||
className={`AMISDebug-inspectIcon ${
|
||||
store.inspectMode ? 'is-active' : ''
|
||||
}`}
|
||||
onClick={store.toggleInspectMode}
|
||||
>
|
||||
<path d="M64 192L128 128h768l64 64v384H896v-384H128v512h320V768H128l-64-64v-512z m941.226667 621.226667L576 384v602.496l173.226667-173.226667h256zM640 832v-293.504l210.773333 210.773333h-128L640 832z" />
|
||||
</svg>
|
||||
{store.inspectMode ? (
|
||||
<span>Select an element in the page to inspect it.</span>
|
||||
) : (
|
||||
<span>Click to inspect an element.</span>
|
||||
)}
|
||||
{activeId ? (
|
||||
<>
|
||||
<h3>
|
||||
Component:{' '}
|
||||
<span className="primary">{activeComponentInspect.name}</span>
|
||||
<span className="primary">
|
||||
{activeComponentInspect?.name}
|
||||
</span>
|
||||
</h3>
|
||||
{stackDataView}
|
||||
</>
|
||||
) : (
|
||||
'Click component to display inspect'
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
{activeId ? (
|
||||
<div className="AMISDebug-footer">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1024 1024"
|
||||
>
|
||||
<path
|
||||
d="M724.48 521.728c-1.8432 7.7824-5.7344 14.848-11.3664 20.48l-341.9136 342.016c-16.6912 16.6912-43.7248 16.6912-60.3136 0s-16.6912-43.7248 0-60.3136L622.6944 512 310.8864 200.0896c-16.6912-16.6912-16.6912-43.7248 0-60.3136 16.6912-16.6912 43.7248-16.6912 60.3136 0l341.9136 341.9136c10.8544 10.8544 14.6432 26.112 11.3664 40.0384z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
<input type="text" placeholder="" onKeyUp={handleInputKeyUp} />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@ -307,7 +381,7 @@ const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
* 鼠标移动到某个组件的效果
|
||||
*/
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
if (!store.isExpanded) {
|
||||
if (!store.inspectMode) {
|
||||
return;
|
||||
}
|
||||
const dom = e.target as HTMLElement;
|
||||
@ -321,14 +395,16 @@ function handleMouseMove(e: MouseEvent) {
|
||||
* 点选某个组件
|
||||
*/
|
||||
function handleMouseclick(e: MouseEvent) {
|
||||
if (!store.isExpanded) {
|
||||
if (!store.inspectMode) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
const dom = e.target as HTMLElement;
|
||||
const target = dom.closest(`[data-debug-id]`);
|
||||
if (target && !target.closest('.AMISDebug')) {
|
||||
store.activeId = target.getAttribute('data-debug-id')!;
|
||||
store.tab = 'inspect';
|
||||
store.inspectMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,6 +413,7 @@ const amisHoverBox = document.createElement('div');
|
||||
amisHoverBox.className = 'AMISDebug-hoverBox';
|
||||
const amisActiveBox = document.createElement('div');
|
||||
amisActiveBox.className = 'AMISDebug-activeBox';
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
autorun(() => {
|
||||
const hoverId = store.hoverId;
|
||||
@ -366,6 +443,12 @@ autorun(() => {
|
||||
amisActiveBox.style.left = `${offset.left}px`;
|
||||
amisActiveBox.style.width = `${offset.width}px`;
|
||||
amisActiveBox.style.height = `${offset.height}px`;
|
||||
amisActiveBox.classList.add('shake');
|
||||
|
||||
clearTimeout(timer!);
|
||||
timer = setTimeout(() => {
|
||||
amisActiveBox.classList.remove('shake');
|
||||
}, 500);
|
||||
} else {
|
||||
amisActiveBox.style.top = '-999999px';
|
||||
}
|
||||
@ -403,7 +486,7 @@ export function enableDebug() {
|
||||
document.body.appendChild(amisHoverBox);
|
||||
document.body.appendChild(amisActiveBox);
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
document.addEventListener('click', handleMouseclick);
|
||||
document.addEventListener('click', handleMouseclick, true);
|
||||
}
|
||||
|
||||
export function disableDebug() {
|
||||
@ -451,6 +534,12 @@ export class DebugWrapper extends Component<DebugWrapperProps> {
|
||||
|
||||
componentWillUnmount() {
|
||||
delete ComponentInfo[this.debugId];
|
||||
if (this.debugId === store.activeId) {
|
||||
store.activeId = '';
|
||||
}
|
||||
if (this.debugId === store.hoverId) {
|
||||
store.hoverId = '';
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -458,14 +547,22 @@ export class DebugWrapper extends Component<DebugWrapperProps> {
|
||||
}
|
||||
}
|
||||
|
||||
type Category = 'api' | 'event';
|
||||
type Category = 'api' | 'event' | 'action' | 'debug' | 'error';
|
||||
|
||||
function parseJson(str: string) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 一般调试日志
|
||||
* @param msg 简单消息
|
||||
* @param ext 扩展信息
|
||||
*/
|
||||
export function debug(cat: Category, msg: string, ext?: object) {
|
||||
export function debug(cat: Category, msg: string, ext?: any) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -474,18 +571,11 @@ export function debug(cat: Category, msg: string, ext?: object) {
|
||||
console.debug(ext);
|
||||
console.groupEnd();
|
||||
|
||||
let extStr = '';
|
||||
try {
|
||||
extStr = JSON.stringify(ext);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
const log = {
|
||||
cat,
|
||||
level: 'debug',
|
||||
msg: msg,
|
||||
ext: extStr
|
||||
ext: ext
|
||||
};
|
||||
store.logs.push(log);
|
||||
}
|
||||
@ -495,23 +585,16 @@ export function debug(cat: Category, msg: string, ext?: object) {
|
||||
* @param msg 简单消息
|
||||
* @param ext 扩展信息
|
||||
*/
|
||||
export function warning(cat: Category, msg: string, ext?: object) {
|
||||
export function warning(cat: Category, msg: string, ext?: any) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let extStr = '';
|
||||
try {
|
||||
extStr = JSON.stringify(ext);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
const log = {
|
||||
const log: Log = {
|
||||
cat,
|
||||
level: 'warn',
|
||||
msg: msg,
|
||||
ext: extStr
|
||||
ext: ext
|
||||
};
|
||||
|
||||
console.groupCollapsed('amis debug', msg);
|
||||
|
@ -28,6 +28,7 @@ export * from './isPureVariable';
|
||||
export * from './json-schema-2-amis-schema';
|
||||
export * from './keyToPath';
|
||||
export * from './labelToString';
|
||||
export * from './loopTooMuch';
|
||||
export * from './makeSorter';
|
||||
export * from './normalizeLink';
|
||||
export * from './normalizeOptions';
|
||||
|
23
packages/amis-core/src/utils/loopTooMuch.ts
Normal file
23
packages/amis-core/src/utils/loopTooMuch.ts
Normal file
@ -0,0 +1,23 @@
|
||||
const loopCount: {[key: string]: number} = {};
|
||||
const loopTimer: {[key: string]: ReturnType<typeof setTimeout>} = {};
|
||||
const loopResult: {[key: string]: boolean} = {};
|
||||
|
||||
export function loopTooMuch(key: string, maxSpeed = 20) {
|
||||
if (loopResult[key]) {
|
||||
return loopResult[key];
|
||||
}
|
||||
|
||||
clearTimeout(loopTimer[key]);
|
||||
loopTimer[key] = setTimeout(() => {
|
||||
delete loopCount[key];
|
||||
delete loopTimer[key];
|
||||
}, 1000);
|
||||
|
||||
if (loopCount[key] && loopCount[key] > maxSpeed) {
|
||||
loopResult[key] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
loopCount[key] = (loopCount[key] || 0) + 1;
|
||||
return false;
|
||||
}
|
@ -35,28 +35,29 @@ export function position(node: HTMLElement, offsetParent?: HTMLElement) {
|
||||
}
|
||||
|
||||
if (nodeName(parent) !== 'html') parentOffset = getOffset(parent);
|
||||
const parentStyle = getComputedStyle(parent);
|
||||
const borderTop = String(
|
||||
getComputedStyle(parent).getPropertyValue('border-top-width') || 0
|
||||
parentStyle.getPropertyValue('border-top-width') || 0
|
||||
);
|
||||
parentOffset.top += parseInt(borderTop, 10) - parent.scrollTop || 0;
|
||||
|
||||
const borderLeft = String(
|
||||
getComputedStyle(parent).getPropertyValue('border-left-width') || 0
|
||||
parentStyle.getPropertyValue('border-left-width') || 0
|
||||
);
|
||||
parentOffset.left += parseInt(borderLeft, 10) - parent.scrollLeft || 0;
|
||||
}
|
||||
|
||||
const marginTop = String(
|
||||
getComputedStyle(node).getPropertyValue('margin-top') || 0
|
||||
);
|
||||
const marginLeft = String(
|
||||
getComputedStyle(node).getPropertyValue('margin-left') || 0
|
||||
);
|
||||
// const marginTop = String(
|
||||
// getComputedStyle(node).getPropertyValue('margin-top') || 0
|
||||
// );
|
||||
// const marginLeft = String(
|
||||
// getComputedStyle(node).getPropertyValue('margin-left') || 0
|
||||
// );
|
||||
// Subtract parent offsets and node margins
|
||||
return {
|
||||
...offset,
|
||||
top: offset.top - parentOffset.top - (parseInt(marginTop, 10) || 0),
|
||||
left: offset.left - parentOffset.left - (parseInt(marginLeft, 10) || 0)
|
||||
top: offset.top - parentOffset.top /*- (parseInt(marginTop, 10) || 0)*/,
|
||||
left: offset.left - parentOffset.left /* - (parseInt(marginLeft, 10) || 0)*/
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -256,14 +256,16 @@ export const validations: {
|
||||
},
|
||||
isPhoneNumber: function (values, value) {
|
||||
return (
|
||||
!isExisty(value) || isEmpty(value) || /^[1]([3-9])[0-9]{9}$/.test(value)
|
||||
!isExisty(value) ||
|
||||
isEmpty(value) ||
|
||||
/^(\+\d{2}-)?[1]([3-9])[0-9]{9}$/.test(value)
|
||||
);
|
||||
},
|
||||
isTelNumber: function (values, value) {
|
||||
return (
|
||||
!isExisty(value) ||
|
||||
isEmpty(value) ||
|
||||
/^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/.test(value)
|
||||
/^(\+\d{2}-)?(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/.test(value)
|
||||
);
|
||||
},
|
||||
isZipcode: function (values, value) {
|
||||
|
@ -27,8 +27,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Warnings: no test specified\"",
|
||||
"build": "npm run clean-dist && NODE_ENV=production rollup -c",
|
||||
"build-esm": "npm run clean-dist && NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"build": "npm run clean-dist && cross-env NODE_ENV=production rollup -c",
|
||||
"build-esm": "npm run clean-dist && cross-env NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"clean-dist": "rimraf lib/* esm/*",
|
||||
"i18n:update": "npx i18n update --config=./i18nConfig.js",
|
||||
"i18n:translate": "npx i18n translate --config=./i18nConfig.js --l=en-US",
|
||||
@ -60,6 +60,7 @@
|
||||
"sortablejs": "^1.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
"@rollup/plugin-commonjs": "^22.0.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
|
@ -50,8 +50,14 @@
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-content-oldentry {
|
||||
margin-top: 100px !important;
|
||||
&-header-m {
|
||||
margin-top: #{px2rem(45px)} !important;
|
||||
}
|
||||
&-content-m {
|
||||
margin-top: #{px2rem(97px)} !important;
|
||||
}
|
||||
&-content-l {
|
||||
margin-top: #{px2rem(150px)} !important;
|
||||
}
|
||||
&-content {
|
||||
padding: 0;
|
||||
@ -192,14 +198,32 @@
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
.variable-left {
|
||||
.action-desc {
|
||||
display: flex;
|
||||
.desc-tag {
|
||||
max-width: 133px;
|
||||
color: #2468f2;
|
||||
display: inline-block;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
.variable-left {
|
||||
margin-left: #{px2rem(4px)};
|
||||
}
|
||||
.variable-right {
|
||||
color: #2468f2;
|
||||
margin-right: #{px2rem(4px)};
|
||||
}
|
||||
.component-action-tag {
|
||||
background-color: rgb(82, 142, 255);
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
padding: 0 5px;
|
||||
border-radius: 3px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
&--dragging {
|
||||
height: 0 !important;
|
||||
@ -297,7 +321,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.action-config-dialog {
|
||||
.ae-action-config-dialog {
|
||||
*:not(svg) {
|
||||
font-size: 12px;
|
||||
}
|
||||
@ -468,7 +492,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.event-item-header-tip {
|
||||
.ae-event-item-header-tip {
|
||||
background: #070c14d9 !important;
|
||||
box-shadow: 0 px2rem(2px) px2rem(8px) 0 rgba(7, 12, 20, 0.12);
|
||||
border: none;
|
||||
@ -476,9 +500,6 @@
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.event-item-header-tip {
|
||||
& > div {
|
||||
&:after {
|
||||
border-top-color: #070c14d9 !important;
|
||||
@ -486,3 +507,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ae-action-relation-panel {
|
||||
width: 255px;
|
||||
max-height: 360px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
@import './style-control/size';
|
||||
@import './style-control/style-common';
|
||||
@import './style-control/theme-css-code';
|
||||
@import './style-control/single-theme-css-code';
|
||||
@import './style-control/flex-layout';
|
||||
@import './style-control/col-count';
|
||||
@import './style-control/col-size';
|
||||
|
@ -0,0 +1,83 @@
|
||||
.ae-SingleThemeCssCode {
|
||||
position: relative;
|
||||
border: 1px solid #e8e9eb;
|
||||
border-radius: var(--input-default-default-top-left-border-radius)
|
||||
var(--input-default-default-top-right-border-radius)
|
||||
var(--input-default-default-bottom-right-border-radius)
|
||||
var(--input-default-default-bottom-left-border-radius);
|
||||
|
||||
&-label {
|
||||
margin-bottom: px2rem(10px);
|
||||
color: #5c5f66;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-header,
|
||||
&-footer {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
&-button {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 12px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
cursor: pointer;
|
||||
color: #5c5f66;
|
||||
&:hover {
|
||||
color: #151b26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ae-SingleThemeCssCode-custom-editor {
|
||||
.suggest-widget {
|
||||
width: auto !important;
|
||||
left: 16px !important;
|
||||
right: 0 !important;
|
||||
|
||||
.monaco-sash:first-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ae-SingleThemeCssCode-panel {
|
||||
height: auto;
|
||||
width: px2rem(460px);
|
||||
padding: px2rem(16px);
|
||||
position: relative;
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
margin-bottom: px2rem(16px);
|
||||
}
|
||||
|
||||
&-close {
|
||||
position: absolute;
|
||||
top: px2rem(14px);
|
||||
right: px2rem(16px);
|
||||
button {
|
||||
height: px2rem(16px);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
height: px2rem(500px);
|
||||
width: 100%;
|
||||
border: 1px solid #e8e9eb;
|
||||
|
||||
.ae-SingleThemeCssCode-content {
|
||||
height: px2rem(454px);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ import Breadcrumb from './Breadcrumb';
|
||||
import {destroy, isAlive} from 'mobx-state-tree';
|
||||
import {ScaffoldModal} from './ScaffoldModal';
|
||||
import {PopOverForm} from './PopOverForm';
|
||||
import {ModalForm} from './ModalForm';
|
||||
import {ContextMenuPanel} from './Panel/ContextMenuPanel';
|
||||
import {LeftPanels} from './Panel/LeftPanels';
|
||||
import {RightPanels} from './Panel/RightPanels';
|
||||
@ -143,6 +144,11 @@ export interface EditorProps extends PluginEventListener {
|
||||
|
||||
getAvaiableContextFields?: (node: EditorNodeType) => Promise<any>;
|
||||
readonly?: boolean;
|
||||
|
||||
onEditorMount?: (manager: EditorManager) => void;
|
||||
onEditorUnmount?: (manager: EditorManager) => void;
|
||||
|
||||
children?: React.ReactNode | ((manager: EditorManager) => React.ReactNode);
|
||||
}
|
||||
|
||||
export default class Editor extends Component<EditorProps> {
|
||||
@ -170,6 +176,7 @@ export default class Editor extends Component<EditorProps> {
|
||||
showCustomRenderersPanel,
|
||||
superEditorData,
|
||||
hostManager,
|
||||
onEditorMount,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@ -225,6 +232,8 @@ export default class Editor extends Component<EditorProps> {
|
||||
this.toDispose.push(
|
||||
this.manager.on('preview2editor', () => this.manager.rebuild())
|
||||
);
|
||||
|
||||
onEditorMount?.(this.manager);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -268,6 +277,7 @@ export default class Editor extends Component<EditorProps> {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.onEditorUnmount?.(this.manager);
|
||||
document.removeEventListener('keydown', this.handleKeyDown);
|
||||
window.removeEventListener('message', this.handleMessage);
|
||||
this.toDispose.forEach(fn => fn());
|
||||
@ -588,7 +598,8 @@ export default class Editor extends Component<EditorProps> {
|
||||
autoFocus,
|
||||
isSubEditor,
|
||||
amisEnv,
|
||||
readonly
|
||||
readonly,
|
||||
children
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -662,6 +673,8 @@ export default class Editor extends Component<EditorProps> {
|
||||
)}
|
||||
|
||||
{!preview && <ContextMenuPanel store={this.store} />}
|
||||
|
||||
{typeof children === 'function' ? children(this.manager) : children}
|
||||
</div>
|
||||
|
||||
<SubEditor
|
||||
@ -677,6 +690,7 @@ export default class Editor extends Component<EditorProps> {
|
||||
theme={theme}
|
||||
/>
|
||||
<PopOverForm store={this.store} manager={this.manager} theme={theme} />
|
||||
<ModalForm store={this.store} manager={this.manager} theme={theme} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
161
packages/amis-editor-core/src/component/ModalForm.tsx
Normal file
161
packages/amis-editor-core/src/component/ModalForm.tsx
Normal file
@ -0,0 +1,161 @@
|
||||
import React from 'react';
|
||||
import {EditorManager} from '../manager';
|
||||
import {EditorStoreType} from '../store/editor';
|
||||
import {
|
||||
render,
|
||||
Modal,
|
||||
getTheme,
|
||||
Icon,
|
||||
Spinner,
|
||||
Button,
|
||||
Overlay,
|
||||
PopOver,
|
||||
Drawer
|
||||
} from 'amis';
|
||||
import {observer} from 'mobx-react';
|
||||
import {diff} from '../util';
|
||||
import {autobind, createObject} from 'amis-core';
|
||||
|
||||
export interface ModalFormProps {
|
||||
store: EditorStoreType;
|
||||
manager: EditorManager;
|
||||
theme?: string;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class ModalForm extends React.Component<ModalFormProps> {
|
||||
@autobind
|
||||
async handleConfirmClick() {
|
||||
const form = this.amisScope?.getComponents()[0];
|
||||
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
const {store} = this.props;
|
||||
const modalFormContext = store.modalForm!;
|
||||
|
||||
try {
|
||||
store.markModalFormBuzy(true);
|
||||
const newValue = await form.doAction(
|
||||
{
|
||||
type: 'submit'
|
||||
},
|
||||
form.props.data,
|
||||
true
|
||||
);
|
||||
|
||||
modalFormContext.callback?.(
|
||||
newValue,
|
||||
diff(modalFormContext.value, newValue)
|
||||
);
|
||||
store.closeModalForm();
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
store.setModalFormError(e.message);
|
||||
}
|
||||
|
||||
store.markModalFormBuzy(false);
|
||||
}
|
||||
|
||||
amisScope: any;
|
||||
@autobind
|
||||
scopeRef(scoped: any) {
|
||||
this.amisScope = scoped;
|
||||
}
|
||||
|
||||
buildSchema() {
|
||||
const {store} = this.props;
|
||||
const modalFormContext = store.modalForm!;
|
||||
|
||||
return {
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
mode: 'normal',
|
||||
wrapperComponent: 'div',
|
||||
initApi: modalFormContext.initApi,
|
||||
api: modalFormContext.api,
|
||||
body: modalFormContext.body,
|
||||
submitOnChange: false,
|
||||
autoFocus: true
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {store, theme, manager} = this.props;
|
||||
const modalFormContext = store.modalForm;
|
||||
const modalMode = store.modalMode || 'dialog';
|
||||
const contents = modalFormContext
|
||||
? render(
|
||||
this.buildSchema(),
|
||||
{
|
||||
data: createObject(store.ctx, modalFormContext?.value),
|
||||
manager,
|
||||
scopeRef: this.scopeRef
|
||||
},
|
||||
{
|
||||
...manager.env,
|
||||
session: 'modal-form',
|
||||
theme: theme
|
||||
}
|
||||
)
|
||||
: null;
|
||||
|
||||
return modalMode === 'drawer' ? (
|
||||
<Drawer
|
||||
position={(modalFormContext?.postion as any) || 'left'}
|
||||
size={modalFormContext?.size || 'md'}
|
||||
theme={theme}
|
||||
show={!!modalFormContext}
|
||||
onHide={store.closeModalForm}
|
||||
>
|
||||
<div className="cxd-Drawer-header">{modalFormContext?.title}</div>
|
||||
<div className="cxd-Drawer-body">{contents}</div>
|
||||
<div className="cxd-Drawer-footer">
|
||||
<div className="cxd-Drawer-info">
|
||||
{store.modalFormError ? (
|
||||
<div className="cxd-Drawer-error">{store.modalFormError}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<Button
|
||||
disabled={store.modalFormBuzy}
|
||||
level="primary"
|
||||
onClick={this.handleConfirmClick}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
<Button onClick={store.closeModalForm}>取消</Button>
|
||||
</div>
|
||||
</Drawer>
|
||||
) : (
|
||||
<Modal
|
||||
theme={theme}
|
||||
size={modalFormContext?.size || 'md'}
|
||||
show={!!modalFormContext}
|
||||
onHide={store.closeModalForm}
|
||||
closeOnEsc={false}
|
||||
>
|
||||
{modalFormContext?.title ? (
|
||||
<Modal.Header onClose={store.closeModalForm}>
|
||||
{modalFormContext.title}
|
||||
</Modal.Header>
|
||||
) : null}
|
||||
<Modal.Body>{contents}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<div className="cxd-Dialog-info">
|
||||
{store.modalFormError ? (
|
||||
<div className="cxd-Dialog-error">{store.modalFormError}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<Button
|
||||
disabled={store.modalFormBuzy}
|
||||
level="primary"
|
||||
onClick={this.handleConfirmClick}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
<Button onClick={store.closeModalForm}>取消</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ export class AvailableRenderersPanel extends React.Component<
|
||||
}
|
||||
|
||||
render() {
|
||||
const {store, manager} = this.props;
|
||||
const {store, manager, children} = this.props;
|
||||
const renderersTabsKey = store.renderersTabsKey || 'base-renderers';
|
||||
const curTheme = store.theme;
|
||||
const customRenderersByOrder = store.customRenderersByOrder || [];
|
||||
@ -33,6 +33,7 @@ export class AvailableRenderersPanel extends React.Component<
|
||||
<div className="ae-RendererPanel">
|
||||
<div className="panel-header">组件</div>
|
||||
<div className="ae-RendererPanel-content">
|
||||
{typeof children === 'function' ? children(this.props) : children}
|
||||
{store.showCustomRenderersPanel &&
|
||||
customRenderersByOrder.length > 0 && (
|
||||
<Tabs
|
||||
|
@ -728,7 +728,11 @@ class SmartPreview extends React.Component<SmartPreviewProps> {
|
||||
locale: appLocale,
|
||||
editorDialogMountNode: this.getDialogMountRef
|
||||
},
|
||||
env
|
||||
{
|
||||
...env,
|
||||
session: editable ? 'edit-mode' : 'preview-mode',
|
||||
enableAMISDebug: !editable
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
130
packages/amis-editor-core/src/deepSplice.ts
Normal file
130
packages/amis-editor-core/src/deepSplice.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import isPlainObject from 'lodash/isPlainObject';
|
||||
|
||||
/**
|
||||
* 深度 splice 数组,同时返回新的对象,按需拷贝,没有副作用
|
||||
*
|
||||
* 第二个参数可以是一个函数,函数的返回值不为 false 时,表示找到了目标,函数的返回值为 number 时,表示偏移量
|
||||
*
|
||||
* @param target
|
||||
* @param path
|
||||
* @param numberToDelete
|
||||
* @param items
|
||||
* @returns
|
||||
*/
|
||||
export function deepSplice(
|
||||
target: any,
|
||||
path:
|
||||
| string
|
||||
| ((value: any, index: number | string, stack: Array<any>) => any),
|
||||
numberToDelete: number,
|
||||
provider?: ((origin: any) => any) | any,
|
||||
...items: any[]
|
||||
) {
|
||||
if (typeof path === 'function') {
|
||||
path = getPathByFunction(target, path);
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
return target;
|
||||
}
|
||||
|
||||
const paths = (path as string).split('.');
|
||||
const last = paths.pop()!;
|
||||
let host = target;
|
||||
const stack: Array<{
|
||||
host: any;
|
||||
key: string | number | undefined;
|
||||
}> = [];
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
stack.unshift({
|
||||
key: paths[i]!,
|
||||
host: host
|
||||
});
|
||||
host = host[paths[i]];
|
||||
}
|
||||
|
||||
if (!Array.isArray(host)) {
|
||||
throw new Error('deepSplice: target is not an array');
|
||||
}
|
||||
host = host.concat();
|
||||
|
||||
if (provider && typeof provider === 'function') {
|
||||
host.splice.apply(
|
||||
host,
|
||||
[last, numberToDelete].concat(provider(host[last]))
|
||||
);
|
||||
} else {
|
||||
host.splice.apply(host, [last, numberToDelete, provider].concat(items));
|
||||
}
|
||||
|
||||
return stack.reduce((prefix, {host, key}) => {
|
||||
host = Array.isArray(host) ? host.concat() : {...host};
|
||||
host[key!] = prefix;
|
||||
|
||||
return host;
|
||||
}, host);
|
||||
}
|
||||
|
||||
function getPathByFunction(
|
||||
target: any,
|
||||
fn: (value: any, index: number | string, stack: Array<any>) => any
|
||||
): string {
|
||||
let paths: Array<string> = [];
|
||||
let resolved: boolean = false;
|
||||
let stack: Array<any> = [
|
||||
{
|
||||
path: '',
|
||||
key: '',
|
||||
stack: [],
|
||||
data: target
|
||||
}
|
||||
];
|
||||
|
||||
while (stack.length) {
|
||||
let cur = stack.shift()!;
|
||||
let data = cur.data;
|
||||
let path = cur.path;
|
||||
let nodeStack = cur.stack;
|
||||
let key = cur.key;
|
||||
|
||||
const result = fn(data, key, nodeStack);
|
||||
|
||||
if (result) {
|
||||
resolved = true;
|
||||
paths = path.split('.').filter((item: any) => item);
|
||||
|
||||
// apply offset
|
||||
if (typeof result === 'number') {
|
||||
paths[paths.length - 1] = (
|
||||
parseInt(paths[paths.length - 1], 10) + result
|
||||
).toString();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
// 注意 Object.keys 返回的 key 是字符串,所以这里要转换一下
|
||||
data.forEach((prop, key) => {
|
||||
stack.push({
|
||||
path: `${path}.${key}`,
|
||||
key: key,
|
||||
stack: [data].concat(nodeStack),
|
||||
data: prop
|
||||
});
|
||||
});
|
||||
} else if (isPlainObject(data)) {
|
||||
Object.keys(data).forEach(key => {
|
||||
let prop = data[key];
|
||||
stack.push({
|
||||
path: `${path}.${key}`,
|
||||
key: key,
|
||||
stack: [data].concat(nodeStack),
|
||||
data: prop
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return resolved ? paths.join('.') : '';
|
||||
}
|
@ -42,6 +42,9 @@ import {UnknownRendererPlugin} from './plugin/Unknown';
|
||||
import ShortcutKey from './component/base/ShortcutKey';
|
||||
import WidthDraggableContainer from './component/base/WidthDraggableContainer';
|
||||
import {SchemaFrom} from './component/base/SchemaForm';
|
||||
import {RendererThumb} from './component/RendererThumb';
|
||||
import {AvailableRenderersPanel} from './component/Panel/AvailableRenderersPanel';
|
||||
import {deepSplice} from './deepSplice';
|
||||
|
||||
export const version = '__buildVersion';
|
||||
(window as any).amisEditorVersionInfo = {
|
||||
@ -55,6 +58,7 @@ export {
|
||||
Editor,
|
||||
MiniEditor,
|
||||
utils,
|
||||
deepSplice,
|
||||
mapReactElement,
|
||||
RendererEditor,
|
||||
BasicEditor,
|
||||
@ -68,6 +72,7 @@ export {
|
||||
EditorStoreType,
|
||||
ContainerWrapper,
|
||||
AvailableRenderersPlugin,
|
||||
AvailableRenderersPanel,
|
||||
BasicToolbarPlugin,
|
||||
CodePlugin,
|
||||
ErrorRendererPlugin,
|
||||
@ -75,5 +80,6 @@ export {
|
||||
UnknownRendererPlugin,
|
||||
ShortcutKey,
|
||||
SchemaFrom,
|
||||
WidthDraggableContainer
|
||||
WidthDraggableContainer,
|
||||
RendererThumb
|
||||
};
|
||||
|
@ -9,7 +9,12 @@ import debounce from 'lodash/debounce';
|
||||
import findIndex from 'lodash/findIndex';
|
||||
import omit from 'lodash/omit';
|
||||
import {openContextMenus, toast, alert, DataScope, DataSchema} from 'amis';
|
||||
import {getRenderers, RenderOptions, JSONTraverse} from 'amis-core';
|
||||
import {
|
||||
getRenderers,
|
||||
RenderOptions,
|
||||
JSONTraverse,
|
||||
wrapFetcher
|
||||
} from 'amis-core';
|
||||
import {
|
||||
PluginInterface,
|
||||
BasicPanelItem,
|
||||
@ -69,7 +74,7 @@ import {VariableManager} from './variable';
|
||||
|
||||
import type {IScopedContext} from 'amis';
|
||||
import type {SchemaObject, SchemaCollection} from 'amis';
|
||||
import type {RendererConfig} from 'amis-core';
|
||||
import type {Api, Payload, RendererConfig, RendererEnv} from 'amis-core';
|
||||
import {loadAsyncRenderer} from 'amis-core';
|
||||
|
||||
export interface EditorManagerConfig
|
||||
@ -215,6 +220,7 @@ export class EditorManager {
|
||||
|
||||
/** 变量管理 */
|
||||
readonly variableManager;
|
||||
fetch?: (api: Api, data?: any, options?: object) => Promise<Payload>;
|
||||
|
||||
constructor(
|
||||
readonly config: EditorManagerConfig,
|
||||
@ -223,10 +229,17 @@ export class EditorManager {
|
||||
) {
|
||||
// 传给 amis 渲染器的默认 env
|
||||
this.env = {
|
||||
...env, // 默认的 env 中带 jumpTo
|
||||
...(env as any), // 默认的 env 中带 jumpTo
|
||||
...omit(config.amisEnv, 'replaceText'), // 用户也可以设置自定义环境配置,用于覆盖默认的 env
|
||||
theme: config.theme
|
||||
theme: config.theme!
|
||||
};
|
||||
|
||||
// 内部统一使用 wrapFetcher 包装 fetcher
|
||||
if (this.env.fetcher) {
|
||||
this.env.fetcher = wrapFetcher(this.env.fetcher as any, this.env.tracker);
|
||||
this.fetch = this.env.fetcher as any;
|
||||
}
|
||||
|
||||
this.env.beforeDispatchEvent = this.beforeDispatchEvent.bind(
|
||||
this,
|
||||
this.env.beforeDispatchEvent
|
||||
@ -1837,8 +1850,11 @@ export class EditorManager {
|
||||
this.dnd.startDrag(id, e.nativeEvent);
|
||||
}
|
||||
|
||||
async scaffold(form: any, value: any): Promise<SchemaObject> {
|
||||
async scaffold(form: ScaffoldForm, value: any): Promise<SchemaObject> {
|
||||
const scaffoldFormData = form.pipeIn ? await form.pipeIn(value) : value;
|
||||
if (form.getSchema) {
|
||||
form = Object.assign({}, form, await form.getSchema(scaffoldFormData));
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
this.store.openScaffoldForm({
|
||||
@ -1857,7 +1873,7 @@ export class EditorManager {
|
||||
// 根据元素ID实时拿取上下文数据
|
||||
async reScaffoldV2(id: string) {
|
||||
const commonContext = this.buildEventContext(id);
|
||||
const scaffoldForm = commonContext.info?.scaffoldForm;
|
||||
const scaffoldForm = commonContext.info?.scaffoldForm!;
|
||||
const curSchema = commonContext.schema;
|
||||
const replaceWith = await this.scaffold(scaffoldForm, curSchema);
|
||||
this.replaceChild(id, replaceWith);
|
||||
|
@ -335,6 +335,9 @@ export interface PopOverForm {
|
||||
* @deprecated 改用 body 代替
|
||||
*/
|
||||
controls?: Array<any>;
|
||||
|
||||
initApi?: any;
|
||||
api?: any;
|
||||
}
|
||||
|
||||
export interface ScaffoldForm extends PopOverForm {
|
||||
@ -342,6 +345,7 @@ export interface ScaffoldForm extends PopOverForm {
|
||||
stepsBody?: boolean;
|
||||
/** 是否可跳过创建向导直接创建 */
|
||||
canSkip?: boolean;
|
||||
getSchema?: (value: any) => PopOverForm | Promise<PopOverForm>;
|
||||
mode?:
|
||||
| 'normal'
|
||||
| 'horizontal'
|
||||
@ -453,6 +457,7 @@ export interface PanelProps {
|
||||
manager: EditorManager;
|
||||
popOverContainer?: () => HTMLElement | void;
|
||||
readonly?: boolean;
|
||||
children?: React.ReactNode | ((props: PanelProps) => React.ReactNode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,6 +122,14 @@ export interface PopOverFormContext extends PopOverForm {
|
||||
node?: EditorNodeType;
|
||||
}
|
||||
|
||||
export interface ModalFormContext extends PopOverForm {
|
||||
mode?: 'dialog' | 'drawer';
|
||||
size?: string;
|
||||
postion?: string;
|
||||
value: any;
|
||||
callback: (value: any, diff: any) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜集的 name 信息
|
||||
*/
|
||||
@ -233,6 +241,12 @@ export const MainStore = types
|
||||
|
||||
popOverForm: types.maybe(types.frozen<PopOverFormContext>()),
|
||||
|
||||
// 弹出层表单
|
||||
modalForm: types.maybe(types.frozen<ModalFormContext>()),
|
||||
modalMode: '',
|
||||
modalFormBuzy: false,
|
||||
modalFormError: '',
|
||||
|
||||
// 弹出子编辑器相关的信息
|
||||
subEditorContext: types.maybe(types.frozen<SubEditorContext>()),
|
||||
// 子编辑器中可能需要拿到父编辑器的数据
|
||||
@ -278,6 +292,10 @@ export const MainStore = types
|
||||
return false;
|
||||
},
|
||||
|
||||
get rootId() {
|
||||
return this.getRootId();
|
||||
},
|
||||
|
||||
getRootId() {
|
||||
const curSchema = this.getSchema();
|
||||
return curSchema?.$$id;
|
||||
@ -2105,6 +2123,24 @@ export const MainStore = types
|
||||
self.popOverForm = undefined;
|
||||
},
|
||||
|
||||
openModalForm(context: ModalFormContext) {
|
||||
self.modalForm = context;
|
||||
self.modalMode = context?.mode || self.modalMode;
|
||||
self.modalFormError = '';
|
||||
},
|
||||
|
||||
closeModalForm() {
|
||||
self.modalForm = undefined;
|
||||
},
|
||||
|
||||
markModalFormBuzy(value: any) {
|
||||
self.modalFormBuzy = !!value;
|
||||
},
|
||||
|
||||
setModalFormError(msg: string = '') {
|
||||
self.modalFormError = msg;
|
||||
},
|
||||
|
||||
activeHighlightNodes(ids: Array<string>) {
|
||||
ids.forEach(id => {
|
||||
const node = self.getNodeById(id);
|
||||
|
@ -21,8 +21,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Warnings: no test specified\"",
|
||||
"build": "npm run clean-dist && NODE_ENV=production rollup -c ",
|
||||
"build-esm": "npm run clean-dist && NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"build": "npm run clean-dist && cross-env NODE_ENV=production rollup -c ",
|
||||
"build-esm": "npm run clean-dist && cross-env NODE_ENV=production rollup -c rollup.esm.config.js",
|
||||
"clean-dist": "rimraf lib/** esm/**",
|
||||
"i18n:update": "npx i18n update --config=./i18nConfig.js",
|
||||
"i18n:translate": "npx i18n translate --config=./i18nConfig.js --l=en-US",
|
||||
@ -49,6 +49,7 @@
|
||||
"mobx-state-tree": "^3.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
"@rollup/plugin-commonjs": "^22.0.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
|
@ -3,12 +3,11 @@
|
||||
*/
|
||||
|
||||
import flatten from 'lodash/flatten';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
SUPPORT_STATIC_FORMITEM_CMPTS
|
||||
} from '../renderer/event-control/helper';
|
||||
import {NO_SUPPORT_STATIC_FORMITEM_CMPTS} from '../renderer/event-control/constants';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {getSchemaTpl, isObject, tipedLabel} from 'amis-editor-core';
|
||||
import type {BaseEventContext} from 'amis-editor-core';
|
||||
import {getRendererByName} from 'amis-core';
|
||||
|
||||
// 默认动作
|
||||
export const BUTTON_DEFAULT_ACTION = {
|
||||
@ -199,7 +198,9 @@ export const formItemControl: (
|
||||
context?: BaseEventContext
|
||||
) => Array<any> = (panels, context) => {
|
||||
const type = context?.schema?.type || '';
|
||||
const supportStatic = SUPPORT_STATIC_FORMITEM_CMPTS.includes(type);
|
||||
const render = getRendererByName(type);
|
||||
const supportStatic =
|
||||
!!render?.isFormItem && !NO_SUPPORT_STATIC_FORMITEM_CMPTS.includes(type);
|
||||
const collapseProps = {
|
||||
type: 'collapse',
|
||||
headingClassName: 'ae-formItemControl-header ae-Collapse-header',
|
||||
|
@ -5,6 +5,8 @@ export * from './builder';
|
||||
import './tpl/index';
|
||||
export * from './plugin';
|
||||
export * from './validator';
|
||||
export * from './renderer/event-control/actionsPanelManager';
|
||||
export * from './renderer/event-control/helper';
|
||||
|
||||
import './renderer/OptionControl';
|
||||
import './renderer/ValueFormatControl';
|
||||
@ -45,6 +47,7 @@ import './renderer/event-control/index';
|
||||
import './renderer/TreeOptionControl';
|
||||
import './renderer/TransferTableControl';
|
||||
import './renderer/style-control/ThemeCssCode';
|
||||
import './renderer/style-control/SingleThemeCssCode';
|
||||
import './renderer/style-control/ColCount';
|
||||
import './renderer/style-control/ColSize';
|
||||
import './renderer/style-control/LabelAlign';
|
||||
|
@ -80,6 +80,7 @@ export class AnchorNavPlugin extends BasePlugin {
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
id: 'properties-basic',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
getSchemaTpl('combo-container', {
|
||||
@ -163,6 +164,7 @@ export class AnchorNavPlugin extends BasePlugin {
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
id: 'appearance-basic',
|
||||
body: [
|
||||
{
|
||||
type: 'button-group-select',
|
||||
|
@ -204,6 +204,7 @@ export class ButtonPlugin extends BasePlugin {
|
||||
formType: 'extend',
|
||||
mode: 'normal',
|
||||
label: '气泡提示',
|
||||
id: 'button-tooltip', //便于扩充定位
|
||||
hidden: isInDropdown,
|
||||
form: {
|
||||
body: [
|
||||
@ -351,11 +352,16 @@ export class ButtonPlugin extends BasePlugin {
|
||||
...buttonStateFunc("${__editorState == 'active'}", 'active')
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: [
|
||||
getSchemaTpl('theme:singleCssCode', {
|
||||
selectors: [
|
||||
{
|
||||
value: '',
|
||||
state: ['default', 'hover', 'active']
|
||||
label: '按钮基本样式',
|
||||
isRoot: true,
|
||||
selector: '.cxd-Button'
|
||||
},
|
||||
{
|
||||
label: '按钮内容样式',
|
||||
selector: 'span'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
@ -1,7 +1,10 @@
|
||||
import {toast, normalizeApiResponseData} from 'amis';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import React from 'react';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
import {genCodeSchema} from '../renderer/APIAdaptorControl';
|
||||
import {
|
||||
getI18nEnabled,
|
||||
@ -20,12 +23,12 @@ import {
|
||||
RendererEventContext,
|
||||
RendererInfoResolveEventContext,
|
||||
ScaffoldForm,
|
||||
SubRendererInfo
|
||||
SubRendererInfo,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
JSONPipeIn
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {isObject, JSONPipeIn} from 'amis-editor-core';
|
||||
import {setVariable, someTree} from 'amis-core';
|
||||
import type {ActionSchema} from 'amis';
|
||||
import {setVariable, someTree, normalizeApi} from 'amis-core';
|
||||
import type {CRUDCommonSchema} from 'amis';
|
||||
import {getEnv} from 'mobx-state-tree';
|
||||
import type {
|
||||
@ -33,7 +36,6 @@ import type {
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {normalizeApi} from 'amis-core';
|
||||
import isPlainObject from 'lodash/isPlainObject';
|
||||
import findLastIndex from 'lodash/findLastIndex';
|
||||
|
||||
@ -367,12 +369,14 @@ export class CRUDPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionLabel: '变量赋值',
|
||||
actionType: 'setValue',
|
||||
description: '更新列表记录'
|
||||
description: '更新列表记录',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -30,9 +30,10 @@ import {
|
||||
} from '../../builder';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getArgsWrapper
|
||||
getArgsWrapper,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {CRUD2Schema} from 'amis/lib/renderers/CRUD2';
|
||||
import {CRUD2Schema} from 'amis';
|
||||
import {deepRemove, findObj, findSchema} from './utils';
|
||||
import {
|
||||
ToolsConfig,
|
||||
@ -113,9 +114,9 @@ export class BaseCRUDPlugin extends BasePlugin {
|
||||
actionType: 'search',
|
||||
actionLabel: '数据查询',
|
||||
description: '使用指定条件完成列表数据查询',
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
触发数据查询
|
||||
</div>
|
||||
@ -134,9 +135,9 @@ export class BaseCRUDPlugin extends BasePlugin {
|
||||
actionType: 'loadMore',
|
||||
actionLabel: '加载更多',
|
||||
description: '加载更多条数据到列表容器',
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
加载更多数据
|
||||
</div>
|
||||
@ -156,7 +157,8 @@ export class BaseCRUDPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
...(actions || [])
|
||||
],
|
||||
|
@ -1,9 +1,15 @@
|
||||
import {registerEditorPlugin, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {BaseEventContext, BasePlugin, tipedLabel} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
RendererPluginEvent,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control';
|
||||
import {FormulaDateType} from '../renderer/FormulaControl';
|
||||
import type {Schema} from 'amis';
|
||||
|
||||
export class CalendarPlugin extends BasePlugin {
|
||||
static id = 'CalendarPlugin';
|
||||
@ -126,17 +132,20 @@ export class CalendarPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空'
|
||||
description: '清空',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -12,7 +12,10 @@ import {
|
||||
RendererPluginEvent,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
|
||||
const ChartConfigEditor = ({value, onChange}: any) => {
|
||||
return (
|
||||
@ -181,12 +184,14 @@ export class ChartPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
// 特性动作太多了,这里先不加了,可以通过写代码配置
|
||||
];
|
||||
|
@ -1,12 +1,17 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
getI18nEnabled,
|
||||
registerEditorPlugin
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
RegionConfig,
|
||||
BaseEventContext,
|
||||
defaultValue,
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {getActionCommonProps} from '../renderer/event-control/helper';
|
||||
|
||||
export class CollapsePlugin extends BasePlugin {
|
||||
static id = 'CollapsePlugin';
|
||||
@ -114,12 +119,21 @@ export class CollapsePlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'expand',
|
||||
actionLabel: '组件展开',
|
||||
description: '组件折叠状态变更为展开'
|
||||
description: '组件折叠状态变更为展开',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.rendererLabel}</span>
|
||||
展开
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
actionLabel: '组件收起',
|
||||
actionType: 'collapse',
|
||||
description: '组件折叠状态变更为收起'
|
||||
description: '组件折叠状态变更为收起',
|
||||
...getActionCommonProps('collapse')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -27,6 +27,7 @@ export class CollapseGroupPlugin extends BasePlugin {
|
||||
pluginIcon = 'collapse-plugin';
|
||||
scaffold = {
|
||||
type: 'collapse-group',
|
||||
enableFieldSetStyle: true,
|
||||
activeKey: ['1'],
|
||||
body: [
|
||||
{
|
||||
@ -101,6 +102,7 @@ export class CollapseGroupPlugin extends BasePlugin {
|
||||
panelJustify = true;
|
||||
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
const isInForm = context.path.includes('/form/');
|
||||
const i18nEnabled = getI18nEnabled();
|
||||
return [
|
||||
getSchemaTpl('tabs', [
|
||||
@ -111,6 +113,22 @@ export class CollapseGroupPlugin extends BasePlugin {
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
{
|
||||
name: 'enableFieldSetStyle',
|
||||
label: '展示风格',
|
||||
visible: isInForm,
|
||||
type: 'button-group-select',
|
||||
options: [
|
||||
{
|
||||
label: '默认',
|
||||
value: false
|
||||
},
|
||||
{
|
||||
label: '简洁',
|
||||
value: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'expandIconPosition',
|
||||
label: '图标位置',
|
||||
|
@ -18,7 +18,10 @@ import {
|
||||
ChangeEventContext,
|
||||
JSONPipeOut
|
||||
} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
import omit from 'lodash/omit';
|
||||
import type {RendererConfig, Schema} from 'amis-core';
|
||||
import {ModalProps} from 'amis-ui/lib/components/Modal';
|
||||
@ -119,7 +122,8 @@ export class DialogPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'confirm',
|
||||
actionLabel: '确认',
|
||||
description: '触发弹窗确认操作'
|
||||
description: '触发弹窗确认操作',
|
||||
descDetail: (info: any) => <div>打开确认对话框</div>
|
||||
},
|
||||
{
|
||||
actionType: 'cancel',
|
||||
@ -129,7 +133,8 @@ export class DialogPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
@ -12,7 +13,10 @@ import {
|
||||
getI18nEnabled,
|
||||
JSONPipeOut
|
||||
} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import omit from 'lodash/omit';
|
||||
import {InlineModal} from './Dialog';
|
||||
@ -100,7 +104,8 @@ export class DrawerPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'confirm',
|
||||
actionLabel: '确认',
|
||||
description: '触发抽屉确认操作'
|
||||
description: '触发抽屉确认操作',
|
||||
descDetail: (info: any) => <div>触发确认操作</div>
|
||||
},
|
||||
{
|
||||
actionType: 'cancel',
|
||||
@ -110,7 +115,8 @@ export class DrawerPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,20 +1,22 @@
|
||||
import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
tipedLabel
|
||||
tipedLabel,
|
||||
getSchemaTpl,
|
||||
defaultValue
|
||||
} from 'amis-editor-core';
|
||||
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import type {Schema} from 'amis';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import type {Schema} from 'amis';
|
||||
|
||||
export class ButtonGroupControlPlugin extends BasePlugin {
|
||||
static id = 'ButtonGroupControlPlugin';
|
||||
@ -95,22 +97,26 @@ export class ButtonGroupControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,23 +1,21 @@
|
||||
import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
tipedLabel,
|
||||
getSchemaTpl,
|
||||
defaultValue
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import type {Schema} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {resolveOptionEventDataSchame} from '../../util';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
@ -84,22 +82,26 @@ export class ChainedSelectControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -2,26 +2,24 @@ import {
|
||||
defaultValue,
|
||||
setSchemaTpl,
|
||||
getSchemaTpl,
|
||||
valuePipeOut,
|
||||
undefinedPipeOut,
|
||||
EditorNodeType,
|
||||
EditorManager
|
||||
EditorManager,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
tipedLabel,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {isPureVariable} from 'amis';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import omit from 'lodash/omit';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
setSchemaTpl('option', {
|
||||
name: 'option',
|
||||
@ -105,17 +103,20 @@ export class CheckboxControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
|
@ -5,21 +5,22 @@ import {
|
||||
valuePipeOut,
|
||||
EditorNodeType,
|
||||
EditorManager,
|
||||
undefinedPipeOut
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
undefinedPipeOut,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext
|
||||
BaseEventContext,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
|
||||
import type {Schema} from 'amis';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
OPTION_EDIT_EVENTS,
|
||||
resolveOptionEventDataSchame,
|
||||
@ -109,22 +110,26 @@ export class CheckboxesControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
panelJustify = true;
|
||||
@ -192,6 +197,7 @@ export class CheckboxesControlPlugin extends BasePlugin {
|
||||
},
|
||||
{
|
||||
title: '选项',
|
||||
id: 'properties-options',
|
||||
body: [
|
||||
getSchemaTpl('optionControlV2', {
|
||||
multiple: true
|
||||
|
@ -1,12 +1,17 @@
|
||||
import {EditorAvailableLanguages as availableLanguages} from 'amis';
|
||||
import {defaultValue, getSchemaTpl, undefinedPipeOut} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin} from 'amis-editor-core';
|
||||
|
||||
import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
undefinedPipeOut,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
RendererPluginEvent,
|
||||
RendererPluginAction
|
||||
} from 'amis-editor-core';
|
||||
import type {BaseEventContext} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {RendererPluginEvent, RendererPluginAction} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class CodeEditorControlPlugin extends BasePlugin {
|
||||
static id = 'CodeEditorControlPlugin';
|
||||
@ -115,22 +120,26 @@ export class CodeEditorControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'focus',
|
||||
actionLabel: '获取焦点',
|
||||
description: '输入框获取焦点'
|
||||
description: '输入框获取焦点',
|
||||
...getActionCommonProps('focus')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -18,7 +18,8 @@ import {DSBuilderManager} from '../../builder/DSBuilderManager';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getArgsWrapper,
|
||||
getEventControlConfig
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {resolveInputTableEventDataSchame} from '../../util';
|
||||
|
||||
@ -249,12 +250,14 @@ export class ComboControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'addItem',
|
||||
@ -292,7 +295,8 @@ export class ComboControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -3,15 +3,14 @@ import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
undefinedPipeOut,
|
||||
valuePipeOut
|
||||
registerEditorPlugin,
|
||||
BasePlugin
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin} from 'amis-editor-core';
|
||||
|
||||
import type {BaseEventContext} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {RendererPluginEvent, RendererPluginAction} from 'amis-editor-core';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class DiffEditorControlPlugin extends BasePlugin {
|
||||
static id = 'DiffEditorControlPlugin';
|
||||
@ -122,22 +121,26 @@ export class DiffEditorControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'focus',
|
||||
actionLabel: '获取焦点',
|
||||
description: '获取焦点,焦点落在右侧编辑面板'
|
||||
description: '获取焦点,焦点落在右侧编辑面板',
|
||||
...getActionCommonProps('focus')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import DeepDiff from 'deep-diff';
|
||||
import flatten from 'lodash/flatten';
|
||||
@ -20,11 +21,15 @@ import {
|
||||
ScaffoldForm,
|
||||
RegionConfig,
|
||||
registerEditorPlugin,
|
||||
JSONPipeOut,
|
||||
InsertEventContext,
|
||||
MoveEventContext,
|
||||
DeleteEventContext
|
||||
JSONPipeOut
|
||||
} from 'amis-editor-core';
|
||||
import type {FormSchema} from 'amis';
|
||||
import type {
|
||||
IFormStore,
|
||||
IFormItemStore,
|
||||
Schema,
|
||||
RendererConfig
|
||||
} from 'amis-core';
|
||||
import {
|
||||
DSFeatureType,
|
||||
DSBuilderManager,
|
||||
@ -33,17 +38,13 @@ import {
|
||||
ApiDSBuilderKey
|
||||
} from '../../builder';
|
||||
import {FormOperatorMap} from '../../builder/constants';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {FieldSetting} from '../../renderer/FieldSetting';
|
||||
import {_isModelComp} from '../../util';
|
||||
|
||||
import type {FormSchema} from 'amis/lib/Schema';
|
||||
import type {
|
||||
IFormStore,
|
||||
IFormItemStore,
|
||||
Schema,
|
||||
RendererConfig
|
||||
} from 'amis-core';
|
||||
import type {FormScaffoldConfig} from '../../builder';
|
||||
|
||||
export type FormPluginFeat = Extract<
|
||||
@ -344,32 +345,48 @@ export class FormPlugin extends BasePlugin {
|
||||
{
|
||||
actionLabel: '提交表单',
|
||||
actionType: 'submit',
|
||||
description: '触发表单提交'
|
||||
description: '触发表单提交',
|
||||
...getActionCommonProps('submit')
|
||||
},
|
||||
{
|
||||
actionLabel: '重置表单',
|
||||
actionType: 'reset',
|
||||
description: '触发表单重置'
|
||||
description: '触发表单重置',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionLabel: '清空表单',
|
||||
actionType: 'clear',
|
||||
description: '触发表单清空'
|
||||
description: '触发表单清空',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionLabel: '校验表单',
|
||||
actionType: 'validate',
|
||||
description: '触发表单校验'
|
||||
description: '触发表单校验',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
校验
|
||||
<span className="variable-left variable-right">
|
||||
{info?.rendererLabel}
|
||||
</span>
|
||||
的数据
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
actionLabel: '重新加载',
|
||||
actionType: 'reload',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionLabel: '变量赋值',
|
||||
actionType: 'setValue',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,25 +1,21 @@
|
||||
import {
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
registerEditorPlugin,
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
valuePipeOut
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import type {Schema} from 'amis';
|
||||
|
||||
import {formItemControl} from '../../component/BaseControl';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class CityControlPlugin extends BasePlugin {
|
||||
static id = 'CityControlPlugin';
|
||||
@ -102,17 +98,20 @@ export class CityControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
description: '重置为默认值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,12 +1,20 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext, tipedLabel} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {FormulaDateType} from '../../renderer/FormulaControl';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import type {Schema} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {FormulaDateType} from '../../renderer/FormulaControl';
|
||||
|
||||
const formatX = [
|
||||
{
|
||||
@ -248,17 +256,20 @@ export class DateControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空输入框内容'
|
||||
description: '清空输入框内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -347,6 +358,9 @@ export class DateControlPlugin extends BasePlugin {
|
||||
getSchemaTpl('clearable', {
|
||||
pipeIn: defaultValue(true)
|
||||
}),
|
||||
getSchemaTpl('inputForbid', {
|
||||
pipeIn: defaultValue(false)
|
||||
}),
|
||||
getSchemaTpl('valueFormula', {
|
||||
rendererSchema: (schema: Schema) => schema,
|
||||
placeholder: '请选择静态值',
|
||||
|
@ -1,14 +1,22 @@
|
||||
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {FormulaDateType} from '../../renderer/FormulaControl';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
tipedLabel,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {getRendererByName} from 'amis-core';
|
||||
import omit from 'lodash/omit';
|
||||
import type {Schema} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {FormulaDateType} from '../../renderer/FormulaControl';
|
||||
|
||||
const formatX = [
|
||||
{
|
||||
@ -294,17 +302,20 @@ export class DateRangeControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空输入框内容'
|
||||
description: '清空输入框内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -404,7 +415,9 @@ export class DateRangeControlPlugin extends BasePlugin {
|
||||
getSchemaTpl('clearable', {
|
||||
pipeIn: defaultValue(true)
|
||||
}),
|
||||
|
||||
getSchemaTpl('inputForbid', {
|
||||
pipeIn: defaultValue(false)
|
||||
}),
|
||||
getSchemaTpl('valueFormula', {
|
||||
rendererSchema: (schema: Schema) => ({
|
||||
...schema,
|
||||
|
@ -1,17 +1,17 @@
|
||||
/**
|
||||
* @file input-excel 组件的素项目部
|
||||
*/
|
||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {formItemControl} from '../../component/BaseControl';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class ExcelControlPlugin extends BasePlugin {
|
||||
static id = 'ExcelControlPlugin';
|
||||
@ -80,17 +80,20 @@ export class ExcelControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
|
@ -1,9 +1,19 @@
|
||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||
import {registerEditorPlugin, tipedLabel} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
valuePipeOut,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
registerEditorPlugin,
|
||||
tipedLabel,
|
||||
BasePlugin,
|
||||
BaseEventContext
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class FileControlPlugin extends BasePlugin {
|
||||
static id = 'FileControlPlugin';
|
||||
@ -146,12 +156,14 @@ export class FileControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空数据',
|
||||
description: '清除选择的文件'
|
||||
description: '清除选择的文件',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -5,10 +5,13 @@ import {
|
||||
RendererPluginEvent,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
registerEditorPlugin
|
||||
registerEditorPlugin,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
|
||||
const addBtnCssClassName = 'themeCss.addBtnControlClassName';
|
||||
@ -189,12 +192,14 @@ export class ImageControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空数据',
|
||||
description: '清除选择的文件'
|
||||
description: '清除选择的文件',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
/**
|
||||
* @file input-kv 组件的素项目部
|
||||
*/
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BasePlugin
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
export class KVControlPlugin extends BasePlugin {
|
||||
static id = 'KVControlPlugin';
|
||||
static scene = ['layout'];
|
||||
@ -113,17 +112,20 @@ export class KVControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -3,25 +3,22 @@ import {
|
||||
getI18nEnabled,
|
||||
RAW_TYPE_MAP,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import flatten from 'lodash/flatten';
|
||||
import {ContainerWrapper} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {isObject} from 'amis-editor-core';
|
||||
import {
|
||||
RendererPluginEvent,
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext
|
||||
BaseEventContext,
|
||||
registerEditorPlugin,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
import {Schema} from 'amis-core';
|
||||
import type {SchemaType} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class NumberControlPlugin extends BasePlugin {
|
||||
static id = 'NumberControlPlugin';
|
||||
@ -42,6 +39,7 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
type: 'input-number',
|
||||
label: '数字',
|
||||
name: 'number',
|
||||
showSteps: true,
|
||||
keyboard: true
|
||||
};
|
||||
previewSchema: any = {
|
||||
@ -137,17 +135,20 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空数字框内容'
|
||||
description: '清空数字框内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
description: '重置为默认值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -210,6 +211,13 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
label: '最大值',
|
||||
valueType: 'number'
|
||||
}),
|
||||
{
|
||||
type: 'switch',
|
||||
label: '显示上下按钮',
|
||||
name: 'showSteps',
|
||||
value: true,
|
||||
inputClassName: 'is-inline'
|
||||
},
|
||||
{
|
||||
type: 'input-number',
|
||||
name: 'step',
|
||||
@ -217,6 +225,7 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
min: 0,
|
||||
value: 1,
|
||||
precision: '${precision}',
|
||||
visibleOn: '${showSteps}',
|
||||
strictMode: false
|
||||
},
|
||||
{
|
||||
@ -322,16 +331,26 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
)
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: [
|
||||
getSchemaTpl('theme:singleCssCode', {
|
||||
selectors: [
|
||||
{
|
||||
name: '数字输入框',
|
||||
value: '',
|
||||
className: 'inputControlClassName',
|
||||
state: ['default', 'hover', 'active']
|
||||
label: '表单项基本样式',
|
||||
isRoot: true,
|
||||
selector: '.cxd-from-item'
|
||||
},
|
||||
{
|
||||
label: '标题样式',
|
||||
selector: '.cxd-Form-label'
|
||||
},
|
||||
{
|
||||
label: '数字框基本样式',
|
||||
selector: '.cxd-Number'
|
||||
},
|
||||
{
|
||||
label: '输入框样式',
|
||||
selector: '.cxd-Number-input'
|
||||
}
|
||||
],
|
||||
isFormItem: true
|
||||
]
|
||||
})
|
||||
],
|
||||
{...context?.schema, configTitle: 'style'}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {isObject} from 'amis';
|
||||
import type {IFormStore, IFormItemStore} from 'amis-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
defaultValue,
|
||||
@ -6,10 +7,6 @@ import {
|
||||
tipedLabel,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
|
||||
import type {IFormStore, IFormItemStore} from 'amis-core';
|
||||
import type {
|
||||
EditorNodeType,
|
||||
RendererPluginAction,
|
||||
@ -17,6 +14,11 @@ import type {
|
||||
BaseEventContext,
|
||||
EditorManager
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class RangeControlPlugin extends BasePlugin {
|
||||
static id = 'RangeControlPlugin';
|
||||
@ -155,17 +157,20 @@ export class RangeControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除输入框'
|
||||
description: '清除输入框',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -4,13 +4,19 @@ import {
|
||||
getI18nEnabled,
|
||||
getSchemaTpl,
|
||||
isObject,
|
||||
undefinedPipeOut
|
||||
undefinedPipeOut,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext, tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class RateControlPlugin extends BasePlugin {
|
||||
static id = 'RateControlPlugin';
|
||||
@ -80,17 +86,20 @@ export class RateControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空评分值'
|
||||
description: '清空评分值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -12,18 +12,17 @@ import {
|
||||
RendererPluginAction,
|
||||
tipedLabel,
|
||||
getI18nEnabled,
|
||||
repeatArray,
|
||||
mockValue,
|
||||
EditorNodeType,
|
||||
EditorManager,
|
||||
RAW_TYPE_MAP
|
||||
} from 'amis-editor-core';
|
||||
import {setVariable, someTree} from 'amis-core';
|
||||
import {someTree} from 'amis-core';
|
||||
import {DSBuilderManager} from '../../builder/DSBuilderManager';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getArgsWrapper
|
||||
getArgsWrapper,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {
|
||||
@ -951,7 +950,8 @@ export class TableControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
},
|
||||
{
|
||||
actionType: 'addItem',
|
||||
@ -1101,7 +1101,8 @@ export class TableControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空组件数据'
|
||||
description: '清空组件数据',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'initDrag',
|
||||
|
@ -2,21 +2,17 @@ import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
tipedLabel,
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext
|
||||
BaseEventContext,
|
||||
registerEditorPlugin,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {formItemControl} from '../../component/BaseControl';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import type {Schema} from 'amis';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class TagControlPlugin extends BasePlugin {
|
||||
static id = 'TagControlPlugin';
|
||||
@ -153,17 +149,20 @@ export class TagControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
description: '重置为默认值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -2,21 +2,21 @@ import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
RAW_TYPE_MAP,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BasicSubRenderInfo,
|
||||
RendererEventContext,
|
||||
SubRendererInfo,
|
||||
BaseEventContext
|
||||
BaseEventContext,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import type {SchemaType} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
import {resolveOptionType} from '../../util';
|
||||
import type {SchemaType} from 'amis';
|
||||
|
||||
const isText = 'this.type === "input-text"';
|
||||
const isPassword = 'this.type === "input-password"';
|
||||
@ -187,22 +187,26 @@ export class TextControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空输入框内容'
|
||||
description: '清空输入框内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -3,20 +3,28 @@ import {
|
||||
EditorNodeType,
|
||||
getI18nEnabled,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
RendererPluginEvent,
|
||||
registerEditorPlugin,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
tipedLabel,
|
||||
diff
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import type {Schema} from 'amis';
|
||||
import {
|
||||
getArgsWrapper,
|
||||
getEventControlConfig
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {resolveOptionType, TREE_BASE_EVENTS} from '../../util';
|
||||
import type {Schema} from 'amis';
|
||||
import {
|
||||
resolveOptionType,
|
||||
schemaArrayFormat,
|
||||
schemaToArray,
|
||||
TREE_BASE_EVENTS
|
||||
} from '../../util';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
// 树组件公共动作
|
||||
export const TreeCommonAction: RendererPluginAction[] = [
|
||||
@ -176,6 +184,8 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
|
||||
panelTitle = '树选择';
|
||||
|
||||
regions = [{key: 'toolbar', label: '工具栏', preferTag: '工具栏内容'}];
|
||||
|
||||
// 事件定义
|
||||
events: (schema: any) => RendererPluginEvent[] = (schema: any) =>
|
||||
TREE_BASE_EVENTS(schema);
|
||||
@ -187,9 +197,9 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
actionLabel: '展开',
|
||||
description: '展开指定层级',
|
||||
innerArgs: ['openLevel'],
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
展开到第
|
||||
<span className="variable-left variable-right">
|
||||
@ -212,29 +222,101 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'collapse',
|
||||
actionLabel: '收起',
|
||||
description: '收起树节点'
|
||||
description: '收起树节点',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.rendererLabel}</span>
|
||||
{info?.args?.closeLevel ? (
|
||||
<>
|
||||
收起到第
|
||||
<span className="variable-left variable-right">
|
||||
{info?.args?.closeLevel}
|
||||
</span>
|
||||
层
|
||||
</>
|
||||
) : (
|
||||
'收起'
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
innerArgs: ['closeLevel'],
|
||||
schema: getArgsWrapper(
|
||||
getSchemaTpl('formulaControl', {
|
||||
name: 'closeLevel',
|
||||
label: '收起层级',
|
||||
variables: '${variables}',
|
||||
size: 'lg',
|
||||
mode: 'horizontal',
|
||||
horizontal: {
|
||||
left: 'normal'
|
||||
}
|
||||
})
|
||||
)
|
||||
},
|
||||
/** 新增、编辑、删除 */
|
||||
...TreeCommonAction,
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除数据'
|
||||
description: '清除数据',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置数据'
|
||||
description: '重置数据',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
},
|
||||
// 检索
|
||||
{
|
||||
actionType: 'search',
|
||||
actionLabel: '搜索',
|
||||
description: '搜索当前数据源内的选项',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.rendererLabel}</span>
|
||||
{info?.args?.keyword ? (
|
||||
<>
|
||||
搜索
|
||||
<span className="variable-left variable-right">
|
||||
{info?.args?.keyword}
|
||||
</span>
|
||||
的选项
|
||||
</>
|
||||
) : (
|
||||
'搜索'
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
innerArgs: ['keyword'],
|
||||
schema: getArgsWrapper(
|
||||
getSchemaTpl('formulaControl', {
|
||||
name: 'keyword',
|
||||
label: '关键词',
|
||||
variables: '${variables}',
|
||||
size: 'lg',
|
||||
mode: 'horizontal',
|
||||
horizontal: {
|
||||
left: 'normal'
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
@ -359,6 +441,14 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
name: 'cascade',
|
||||
hiddenOn: '!this.multiple || !this.autoCheckChildren'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'子节点反选取消父节点',
|
||||
'取消任意子节点选中状态的同时取消父节点选中状态'
|
||||
),
|
||||
name: 'autoCancelParent',
|
||||
hiddenOn: '!this.multiple || !this.cascade'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'值包含父节点',
|
||||
@ -414,6 +504,25 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
},
|
||||
{context}
|
||||
),
|
||||
{
|
||||
type: 'checkboxes',
|
||||
name: 'nodeBehavior',
|
||||
label: '节点行为',
|
||||
value: ['check'],
|
||||
joinValues: false,
|
||||
extractValue: true,
|
||||
inline: true,
|
||||
options: [
|
||||
{
|
||||
label: '选中',
|
||||
value: 'check'
|
||||
},
|
||||
{
|
||||
label: '展开',
|
||||
value: 'unfold'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('switch', {
|
||||
label: '只可选择叶子节点',
|
||||
name: 'onlyLeaf'
|
||||
@ -466,7 +575,57 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
name: 'removeTip'
|
||||
}
|
||||
]
|
||||
})
|
||||
}),
|
||||
{
|
||||
type: 'select',
|
||||
label: '操作栏位置',
|
||||
value: '',
|
||||
name: 'themeCss.actionControlClassName.marginLeft',
|
||||
options: [
|
||||
{
|
||||
label: '左侧',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'auto'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'ae-switch-more',
|
||||
mode: 'normal',
|
||||
label: '自定义操作',
|
||||
bulk: false,
|
||||
name: 'itemActions',
|
||||
formType: 'extend',
|
||||
form: {
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
level: 'primary',
|
||||
size: 'sm',
|
||||
block: true,
|
||||
onClick: this.editDetail.bind(this, context.id),
|
||||
label: '配置自定义操作模板'
|
||||
}
|
||||
]
|
||||
},
|
||||
pipeIn: (value: any) => {
|
||||
return value !== undefined;
|
||||
},
|
||||
pipeOut: (value: any) => {
|
||||
if (value === true) {
|
||||
return {
|
||||
type: 'button',
|
||||
icon: 'fa fa-plus',
|
||||
level: 'link',
|
||||
size: 'xs'
|
||||
};
|
||||
}
|
||||
return value ? value : undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -546,19 +705,6 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
label: tipedLabel('显示层级展开线', '显示树层级展开线'),
|
||||
name: 'showOutline'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'withChildren',
|
||||
label: '数值是否携带子节点',
|
||||
visibleOn: 'this.cascade !== true && this.multiple',
|
||||
disabledOn: 'this.onlyChildren'
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'onlyChildren',
|
||||
label: '数值是否只包含子节点',
|
||||
visibleOn: 'this.cascade !== true && this.multiple',
|
||||
disabledOn: 'this.withChildren'
|
||||
}),
|
||||
{
|
||||
type: 'ae-Switch-More',
|
||||
mode: 'normal',
|
||||
@ -598,13 +744,32 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('style:formItem', {renderer}),
|
||||
getSchemaTpl('style:classNames', {
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
label: '外层容器',
|
||||
name: 'treeContainerClassName'
|
||||
})
|
||||
getSchemaTpl('theme:formItem', {
|
||||
schema: {
|
||||
type: 'input-number',
|
||||
label: '高度',
|
||||
name: 'wrapperCustomStyle.root.height',
|
||||
clearable: true,
|
||||
unitOptions: ['px', '%', 'em', 'vh', 'vw']
|
||||
}
|
||||
}),
|
||||
getSchemaTpl('theme:form-label'),
|
||||
getSchemaTpl('theme:form-description'),
|
||||
getSchemaTpl('theme:base', {
|
||||
classname: 'toolbarControlClassName',
|
||||
title: '工具栏样式',
|
||||
visibleOn: 'this.searchable'
|
||||
}),
|
||||
getSchemaTpl('theme:singleCssCode', {
|
||||
selectors: [
|
||||
{
|
||||
label: '树基本样式',
|
||||
selector: '.cxd-TreeControl'
|
||||
},
|
||||
{
|
||||
label: '树工具栏样式',
|
||||
selector: '.cxd-Tabs-toolbar'
|
||||
}
|
||||
]
|
||||
})
|
||||
])
|
||||
@ -671,6 +836,76 @@ export class TreeControlPlugin extends BasePlugin {
|
||||
|
||||
return dataSchema;
|
||||
}
|
||||
|
||||
getSubEditorVariable(schema: any): Array<{label: string; children: any}> {
|
||||
let labelField = schema?.labelField || 'label';
|
||||
let valueField = schema?.valueField || 'value';
|
||||
|
||||
return [
|
||||
{
|
||||
label: '当前节点',
|
||||
children: [
|
||||
{
|
||||
label: '节点索引',
|
||||
value: 'index'
|
||||
},
|
||||
{
|
||||
label: '节点名称',
|
||||
value: labelField
|
||||
},
|
||||
{
|
||||
label: '节点值',
|
||||
value: valueField
|
||||
},
|
||||
{
|
||||
label: '节点状态',
|
||||
value: 'checked'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
getDisplayField(data: any) {
|
||||
if (
|
||||
data.source ||
|
||||
(data.map &&
|
||||
Array.isArray(data.map) &&
|
||||
data.map[0] &&
|
||||
Object.keys(data.map[0]).length > 1)
|
||||
) {
|
||||
return data.labelField ?? 'label';
|
||||
}
|
||||
return 'item';
|
||||
}
|
||||
|
||||
editDetail(id: string) {
|
||||
const manager = this.manager;
|
||||
const store = manager.store;
|
||||
const node = store.getNodeById(id);
|
||||
const value = store.getValueOf(id);
|
||||
const defaultItemSchema = {
|
||||
type: 'button',
|
||||
icon: 'fa fa-plus',
|
||||
level: 'link',
|
||||
size: 'xs'
|
||||
};
|
||||
|
||||
node &&
|
||||
value &&
|
||||
this.manager.openSubEditor({
|
||||
title: '配置自定义操作模板',
|
||||
value: schemaToArray(value.itemActions ?? defaultItemSchema),
|
||||
slot: {
|
||||
type: 'container',
|
||||
body: '$$'
|
||||
},
|
||||
onChange: (newValue: any) => {
|
||||
newValue = {...value, itemActions: schemaArrayFormat(newValue)};
|
||||
manager.panelChangeValue(newValue, diff(value, newValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorPlugin(TreeControlPlugin);
|
||||
|
@ -15,8 +15,12 @@ import {
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import find from 'lodash/find';
|
||||
import {JSONDelete, JSONPipeIn, JSONUpdate} from 'amis-editor-core';
|
||||
import {SUPPORT_STATIC_FORMITEM_CMPTS} from '../../renderer/event-control/helper';
|
||||
import {isExpression, resolveVariableAndFilter} from 'amis-core';
|
||||
import {NO_SUPPORT_STATIC_FORMITEM_CMPTS} from '../../renderer/event-control/constants';
|
||||
import {
|
||||
isExpression,
|
||||
resolveVariableAndFilter,
|
||||
getRendererByName
|
||||
} from 'amis-core';
|
||||
|
||||
export class ItemPlugin extends BasePlugin {
|
||||
static id = 'ItemPlugin';
|
||||
@ -59,7 +63,10 @@ export class ItemPlugin extends BasePlugin {
|
||||
}
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
const type = context.schema.type || '';
|
||||
const supportStatic = SUPPORT_STATIC_FORMITEM_CMPTS.includes(type);
|
||||
const render = getRendererByName(type);
|
||||
// 支持静态表单项条件:是表单项组件,切不在不支持静态列表组件中
|
||||
const supportStatic =
|
||||
!!render?.isFormItem && !NO_SUPPORT_STATIC_FORMITEM_CMPTS.includes(type);
|
||||
const ignoreName = ~['button', 'submit', 'reset'].indexOf(type);
|
||||
const notRequiredName = ~[
|
||||
'button-toobar',
|
||||
|
@ -2,23 +2,25 @@ import {
|
||||
EditorNodeType,
|
||||
JSONPipeIn,
|
||||
JSONPipeOut,
|
||||
getSchemaTpl
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
diff
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext, diff} from 'amis-editor-core';
|
||||
import {formItemControl} from '../../component/BaseControl';
|
||||
import type {
|
||||
EditorManager,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import type {Schema} from 'amis';
|
||||
import {formItemControl} from '../../component/BaseControl';
|
||||
import {
|
||||
resolveOptionEventDataSchame,
|
||||
resolveOptionType,
|
||||
schemaArrayFormat,
|
||||
schemaToArray
|
||||
schemaArrayFormat
|
||||
} from '../../util';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class ListControlPlugin extends BasePlugin {
|
||||
static id = 'ListControlPlugin';
|
||||
@ -102,22 +104,26 @@ export class ListControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,8 +1,18 @@
|
||||
import {EditorNodeType, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
EditorNodeType,
|
||||
getSchemaTpl,
|
||||
tipedLabel,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
|
||||
export class LocationControlPlugin extends BasePlugin {
|
||||
@ -89,17 +99,20 @@ export class LocationControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -10,7 +10,10 @@ import {
|
||||
EditorNodeType
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class MatrixControlPlugin extends BasePlugin {
|
||||
static id = 'MatrixControlPlugin';
|
||||
@ -95,22 +98,26 @@ export class MatrixControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
description: '重置为默认值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -2,15 +2,20 @@ import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
RendererPluginEvent,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {getSchemaTpl} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext, tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import type {Schema} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class NestedSelectControlPlugin extends BasePlugin {
|
||||
@ -197,22 +202,26 @@ export class NestedSelectControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
|
@ -3,16 +3,20 @@ import {
|
||||
EditorNodeType,
|
||||
RAW_TYPE_MAP,
|
||||
defaultValue,
|
||||
getSchemaTpl
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import type {Schema, SchemaType} from 'amis';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class RadiosControlPlugin extends BasePlugin {
|
||||
@ -100,22 +104,26 @@ export class RadiosControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -148,6 +156,7 @@ export class RadiosControlPlugin extends BasePlugin {
|
||||
},
|
||||
{
|
||||
title: '选项',
|
||||
id: 'properties-options',
|
||||
body: [getSchemaTpl('optionControlV2'), getSchemaTpl('selectFirst')]
|
||||
},
|
||||
getSchemaTpl('status', {isFormItem: true}),
|
||||
|
@ -1,27 +1,12 @@
|
||||
import React from 'react';
|
||||
import omit from 'lodash/omit';
|
||||
import {findObjectsWithKey} from 'amis-core';
|
||||
import {Button, Icon} from 'amis-ui';
|
||||
import type {Schema, SchemaType} from 'amis';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
getSchemaTpl,
|
||||
BasePlugin,
|
||||
tipedLabel,
|
||||
JSONPipeOut,
|
||||
undefinedPipeOut,
|
||||
RAW_TYPE_MAP
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
OPTION_EDIT_EVENTS,
|
||||
OPTION_EDIT_EVENTS_OLD,
|
||||
resolveOptionEventDataSchame,
|
||||
resolveOptionType
|
||||
} from '../../util';
|
||||
|
||||
import type {Schema, SchemaType} from 'amis';
|
||||
import type {
|
||||
EditorNodeType,
|
||||
RendererPluginAction,
|
||||
@ -29,6 +14,19 @@ import type {
|
||||
BaseEventContext,
|
||||
EditorManager
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
OPTION_EDIT_EVENTS,
|
||||
OPTION_EDIT_EVENTS_OLD,
|
||||
resolveOptionEventDataSchame,
|
||||
resolveOptionType
|
||||
} from '../../util';
|
||||
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class SelectControlPlugin extends BasePlugin {
|
||||
@ -173,22 +171,26 @@ export class SelectControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -199,6 +201,7 @@ export class SelectControlPlugin extends BasePlugin {
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
id: 'properties-basic',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
getSchemaTpl('formItemName', {
|
||||
@ -232,6 +235,7 @@ export class SelectControlPlugin extends BasePlugin {
|
||||
},
|
||||
{
|
||||
title: '选项',
|
||||
id: 'properties-options',
|
||||
body: [
|
||||
getSchemaTpl('optionControlV2'),
|
||||
getSchemaTpl('selectFirst', {
|
||||
|
@ -2,13 +2,9 @@ import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
undefinedPipeOut,
|
||||
valuePipeOut
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin, tipedLabel} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import type {
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
RendererPluginAction,
|
||||
@ -16,6 +12,11 @@ import type {
|
||||
} from 'amis-editor-core';
|
||||
import {isExpression, isPureVariable} from 'amis-core';
|
||||
import omit from 'lodash/omit';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
|
||||
export class SwitchControlPlugin extends BasePlugin {
|
||||
static id = 'SwitchControlPlugin';
|
||||
@ -97,17 +98,20 @@ export class SwitchControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除选中值'
|
||||
description: '清除选中值',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -3,13 +3,17 @@ import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
tipedLabel,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
registerEditorPlugin,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
|
||||
export class TabsTransferPlugin extends BasePlugin {
|
||||
@ -196,20 +200,22 @@ export class TabsTransferPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空选中内容'
|
||||
description: '清空选中内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置选择的内容'
|
||||
description: '重置选择的内容',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'changeTabKey',
|
||||
actionLabel: '修改选中tab',
|
||||
description: '修改当前选中tab,来选择其他选项',
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
修改选中tab
|
||||
</div>
|
||||
@ -219,7 +225,8 @@ export class TabsTransferPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,11 +1,18 @@
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, tipedLabel} from 'amis-editor-core';
|
||||
|
||||
import {
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BasePlugin,
|
||||
tipedLabel,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import type {BaseEventContext} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class TextareaControlPlugin extends BasePlugin {
|
||||
@ -115,17 +122,20 @@ export class TextareaControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空输入框内容'
|
||||
description: '清空输入框内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '将值重置为初始值'
|
||||
description: '将值重置为初始值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -2,21 +2,20 @@ import {
|
||||
EditorManager,
|
||||
EditorNodeType,
|
||||
defaultValue,
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {
|
||||
getSchemaTpl,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
registerEditorPlugin,
|
||||
tipedLabel,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
undefinedPipeOut
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import type {Schema} from 'amis';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {resolveOptionEventDataSchame, resolveOptionType} from '../../util';
|
||||
import {getActionCommonProps} from '../../renderer/event-control/helper';
|
||||
|
||||
export class TransferPlugin extends BasePlugin {
|
||||
static id = 'TransferPlugin';
|
||||
@ -118,22 +117,26 @@ export class TransferPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空选中内容'
|
||||
description: '清空选中内容',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置选择的内容'
|
||||
description: '重置选择的内容',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'selectAll',
|
||||
actionLabel: '全选',
|
||||
description: '选中所有选项'
|
||||
description: '选中所有选项',
|
||||
...getActionCommonProps('selectAll')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新,多值用“,”分隔'
|
||||
description: '触发组件数据更新,多值用“,”分隔',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -247,11 +250,6 @@ export class TransferPlugin extends BasePlugin {
|
||||
}
|
||||
},
|
||||
|
||||
getSchemaTpl('optionControl', {
|
||||
visibleOn: 'this.selectMode === "list"',
|
||||
multiple: true
|
||||
}),
|
||||
|
||||
getSchemaTpl(
|
||||
'loadingConfig',
|
||||
{
|
||||
@ -259,6 +257,10 @@ export class TransferPlugin extends BasePlugin {
|
||||
},
|
||||
{context}
|
||||
),
|
||||
getSchemaTpl('optionControl', {
|
||||
visibleOn: 'this.selectMode === "list"',
|
||||
multiple: true
|
||||
}),
|
||||
|
||||
{
|
||||
type: 'ae-transferTableControl',
|
||||
@ -291,6 +293,21 @@ export class TransferPlugin extends BasePlugin {
|
||||
label: '可检索',
|
||||
name: 'searchable'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'仅包含子节点的值',
|
||||
'仅在autoCheckChildren=true时生效'
|
||||
),
|
||||
value: true,
|
||||
name: 'onlyChildren',
|
||||
visibleOn: 'this.selectMode === "tree"'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: '选中父节点自动选中子节点',
|
||||
name: 'autoCheckChildren',
|
||||
value: true,
|
||||
visibleOn: 'this.selectMode === "tree"'
|
||||
}),
|
||||
|
||||
getSchemaTpl('optionsMenuTpl', {
|
||||
manager: this.manager,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {registerEditorPlugin, RendererPluginEvent} from 'amis-editor-core';
|
||||
|
||||
import {TransferPlugin} from './Transfer';
|
||||
|
||||
@ -45,6 +45,32 @@ export class TransferPickerPlugin extends TransferPlugin {
|
||||
]
|
||||
};
|
||||
|
||||
events: RendererPluginEvent[] = [
|
||||
...this.events,
|
||||
{
|
||||
eventName: 'itemClick',
|
||||
eventLabel: '点击选项',
|
||||
description: '选项被点击时触发',
|
||||
dataSchema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: {
|
||||
type: 'object',
|
||||
title: '数据',
|
||||
properties: {
|
||||
item: {
|
||||
type: 'object',
|
||||
title: '当前选项'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
notRenderFormZone = true;
|
||||
}
|
||||
|
||||
|
@ -3,24 +3,29 @@ import {
|
||||
EditorNodeType,
|
||||
getI18nEnabled,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
RendererPluginEvent,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
tipedLabel,
|
||||
diff
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {
|
||||
getArgsWrapper,
|
||||
getEventControlConfig
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {
|
||||
resolveOptionEventDataSchame,
|
||||
resolveOptionType,
|
||||
schemaArrayFormat,
|
||||
schemaToArray,
|
||||
TREE_BASE_EVENTS
|
||||
} from '../../util';
|
||||
import {TreeCommonAction} from './InputTree';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class TreeSelectControlPlugin extends BasePlugin {
|
||||
static id = 'TreeSelectControlPlugin';
|
||||
@ -154,22 +159,26 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清除数据'
|
||||
description: '清除数据',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置数据'
|
||||
description: '重置数据',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
}
|
||||
];
|
||||
|
||||
@ -297,6 +306,14 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
name: 'cascade',
|
||||
hiddenOn: '!this.multiple || !this.autoCheckChildren'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'子节点反选取消父节点',
|
||||
'取消任意子节点选中状态的同时取消父节点选中状态'
|
||||
),
|
||||
name: 'autoCancelParent',
|
||||
hiddenOn: '!this.multiple || !this.cascade'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'值包含父节点',
|
||||
@ -353,6 +370,25 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
},
|
||||
{context}
|
||||
),
|
||||
{
|
||||
type: 'checkboxes',
|
||||
name: 'nodeBehavior',
|
||||
label: '节点行为',
|
||||
value: ['check'],
|
||||
joinValues: false,
|
||||
extractValue: true,
|
||||
inline: true,
|
||||
options: [
|
||||
{
|
||||
label: '选中',
|
||||
value: 'check'
|
||||
},
|
||||
{
|
||||
label: '展开',
|
||||
value: 'unfold'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('switch', {
|
||||
label: '只可选择叶子节点',
|
||||
name: 'onlyLeaf'
|
||||
@ -404,7 +440,57 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
name: 'removeTip'
|
||||
}
|
||||
]
|
||||
})
|
||||
}),
|
||||
{
|
||||
type: 'select',
|
||||
label: '操作栏位置',
|
||||
value: '',
|
||||
name: 'themeCss.actionControlClassName.marginLeft',
|
||||
options: [
|
||||
{
|
||||
label: '左侧',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'auto'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'ae-switch-more',
|
||||
mode: 'normal',
|
||||
label: '自定义操作',
|
||||
bulk: false,
|
||||
name: 'itemActions',
|
||||
formType: 'extend',
|
||||
form: {
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
level: 'primary',
|
||||
size: 'sm',
|
||||
block: true,
|
||||
onClick: this.editDetail.bind(this, context.id),
|
||||
label: '配置自定义操作模板'
|
||||
}
|
||||
]
|
||||
},
|
||||
pipeIn: (value: any) => {
|
||||
return value !== undefined;
|
||||
},
|
||||
pipeOut: (value: any) => {
|
||||
if (value === true) {
|
||||
return {
|
||||
type: 'button',
|
||||
icon: 'fa fa-plus',
|
||||
level: 'link',
|
||||
size: 'xs'
|
||||
};
|
||||
}
|
||||
return value ? value : undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -484,19 +570,6 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
label: tipedLabel('显示层级展开线', '显示树层级展开线'),
|
||||
name: 'showOutline'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'withChildren',
|
||||
label: '数值是否携带子节点',
|
||||
visibleOn: 'this.cascade !== true && this.multiple',
|
||||
disabledOn: 'this.onlyChildren'
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'onlyChildren',
|
||||
label: '数值是否只包含子节点',
|
||||
visibleOn: 'this.cascade !== true && this.multiple',
|
||||
disabledOn: 'this.withChildren'
|
||||
}),
|
||||
{
|
||||
type: 'ae-Switch-More',
|
||||
mode: 'normal',
|
||||
@ -536,15 +609,18 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('style:formItem', {renderer}),
|
||||
getSchemaTpl('style:classNames', {
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
label: '外层容器',
|
||||
name: 'treeContainerClassName'
|
||||
})
|
||||
getSchemaTpl('theme:formItem'),
|
||||
getSchemaTpl('theme:form-label'),
|
||||
getSchemaTpl('theme:form-description'),
|
||||
{
|
||||
title: '输入框样式',
|
||||
body: [
|
||||
...inputStateTpl(
|
||||
'themeCss.inputControlClassName',
|
||||
'--input-default'
|
||||
)
|
||||
]
|
||||
})
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
@ -609,6 +685,76 @@ export class TreeSelectControlPlugin extends BasePlugin {
|
||||
|
||||
return dataSchema;
|
||||
}
|
||||
|
||||
getSubEditorVariable(schema: any): Array<{label: string; children: any}> {
|
||||
let labelField = schema?.labelField || 'label';
|
||||
let valueField = schema?.valueField || 'value';
|
||||
|
||||
return [
|
||||
{
|
||||
label: '节点选项',
|
||||
children: [
|
||||
{
|
||||
label: '节点索引',
|
||||
value: 'index'
|
||||
},
|
||||
{
|
||||
label: '节点名称',
|
||||
value: labelField
|
||||
},
|
||||
{
|
||||
label: '节点值',
|
||||
value: valueField
|
||||
},
|
||||
{
|
||||
label: '节点状态',
|
||||
value: 'checked'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
getDisplayField(data: any) {
|
||||
if (
|
||||
data.source ||
|
||||
(data.map &&
|
||||
Array.isArray(data.map) &&
|
||||
data.map[0] &&
|
||||
Object.keys(data.map[0]).length > 1)
|
||||
) {
|
||||
return data.labelField ?? 'label';
|
||||
}
|
||||
return 'item';
|
||||
}
|
||||
|
||||
editDetail(id: string) {
|
||||
const manager = this.manager;
|
||||
const store = manager.store;
|
||||
const node = store.getNodeById(id);
|
||||
const value = store.getValueOf(id);
|
||||
const defaultItemSchema = {
|
||||
type: 'button',
|
||||
icon: 'fa fa-plus',
|
||||
level: 'link',
|
||||
size: 'xs'
|
||||
};
|
||||
|
||||
node &&
|
||||
value &&
|
||||
this.manager.openSubEditor({
|
||||
title: '配置自定义操作模板',
|
||||
value: schemaToArray(value.itemActions ?? defaultItemSchema),
|
||||
slot: {
|
||||
type: 'container',
|
||||
body: '$$'
|
||||
},
|
||||
onChange: (newValue: any) => {
|
||||
newValue = {...value, itemActions: schemaArrayFormat(newValue)};
|
||||
manager.panelChangeValue(newValue, diff(value, newValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorPlugin(TreeSelectControlPlugin);
|
||||
|
@ -58,6 +58,7 @@ export class MappingPlugin extends BasePlugin {
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
id: 'properties-basic',
|
||||
body: [
|
||||
isUnderField
|
||||
? {
|
||||
|
@ -10,7 +10,11 @@ import {
|
||||
RendererPluginAction,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
|
||||
export class NavPlugin extends BasePlugin {
|
||||
static id = 'NavPlugin';
|
||||
static scene = ['layout'];
|
||||
@ -254,12 +258,14 @@ export class NavPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'collapse',
|
||||
actionLabel: '菜单折叠',
|
||||
description: '触发组件的折叠与展开'
|
||||
description: '触发组件的折叠与展开',
|
||||
...getActionCommonProps('collapse')
|
||||
},
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
import {Button} from 'amis';
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import {getI18nEnabled, registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
getI18nEnabled,
|
||||
registerEditorPlugin,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BasicRendererInfo,
|
||||
@ -427,10 +431,35 @@ export class TableCellPlugin extends BasePlugin {
|
||||
? value.replace(/\*\s*,\s*|\s*,\s*\*/g, '')
|
||||
: value
|
||||
},
|
||||
|
||||
{
|
||||
name: 'textOverflow',
|
||||
type: 'button-group-select',
|
||||
label: '文本超出处理',
|
||||
size: 'xs',
|
||||
mode: 'inline',
|
||||
inputClassName: 'mt-1 w-full',
|
||||
pipeIn: defaultValue('default'),
|
||||
options: [
|
||||
{
|
||||
label: '默认',
|
||||
value: 'default'
|
||||
},
|
||||
{
|
||||
label: '溢出隐藏',
|
||||
value: 'ellipsis'
|
||||
},
|
||||
{
|
||||
label: '取消换行',
|
||||
value: 'noWrap'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('switch', {
|
||||
name: 'className',
|
||||
label: '内容强制换行',
|
||||
label: tipedLabel(
|
||||
'允许任意字符间断行',
|
||||
'开启此项,换行处理将在任意字母处断行,长英文单词或长英文字符会被切断,如url链接'
|
||||
),
|
||||
pipeIn: (value: any) =>
|
||||
typeof value === 'string' && /\word\-break\b/.test(value),
|
||||
pipeOut: (value: any, originValue: any) =>
|
||||
|
@ -6,7 +6,10 @@ import {
|
||||
getSchemaTpl,
|
||||
defaultValue
|
||||
} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import type {SchemaObject} from 'amis';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
@ -110,12 +113,14 @@ export class PagePlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
@ -222,6 +227,24 @@ export class PagePlugin extends BasePlugin {
|
||||
inputClassName: 'is-inline',
|
||||
pipeIn: defaultValue(true),
|
||||
hiddenOn: 'this.regions && !this.regions.includes("aside")'
|
||||
},
|
||||
{
|
||||
type: 'button-group-select',
|
||||
name: 'asidePosition',
|
||||
size: 'sm',
|
||||
label: '边栏位置',
|
||||
pipeIn: defaultValue('left'),
|
||||
options: [
|
||||
{
|
||||
label: '左',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右',
|
||||
value: 'right'
|
||||
}
|
||||
],
|
||||
hiddenOn: 'this.regions && !this.regions.includes("aside")'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -288,7 +311,7 @@ export class PagePlugin extends BasePlugin {
|
||||
body: [
|
||||
getSchemaTpl('collapseGroup', [
|
||||
...getSchemaTpl('theme:common', {
|
||||
exclude: ['layout'],
|
||||
exclude: ['layout', 'theme-css-code'],
|
||||
classname: 'baseControlClassName',
|
||||
baseTitle: '基本样式',
|
||||
extra: [
|
||||
@ -320,6 +343,31 @@ export class PagePlugin extends BasePlugin {
|
||||
hiddenOn: 'this.regions && !this.regions.includes("aside")'
|
||||
})
|
||||
]
|
||||
}),
|
||||
getSchemaTpl('theme:singleCssCode', {
|
||||
selectors: [
|
||||
{
|
||||
label: '页面基本样式',
|
||||
isRoot: true,
|
||||
selector: '.cxd-Page'
|
||||
},
|
||||
{
|
||||
label: '页面内容区样式',
|
||||
selector: '.cxd-Page-body'
|
||||
},
|
||||
{
|
||||
label: '页面标题栏样式',
|
||||
selector: '.cxd-Page-title'
|
||||
},
|
||||
{
|
||||
label: '页面工具栏样式',
|
||||
selector: '.cxd-Page-toolbar'
|
||||
},
|
||||
{
|
||||
label: '页面边栏样式',
|
||||
selector: '.cxd-Page-aside'
|
||||
}
|
||||
]
|
||||
})
|
||||
])
|
||||
]
|
||||
|
@ -97,6 +97,7 @@ export class PanelPlugin extends BasePlugin {
|
||||
getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
className: 'p-none',
|
||||
id: 'properties-basic',
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
@ -199,6 +200,7 @@ export class PanelPlugin extends BasePlugin {
|
||||
label: '主题',
|
||||
type: 'select',
|
||||
size: 'sm',
|
||||
id: 'panel-settings-panelClassName',
|
||||
pipeIn: (value: any) =>
|
||||
typeof value === 'string' &&
|
||||
/(?:^|\s)(Panel\-\-(\w+))(?:$|\s)/.test(value)
|
||||
|
@ -1,9 +1,13 @@
|
||||
import {registerEditorPlugin, RendererPluginAction} from 'amis-editor-core';
|
||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../validator';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
RendererPluginAction,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {getActionCommonProps} from '../renderer/event-control/helper';
|
||||
|
||||
export class ProgressPlugin extends BasePlugin {
|
||||
static id = 'ProgressPlugin';
|
||||
@ -37,12 +41,14 @@ export class ProgressPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reset',
|
||||
actionLabel: '重置',
|
||||
description: '重置为默认值'
|
||||
description: '重置为默认值',
|
||||
...getActionCommonProps('reset')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
RendererPluginEvent,
|
||||
RendererPluginAction
|
||||
RendererPluginAction,
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import {getSchemaTpl} from 'amis-editor-core';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
|
||||
import type {Schema} from 'amis-core';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
|
||||
export class SearchBoxPlugin extends BasePlugin {
|
||||
static id = 'SearchBoxPlugin';
|
||||
@ -144,12 +145,14 @@ export class SearchBoxPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'clear',
|
||||
actionLabel: '清空',
|
||||
description: '清空输入框'
|
||||
description: '清空输入框',
|
||||
...getActionCommonProps('clear')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '更新数据',
|
||||
description: '更新数据'
|
||||
description: '更新数据',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -16,7 +16,10 @@ import {
|
||||
} from 'amis-editor-core';
|
||||
import {DSBuilderManager} from '../builder/DSBuilderManager';
|
||||
import {DSFeatureEnum, ModelDSBuilderKey, ApiDSBuilderKey} from '../builder';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
|
||||
import type {Schema} from 'amis-core';
|
||||
import type {
|
||||
@ -168,7 +171,8 @@ export class ServicePlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'rebuild',
|
||||
@ -178,7 +182,8 @@ export class ServicePlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '更新数据域数据'
|
||||
description: '更新数据域数据',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -107,6 +107,11 @@ export class StepsPlugin extends BasePlugin {
|
||||
{
|
||||
title: '外观',
|
||||
body: [
|
||||
getSchemaTpl('switch', {
|
||||
name: 'iconPosition',
|
||||
label: '图标文字垂直展示',
|
||||
value: false
|
||||
}),
|
||||
{
|
||||
name: 'mode',
|
||||
type: 'select',
|
||||
|
@ -1,13 +1,10 @@
|
||||
import React from 'react';
|
||||
import {Button, resolveVariable} from 'amis';
|
||||
import type {DataScope, SchemaObject} from 'amis';
|
||||
import {
|
||||
getI18nEnabled,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {findTree, setVariable, someTree} from 'amis-core';
|
||||
import {registerEditorPlugin, repeatArray, diff} from 'amis-editor-core';
|
||||
import {
|
||||
RendererPluginEvent,
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
PluginEvent,
|
||||
@ -16,13 +13,20 @@ import {
|
||||
BasicRendererInfo,
|
||||
PluginInterface,
|
||||
InsertEventContext,
|
||||
ScaffoldForm
|
||||
ScaffoldForm,
|
||||
registerEditorPlugin,
|
||||
repeatArray,
|
||||
diff,
|
||||
mockValue,
|
||||
EditorNodeType,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import type {EditorManager} from 'amis-editor-core';
|
||||
import {setVariable, someTree} from 'amis-core';
|
||||
import {reaction} from 'mobx';
|
||||
import {DSBuilderManager} from '../builder/DSBuilderManager';
|
||||
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import {mockValue} from 'amis-editor-core';
|
||||
import {EditorNodeType} from 'amis-editor-core';
|
||||
import type {DataScope, SchemaObject} from 'amis';
|
||||
import {
|
||||
getEventControlConfig,
|
||||
getArgsWrapper
|
||||
@ -32,9 +36,7 @@ import {
|
||||
schemaToArray,
|
||||
resolveArrayDatasource
|
||||
} from '../util';
|
||||
import {reaction} from 'mobx';
|
||||
|
||||
import type {EditorManager} from 'amis-editor-core';
|
||||
import {getActionCommonProps} from '../renderer/event-control/helper';
|
||||
|
||||
export class TablePlugin extends BasePlugin {
|
||||
static id = 'TablePlugin';
|
||||
@ -464,7 +466,8 @@ export class TablePlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'selectAll',
|
||||
actionLabel: '设置全部选中',
|
||||
description: '设置表格全部项选中'
|
||||
description: '设置表格全部项选中',
|
||||
...getActionCommonProps('selectAll')
|
||||
},
|
||||
{
|
||||
actionType: 'clearAll',
|
||||
|
@ -33,6 +33,7 @@ import {resolveArrayDatasource} from '../util';
|
||||
import type {SchemaObject} from 'amis';
|
||||
import type {IFormItemStore, IFormStore} from 'amis-core';
|
||||
import type {EditorManager} from 'amis-editor-core';
|
||||
import {getActionCommonProps} from '../renderer/event-control/helper';
|
||||
|
||||
export const Table2RenderereEvent: RendererPluginEvent[] = [
|
||||
{
|
||||
@ -307,7 +308,8 @@ export const Table2RendererAction: RendererPluginAction[] = [
|
||||
{
|
||||
actionType: 'selectAll',
|
||||
actionLabel: '设置全部选中',
|
||||
description: '设置表格全部项选中'
|
||||
description: '设置表格全部项选中',
|
||||
...getActionCommonProps('selectAll')
|
||||
},
|
||||
{
|
||||
actionType: 'clearAll',
|
||||
|
@ -17,7 +17,6 @@ import findIndex from 'lodash/findIndex';
|
||||
import {RegionWrapper as Region} from 'amis-editor-core';
|
||||
import {Tab} from 'amis';
|
||||
import {tipedLabel} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../validator';
|
||||
import {
|
||||
getArgsWrapper,
|
||||
getEventControlConfig
|
||||
@ -89,6 +88,28 @@ export class TabsPlugin extends BasePlugin {
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
eventName: 'delete',
|
||||
eventLabel: '选项卡删除',
|
||||
description: '选项卡删除',
|
||||
dataSchema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: {
|
||||
type: 'object',
|
||||
title: '数据',
|
||||
properties: {
|
||||
value: {
|
||||
type: 'string',
|
||||
title: '选项卡索引'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@ -96,11 +117,11 @@ export class TabsPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'changeActiveKey',
|
||||
actionLabel: '激活指定选项卡',
|
||||
description: '修改当前激活tab项的key',
|
||||
description: '修改当前激活tab项',
|
||||
config: ['activeKey'],
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
激活第
|
||||
<span className="variable-left variable-right">
|
||||
{info?.args?.activeKey}
|
||||
@ -115,7 +136,39 @@ export class TabsPlugin extends BasePlugin {
|
||||
label: '激活项',
|
||||
variables: '${variables}',
|
||||
size: 'lg',
|
||||
mode: 'horizontal'
|
||||
mode: 'horizontal',
|
||||
horizontal: {
|
||||
left: 'normal'
|
||||
}
|
||||
})
|
||||
)
|
||||
},
|
||||
{
|
||||
actionType: 'deleteTab',
|
||||
actionLabel: '删除指定选项卡',
|
||||
description: '删除指定hash的tab项',
|
||||
descDetail: (info: any) => {
|
||||
return (
|
||||
<div>
|
||||
删除hash为
|
||||
<span className="variable-left variable-right">
|
||||
{info?.args?.deleteHash}
|
||||
</span>
|
||||
的tab项
|
||||
</div>
|
||||
);
|
||||
},
|
||||
schema: getArgsWrapper(
|
||||
getSchemaTpl('formulaControl', {
|
||||
name: 'deleteHash',
|
||||
label: '删除项',
|
||||
variables: '${variables}',
|
||||
size: 'lg',
|
||||
mode: 'horizontal',
|
||||
placeholder: '请输入hash值',
|
||||
horizontal: {
|
||||
left: 'normal'
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
@ -193,7 +246,8 @@ export class TabsPlugin extends BasePlugin {
|
||||
placeholder: '默认激活的选项卡',
|
||||
pipeOut: (data: string) =>
|
||||
data === '' || isNaN(Number(data)) ? data : Number(data)
|
||||
}
|
||||
},
|
||||
getSchemaTpl('closable')
|
||||
]
|
||||
},
|
||||
getSchemaTpl('status'),
|
||||
@ -233,7 +287,7 @@ export class TabsPlugin extends BasePlugin {
|
||||
body: [
|
||||
{
|
||||
name: 'tabsMode',
|
||||
label: '样式',
|
||||
label: '展示形式',
|
||||
type: 'select',
|
||||
options: [
|
||||
{
|
||||
@ -289,31 +343,54 @@ export class TabsPlugin extends BasePlugin {
|
||||
})
|
||||
]
|
||||
},
|
||||
getSchemaTpl('style:classNames', {
|
||||
isFormItem: false,
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
name: 'linksClassName',
|
||||
label: '标题区'
|
||||
getSchemaTpl('theme:base', {
|
||||
classname: 'titleControlClassName',
|
||||
title: '标题样式',
|
||||
hidePaddingAndMargin: true,
|
||||
hideRadius: true,
|
||||
hideShadow: true,
|
||||
hideBorder: true,
|
||||
hideBackground: true,
|
||||
state: ['default', 'hover', 'focused', 'disabled'],
|
||||
extra: [
|
||||
getSchemaTpl('theme:select', {
|
||||
label: '宽度',
|
||||
name: 'themeCss.titleControlClassName.width'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'toolbarClassName',
|
||||
label: '工具栏'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'contentClassName',
|
||||
label: '内容区'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'showTipClassName',
|
||||
label: '提示',
|
||||
visibleOn: 'this.showTip',
|
||||
clearValueOnHidden: true
|
||||
getSchemaTpl('theme:font', {
|
||||
label: '文字',
|
||||
name: 'themeCss.titleControlClassName.font'
|
||||
})
|
||||
]
|
||||
}),
|
||||
getSchemaTpl('theme:base', {
|
||||
classname: 'toolbarControlClassName',
|
||||
title: '工具栏样式'
|
||||
}),
|
||||
getSchemaTpl('theme:base', {
|
||||
classname: 'contentControlClassName',
|
||||
title: '内容区样式'
|
||||
}),
|
||||
getSchemaTpl('theme:singleCssCode', {
|
||||
selectors: [
|
||||
{
|
||||
label: '选项卡基本样式',
|
||||
isRoot: true,
|
||||
selector: '.cxd-Tabs'
|
||||
},
|
||||
{
|
||||
label: '选项卡工具栏样式',
|
||||
selector: '.cxd-Tabs-toolbar'
|
||||
},
|
||||
{
|
||||
label: '选项卡标题样式',
|
||||
selector: '.cxd-Tabs-link'
|
||||
},
|
||||
{
|
||||
label: '选项卡内容区样式',
|
||||
selector: '.cxd-Tabs-content'
|
||||
}
|
||||
]
|
||||
})
|
||||
])
|
||||
]
|
||||
@ -377,7 +454,7 @@ export class TabsPlugin extends BasePlugin {
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
getSchemaTpl('closable'),
|
||||
{
|
||||
label: tipedLabel(
|
||||
'Hash',
|
||||
@ -418,8 +495,9 @@ export class TabsPlugin extends BasePlugin {
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('style:classNames', {
|
||||
isFormItem: false
|
||||
getSchemaTpl('theme:base', {
|
||||
classname: 'panelControlClassName',
|
||||
title: '基本样式'
|
||||
})
|
||||
])
|
||||
}
|
||||
|
@ -1,26 +1,25 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
EditorNodeType,
|
||||
getI18nEnabled,
|
||||
jsonToJsonSchema,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
BasicToolbarItem,
|
||||
RendererInfo,
|
||||
VRendererConfig
|
||||
VRendererConfig,
|
||||
getSchemaTpl,
|
||||
VRenderer,
|
||||
mapReactElement,
|
||||
RegionWrapper as Region,
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import React from 'react';
|
||||
import {VRenderer} from 'amis-editor-core';
|
||||
import {mapReactElement} from 'amis-editor-core';
|
||||
import {RegionWrapper as Region} from 'amis-editor-core';
|
||||
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import {
|
||||
getArgsWrapper,
|
||||
getEventControlConfig
|
||||
getEventControlConfig,
|
||||
getActionCommonProps
|
||||
} from '../renderer/event-control/helper';
|
||||
|
||||
export class WizardPlugin extends BasePlugin {
|
||||
@ -252,15 +251,16 @@ export class WizardPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'submit',
|
||||
actionLabel: '全部提交',
|
||||
description: '提交全部数据'
|
||||
description: '提交全部数据',
|
||||
...getActionCommonProps('submit')
|
||||
},
|
||||
{
|
||||
actionType: 'stepSubmit',
|
||||
actionLabel: '分步提交',
|
||||
description: '提交当前步骤数据',
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
提交当前步骤数据
|
||||
</div>
|
||||
@ -270,21 +270,39 @@ export class WizardPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'prev',
|
||||
actionLabel: '上一步',
|
||||
description: '返回上一步'
|
||||
description: '返回上一步',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.rendererLabel}</span>
|
||||
{info?.__rendererName === 'carousel' ? '滚动至上一张' : null}
|
||||
{info?.__rendererName === 'wizard' ? '返回前一步' : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
actionType: 'next',
|
||||
actionLabel: '下一步',
|
||||
description: '提交当前步骤数据'
|
||||
description: '提交当前步骤数据',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.rendererLabel}</span>
|
||||
{info?.__rendererName === 'carousel' ? '滚动至下一张' : null}
|
||||
{info?.__rendererName === 'wizard' ? '提交当前步骤数据' : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
actionType: 'goto-step',
|
||||
actionLabel: '定位步骤',
|
||||
description: '切换到指定步骤',
|
||||
innerArgs: ['step'],
|
||||
descDetail: (info: any) => {
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="action-desc">
|
||||
<span className="variable-right">{info?.__rendererLabel}</span>
|
||||
切换到第
|
||||
<span className="variable-left variable-right">
|
||||
@ -308,12 +326,14 @@ export class WizardPlugin extends BasePlugin {
|
||||
{
|
||||
actionType: 'reload',
|
||||
actionLabel: '重新加载',
|
||||
description: '触发组件数据刷新并重新渲染'
|
||||
description: '触发组件数据刷新并重新渲染',
|
||||
...getActionCommonProps('reload')
|
||||
},
|
||||
{
|
||||
actionType: 'setValue',
|
||||
actionLabel: '变量赋值',
|
||||
description: '触发组件数据更新'
|
||||
description: '触发组件数据更新',
|
||||
...getActionCommonProps('setValue')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -14,9 +14,10 @@ import React from 'react';
|
||||
import {ActionConfig, ComponentInfo} from './types';
|
||||
import ActionConfigPanel from './action-config-panel';
|
||||
import {BASE_ACTION_PROPS} from './comp-action-select';
|
||||
import {findActionNode} from './helper';
|
||||
import {findActionNode} from './eventControlConfigHelper';
|
||||
import {PlainObject, SchemaNode, Option} from 'amis-core';
|
||||
import {i18n as _i18n} from 'i18n-runtime';
|
||||
import './actionsPanelPlugins';
|
||||
|
||||
interface ActionDialogProp {
|
||||
show: boolean;
|
||||
@ -236,7 +237,7 @@ export default class ActionDialog extends React.Component<ActionDialogProp> {
|
||||
type: 'dialog',
|
||||
title: '动作配置',
|
||||
headerClassName: 'font-bold',
|
||||
className: 'action-config-dialog',
|
||||
className: 'ae-action-config-dialog',
|
||||
bodyClassName: 'action-config-dialog-body',
|
||||
closeOnEsc: closeOnEsc,
|
||||
closeOnOutside: false,
|
||||
@ -323,16 +324,37 @@ export default class ActionDialog extends React.Component<ActionDialogProp> {
|
||||
{
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '动作说明',
|
||||
type: 'container',
|
||||
className: 'right-panel-container',
|
||||
body: [
|
||||
{
|
||||
type: 'container',
|
||||
className: 'action-panel-title',
|
||||
visibleOn: 'this.actionType',
|
||||
inline: false
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
className: 'action-desc',
|
||||
tpl: '${__actionDesc}',
|
||||
tpl: '动作说明',
|
||||
visibleOn: 'this.actionType'
|
||||
},
|
||||
{
|
||||
type: 'tooltip-wrapper',
|
||||
content: '${__actionDesc}',
|
||||
visibleOn: 'this.actionType',
|
||||
body: {
|
||||
type: 'icon',
|
||||
icon: 'far fa-question-circle',
|
||||
vendor: '',
|
||||
className: 'ml-0.5'
|
||||
},
|
||||
className: 'inline-block ml-0.5 mb-1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
label: '动作描述',
|
||||
mode: 'horizontal',
|
||||
visibleOn: 'this.actionType'
|
||||
},
|
||||
{
|
||||
@ -342,10 +364,6 @@ export default class ActionDialog extends React.Component<ActionDialogProp> {
|
||||
visibleOn: 'this.actionType',
|
||||
inline: false
|
||||
},
|
||||
{
|
||||
type: 'container',
|
||||
className: 'right-panel-container',
|
||||
body: [
|
||||
{
|
||||
asFormItem: true,
|
||||
component: ActionConfigPanel,
|
||||
|
@ -6,7 +6,8 @@ import {RendererProps, Schema} from 'amis-core';
|
||||
import {RendererPluginAction} from 'amis-editor-core';
|
||||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import {COMMON_ACTION_SCHEMA_MAP, renderCmptActionSelect} from './helper';
|
||||
import isFunction from 'lodash/isFunction';
|
||||
import {renderCmptActionSelect} from './helper';
|
||||
|
||||
export default class ActionConfigPanel extends React.Component<RendererProps> {
|
||||
render() {
|
||||
@ -19,10 +20,6 @@ export default class ActionConfigPanel extends React.Component<RendererProps> {
|
||||
manager
|
||||
} = this.props;
|
||||
const actionType = data.__subActions ? data.groupType : data.actionType;
|
||||
const commonActionConfig = {
|
||||
...COMMON_ACTION_SCHEMA_MAP,
|
||||
...actionConfigItemsMap
|
||||
};
|
||||
let schema: any = null;
|
||||
|
||||
if (data.actionType === 'component') {
|
||||
@ -30,7 +27,8 @@ export default class ActionConfigPanel extends React.Component<RendererProps> {
|
||||
const subActionSchema =
|
||||
pluginActions?.[data.__rendererName]?.find(
|
||||
(item: RendererPluginAction) => item.actionType === data.groupType
|
||||
)?.schema ?? commonActionConfig[data.groupType]?.schema;
|
||||
)?.schema ??
|
||||
(actionConfigItemsMap && actionConfigItemsMap[data.groupType]?.schema);
|
||||
const baseSchema = renderCmptActionSelect(
|
||||
'选择组件',
|
||||
true,
|
||||
@ -46,7 +44,10 @@ export default class ActionConfigPanel extends React.Component<RendererProps> {
|
||||
: [subActionSchema])
|
||||
];
|
||||
} else {
|
||||
schema = data.__actionSchema;
|
||||
const __originActionSchema = data.__actionSchema;
|
||||
schema = isFunction(__originActionSchema)
|
||||
? __originActionSchema(manager)
|
||||
: __originActionSchema;
|
||||
}
|
||||
|
||||
return schema ? (
|
||||
|
@ -0,0 +1,111 @@
|
||||
import {RendererPluginAction, EditorManager} from 'amis-editor-core';
|
||||
const builtInActionsPanel: Array<RendererPluginAction> = [];
|
||||
|
||||
export interface ActionLeftPanelTree {
|
||||
actionType?: string;
|
||||
actionLabel?: string;
|
||||
children?: RendererPluginAction | Array<RendererPluginAction>;
|
||||
}
|
||||
|
||||
type ActionPanel = Omit<RendererPluginAction, 'actionType' | 'actionLabel'> & {
|
||||
label: string;
|
||||
tag: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 构建actionTypeTree 数据结构
|
||||
*
|
||||
* @param actionPanel
|
||||
*/
|
||||
|
||||
const builtInActionPanelData = (
|
||||
actionType: string,
|
||||
actionPanel: ActionPanel | undefined
|
||||
) => {
|
||||
const {label, description, ...rest} = actionPanel || {};
|
||||
return {
|
||||
actionType,
|
||||
actionLabel: label,
|
||||
description,
|
||||
...rest
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 注册动作面板插件
|
||||
*
|
||||
* @param actionPanel
|
||||
*/
|
||||
export const registerActionPanel = (
|
||||
actionType: string,
|
||||
actionPanel?: ActionPanel
|
||||
) => {
|
||||
const {label, tag} = actionPanel || {};
|
||||
if (!actionType) {
|
||||
console.warn(`actionType 不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!label || !tag) {
|
||||
console.warn(`label 或 tag 不能为空`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (builtInActionsPanel.length === 0) {
|
||||
builtInActionsPanel.push({
|
||||
actionType: tag,
|
||||
actionLabel: tag,
|
||||
children: [builtInActionPanelData(actionType, actionPanel)]
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const idx = builtInActionsPanel.findIndex(item => item.actionType === tag);
|
||||
if (idx === -1) {
|
||||
builtInActionsPanel.push({
|
||||
actionType: tag,
|
||||
actionLabel: tag,
|
||||
children: [builtInActionPanelData(actionType, actionPanel)]
|
||||
});
|
||||
} else {
|
||||
const subActionsPanel = builtInActionsPanel[idx]?.children || [];
|
||||
const idx2 = subActionsPanel.findIndex(
|
||||
item => item.actionType === actionType
|
||||
);
|
||||
const processData = builtInActionPanelData(actionType, actionPanel);
|
||||
if (idx2 === -1) {
|
||||
subActionsPanel.push(processData);
|
||||
} else {
|
||||
console.warn(
|
||||
`存在actionType:${actionType}相同的动作面板,将会覆盖原有的动作面板`
|
||||
);
|
||||
subActionsPanel.splice(idx2, 1, processData);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 注销动作面板插件
|
||||
*
|
||||
* @param actionType
|
||||
*/
|
||||
export const unRegisterActionsPanel = (actionType: string | string[]) => {
|
||||
if (!Array.isArray(actionType)) {
|
||||
actionType = [actionType];
|
||||
}
|
||||
|
||||
actionType.forEach(type => {
|
||||
builtInActionsPanel.forEach((item, index) => {
|
||||
item.children?.forEach((subItem, index) => {
|
||||
if (subItem.actionType === type) {
|
||||
subItem.children?.splice(index, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const ACTION_TYPE_TREE = (
|
||||
manager: EditorManager
|
||||
): RendererPluginAction[] => {
|
||||
return builtInActionsPanel;
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import {registerActionPanel} from '../../actionsPanelManager';
|
||||
import {renderCmptSelect, renderCmptIdInput} from './helper';
|
||||
import {buildLinkActionDesc} from '../../helper';
|
||||
|
||||
registerActionPanel('clear', {
|
||||
label: '清空表单',
|
||||
tag: '组件',
|
||||
description: '清空表单数据',
|
||||
descDetail: (info: any, context: any, props: any) => {
|
||||
return (
|
||||
<div className="action-desc">
|
||||
清空
|
||||
{buildLinkActionDesc(props.manager, info)}
|
||||
的数据
|
||||
</div>
|
||||
);
|
||||
},
|
||||
supportComponents: 'form',
|
||||
schema: () => [...renderCmptSelect('目标组件', true), renderCmptIdInput()]
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import {registerActionPanel} from '../../actionsPanelManager';
|
||||
import {renderCmptActionSelect} from './helper';
|
||||
|
||||
registerActionPanel('component', {
|
||||
label: '组件特性动作',
|
||||
tag: '组件',
|
||||
description: '触发所选组件的特性动作',
|
||||
supportComponents: '*',
|
||||
schema: () => renderCmptActionSelect('目标组件', true)
|
||||
});
|
@ -0,0 +1,135 @@
|
||||
import {JSONGetById, EditorManager} from 'amis-editor-core';
|
||||
import {DataSchema} from 'amis-core';
|
||||
import CmptActionSelect from '../../comp-action-select';
|
||||
|
||||
// 下拉展示可赋值属性范围
|
||||
export const SELECT_PROPS_CONTAINER = ['form'];
|
||||
|
||||
export const renderCmptActionSelect = (
|
||||
componentLabel: string,
|
||||
required: boolean,
|
||||
onChange?: (value: string, oldVal: any, data: any, form: any) => void,
|
||||
hideAutoFill?: boolean,
|
||||
manager?: EditorManager
|
||||
) => {
|
||||
return [
|
||||
...renderCmptSelect(
|
||||
componentLabel || '选择组件',
|
||||
true,
|
||||
async (value: string, oldVal: any, data: any, form: any) => {
|
||||
// 获取组件上下文
|
||||
if (form.data.__nodeId) {
|
||||
if (form.data.actionType === 'setValue') {
|
||||
// todo:这里会闪一下,需要从amis查下问题
|
||||
form.setValueByName('args.value', []);
|
||||
form.setValueByName('args.__comboType', undefined);
|
||||
form.setValueByName('args.__valueInput', undefined);
|
||||
form.setValueByName('args.__containerType', undefined);
|
||||
|
||||
if (SELECT_PROPS_CONTAINER.includes(form.data.__rendererName)) {
|
||||
const contextSchema: any = await form.data.getContextSchemas?.(
|
||||
form.data.__nodeId,
|
||||
true
|
||||
);
|
||||
|
||||
const dataSchema = new DataSchema(contextSchema || []);
|
||||
const variables = dataSchema?.getDataPropsAsOptions() || [];
|
||||
form.setValueByName(
|
||||
'__setValueDs',
|
||||
variables.filter(item => item.value !== '$$id')
|
||||
);
|
||||
} else {
|
||||
form.setValueByName('__setValueDs', []);
|
||||
}
|
||||
}
|
||||
}
|
||||
form.setValueByName('groupType', '');
|
||||
onChange?.(value, oldVal, data, form);
|
||||
},
|
||||
hideAutoFill
|
||||
),
|
||||
{
|
||||
type: 'input-text',
|
||||
name: '__cmptId',
|
||||
mode: 'horizontal',
|
||||
size: 'lg',
|
||||
required: true,
|
||||
label: '组件id',
|
||||
visibleOn:
|
||||
'this.componentId === "customCmptId" && this.actionType === "component"',
|
||||
onChange: async (value: string, oldVal: any, data: any, form: any) => {
|
||||
let schema = JSONGetById(manager!.store.schema, value, 'id');
|
||||
if (schema) {
|
||||
form.setValues({
|
||||
__rendererName: schema.type
|
||||
});
|
||||
} else {
|
||||
form.setValues({
|
||||
__rendererName: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
asFormItem: true,
|
||||
label: '组件动作',
|
||||
name: 'groupType',
|
||||
mode: 'horizontal',
|
||||
required: true,
|
||||
visibleOn: 'this.actionType === "component"',
|
||||
component: CmptActionSelect,
|
||||
description: '${__cmptActionDesc}'
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
export const renderCmptSelect = (
|
||||
componentLabel: string,
|
||||
required: boolean,
|
||||
onChange?: (value: string, oldVal: any, data: any, form: any) => void,
|
||||
hideAutoFill?: boolean
|
||||
) => [
|
||||
{
|
||||
type: 'tree-select',
|
||||
name: 'componentId',
|
||||
label: componentLabel || '选择组件',
|
||||
showIcon: false,
|
||||
searchable: true,
|
||||
required,
|
||||
selfDisabledAffectChildren: false,
|
||||
size: 'lg',
|
||||
source: '${__cmptTreeSource}',
|
||||
mode: 'horizontal',
|
||||
autoFill: {
|
||||
__isScopeContainer: '${isScopeContainer}',
|
||||
...(hideAutoFill
|
||||
? {}
|
||||
: {
|
||||
__rendererLabel: '${label}',
|
||||
__rendererName: '${type}',
|
||||
__nodeId: '${id}',
|
||||
__nodeSchema: '${schema}'
|
||||
})
|
||||
},
|
||||
onChange: async (value: string, oldVal: any, data: any, form: any) => {
|
||||
onChange?.(value, oldVal, data, form);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export const renderCmptIdInput = (
|
||||
onChange?: (value: string, oldVal: any, data: any, form: any) => void
|
||||
) => {
|
||||
return {
|
||||
type: 'input-text',
|
||||
name: '__cmptId',
|
||||
mode: 'horizontal',
|
||||
size: 'lg',
|
||||
required: true,
|
||||
label: '组件id',
|
||||
visibleOn: 'this.componentId === "customCmptId"',
|
||||
onChange: async (value: string, oldVal: any, data: any, form: any) => {
|
||||
onChange?.(value, oldVal, data, form);
|
||||
}
|
||||
};
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user