Skip to content

Commit 4fafa86

Browse files
committed
Improved data editable check logic.
1 parent 9a440e9 commit 4fafa86

File tree

7 files changed

+112
-82
lines changed

7 files changed

+112
-82
lines changed

docs/TableDemo.vue

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<script setup lang="ts">
2-
import type { Ref } from 'vue'
3-
import { onMounted, ref, toRaw } from 'vue'
4-
import { IwEvents, IwProps, IwUtils } from '../src'
2+
import type { Ref } from 'vue';
3+
import { onMounted, ref, toRaw } from 'vue';
4+
import { IwEvents, IwProps, IwUtils } from '../src';
5+
import type { EditableDataResp } from '../src/props';
56
67
const selectedRecordPks: Ref<any[]> = ref([])
78
@@ -300,11 +301,21 @@ const events: IwProps.TableEventProps = {
300301
records: attachDict(records),
301302
totalNumber: data.length,
302303
aggs: aggResult,
303-
nonEditablePks: [1],
304304
}
305305
}
306306
},
307307
308+
loadEditableData: async (_checkRecordPks: any): Promise<EditableDataResp> => {
309+
return {
310+
whiteListMode: true,
311+
cells: {
312+
1: ['name', 'creator', 'stats', 'planStartTime', 'planEndTime', 'actualStartTime', 'actualEndTime', 'disabled', 'attachment'],
313+
11: ['name'],
314+
17: ['name'],
315+
},
316+
}
317+
},
318+
308319
newData: async (newRecords: { [columnName: string]: any }[]): Promise<void> => {
309320
// TODO targetSortValue
310321
DATA.push(...newRecords)

src/components/eventbus.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type { Ref } from 'vue'
22
import { toRaw } from 'vue'
33
import locales from '../locales'
44

5-
import { type DataGroupResp, type DataQuerySliceReq, type DataResp, type DictItemsResp, type LayoutModifyProps, type SimpleLayoutProps, type TableStyleModifyProps, generateLayoutProps } from '../props'
5+
import type { DataGroupResp, DataQuerySliceReq, DataResp, DictItemsResp, EditableDataResp, LayoutModifyProps, SimpleLayoutProps, TableStyleModifyProps } from '../props'
6+
import { generateLayoutProps } from '../props'
67

78
import { SubDataShowKind } from '../props/enumProps'
89
import type { TableEventProps } from '../props/eventProps'
@@ -264,6 +265,32 @@ export async function deleteData(deletedRecordPks: any[]) {
264265
})
265266
}
266267

268+
/**
269+
* 加载可编辑数据
270+
*
271+
* Load editable data
272+
*
273+
* @param checkRecordPks 要检查的数据主键 / Data primary keys to be checked
274+
*/
275+
export async function loadEditableData(checkRecordPks: any[]): Promise<EditableDataResp> {
276+
checkRecordPks = toRaw(checkRecordPks)
277+
278+
const layout = layoutsConf.find(layout => layout.id === currentLayoutId.value)!
279+
280+
if (!events.loadEditableData) {
281+
showAlert(t('_.event.notConfigured', { name: 'loadEditableData' }), 2, AlertKind.WARNING, getParentWithClass(document.getElementById(`iw-tt-layout-${layout.id}`), 'iw-tt')!)
282+
throw new Error('[events.loadEditableData] Event not Configured')
283+
}
284+
285+
try {
286+
return await events.loadEditableData(checkRecordPks)
287+
}
288+
catch (e: any) {
289+
showAlert(t('_.event.invokeError', { msg: e.message }), 6, AlertKind.ERROR, getParentWithClass(document.getElementById(`iw-tt-layout-${layout.id}`), 'iw-tt')!)
290+
throw new Error(`[events.loadEditableData] Invoke Error:${e.message}`)
291+
}
292+
}
293+
267294
/**
268295
* 选择数据
269296
*

src/components/function/CellEdit.vue

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { onMounted, ref, watch } from 'vue'
3-
import type { EditDataProps } from '../../props'
3+
import type { EditDataProps, EditableDataResp } from '../../props'
44
import type { DataGroupResp, DataResp } from '../../props/basicProps'
55
import { DataKind, getInputTypeByDataKind } from '../../props/enumProps'
66
import { delegateEvent } from '../../utils/basic'
@@ -45,6 +45,10 @@ const props = defineProps<{
4545
// Edit container, used to display edit function
4646
const cellEditContainerRef = ref<InstanceType<typeof HTMLElement>>()
4747
48+
// 可编辑数据
49+
// Editable data
50+
const editableDataResp = ref<EditableDataResp>()
51+
4852
// 当前正在编辑的列配置
4953
// Column configuration currently being edited
5054
const curColumnConf = ref<ColumnConf>()
@@ -125,30 +129,31 @@ async function setValue(value: any) {
125129
* Check if it is editable
126130
*
127131
* 逻辑:
128-
* 1. 优先看返回数据的要求:
129-
* 1. 如果存在不可编辑的数据行的主键,且当前主键值在不可编辑主键值列表中,则不可编辑
130-
* 2. 如果存在可编辑的数据行的主键,且当前主键值不在可编辑主键值列表中,则不可编辑
132+
* 1. 优先看可编辑数据:
133+
* 1. 白名单模式 且 存在行列,返回可编辑
134+
* 2. 黑名单模式 且 不存在行列,返回可编辑
135+
* 3. 其他情况返回不可编辑
131136
* 2. 最后看配置的列是否可编辑
132137
*
133138
* Logic:
134-
* 1. First look at the requirements of the returned data:
135-
* 1. If there are primary keys of data rows that cannot be edited, and the current primary key value is in the list of primary keys that cannot be edited, it cannot be edited
136-
* 2. If there are primary keys of data rows that can be edited, and the current primary key value is not in the list of primary keys that can be edited, it cannot be edited
137-
* 2. Finally, see if the configured column is editable
139+
* 1. Check editable data first:
140+
* 1. White list mode and row-column exist, return editable
141+
* 2. Blacklist mode and row-column do not exist, return editable
142+
* 3. Return not editable in other cases
143+
* 2. Finally check if the configured column is editable
138144
*
139-
* @param data 数据 / Data
140145
* @param pkValue 主键值 / Primary key value
141-
* @param columnConf 列配置 / Column configuration
146+
* @param columnName 列名称 / Column name
147+
* @param editable 可编辑数据,用于进一步限定编辑范围 / Editable data, used to further limit the editing range
142148
* @returns 是否可编辑 / Whether it is editable
143149
*/
144-
function checkEditable(data: DataResp, pkValue: any, columnConf: ColumnConf) {
145-
if (data.nonEditablePks?.includes(pkValue)) {
146-
return false
150+
function checkEditable(pkValue: any, columnName: string, editable?: EditableDataResp): boolean {
151+
if (editable) {
152+
return editable.cells[pkValue]?.includes(columnName) && editable.whiteListMode
147153
}
148-
if (data.editablePks && !data.editablePks.includes(pkValue)) {
149-
return false
154+
else {
155+
return props.edit.enabledColumnNames.includes(columnName) ?? false
150156
}
151-
return props.edit.enabledColumnNames.includes(columnConf.name) ?? false
152157
}
153158
154159
/**
@@ -176,15 +181,14 @@ function markEditable(containerEle: HTMLElement) {
176181
// Find row information
177182
const editRowEle = ele as HTMLElement
178183
const pkValue = props.pkKindIsNumber ? Number.parseInt(editRowEle.dataset[props.editRowPkValueProp]!) : editRowEle.dataset[props.editRowPkValueProp]!
179-
const data: DataResp = Array.isArray(props.data) ? props.data.find(groupData => groupData.records.some(record => record[props.pkColumnName] === pkValue))! : props.data
180184
181185
editRowEle.querySelectorAll(`.${props.editCellClass}`).forEach((ele) => {
182186
// 找到单元格信息,并附加可编辑标记
183187
// Find cell information and attach editable mark
184188
const editCellEle = ele as HTMLElement
185189
const columnName = editCellEle.dataset[props.editCellColumnNameProp] as string
186190
const columnConf = props.columnsConf.find(column => column.name === columnName)!
187-
if (checkEditable(data, pkValue, columnConf)) {
191+
if (checkEditable(pkValue, columnConf.name, editableDataResp.value)) {
188192
editCellEle.appendChild(editableMarkEles.cloneNode(true))
189193
}
190194
})
@@ -193,8 +197,10 @@ function markEditable(containerEle: HTMLElement) {
193197
194198
// 监听配置变化,重新标记可编辑单元格
195199
// Listen for configuration changes and re-mark editable cells
196-
watch([() => props.columnsConf, () => props.data], () => {
200+
watch([() => props.columnsConf, () => props.data], async () => {
197201
if (props.edit.markEditable) {
202+
const pks: any[] = Array.isArray(props.data) ? props.data.flatMap(d => d.records.map(r => r[props.pkColumnName])) : props.data.records.map(r => r[props.pkColumnName])
203+
editableDataResp.value = await eb.loadEditableData(pks)
198204
markEditable(cellEditContainerRef.value!.closest(`.${props.containerClass}`) as HTMLElement)
199205
}
200206
})
@@ -213,7 +219,7 @@ onMounted(() => {
213219
const columnConf = props.columnsConf.find(column => column.name === columnName)!
214220
const pkValue = props.pkKindIsNumber ? Number.parseInt(editRowEle.dataset[props.editRowPkValueProp]!) : editRowEle.dataset[props.editRowPkValueProp]!
215221
const data: DataResp = Array.isArray(props.data) ? props.data.find(groupData => groupData.records.some(record => record[props.pkColumnName] === pkValue))! : props.data
216-
if (checkEditable(data, pkValue, columnConf)) {
222+
if (checkEditable(pkValue, columnConf.name, editableDataResp.value)) {
217223
const value = data.records.find(record => record[props.pkColumnName] === pkValue)![columnName]!
218224
enterEditMode(value, pkValue, columnConf, editCellEle)
219225
}

src/events.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import * as eb from './components/eventbus'
7-
import type { DataQuerySliceReq, DictItemsResp, LayoutModifyProps, SimpleLayoutProps, TableStyleModifyProps } from './props'
7+
import type { LayoutModifyProps, SimpleLayoutProps, TableStyleModifyProps } from './props'
88

99
/**
1010
* 加载数据
@@ -76,33 +76,6 @@ export async function selectData(selectedRecordPks: any[]) {
7676
await eb.selectData(selectedRecordPks)
7777
}
7878

79-
/**
80-
* 加载字典项列表
81-
*
82-
* Load dictionary item list
83-
*
84-
* @param dictName 字典名 / Dictionary name
85-
* @param filterValue 过滤值 / Filter value
86-
* @param slice 分片 / Slice
87-
* @returns 字典项列表 / Dictionary item list
88-
*/
89-
export async function loadCellDictItems(dictName: string, filterValue?: any, slice?: DataQuerySliceReq): Promise<DictItemsResp> {
90-
return await eb.loadCellDictItems(dictName, filterValue, slice)
91-
}
92-
93-
/**
94-
* 加载多条件字典项列表
95-
*
96-
* Load multi-condition dictionary item list
97-
*
98-
* @param conds 条件 / Conditions
99-
* @param slice 分片 / Slice
100-
* @returns 字典项列表 / Dictionary item list
101-
*/
102-
export async function loadCellDictItemsWithMultiConds(conds: { [dictName: string]: any[] }, slice?: DataQuerySliceReq): Promise<{ [dictName: string]: DictItemsResp }> {
103-
return await eb.loadCellDictItemsWithMultiConds(conds, slice)
104-
}
105-
10679
/**
10780
* 修改样式
10881
*

src/props/basicProps.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,6 @@ export interface DataResp {
3030
* Total number
3131
*/
3232
totalNumber: number
33-
/**
34-
* 不可编辑的数据行的主键
35-
*
36-
* Primary key of non-editable data row
37-
*
38-
* 最高优先级
39-
*
40-
* Highest priority
41-
*/
42-
nonEditablePks?: any[]
43-
/**
44-
* 可编辑的数据行的主键
45-
*
46-
* Primary key of editable data row
47-
*
48-
* 优先级低于 nonEditablePks
49-
*
50-
* Priority lower than nonEditablePks
51-
*/
52-
editablePks?: any[]
5333
}
5434

5535
/**

src/props/eventProps.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import type { DataGroupResp, DataResp, DictItemsResp } from './basicProps'
66
import type { LayoutKind } from './enumProps'
7-
import type { AggDataProps, DataQuerySliceReq, FilterDataProps, GroupDataProps, SortDataProps } from './functionProps'
7+
import type { AggDataProps, DataQuerySliceReq, EditableDataResp, FilterDataProps, GroupDataProps, SortDataProps } from './functionProps'
88
import type { LayoutModifyProps, LayoutProps, TableStyleModifyProps } from './kernelProps'
99

1010
/**
@@ -55,14 +55,14 @@ export interface TableEventProps {
5555
*/
5656
newData?: (newRecords: { [columnName: string]: any }[]) => Promise<void>
5757

58-
/**
59-
* 复制数据
60-
*
61-
* Copy data
62-
*
63-
* @param targetRecordPks 要复制的数据主键 / Data primary keys to be copied
64-
*/
65-
copyData?: (targetRecordPks: any[]) => Promise<void>
58+
/**
59+
* 复制数据
60+
*
61+
* Copy data
62+
*
63+
* @param targetRecordPks 要复制的数据主键 / Data primary keys to be copied
64+
*/
65+
copyData?: (targetRecordPks: any[]) => Promise<void>
6666

6767
/**
6868
* 修改数据
@@ -84,6 +84,15 @@ export interface TableEventProps {
8484
*/
8585
deleteData?: (deletedRecordPks: any[]) => Promise<void>
8686

87+
/**
88+
* 加载可编辑数据
89+
*
90+
* Load editable data
91+
*
92+
* @param checkRecordPks 要检查的数据主键 / Data primary keys to be checked
93+
*/
94+
loadEditableData?: (checkRecordPks: any[]) => Promise<EditableDataResp>
95+
8796
/**
8897
* 选择数据
8998
*

src/props/functionProps.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,27 @@ export function generateEditDataProps(tableSimple?: SimpleEditDataProps, layoutS
503503
markEditable: layoutSimple?.markEditable ?? tableSimple?.markEditable ?? false,
504504
}
505505
}
506+
507+
/**
508+
* 编辑数据返回对象
509+
*
510+
* Edit data response object
511+
*/
512+
export interface EditableDataResp {
513+
/**
514+
* 白名单模式,该模式下只有在此列表中的行列才会被编辑
515+
*
516+
* White list mode, in this mode, only rows and columns in this list will be edited
517+
*/
518+
whiteListMode: boolean
519+
/**
520+
* 行列
521+
*
522+
* Rows and columns to be edited
523+
*
524+
* 格式:{行主键: 列名[]}
525+
*
526+
* Format: {row primary key: column name[]}
527+
*/
528+
cells: { [pk: string | number]: string[] }
529+
}

0 commit comments

Comments
 (0)