mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Merge pull request #8706 from lurunze1226/feat-crud-head-filter-source
feat: CRUD表头快速过滤支持上下文变量作为数据源
This commit is contained in:
commit
3af3a4b2c6
@ -1072,6 +1072,51 @@ amis 只负责生成下拉选择器组件,并将搜索参数传递给接口,
|
||||
|
||||
你可以通过[数据映射](../../docs/concepts/data-mapping),在`api`中获取这些参数。
|
||||
|
||||
#### 下拉数据源
|
||||
|
||||
过滤器的数据域支持API接口和上下文数据(`3.6.0`及以上版本)
|
||||
|
||||
```schema
|
||||
{
|
||||
"type": "page",
|
||||
"data": {
|
||||
"options": [
|
||||
{"label": "4", "value": 3},
|
||||
{"label": "5", "value": 5},
|
||||
{"label": "5.5", "value": 5.5},
|
||||
{"label": "6", "value": 6}
|
||||
]
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "crud",
|
||||
"syncLocation": false,
|
||||
"api": "/api/mock2/sample",
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"label": "ID"
|
||||
},
|
||||
{
|
||||
"name": "grade",
|
||||
"label": "CSS grade",
|
||||
"filterable": {
|
||||
"source": "/api/mock2/crud/filterOptions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"label": "Version",
|
||||
"filterable": {
|
||||
"source": "${options}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 快速编辑
|
||||
|
||||
可以通过给列配置:`"quickEdit":true`和`quickSaveApi` 可以实现表格内快速编辑并批量保存的功能。
|
||||
@ -3332,7 +3377,7 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,
|
||||
|
||||
除了 Table 组件默认支持的列配置,CRUD 的列配置还额外支持以下属性:
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
|
||||
| ------------------ | --------------------------------------------------------------- | ------- | --------------------------------------------------------------------------- | --- |
|
||||
| sortable | `boolean` | `false` | 是否可排序 |
|
||||
| searchable | `boolean` \| `Schema` | `false` | 是否可快速搜索,开启`autoGenerateFilter`后,`searchable`支持配置`Schema` |
|
||||
@ -3346,7 +3391,7 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,
|
||||
| ------------- | ----------------------------- | ------- | -------------------------------------------------------- | ------- |
|
||||
| options | `Array<any>` | - | 静态选项 | |
|
||||
| multiple | `boolean` | `false` | 是否支持多选 | |
|
||||
| source | [`Api`](../../docs/types/api) | - | 选项 API 接口 | |
|
||||
| source | [`Api`](../../docs/types/api) \| `string` | - | 选项 API 接口 | `3.6.0`版本后支持上下文变量 |
|
||||
| refreshOnOpen | `boolean` | `false` | 配置 source 前提下,每次展开筛选浮层是否重新加载选项数据 | `2.9.0` |
|
||||
| strictMode | `boolean` | `false` | 严格模式,开启严格模式后,会采用 JavaScript 严格相等比较 | `2.3.0` |
|
||||
|
||||
|
@ -24,4 +24,4 @@ export default {
|
||||
aside: '边栏',
|
||||
toolbar: '工具栏',
|
||||
initApi: '/api/mock2/page/initDataError'
|
||||
};
|
||||
}
|
||||
|
32
mock/cfc/mock/crud/filterOptions.js
Normal file
32
mock/cfc/mock/crud/filterOptions.js
Normal file
@ -0,0 +1,32 @@
|
||||
module.exports = function (req, res) {
|
||||
const ret = {
|
||||
status: 0,
|
||||
msg: '',
|
||||
data: {
|
||||
options: [
|
||||
{
|
||||
"label": "A",
|
||||
"value": "A"
|
||||
},
|
||||
{
|
||||
"label": "B",
|
||||
"value": "B"
|
||||
},
|
||||
{
|
||||
"label": "C",
|
||||
"value": "C"
|
||||
},
|
||||
{
|
||||
"label": "D",
|
||||
"value": "D"
|
||||
},
|
||||
{
|
||||
"label": "X",
|
||||
"value": "X"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
res.json(ret);
|
||||
};
|
@ -1,23 +1,27 @@
|
||||
import React from 'react';
|
||||
import {RendererProps} from 'amis-core';
|
||||
import {isApiOutdated, isEffectiveApi, normalizeApi} from 'amis-core';
|
||||
import {Icon} from 'amis-ui';
|
||||
import {Overlay} from 'amis-core';
|
||||
import {PopOver} from 'amis-core';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import {Checkbox} from 'amis-ui';
|
||||
import xor from 'lodash/xor';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import {
|
||||
Overlay,
|
||||
PopOver,
|
||||
isApiOutdated,
|
||||
isEffectiveApi,
|
||||
normalizeApi,
|
||||
normalizeOptions,
|
||||
getVariable,
|
||||
createObject,
|
||||
isNumeric
|
||||
isNumeric,
|
||||
isPureVariable,
|
||||
resolveVariableAndFilter
|
||||
} from 'amis-core';
|
||||
import type {Option} from 'amis-core';
|
||||
import {Checkbox, Icon} from 'amis-ui';
|
||||
|
||||
import type {RendererProps, Option} from 'amis-core';
|
||||
|
||||
export interface QuickFilterConfig {
|
||||
options: Array<any>;
|
||||
// source: Api;
|
||||
/** 数据源:API或上下文变量 */
|
||||
source: any;
|
||||
multiple: boolean;
|
||||
/* 是否开启严格对比模式 */
|
||||
strictMode?: boolean;
|
||||
@ -26,7 +30,10 @@ export interface QuickFilterConfig {
|
||||
}
|
||||
|
||||
export interface HeadCellFilterProps extends RendererProps {
|
||||
/** 所在的CRUD的Query数据 */
|
||||
data: any;
|
||||
/** 所在的CRUD的数据以及上层数据 */
|
||||
superData: Record<string, any>;
|
||||
name: string;
|
||||
filterable: QuickFilterConfig;
|
||||
onQuery: (
|
||||
@ -57,11 +64,21 @@ export class HeadCellFilterDropDown extends React.Component<
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {filterable} = this.props;
|
||||
const {filterable, data} = this.props;
|
||||
const {source, options} = filterable || {};
|
||||
|
||||
if (filterable.source) {
|
||||
if (source && isPureVariable(source)) {
|
||||
const datasource = resolveVariableAndFilter(
|
||||
source,
|
||||
this.props.superData,
|
||||
'| raw'
|
||||
);
|
||||
this.setState({
|
||||
filterOptions: this.alterOptions(datasource)
|
||||
});
|
||||
} else if (source && isEffectiveApi(source, data)) {
|
||||
this.fetchOptions();
|
||||
} else if (filterable.options?.length > 0) {
|
||||
} else if (options?.length > 0) {
|
||||
this.setState({
|
||||
filterOptions: this.alterOptions(filterable.options)
|
||||
});
|
||||
@ -70,7 +87,6 @@ export class HeadCellFilterDropDown extends React.Component<
|
||||
|
||||
componentDidUpdate(prevProps: HeadCellFilterProps, prevState: any) {
|
||||
const name = this.props.name;
|
||||
|
||||
const props = this.props;
|
||||
|
||||
this.sourceInvalid = false;
|
||||
@ -186,9 +202,22 @@ export class HeadCellFilterDropDown extends React.Component<
|
||||
}
|
||||
|
||||
async open() {
|
||||
const {filterable} = this.props;
|
||||
const {filterable, source} = this.props;
|
||||
|
||||
if (filterable.refreshOnOpen && filterable.source) {
|
||||
await this.fetchOptions();
|
||||
if (source && isPureVariable(source)) {
|
||||
const datasource = resolveVariableAndFilter(
|
||||
source,
|
||||
this.props.superData,
|
||||
'| raw'
|
||||
);
|
||||
|
||||
this.setState({
|
||||
filterOptions: this.alterOptions(datasource)
|
||||
});
|
||||
} else {
|
||||
await this.fetchOptions();
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
isOpened: true
|
||||
|
@ -2018,6 +2018,7 @@ export default class Table extends React.Component<TableProps, object> {
|
||||
name={column.name}
|
||||
type={column.type}
|
||||
data={query}
|
||||
superData={createObject(data, query)}
|
||||
filterable={column.filterable}
|
||||
popOverContainer={this.getPopOverContainer}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user