feat(grid): [grid] add dynamic filter (#912)

This commit is contained in:
ajaxzheng 2023-11-24 19:17:03 +08:00 committed by GitHub
parent f58ace3c69
commit 199b21ace1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 296 additions and 17 deletions

View File

@ -0,0 +1,127 @@
<template>
<tiny-grid :data="tableData" @toolbar-button-click="toolbarButtonClickEvent">
<template #toolbar>
<tiny-grid-toolbar :buttons="toolbarButtons"> </tiny-grid-toolbar>
</template>
<tiny-grid-column type="index" width="60"></tiny-grid-column>
<tiny-grid-column type="selection" width="60"></tiny-grid-column>
<tiny-grid-column field="name" title="公司名称" :filter="nameFilter"></tiny-grid-column>
<tiny-grid-column field="employees" title="员工数"></tiny-grid-column>
<tiny-grid-column field="createdDate" title="创建日期"></tiny-grid-column>
<tiny-grid-column field="city" title="城市" :filter="cityFilter"></tiny-grid-column>
</tiny-grid>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { Grid as TinyGrid, GridColumn as TinyGridColumn, GridToolbar as TinyGridToolbar } from '@opentiny/vue'
const filteData = [
{ label: '福州', value: '福州' },
{ label: '深圳', value: '深圳' },
{ label: '中山', value: '中山' },
{ label: '龙岩', value: '龙岩' },
{ label: '韶关', value: '韶关' }
]
const nameFilterData = [
{ label: 'GFD科技YX公司', value: 'GFD科技YX公司' },
{ label: 'WWW科技YX公司', value: 'WWW科技YX公司' }
]
let filterNumber = 1
const toolbarButtons = [
{
code: 'changeCityFilter',
name: '动态改变城市列筛选项'
}
]
const tableData = reactive([
{
id: '1',
name: 'GFD科技YX公司',
city: '福州',
employees: 800,
createdDate: '2014-04-30 00:56:00'
},
{
id: '2',
name: 'WWW科技YX公司',
city: '深圳',
employees: 300,
createdDate: '2016-07-08 12:36:22'
},
{
id: '3',
name: 'RFV有限责任公司',
city: '中山',
employees: 1300,
createdDate: '2014-02-14 14:14:14'
},
{
id: '4',
name: 'TGB科技YX公司',
city: '龙岩',
employees: 360,
createdDate: '2013-01-13 13:13:13'
},
{
id: '5',
name: 'YHN科技YX公司',
city: '韶关',
employees: 810,
createdDate: '2012-12-12 12:12:12'
},
{
id: '6',
name: 'WSX科技YX公司',
city: '黄冈',
employees: 800,
createdDate: '2011-11-11 11:11:11'
},
{
id: '7',
name: 'KBG物业YX公司',
city: '赤壁',
employees: 400,
createdDate: '2016-04-30 23:56:00'
},
{
id: '8',
name: '深圳市福德宝网络技术YX公司',
city: '厦门',
employees: 540,
createdDate: '2016-06-03 13:53:25'
}
])
const cityFilter = reactive({
multi: true,
enumable: true,
defaultFilter: false,
inputFilter: false,
values: filteData
})
const nameFilter = reactive({
multi: true,
enumable: true,
defaultFilter: false,
inputFilter: true,
values: () => {
nameFilterData.push({ label: `GFD科技YX公司${filterNumber}`, value: 'GFD科技YX公司' })
filterNumber++
return Promise.resolve(nameFilterData)
}
})
const toolbarButtonClickEvent = ({ code, $grid }) => {
switch (code) {
case 'changeCityFilter': {
cityFilter.values.push({ label: '合肥', value: '合肥' })
break
}
}
}
</script>

View File

@ -0,0 +1,11 @@
import { test, expect } from '@playwright/test'
test('动态改变筛选项', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('grid-filter#filter-dynamic-filter')
await page.getByRole('button', { name: '动态改变城市列筛选项' }).click()
await page.getByRole('cell', { name: '城市' }).getByRole('img').click()
await expect(page.getByText('合肥')).toBeVisible()
await page.getByRole('cell', { name: '公司名称' }).getByRole('img').click()
await expect(page.getByText('GFD科技YX公司1')).toBeVisible()
})

View File

@ -0,0 +1,136 @@
<template>
<tiny-grid :data="tableData" @toolbar-button-click="toolbarButtonClickEvent">
<template #toolbar>
<tiny-grid-toolbar :buttons="toolbarButtons"> </tiny-grid-toolbar>
</template>
<tiny-grid-column type="index" width="60"></tiny-grid-column>
<tiny-grid-column type="selection" width="60"></tiny-grid-column>
<tiny-grid-column field="name" title="公司名称" :filter="nameFilter"></tiny-grid-column>
<tiny-grid-column field="employees" title="员工数"></tiny-grid-column>
<tiny-grid-column field="createdDate" title="创建日期"></tiny-grid-column>
<tiny-grid-column field="city" title="城市" :filter="cityFilter"></tiny-grid-column>
</tiny-grid>
</template>
<script>
import { Grid, GridColumn, GridToolbar } from '@opentiny/vue'
const filteData = [
{ label: '福州', value: '福州' },
{ label: '深圳', value: '深圳' },
{ label: '中山', value: '中山' },
{ label: '龙岩', value: '龙岩' },
{ label: '韶关', value: '韶关' }
]
const nameFilterData = [
{ label: 'GFD科技YX公司', value: 'GFD科技YX公司' },
{ label: 'WWW科技YX公司', value: 'WWW科技YX公司' }
]
let filterNumber = 1
export default {
components: {
TinyGrid: Grid,
TinyGridColumn: GridColumn,
TinyGridToolbar: GridToolbar
},
data() {
return {
toolbarButtons: [
{
code: 'changeCityFilter',
name: '动态改变城市列筛选项'
}
],
tableData: [
{
id: '1',
name: 'GFD科技YX公司',
city: '福州',
employees: 800,
createdDate: '2014-04-30 00:56:00'
},
{
id: '2',
name: 'WWW科技YX公司',
city: '深圳',
employees: 300,
createdDate: '2016-07-08 12:36:22'
},
{
id: '3',
name: 'RFV有限责任公司',
city: '中山',
employees: 1300,
createdDate: '2014-02-14 14:14:14'
},
{
id: '4',
name: 'TGB科技YX公司',
city: '龙岩',
employees: 360,
createdDate: '2013-01-13 13:13:13'
},
{
id: '5',
name: 'YHN科技YX公司',
city: '韶关',
employees: 810,
createdDate: '2012-12-12 12:12:12'
},
{
id: '6',
name: 'WSX科技YX公司',
city: '黄冈',
employees: 800,
createdDate: '2011-11-11 11:11:11'
},
{
id: '7',
name: 'KBG物业YX公司',
city: '赤壁',
employees: 400,
createdDate: '2016-04-30 23:56:00'
},
{
id: '8',
name: '深圳市福德宝网络技术YX公司',
city: '厦门',
employees: 540,
createdDate: '2016-06-03 13:53:25'
}
],
cityFilter: {
multi: true,
enumable: true,
defaultFilter: false,
inputFilter: false,
values: filteData
},
nameFilter: {
multi: true,
enumable: true,
defaultFilter: false,
inputFilter: true,
values: () => {
nameFilterData.push({ label: `GFD科技YX公司${filterNumber}`, value: 'GFD科技YX公司' })
filterNumber++
return Promise.resolve(nameFilterData)
}
}
}
},
methods: {
toolbarButtonClickEvent({ code, $grid }) {
switch (code) {
case 'changeCityFilter': {
this.cityFilter.values.push({ label: '合肥', value: '合肥' })
break
}
}
}
}
}
</script>

View File

@ -27,6 +27,15 @@ export default {
},
'codeFiles': ['filter/default-filter.vue']
},
{
'demoId': 'filter-dynamic-filter',
'name': { 'zh-CN': '动态改变筛选项', 'en-US': 'Filter' },
'desc': {
'zh-CN': `<p>通过改变自定义的 <code>filter</code> 自定义筛选的规则中的 <code>values</code> 数组,或者将 <code>values</code> 定义成方法可以动态的返回筛选项`,
'en-US': ''
},
'codeFiles': ['filter/dynamic-filter.vue']
},
{
'demoId': 'filter-simple-filter',
'name': { 'zh-CN': '简化版筛选-单选/多选菜单', 'en-US': 'Custom Parameter' },

View File

@ -3353,13 +3353,13 @@ interface IFilterConfig {
defaultFilter: boolean
// 设置在过滤面板中显示输入筛选的项
inputFilter: boolean
// 设置在显示枚举选项功能(enumable)下制定静态数据源
// 设置在显示枚举选项功能(enumable)下制定静态数据源也可以是函数返回一个Promise对象
values: {
// 设置枚举数据的显示值属性字段, 默认'label'
label: string
// 设置枚举数据的实际值属性字段, 默认'value'
value: string
}[]
}[] | ()=> Promise
}
`
},

View File

@ -23,7 +23,6 @@
*
*/
import { extend } from '../../common/object'
import { isNull } from '../../common/type'
import { find } from '../../common/array'
import { get, isFunction, set, findTree } from '../static'
@ -67,21 +66,18 @@ export const getFilters = (filters) =>
export const initFilter = (filter) => {
// 改成这种方式可以让用户配置一些筛选的默认行为,如果用户不配置就采用默认的
return extend(
{
condition: {
input: '',
relation: 'equals',
empty: null,
type: null,
value: []
},
hasFilter: false,
custom: null
return {
condition: {
input: '',
relation: 'equals',
empty: null,
type: null,
value: []
},
filter,
true
)
hasFilter: false,
custom: null,
...filter
}
}
export const formatText = (value) => `${isNull(value) ? '' : value}`