Skip to content
Open
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
4 changes: 2 additions & 2 deletions examples/sites/demos/pc/app/grid/custom/column-simple.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ test('简化版列设置测试', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('grid-custom#custom-column-simple')
await page.locator('.tiny-select > div').click()
await page.getByRole('listitem').filter({ hasText: '员工数' }).click()
await page.locator('.tiny-option-label').filter({ hasText: '员工数' }).click()
const thHeader = page.locator('th.tiny-grid-header__column').nth(3)
await expect(thHeader).toContainText('地址')
await page.getByRole('listitem').filter({ hasText: '名称' }).click()
await page.locator('.tiny-option-label').filter({ hasText: '名称' }).click()
const thHeader2 = page.locator('th.tiny-grid-header__column').nth(1)

await expect(thHeader2).toContainText('员工数')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<div>
<tiny-button @click="addRow">新增行</tiny-button>
<tiny-grid ref="gridRef" :data="tableData" :edit-config="editConfig">
<template #toolbar>
<tiny-grid-toolbar id="undefined-field-defalut-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
</template>
<tiny-grid-column field="field1" title="所属区域" :editor="{}">
<template #edit="{ row }">
<tiny-input v-model="row.field1" />
Expand All @@ -22,7 +25,7 @@
</template>

<script setup>
import { TinyGrid, TinyGridColumn, TinyInput, TinyButton } from '@opentiny/vue'
import { TinyGrid, TinyGridColumn, TinyInput, TinyButton, TinyGridToolbar } from '@opentiny/vue'
import { ref } from 'vue'

const tableData = ref([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ test('缺省数据默认值', async ({ page }) => {
await page.goto('grid-data-source#undefined-field-defalut-value')

const demo = page.locator('#undefined-field-defalut-value')
const custom = page.locator('.tiny-grid-custom')

const firstRow = demo.locator('.tiny-grid-body__row:visible').nth(0)

Expand All @@ -25,4 +26,27 @@ test('缺省数据默认值', async ({ page }) => {
await firstRow.locator('.tiny-input__inner').click()
await firstRow.locator('.tiny-input__inner').fill('1')
await expect(firstRow.locator('.tiny-input__inner')).toHaveValue('1')

// 测试:新增行后通过个性化面板设置列隐藏,新增的行不应该消失
const rowsBefore = await demo.locator('.tiny-grid-body__row:visible').count()
expect(rowsBefore).toBeGreaterThan(2) // 原始2行 + 新增的1行

await page.locator('.tiny-grid-custom__setting-btn').click()

await custom.getByRole('row', { name: '地址' }).getByTitle('显示').getByRole('img').click()

await custom.getByRole('button', { name: '确定' }).click()

await expect(page.getByRole('cell', { name: '地址' })).not.toBeVisible()

// 6. 验证新增的行仍然存在(行数应该保持不变)
const rowsAfter = await demo.locator('.tiny-grid-body__row:visible').count()
expect(rowsAfter).toBe(rowsBefore)

// 7. 验证新增的行数据仍然可以编辑
const newRow = demo.locator('.tiny-grid-body__row:visible').first()
await newRow.locator('td').nth(0).click() // 点击第一列
await newRow.locator('.tiny-input__inner').click()
await newRow.locator('.tiny-input__inner').fill('test')
await expect(newRow.locator('.tiny-input__inner')).toHaveValue('test')
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<div>
<tiny-button @click="addRow">新增行</tiny-button>
<tiny-grid ref="grid" :data="tableData" :edit-config="editConfig">
<template #toolbar>
<tiny-grid-toolbar id="undefined-field-defalut-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
</template>
Comment on lines +5 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo in the toolbar ID attribute.

The ID contains "defalut" instead of "default". While this is consistent with the filename, it's still a typo that should be corrected.

Apply this diff to fix the typo:

       <template #toolbar>
-        <tiny-grid-toolbar id="undefined-field-defalut-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
+        <tiny-grid-toolbar id="undefined-field-default-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
       </template>

Note: You may also want to rename the file itself to maintain consistency.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<template #toolbar>
<tiny-grid-toolbar id="undefined-field-defalut-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
</template>
<template #toolbar>
<tiny-grid-toolbar id="undefined-field-default-value" :setting="{ storage: 'local' }"></tiny-grid-toolbar>
</template>
🤖 Prompt for AI Agents
In
examples/sites/demos/pc/app/grid/data-source/undefined-field-defalut-value.vue
around lines 5 to 7, the toolbar id contains a typo "defalut" instead of
"default"; update the id attribute value to "undefined-field-default-value" to
correct the spelling, and optionally rename the file to
examples/sites/demos/pc/app/grid/data-source/undefined-field-default-value.vue
(and update any imports/references) to keep filename consistent with the
corrected id.

<tiny-grid-column field="field1" title="所属区域" :editor="{}">
<template #edit="{ row }">
<tiny-input v-model="row.field1" />
Expand All @@ -22,14 +25,15 @@
</template>

<script>
import { TinyGrid, TinyGridColumn, TinyInput, TinyButton } from '@opentiny/vue'
import { TinyGrid, TinyGridColumn, TinyInput, TinyButton, TinyGridToolbar } from '@opentiny/vue'
export default {
components: {
TinyGrid,
TinyGridColumn,
TinyInput,
TinyButton
TinyButton,
TinyGridToolbar
},
data() {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { test, expect } from '@playwright/test'
test('引入组件作为编辑器', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('grid-editor#editor-custom-editor-select')
await page.getByText('华中区').first().click()
await page.getByRole('textbox', { name: '请选择' }).click()
await page.getByRole('list').getByText('西南区').click()
await page.getByRole('cell', { name: '创建时间' }).click()
const demo = page.locator('#editor-custom-editor-select')
await demo.getByText('华中区').first().click()
await demo.locator('.tiny-input__inner').click()
await page.locator('.tiny-option-label').filter({ hasText: '西南区' }).click()
await demo.locator('.tiny-grid__body thead').click()
await expect(page.locator('.tiny-grid-body__row').first()).toContainText('西南区')
})
2 changes: 1 addition & 1 deletion packages/theme/src/grid/header.less
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
color: var(--tv-Grid-header-text-color);

// 去掉最后一个竖线
&:nth-last-of-type(2) {
&:nth-last-of-type(1) {
.@{grid-prefix-cls}-resizable.is__line:before {
width: 0;
}
Expand Down
66 changes: 55 additions & 11 deletions packages/vue/src/grid/src/composable/useNormalData.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,72 @@
import { hooks } from '@opentiny/vue-common'

export const useNormalData = ({ props, visibleColumn }) => {
export const useNormalData = ({ props, tableFullColumn }) => {
const $table = hooks.getCurrentInstance()?.proxy
// 原始数据
const rawData = hooks.ref([])
// 原始数据版本
const rawDataVersion = hooks.ref(0)
// 所有的可编辑列
const editorColumns = hooks.ref([])
const editorColumnKey = hooks.ref('')

hooks.watch([rawData, () => visibleColumn.value], ([_data, _visibleColumn]) => {
if (props.editConfig && Array.isArray(_data) && _data.length > 0 && _visibleColumn.length > 0) {
// 对于可编辑表格,如果编辑器对应数据行字段不存在,通过编辑器修改字段时会动态添加字段
// 对于旧数据处理:watch -> handleDataChange -> loadTableData -> updateCache
// 在Vue2,这种动态添加字段会触发选项式watch data,更新cache,最终导致脏数据状态不显示
// 在Vue3,不会触发选项式watch data 和更新cache,不会导致脏数据状态不显示
// 这里修复这种数据处理过程的不一致性:在数据改变后,先规范化数据,再更新数据缓存,再处理数据改变
_data.forEach((row) => $table.defineField(row))
rawDataVersion.value += 1
hooks.watch(tableFullColumn, (_tableFullColumn) => {
let columns = []
let columnKeys = []

for (let i = 0; i < _tableFullColumn.length; i++) {
const column = _tableFullColumn[i]

if (column.property && column.editor) {
columns.push(column)
columnKeys.push(column.propety)
}
}

// 在显示隐藏或者拖动可编辑列时,不触发editorColumns响应性更新
// 在初始化时和在增加可编辑列时触发editorColumns响应性更新
const keyString = columnKeys.sort().join()

if (editorColumnKey.value !== keyString) {
editorColumnKey.value = keyString
editorColumns.value = columns
}
})

// 在可编辑列改变时,尝试规范化可编辑字段,包括原始数据和临时插入数据
hooks.watch(editorColumns, (_editorColumns) => {
if (props.editConfig && _editorColumns.length > 0) {
const _insertData = $table.editStore.insertList || []
const _rawData = rawData.value || []
const _data = [..._insertData, ..._rawData]

if (Array.isArray(_data)) {
// 在增加可编辑列时,同步修改原始备份,保证字段存在
_data.forEach((row) => $table.defineField(row, false, _editorColumns, true))
}
}
})

// 在原始数据改变时,尝试规范化可编辑字段。不处理临时插入数据,因为后续会被清理掉。
hooks.watch(rawData, (_rawData) => {
const _editorColumns = editorColumns.value

if (props.editConfig && _editorColumns.length > 0) {
const _data = _rawData || []

if (Array.isArray(_data)) {
_data.forEach((row) => $table.defineField(row, false, _editorColumns))
}
}

// 触发表格数据刷新
rawDataVersion.value += 1
})

hooks.watch(rawDataVersion, () => {
// 设置数据查找缓存,对数据进行备份,深度克隆
$table.updateCache(true, props.saveSource === 'deep')
// 处理数据改变
// 处理表格数据刷新
$table.handleDataChange()
})

Expand Down
6 changes: 3 additions & 3 deletions packages/vue/src/grid/src/edit/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,14 @@ export default {
* 如果还额外传了field则还原指定单元格。
*/
_revertData(rows, field) {
let { tableSynchData } = this
let { rawData } = this

if (arguments.length && rows && !isArray(rows)) {
rows = [rows]
}

if (!arguments.length) {
rows = tableSynchData || []
rows = rawData || []
}

for (let i = 0; i < rows.length; i++) {
Expand All @@ -281,7 +281,7 @@ export default {
return this.$nextTick()
}

return this.reloadData(tableSynchData)
return this.reloadData(rawData || [])
},

/**
Expand Down
23 changes: 18 additions & 5 deletions packages/vue/src/grid/src/table/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ const Methods = {
editStore.insertList = []
editStore.insertMap = new Map()
editStore.removeList = []
// 设置全量数据,原始数据,行虚滚标记
Object.assign(this, { tableFullData, tableSynchData: datas, scrollYLoad })
// 设置全量数据,行虚滚标记
Object.assign(this, { tableFullData, scrollYLoad })

if (scrollYLoad && !(height || maxHeight)) {
error('ui.grid.error.scrollYHeight')
Expand Down Expand Up @@ -585,28 +585,41 @@ const Methods = {
hasIndexColumn(column) {
return column?.type === 'index'
},
defineField(row, copy) {
defineField(row, copy, editorColumns, cache) {
if (!row || typeof row !== 'object') return row

if (copy) {
row = clone(row, true)
}

const rowKey = getRowkey(this)
const columns = editorColumns || this.visibleColumn

this.visibleColumn.forEach(({ property, editor }) => {
columns.forEach((column) => {
const { property, editor } = column
const propNotExist = property && !has(row, property)

// 对于可编辑表格,如果编辑器对应数据行字段不存在,就修复这种字段为值 editor.defaultValue 或者 null
const propDefaultValue = editor && !isUndefined(editor.defaultValue) ? editor.defaultValue : null

if (propNotExist) {
// 在增加可编辑列时,同步修改原始备份,保证字段存在
if (cache) {
const originRow = this.getOriginRow(row)

if (originRow) {
originRow[property] = propDefaultValue
}
}

if (isVue2) {
this.$set(row, property, propDefaultValue)
} else {
set(row, property, propDefaultValue)
}
}
})

// 如果行数据的唯一主键不存在,则生成
const rowId = get(row, rowKey)
if (isNull(rowId) || rowId === '') {
Expand Down Expand Up @@ -751,7 +764,7 @@ const Methods = {
},
// 获取表格所有数据
getData(rowIndex) {
const allRows = this.rawData || this.tableSynchData
const allRows = this.rawData || []

if (!arguments.length) {
return allRows.slice(0)
Expand Down
2 changes: 1 addition & 1 deletion packages/vue/src/grid/src/table/src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ export default defineComponent({
// 模板引用
const tableWrapper = hooks.ref()

const { rawData, rawDataVersion } = useNormalData({ props, visibleColumn })
const { rawData, rawDataVersion } = useNormalData({ props, tableFullColumn })

// TINY主题变量
const tinyTheme = hooks.ref(resolveTheme(props, context))
Expand Down
Loading