1
+ import _ from "lodash" ;
2
+ import { fromRecord , Node , RecordNode , ValueAndMsg , withFunction } from "lowcoder-core" ;
3
+ import { lastValueIfEqual , shallowEqual } from "util/objectUtils" ;
4
+ import { JSONObject } from "util/jsonTypes" ;
5
+ import { getPageSize } from "../paginationControl" ;
6
+ import {
7
+ getOriDisplayData ,
8
+ getColumnsAggr ,
9
+ OB_ROW_ORI_INDEX ,
10
+ RecordType ,
11
+ sortData ,
12
+ tranToTableRecord ,
13
+ } from "../tableUtils" ;
14
+ import type { SortValue } from "../tableTypes" ;
15
+ import type { TableImplComp } from "../tableComp" ;
16
+
17
+ export function buildSortedDataNode ( comp : TableImplComp ) {
18
+ const nodes : {
19
+ data : Node < JSONObject [ ] > ;
20
+ sort : Node < SortValue [ ] > ;
21
+ dataIndexes : RecordNode < Record < string , Node < string > > > ;
22
+ sortables : RecordNode < Record < string , Node < ValueAndMsg < boolean > > > > ;
23
+ withParams : RecordNode < _ . Dictionary < any > > ;
24
+ } = {
25
+ data : comp . children . data . exposingNode ( ) ,
26
+ sort : comp . children . sort . node ( ) ,
27
+ dataIndexes : comp . children . columns . getColumnsNode ( "dataIndex" ) ,
28
+ sortables : comp . children . columns . getColumnsNode ( "sortable" ) ,
29
+ withParams : comp . children . columns . withParamsNode ( ) ,
30
+ } ;
31
+
32
+ const sortedDataNode = withFunction ( fromRecord ( nodes ) , ( input ) => {
33
+ const { data, sort, dataIndexes, sortables } = input ;
34
+ const sortColumns = _ ( dataIndexes )
35
+ . mapValues ( ( dataIndex , idx ) => ( { sortable : ! ! sortables [ idx ] } ) )
36
+ . mapKeys ( ( sortable , idx ) => dataIndexes [ idx ] )
37
+ . value ( ) ;
38
+ const dataColumns = _ ( dataIndexes )
39
+ . mapValues ( ( dataIndex , idx ) => ( {
40
+ dataIndex,
41
+ render : input . withParams [ idx ] as any ,
42
+ } ) )
43
+ . value ( ) ;
44
+
45
+ const updatedData : Array < RecordType > = data . map ( ( row , index ) => ( {
46
+ ...row ,
47
+ [ OB_ROW_ORI_INDEX ] : index + "" ,
48
+ } ) ) ;
49
+
50
+ const updatedDataMap : Record < string , RecordType > = { } ;
51
+ updatedData . forEach ( ( row ) => {
52
+ updatedDataMap [ row [ OB_ROW_ORI_INDEX ] ] = row ;
53
+ } ) ;
54
+
55
+ const originalData = getOriDisplayData ( updatedData , 1000 , Object . values ( dataColumns ) ) ;
56
+ const sorted = sortData ( originalData , sortColumns , sort ) ;
57
+
58
+ const newData = sorted . map ( ( row ) => ( {
59
+ ...row ,
60
+ ...updatedDataMap [ row [ OB_ROW_ORI_INDEX ] ] ,
61
+ } ) ) ;
62
+ return newData ;
63
+ } ) ;
64
+
65
+ return lastValueIfEqual ( comp , "sortedDataNode" , [ sortedDataNode , nodes ] as const , ( a , b ) =>
66
+ shallowEqual ( a [ 1 ] , b [ 1 ] )
67
+ ) [ 0 ] ;
68
+ }
69
+
70
+ export function buildFilteredDataNode ( comp : TableImplComp ) {
71
+ const nodes = {
72
+ data : buildSortedDataNode ( comp ) ,
73
+ } ;
74
+ const filteredDataNode = withFunction ( fromRecord ( nodes ) , ( { data } ) => {
75
+ // No pre-filtering here; AntD header filters are handled internally by Table
76
+ return data . map ( ( row ) => tranToTableRecord ( row , ( row as any ) [ OB_ROW_ORI_INDEX ] ) ) ;
77
+ } ) ;
78
+ return lastValueIfEqual ( comp , "filteredDataNode" , [ filteredDataNode , nodes ] as const , ( a , b ) =>
79
+ shallowEqual ( a [ 1 ] , b [ 1 ] )
80
+ ) [ 0 ] ;
81
+ }
82
+
83
+ export function buildOriDisplayDataNode ( comp : TableImplComp ) {
84
+ const nodes = {
85
+ data : buildFilteredDataNode ( comp ) ,
86
+ showSizeChanger : comp . children . pagination . children . showSizeChanger . node ( ) ,
87
+ pageSize : comp . children . pagination . children . pageSize . node ( ) ,
88
+ pageSizeOptions : comp . children . pagination . children . pageSizeOptions . node ( ) ,
89
+ changablePageSize : comp . children . pagination . children . changeablePageSize . node ( ) ,
90
+ withParams : comp . children . columns . withParamsNode ( ) ,
91
+ dataIndexes : comp . children . columns . getColumnsNode ( "dataIndex" ) ,
92
+ } ;
93
+ const resNode = withFunction ( fromRecord ( nodes ) , ( input ) => {
94
+ const columns = _ ( input . dataIndexes )
95
+ . mapValues ( ( dataIndex , idx ) => ( {
96
+ dataIndex,
97
+ render : input . withParams [ idx ] ,
98
+ } ) )
99
+ . value ( ) ;
100
+ const pageSize = getPageSize (
101
+ input . showSizeChanger . value ,
102
+ input . pageSize . value ,
103
+ input . pageSizeOptions . value ,
104
+ input . changablePageSize
105
+ ) ;
106
+ return getOriDisplayData ( input . data , pageSize , Object . values ( columns ) ) ;
107
+ } ) ;
108
+ return lastValueIfEqual ( comp , "oriDisplayDataNode" , [ resNode , nodes ] as const , ( a , b ) =>
109
+ shallowEqual ( a [ 1 ] , b [ 1 ] )
110
+ ) [ 0 ] ;
111
+ }
112
+
113
+ export function buildColumnAggrNode ( comp : TableImplComp ) {
114
+ const nodes = {
115
+ oriDisplayData : buildOriDisplayDataNode ( comp ) ,
116
+ withParams : comp . children . columns . withParamsNode ( ) ,
117
+ dataIndexes : comp . children . columns . getColumnsNode ( "dataIndex" ) ,
118
+ } ;
119
+ const resNode = withFunction ( fromRecord ( nodes ) , ( input ) => {
120
+ const dataIndexWithParamsDict = _ ( input . dataIndexes )
121
+ . mapValues ( ( dataIndex , idx ) => input . withParams [ idx ] )
122
+ . mapKeys ( ( withParams , idx ) => input . dataIndexes [ idx ] )
123
+ . value ( ) ;
124
+ const res = getColumnsAggr ( input . oriDisplayData , dataIndexWithParamsDict ) ;
125
+ return res ;
126
+ } ) ;
127
+ return lastValueIfEqual ( comp , "columnAggrNode" , [ resNode , nodes ] as const , ( a , b ) =>
128
+ shallowEqual ( a [ 1 ] , b [ 1 ] )
129
+ ) [ 0 ] ;
130
+ }
0 commit comments