Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions examples/sites/demos/apis/grid-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export default {
'en-US': 'Whether to display the one click clear button, only applicable to radio selection'
},
mode: ['pc'],
pcDemo: 'clearable',
mfDemo: 'clearable'
pcDemo: 'basic-usage'
},
{
name: 'filterable',
Expand All @@ -26,7 +25,7 @@ export default {
'en-US': 'Is it searchable'
},
mode: ['pc'],
pcDemo: 'filter-method'
pcDemo: 'remote'
},
{
name: 'filter-method',
Expand All @@ -37,7 +36,7 @@ export default {
'en-US': 'Custom filtering method'
},
mode: ['pc'],
pcDemo: 'filter-method'
pcDemo: 'remote'
},
{
name: 'grid-op',
Expand Down Expand Up @@ -71,7 +70,7 @@ export default {
'en-US': 'Allow multiple options to be selected'
},
mode: ['pc'],
pcDemo: 'multiple'
pcDemo: 'remote'
},
{
name: 'radio-config',
Expand All @@ -94,7 +93,7 @@ export default {
'en-US': 'Is it a remote search'
},
mode: ['pc'],
pcDemo: 'remote-method'
pcDemo: 'remote'
},
{
name: 'remote-method',
Expand All @@ -105,7 +104,7 @@ export default {
'en-US': 'Remote search methods'
},
mode: ['pc'],
pcDemo: 'remote-method'
pcDemo: 'remote'
},
{
name: 'reserve-keyword',
Expand All @@ -117,7 +116,7 @@ export default {
'When selecting multiple searchable options, do you still keep the current search keywords after selecting one option'
},
mode: ['pc'],
pcDemo: 'remote-method'
pcDemo: 'remote'
},
{
name: 'select-config',
Expand Down
4 changes: 3 additions & 1 deletion examples/sites/demos/pc/app/grid-select/basic-usage.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<template>
<tiny-grid-select v-model="value" :grid-op="gridOpSingle" value-field="id" text-field="city"></tiny-grid-select>
<div id="basic-usage">
<tiny-grid-select v-model="value" :grid-op="gridOpSingle" value-field="id" text-field="city"></tiny-grid-select>
</div>
</template>

<script>
Expand Down
24 changes: 24 additions & 0 deletions examples/sites/demos/pc/app/grid-select/config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect, test } from '@playwright/test'
test.use({
viewport: { width: 1920, height: 1080 }
})
test('grid-select 禁用选项', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('grid-select#config')

const wrap = page.locator('#config')
const single = wrap.locator('.tiny-grid-select').first()
const singleInput = single.locator('.tiny-input__inner')

await singleInput.click()
const dropdown = page.locator('body > .tiny-select-dropdown')
const rows = dropdown.getByRole('row')

// 第 1 行被禁用,点击后不应该选中
await rows.nth(0).getByRole('cell').nth(1).click()
await expect(singleInput).toHaveValue('')

// 第 2 行可用,点击后可以选中
await page.getByRole('row', { name: '华南区 广东省 深圳市' }).locator('div').first().click()
await expect(singleInput).toHaveValue('深圳市')
})
2 changes: 1 addition & 1 deletion examples/sites/demos/pc/app/grid-select/config.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<div id="config">
<p>场景 1:单选</p>
<br />
<tiny-grid-select
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<template>
<div class="demo-select">
<div>父选项:</div>
<br />
<tiny-grid-select
v-model="parentValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:grid-op="gridOpParent"
:init-query="loadParents"
:remote-method="remoteParents"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
@change="handleParentChange"
></tiny-grid-select>
<br /><br />
<div>子选项:</div>
<br />
<tiny-grid-select
v-model="childValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:grid-op="gridOpChild"
:extra-query-params="parentValue"
:init-query="loadChildren"
:remote-method="remoteChildren"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
></tiny-grid-select>
</div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { TinyGridSelect } from '@opentiny/vue'

const parentValue = ref(['001'])
const childValue = ref(['001'])

const parentOptions = [
{ id: '001', label: '指南' },
{ id: '002', label: '组件' }
]

const childOptions = [
{ id: '001', label: '安装', parent: '001' },
{ id: '002', label: '开发', parent: '001' },
{ id: '004', label: '框架风格', parent: '002' },
{ id: '005', label: '表单组件', parent: '002' },
{ id: '006', label: '数据组件', parent: '002' },
{ id: '007', label: '提示组件', parent: '002' },
{ id: '008', label: '导航组件', parent: '002' },
{ id: '009', label: '其他组件', parent: '002' }
]

const gridOpParent = reactive({
data: [],
height: 260,
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '父级' }
]
})

const gridOpChild = reactive({
data: [],
height: 260,
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '子级' }
]
})

const loadParents = () => Promise.resolve(parentOptions)
const remoteParents = (keyword) => {
const list = parentOptions.filter((item) => item.label.includes(keyword || ''))
return Promise.resolve(list)
}

const loadChildren = (value, extraQueryParams) => filterChildren(extraQueryParams)
const remoteChildren = (keyword, extraQueryParams) => filterChildren(extraQueryParams, keyword)

const filterChildren = (parentIds, keyword = '') =>
new Promise((resolve) => {
const list = childOptions
.filter((child) => parentIds.includes(child.parent))
.filter((child) => child.label.includes(keyword || ''))
setTimeout(() => resolve(list), 300)
})

const handleParentChange = (parents) => {
const childIds = childOptions
.filter((child) => parents.includes(child.parent))
.map((child) => child.id)
childValue.value = childValue.value.filter((value) => childIds.includes(value))
}
</script>

<style scoped>
.demo-select .tiny-grid-select {
width: 280px;
}
</style>

26 changes: 26 additions & 0 deletions examples/sites/demos/pc/app/grid-select/extra-query-params.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from '@playwright/test'

test('grid-select 初始化查询传参', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('grid-select#extra-query-params')
await page.waitForTimeout(1000)

// 选中指南
await page
.locator('div')
.filter({ hasText: /^指南$/ })
.click()
await page.getByRole('row', { name: '指南' }).locator('path').nth(2).click()
await page.getByRole('row', { name: '组件' }).locator('path').first().click()
await page.getByRole('textbox').nth(3).click()
await page.waitForTimeout(400)

// 选中框架风格
await page.getByRole('row', { name: '框架风格' }).locator('div').first().click()
await expect(
page
.locator('div')
.filter({ hasText: /^框架风格$/ })
.nth(2)
).toBeVisible()
})
129 changes: 129 additions & 0 deletions examples/sites/demos/pc/app/grid-select/extra-query-params.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>
<div id="extra-query-params" class="demo-select">
<div>父选项:</div>
<br />
<tiny-grid-select
v-model="parentValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:grid-op="gridOpParent"
:init-query="loadParents"
:remote-method="remoteParents"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
@change="handleParentChange"
></tiny-grid-select>
<br /><br />
<div>子选项:</div>
<br />
<tiny-grid-select
v-model="childValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:extra-query-params="parentValue"
:grid-op="gridOpChild"
:init-query="loadChildren"
:remote-method="remoteChildren"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
></tiny-grid-select>
</div>
</template>

<script>
import { TinyGridSelect } from '@opentiny/vue'

export default {
components: {
TinyGridSelect
},
created() {
this.parentOptions = [
{ id: '001', label: '指南' },
{ id: '002', label: '组件' }
]
this.childOptions = [
{ id: '001', label: '安装', parent: '001' },
{ id: '002', label: '开发', parent: '001' },
{ id: '004', label: '框架风格', parent: '002' },
{ id: '005', label: '表单组件', parent: '002' },
{ id: '006', label: '数据组件', parent: '002' },
{ id: '007', label: '提示组件', parent: '002' },
{ id: '008', label: '导航组件', parent: '002' },
{ id: '009', label: '其他组件', parent: '002' }
]
},
data() {
return {
parentValue: ['001'],
childValue: ['001'],
gridOpParent: {
data: [],
height: 260,
optimization: {
animat: true,
scrollY: { gt: 20 }
},
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '父级' }
]
},
gridOpChild: {
data: [],
height: 260,
optimization: {
animat: true,
scrollY: { gt: 20 }
},
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '子级' }
]
}
}
},
methods: {
loadParents() {
return Promise.resolve(this.parentOptions)
},
remoteParents(keyword) {
const list = this.parentOptions.filter((item) => item.label.includes(keyword || ''))
return Promise.resolve(list)
},
loadChildren(value, extraQueryParams) {
return this.filterChildren(extraQueryParams)
},
remoteChildren(keyword, extraQueryParams) {
return this.filterChildren(extraQueryParams, keyword)
},
filterChildren(parentIds, keyword = '') {
const list = this.childOptions
.filter((child) => parentIds.includes(child.parent))
.filter((child) => child.label.includes(keyword || ''))
return new Promise((resolve) => {
setTimeout(() => resolve(list), 300)
})
},
handleParentChange(parents) {
const childIds = this.childOptions
.filter((child) => parents.includes(child.parent))
.map((child) => child.id)
this.childValue = this.childValue.filter((value) => childIds.includes(value))
}
}
}
</script>

<style scoped>
.demo-select .tiny-grid-select {
width: 280px;
}
</style>

Loading
Loading