Skip to content

Commit 25a13f8

Browse files
committed
Adjust data structures to support grouping and aggregation.
1 parent 7161369 commit 25a13f8

File tree

13 files changed

+263
-206
lines changed

13 files changed

+263
-206
lines changed

components.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ export {}
77

88
declare module 'vue' {
99
export interface GlobalComponents {
10-
copy: typeof import('./src/components/list/fill copy.vue')['default']
10+
Aggs: typeof import('./src/components/layout/list/aggs.vue')['default']
11+
copy: typeof import('./src/components/layout/list/delete copy.vue')['default']
1112
Delete: typeof import('./src/components/layout/list/delete.vue')['default']
13+
Event: typeof import('./src/components/event.vue')['default']
1214
Fill: typeof import('./src/components/layout/list/fill.vue')['default']
1315
Fixed: typeof import('./src/components/layout/list/fixed.vue')['default']
1416
Group: typeof import('./src/components/function/group/group.vue')['default']

docs/TableDemo.vue

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
<template>
22
<div style="height: 400px">
3-
<iw-task-table :columns="columns" :events="events"></iw-task-table>
3+
<iw-task-table :columns="columns" :events="events" :layouts="layouts"></iw-task-table>
44
</div>
55
</template>
66

77
<script setup lang="ts">
8-
import { TableFilterGroupProps, TableSortProps } from '../src/components/props'
8+
import { TableDataFilterReq, TableDataSortReq, TableDataGroupReq, DataKind, LayoutKind, AggregateKind } from '../src/components/props'
99
10-
const columns = [{ name: 'no', pk: true, fillable: false }, { name: 'name' }, { name: 'phone' }, { name: 'addr' }, { name: 'time' }]
10+
const columns = [{ name: 'no', pk: true, fillable: false, dataKind: DataKind.NUMBER }, { name: 'name' }, { name: 'phone' }, { name: 'addr' }, { name: 'time' }]
11+
const layouts = [{
12+
id: "hi",
13+
title: "HI",
14+
layoutKind: LayoutKind.LIST,
15+
aggs: { name: AggregateKind.MIN }
16+
}]
1117
const events = {
12-
loadData: (filters: TableFilterGroupProps[], sorts: TableSortProps[], offsetRowNumber?: number, fetchRowNumber?: number) => {
18+
loadData: () => {
1319
return new Promise((resolve) => {
1420
setTimeout(() => {
15-
resolve(data)
21+
resolve({
22+
records: data,
23+
totalNumber: data.length,
24+
aggs: {"name": "Name1"}
25+
})
1626
}, 1000)
1727
})
1828
},
@@ -23,7 +33,7 @@ const events = {
2333
}, 1000)
2434
})
2535
},
26-
deleteData: (ids: string[]) => {
36+
deleteData: (deletedPks: string[]) => {
2737
return new Promise((resolve) => {
2838
setTimeout(() => {
2939
resolve(true)

src/assets/locales/en.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@
1212
},
1313
"group": {
1414
"agg": {
15-
"sum": "SUM"
15+
"count": "COUNT",
16+
"sum": "SUM",
17+
"max": "MAX VALUE",
18+
"min": "MIN VALUE",
19+
"distinct": "DISTINCT COUNT",
20+
"avg": "AVERAGE",
21+
"median": "MEDIAN VALUE",
22+
"stddev": "STDDEV VALUE"
1623
}
1724
}
1825
},

src/assets/locales/zh-CN.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@
1212
},
1313
"group": {
1414
"agg": {
15-
"sum": "求和"
15+
"count": "合计",
16+
"sum": "求和",
17+
"max": "最大值",
18+
"min": "最小值",
19+
"distinct": "去重合计",
20+
"avg": "平均值",
21+
"median": "中值",
22+
"stddev": "标准差值"
1623
}
1724
}
1825
},

src/components/conf.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as iconSvg from "../assets/icon"
22
import locales from '../locales'
3-
import { LayoutKind, SizeKind, TableDataFilterReq, TableDataGroupReq, TableDataGroupResp, TableDataResp, TableDataSliceReq, TableDataSortReq, TableProps } from "./props"
3+
import { AggregateKind, LayoutKind, SizeKind, TableDataFilterReq, TableDataGroupReq, TableDataGroupResp, TableDataResp, TableDataSliceReq, TableDataSortReq, TableProps } from "./props"
44

55
const { t } = locales.global
66

@@ -15,20 +15,24 @@ export interface TableStyleConf {
1515
}
1616

1717
export interface TableLayoutConf {
18+
id: string
1819
title: string
1920
layoutKind: LayoutKind
2021
icon: string
22+
sort: number
2123
dateColumn?: { start: string, end: string }
2224
fixedColumnIdx: number,
2325
filters?: TableDataFilterReq[]
2426
sorts?: TableDataSortReq[]
2527
group?: TableDataGroupReq
28+
aggs?: { [key: string]: AggregateKind }
2629
slice?: TableDataSliceReq
2730
data?: TableDataResp | TableDataGroupResp[]
2831
}
2932

3033
export function initConf(props: TableProps): [TableBasicConf, { [key: string]: TableLayoutConf }, TableStyleConf] {
3134
let layouts: { [key: string]: TableLayoutConf } = {}
35+
let sort = 0
3236
if (props.layouts) {
3337
props.layouts.forEach(layout => {
3438
let icon = ''
@@ -49,21 +53,26 @@ export function initConf(props: TableProps): [TableBasicConf, { [key: string]: T
4953
icon = iconSvg.TEXT
5054
}
5155
layouts[layout.id] = {
56+
id: layout.id,
5257
title: layout.title,
5358
layoutKind: layout.layoutKind,
5459
icon: icon,
60+
sort: sort++,
5561
dateColumn: layout.dateColumn,
5662
fixedColumnIdx: props.columns.findIndex(column => column.name === layout.fixedColumn) ?? -1,
5763
filters: layout.filters,
5864
sorts: layout.sorts,
5965
group: layout.group,
66+
aggs: layout.aggs
6067
}
6168
})
6269
} else {
6370
layouts['default'] = {
71+
id: 'default',
6472
title: t('layout.title.default'),
6573
layoutKind: LayoutKind.LIST,
6674
icon: iconSvg.TEXT,
75+
sort: sort++,
6776
fixedColumnIdx: -1,
6877
filters: [],
6978
sorts: [],

src/components/event.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/components/function/group/group.ts

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,56 @@ export interface GroupAggItem {
77
title: string
88
}
99

10-
export function groupAggMappingByDataKind(dataKind: DataKind): GroupAggItem[] {
10+
export function translateGroupAgg(aggKind: AggregateKind): string {
11+
switch (aggKind) {
12+
case AggregateKind.SUM:
13+
return t('function.group.agg.sum')
14+
case AggregateKind.COUNT: return t('function.group.agg.count')
15+
case AggregateKind.MIN: return t('function.group.agg.min')
16+
case AggregateKind.MAX: return t('function.group.agg.max')
17+
case AggregateKind.AVG: return t('function.group.agg.avg')
18+
case AggregateKind.MEDIAN: return t('function.group.agg.median')
19+
case AggregateKind.STDDEV: return t('function.group.agg.stddev')
20+
case AggregateKind.DISTINCT: return t('function.group.agg.distinct')
21+
}
22+
}
23+
24+
export function showGroupAggMappingByDataKind(dataKind: DataKind): GroupAggItem[] {
25+
let items = [
26+
{ code: AggregateKind.COUNT, title: translateGroupAgg(AggregateKind.COUNT) },
27+
]
1128
switch (dataKind) {
1229
case DataKind.NUMBER:
13-
return [
14-
{ code: AggregateKind.SUM, title: t('function.group.agg.sum') },
15-
]
30+
case DataKind.AMOUNT:
31+
items.push(...[
32+
{ code: AggregateKind.MAX, title: translateGroupAgg(AggregateKind.MAX) },
33+
{ code: AggregateKind.MIN, title: translateGroupAgg(AggregateKind.MIN) },
34+
{ code: AggregateKind.DISTINCT, title: translateGroupAgg(AggregateKind.DISTINCT) }
35+
])
36+
break
37+
case DataKind.TEXT:
38+
case DataKind.TEXTAREA:
39+
items.push(...[
40+
{ code: AggregateKind.SUM, title: translateGroupAgg(AggregateKind.SUM) },
41+
{ code: AggregateKind.AVG, title: translateGroupAgg(AggregateKind.AVG) },
42+
{ code: AggregateKind.MEDIAN, title: translateGroupAgg(AggregateKind.MEDIAN) },
43+
{ code: AggregateKind.STDDEV, title: translateGroupAgg(AggregateKind.STDDEV) },
44+
{ code: AggregateKind.MAX, title: translateGroupAgg(AggregateKind.MAX) },
45+
{ code: AggregateKind.MIN, title: translateGroupAgg(AggregateKind.MIN) },
46+
{ code: AggregateKind.DISTINCT, title: translateGroupAgg(AggregateKind.DISTINCT) }
47+
])
48+
break
1649
case DataKind.DATE:
17-
return [
18-
]
19-
default:
20-
return []
50+
case DataKind.DATETIME:
51+
case DataKind.TIME:
52+
// TODO
53+
break
54+
case DataKind.FILE:
55+
case DataKind.IMAGE:
56+
// TODO
57+
break
2158
}
59+
return items
2260

23-
// export enum AggregateKind {
24-
// SUM = 'SUM',
25-
// COUNT = 'COUNT',
26-
// MIN = 'MIN',
27-
// MAX = 'MAX',
28-
// AVG = 'AVG',
29-
// MEDIAN = 'MEDIAN',
30-
// STDDEV = 'STDDEV',
31-
// DISTINCT = 'DISTINCT',
32-
// // TODO
33-
// }
34-
35-
// export enum DataKind {
36-
// TEXT = 'TEXT',
37-
// TEXTAREA = 'TEXTAREA',
38-
// NUMBER = 'NUMBER',
39-
// BOOLEAN = 'BOOLEAN',
40-
// FILE = 'FILE',
41-
// IMAGE = 'IMAGE',
42-
// AMOUNT = 'AMOUNT',
43-
// SELECT = 'SELECT',
44-
// MULTISELECT = 'MULTISELECT',
45-
// CHECKBOX = 'CHECKBOX',
46-
// DATE = 'DATE',
47-
// DATETIME = 'DATETIME',
48-
// TIME = 'TIME',
49-
// EMAIL = 'EMAIL',
50-
// URL = 'URL',
51-
// PHONE = 'PHONE',
52-
// PASSWORD = 'PASSWORD',
53-
// }
5461

5562
}

src/components/layout/list/aggs.vue

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
import { showGroupAggMappingByDataKind, translateGroupAgg } from '../../function/group/group';
3+
import { AggregateKind, TableDataResp } from '../../props';
4+
import { ListColumnConf, ListStyleConf } from './conf';
5+
6+
const props = defineProps<{
7+
stylesConf: ListStyleConf
8+
columnsConf: ListColumnConf[]
9+
layoutAggs: { [key: string]: AggregateKind }
10+
dataBasic: TableDataResp
11+
pkColumnName: string
12+
setColumnStyles: (colIdx: number) => any
13+
}>()
14+
</script>
15+
16+
<template>
17+
<div :className="props.stylesConf.rowClass + ' iw-list-row iw-list-agg-row'">
18+
<template v-for="(column, colIndex) in props.columnsConf" :key="column.name">
19+
<div :className="props.stylesConf.cellClass + ' iw-list-cell iw-list-row-agg-cell'" :data-column-name="column.name"
20+
:style="props.setColumnStyles(colIndex)" v-if="column.name == props.pkColumnName">
21+
<span class="iw-list-row-agg-cell__agg">{{ $t('function.group.agg.count') }}</span>
22+
<span class="iw-list-row-agg-cell__value">{{ props.dataBasic.totalNumber }}</span>
23+
</div>
24+
<div :className="props.stylesConf.cellClass + ' iw-list-cell iw-list-row-agg-cell'" :data-column-name="column.name"
25+
:style="props.setColumnStyles(colIndex)" v-else>
26+
<template v-if="props.layoutAggs && props.layoutAggs[column.name]">
27+
<span class="iw-list-row-agg-cell__agg">{{ translateGroupAgg(props.layoutAggs[column.name]) }}</span>
28+
<span class="iw-list-row-agg-cell__value">{{ props.dataBasic.aggs[column.name] }}</span>
29+
</template>
30+
<select v-else>
31+
<option v-for="aggItem in showGroupAggMappingByDataKind(column.dataKind)" :value="aggItem.code"> {{
32+
aggItem.title }}</option>
33+
</select>
34+
</div>
35+
</template>
36+
</div>
37+
</template>

src/components/layout/list/delete.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const props = defineProps<{
1010
let closeContextMenuFun = inject(FN_CLOSE_CONTEXT_MENU)
1111
let deleteDataFun = inject(FN_DELETE_DATA)
1212
13-
const deleteData = (event: MouseEvent) => {
13+
const deleteData = () => {
1414
// @ts-ignore
1515
closeContextMenuFun()
1616
// @ts-ignore

0 commit comments

Comments
 (0)