Skip to content

Commit 39b0d98

Browse files
committed
feat: use select
1 parent e931d50 commit 39b0d98

File tree

4 files changed

+63
-21
lines changed

4 files changed

+63
-21
lines changed

app/components/VisTable.vue

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ import { toast } from 'vue-sonner'
66
interface Props {
77
columns: string[]
88
records: Record<string, any>[]
9+
changes?: Record<string, Record<string, any[]>>
910
editable?: boolean
1011
primaryKeys?: string[]
1112
}
1213
1314
const props = withDefaults(defineProps<Props>(), {
15+
changes: () => ({}),
1416
primaryKeys: () => [],
1517
})
1618
19+
const emit = defineEmits(['update:changes'])
20+
1721
const Key = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#09090b">
1822
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z" />
1923
</svg>
@@ -56,7 +60,25 @@ VTable.register.icon('frozenCurrent', {
5660
})
5761
5862
const domRef = ref()
59-
const changes = ref<Record<string, Record<string, any[]>>>({})
63+
const changes = useVModel(props, 'changes', emit)
64+
65+
const records = computed(() => {
66+
if (!props.editable)
67+
return props.records
68+
69+
return props.records.map((record) => {
70+
const key = generateRowKeyFromRecord(record)
71+
record.__TABLITE_ROW_KEY = key
72+
73+
for (const column in record) {
74+
const [_, changed] = changes.value[key]?.[column] ?? []
75+
if (changed)
76+
record[column] = changed
77+
}
78+
79+
return record
80+
})
81+
})
6082
6183
const columns = computed(() => {
6284
const constantColumns = [
@@ -107,7 +129,7 @@ function fieldFormatGenerator(key: string) {
107129
108130
const options = computed<any>(() => ({
109131
columns: columns.value,
110-
records: props.records,
132+
records: records.value,
111133
theme: TABLITE_THEME,
112134
113135
defaultRowHeight: 32,
@@ -141,7 +163,7 @@ onMounted(() => {
141163
const column = columns.value[col]
142164
if (!column)
143165
return
144-
const key = generateRowKeyFromIndex(row)
166+
const key = instance.records[row - 1].__TABLITE_ROW_KEY
145167
if (!key)
146168
return
147169
if (!changes.value[key])
@@ -176,34 +198,26 @@ function triggerUndoToast(key: string, field: string, origin: any, row: number,
176198
177199
watch(props, async () => {
178200
instance.updateOption(options.value)
179-
changes.value = {}
180201
})
181202
182203
function isEmpty(value: any) {
183204
return ['', undefined, null].includes(value)
184205
}
185206
186-
function hasChanged(col: number, row: any) {
207+
function hasChanged(x: number, y: number) {
187208
if (!props.editable || !instance)
188209
return false
189-
const record = instance.records[row - 1]
190-
if (!record)
191-
return false
192-
const key = generateRowKeyFromIndex(row)
210+
const key = instance.records[y - 1]?.__TABLITE_ROW_KEY
193211
if (!key)
194212
return false
195-
const column = columns.value[col]
213+
const column = columns.value[x]
196214
if (!column)
197215
return false
198-
199216
const [_, v] = changes.value[key]?.[column.field] ?? []
200217
return v
201218
}
202219
203-
function generateRowKeyFromIndex(index: number) {
204-
const record = instance.records[index - 1]
205-
if (!record)
206-
return
220+
function generateRowKeyFromRecord(record: any) {
207221
const keys: Record<string, any> = {}
208222
props.primaryKeys.forEach((k) => {
209223
keys[k] = record[k]

app/composables/useSelect.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export interface UseSelectOptions {
2+
where?: MaybeRef<string>
3+
limit?: MaybeRef<number>
4+
offset?: MaybeRef<number>
5+
}
6+
7+
export function useSelect(columns: MaybeRef<string[]>, from: MaybeRef<string>, options: UseSelectOptions = {}) {
8+
const _where = toRef(options.where)
9+
const _limit = toRef(options.limit)
10+
const _offset = toRef(options.offset)
11+
12+
const sql = computed(() => [
13+
'SELECT',
14+
unref(columns).join(', ') || '*',
15+
'FROM',
16+
`\`${unref(from)}\``,
17+
_where.value ? ['WHERE', _where.value] : undefined,
18+
_limit.value ? ['LIMIT', _limit.value] : undefined,
19+
_offset.value ? ['OFFSET', _offset.value] : undefined,
20+
].flat().join(' '))
21+
22+
return {
23+
sql,
24+
}
25+
}

app/composables/useTable.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export function useTable(tableName: MaybeRef<string>, cursorInstance: MaybeRef<D
8181
const primaryKeys = ref<string[]>([])
8282
const backend = useCursorBackend(cursor)
8383
const where = ref('')
84+
const { sql } = useSelect([], table, { where, limit, offset })
8485

8586
async function queryTableSchema(value: string) {
8687
if (backend.value === 'mysql')
@@ -114,7 +115,7 @@ export function useTable(tableName: MaybeRef<string>, cursorInstance: MaybeRef<D
114115
if (table.value && cursor.value) {
115116
try {
116117
isLoading.value[1] = true
117-
data.value = await cursor.value?.select<any[]>(`SELECT * FROM \`${table.value}\` ${where.value} LIMIT ${limit.value} OFFSET ${offset.value};`) ?? []
118+
data.value = await cursor.value?.select<any[]>(sql.value) ?? []
118119
}
119120
catch {
120121
data.value = []

app/pages/[id]/tables/index.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const selectedTable = ref('')
1111
const { data, limit, offset, count, structure, schema, primaryKeys, isLoading, backend, where, setup, execute } = useTable(selectedTable, cursor)
1212
const mode = ref('data')
1313
const columns = computed(() => structure.value.map(({ columnName }) => columnName))
14+
const changes = ref({})
1415
1516
const page = computed({
1617
get() {
@@ -23,6 +24,10 @@ const page = computed({
2324
2425
const pageTotal = computed(() => Math.floor(count.value / limit.value) + 1)
2526
27+
watch(selectedTable, () => {
28+
changes.value = {}
29+
})
30+
2631
async function onSelectTable() {
2732
page.value = 1
2833
await Promise.allSettled([setup(), execute()])
@@ -36,10 +41,7 @@ async function onPaginationChange(value: number) {
3641
}
3742
3843
async function onApplyFliters(value: string) {
39-
if (!value)
40-
where.value = ''
41-
else
42-
where.value = ['WHERE', value].join(' ')
44+
where.value = value
4345
await onPaginationChange(1)
4446
}
4547
</script>
@@ -76,7 +78,7 @@ async function onApplyFliters(value: string) {
7678
<Separator />
7779

7880
<div class="w-full h-0 flex-1 flex flex-col bg-zinc-50 -m-px">
79-
<VisTable editable :columns="columns" :records="data" :primary-keys="primaryKeys" />
81+
<VisTable v-model:changes="changes" editable :columns="columns" :records="data" :primary-keys="primaryKeys" />
8082
</div>
8183

8284
<Separator />

0 commit comments

Comments
 (0)