@@ -288,6 +288,195 @@ export type CustomColumnType<RecordType> = ColumnType<RecordType> & {
288
288
cellColorFn : CellColorViewType ;
289
289
} ;
290
290
291
+ /**
292
+ * Helper: build a mapping of column -> sort order
293
+ */
294
+ function computeSortMap ( sort : SortValue [ ] ) : Map < string | undefined , SortOrder > {
295
+ return new Map ( sort . map ( ( s ) => [ s . column , s . desc ? "descend" : "ascend" ] ) ) ;
296
+ }
297
+
298
+ /**
299
+ * Helper: sort columns by fixed position and dynamic config order
300
+ */
301
+ function orderColumns (
302
+ columns : Array < RawColumnType > ,
303
+ dynamicColumn : boolean ,
304
+ dynamicColumnConfig : string [ ] ,
305
+ ) : Array < RawColumnType > {
306
+ const dynamicPositions : Record < string , number > = { } ;
307
+ if ( dynamicColumn && dynamicColumnConfig . length > 0 ) {
308
+ dynamicColumnConfig . forEach ( ( name , idx ) => {
309
+ dynamicPositions [ name ] = idx ;
310
+ } ) ;
311
+ }
312
+ return _ . sortBy ( columns , ( c ) => {
313
+ if ( c . fixed === "left" ) return - 1 ;
314
+ if ( c . fixed === "right" ) return Number . MAX_SAFE_INTEGER ;
315
+ if ( dynamicColumn && dynamicColumnConfig . length > 0 ) {
316
+ const key = c . isCustom ? c . title : c . dataIndex ;
317
+ const pos = dynamicPositions [ key ] ;
318
+ if ( typeof pos === "number" ) return pos ;
319
+ }
320
+ return 0 ;
321
+ } ) ;
322
+ }
323
+
324
+ /**
325
+ * Helper: should include a column based on hide and dynamic config gating
326
+ */
327
+ function shouldIncludeColumn (
328
+ column : RawColumnType ,
329
+ enableColumnSetting : boolean ,
330
+ dynamicColumn : boolean ,
331
+ dynamicColumnConfig : string [ ] ,
332
+ ) : boolean {
333
+ if (
334
+ columnHide ( {
335
+ hide : column . hide ,
336
+ tempHide : column . tempHide ,
337
+ enableColumnSetting,
338
+ } )
339
+ ) {
340
+ return false ;
341
+ }
342
+ if (
343
+ dynamicColumn &&
344
+ dynamicColumnConfig . length > 0 &&
345
+ ! dynamicColumnConfig . includes ( column . isCustom ? column . title : column . dataIndex )
346
+ ) {
347
+ return false ;
348
+ }
349
+ return true ;
350
+ }
351
+
352
+ /**
353
+ * Helper: aggregate data for a specific column
354
+ */
355
+ function extractAggrForColumn (
356
+ dataIndex : string ,
357
+ columnsAggrData : ColumnsAggrData ,
358
+ ) {
359
+ const aggr = columnsAggrData [ dataIndex ] as any ;
360
+ const candidateTags : string [ ] = Array . isArray ( aggr ?. uniqueTags ) ? aggr . uniqueTags : [ ] ;
361
+ const candidateStatus : { text : string ; status : StatusType } [ ] = Array . isArray ( aggr ?. uniqueStatus )
362
+ ? aggr . uniqueStatus
363
+ : [ ] ;
364
+ const uniqueValues : any [ ] = Array . isArray ( aggr ?. uniqueValues ) ? aggr . uniqueValues : [ ] ;
365
+ return { candidateTags, candidateStatus, uniqueValues } ;
366
+ }
367
+
368
+ /**
369
+ * Helper: build filter props for antd Table column
370
+ */
371
+ function buildFilterProps (
372
+ dataIndex : string ,
373
+ filterable : boolean ,
374
+ candidateTags : any [ ] ,
375
+ uniqueValues : any [ ] ,
376
+ ) {
377
+ if ( ! filterable ) return { } ;
378
+ const candidates = ( Array . isArray ( candidateTags ) && candidateTags . length > 0
379
+ ? candidateTags
380
+ : Array . isArray ( uniqueValues ) && uniqueValues . length > 0
381
+ ? uniqueValues
382
+ : [ ] )
383
+ . slice ( 0 , 100 ) ;
384
+ return {
385
+ filters : candidates . map ( ( v ) => ( { text : String ( v ) , value : v } ) ) ,
386
+ onFilter : ( value : any , record : any ) => String ( record [ dataIndex ] ?? "" ) === String ( value ?? "" ) ,
387
+ } as const ;
388
+ }
389
+
390
+ /**
391
+ * Helper: build sorter props
392
+ */
393
+ function buildSorterProps (
394
+ column : RawColumnType ,
395
+ sortOrder : SortOrder | undefined ,
396
+ multiplePriority : number ,
397
+ ) {
398
+ if ( ! column . sortable ) return { } ;
399
+ const sorter = {
400
+ multiple : multiplePriority ,
401
+ compare :
402
+ column . columnType === 'date' || column . columnType === 'dateTime'
403
+ ? ( a : any , b : any ) => {
404
+ return dayjs ( a [ column . dataIndex ] as string ) . unix ( ) - dayjs ( b [ column . dataIndex ] as string ) . unix ( ) ;
405
+ }
406
+ : undefined ,
407
+ } as const ;
408
+ return {
409
+ sorter,
410
+ sortOrder,
411
+ showSorterTooltip : false ,
412
+ } as const ;
413
+ }
414
+
415
+ /**
416
+ * Helper: build static style props
417
+ */
418
+ function buildStyleProps ( column : RawColumnType ) {
419
+ const style = {
420
+ background : column . background ,
421
+ margin : column . margin ,
422
+ text : column . text ,
423
+ border : column . border ,
424
+ radius : column . radius ,
425
+ textSize : column . textSize ,
426
+ textWeight : column . textWeight ,
427
+ fontStyle : column . fontStyle ,
428
+ fontFamily : column . fontFamily ,
429
+ borderWidth : column . borderWidth ,
430
+ } as TableColumnStyleType ;
431
+ const linkStyle = {
432
+ text : column . linkColor ,
433
+ hoverText : column . linkHoverColor ,
434
+ activeText : column . linkActiveColor ,
435
+ } as TableColumnLinkStyleType ;
436
+ return { style, linkStyle } ;
437
+ }
438
+
439
+ /**
440
+ * Helper: build render function with minimal closure
441
+ */
442
+ function buildRenderFn (
443
+ column : RawColumnType ,
444
+ size : string ,
445
+ candidateTags : string [ ] ,
446
+ candidateStatus : { text : string ; status : StatusType } [ ] ,
447
+ onTableEvent : ( eventName : any ) => void ,
448
+ initialColumns : { label : string ; value : string } [ ] ,
449
+ ) {
450
+ return ( value : any , record : RecordType , index : number ) => {
451
+ const row = _ . omit ( record , OB_ROW_ORI_INDEX ) ;
452
+ return column
453
+ . render (
454
+ {
455
+ currentCell : value ,
456
+ currentRow : row ,
457
+ currentIndex : index ,
458
+ currentOriginalIndex : tryToNumber ( record [ OB_ROW_ORI_INDEX ] ) ,
459
+ initialColumns,
460
+ } ,
461
+ String ( record [ OB_ROW_ORI_INDEX ] )
462
+ )
463
+ . getView ( )
464
+ . view ( {
465
+ tableSize : size ,
466
+ candidateTags,
467
+ candidateStatus,
468
+ textOverflow : column . textOverflow ,
469
+ cellTooltip : column . cellTooltip ( {
470
+ currentCell : value ,
471
+ currentRow : row ,
472
+ currentIndex : index ,
473
+ } ) ,
474
+ onTableEvent,
475
+ cellIndex : `${ column . dataIndex } -${ index } ` ,
476
+ } ) ;
477
+ } ;
478
+ }
479
+
291
480
/**
292
481
* convert column in raw format into antd format
293
482
*/
@@ -303,134 +492,51 @@ export function columnsToAntdFormat(
303
492
) : Array < CustomColumnType < RecordType > > {
304
493
const customColumns = columns . filter ( col => col . isCustom ) . map ( col => col . dataIndex ) ;
305
494
const initialColumns = getInitialColumns ( columnsAggrData , customColumns ) ;
306
- const sortMap : Map < string | undefined , SortOrder > = new Map (
307
- sort . map ( ( s ) => [ s . column , s . desc ? "descend" : "ascend" ] )
308
- ) ;
309
- const sortedColumns = _ . sortBy ( columns , ( c ) => {
310
- if ( c . fixed === "left" ) {
311
- return - 1 ;
312
- } else if ( c . fixed === "right" ) {
313
- return Number . MAX_SAFE_INTEGER ;
314
- } else if ( dynamicColumnConfig . length > 0 ) {
315
- // sort by dynamic config array
316
- const index = dynamicColumnConfig . indexOf ( c . isCustom ? c . title : c . dataIndex ) ;
317
- if ( index >= 0 ) {
318
- return index ;
319
- }
320
- }
321
- return 0 ;
322
- } ) ;
323
- return sortedColumns . flatMap ( ( column , mIndex ) => {
324
- if (
325
- columnHide ( {
326
- hide : column . hide ,
327
- tempHide : column . tempHide ,
328
- enableColumnSetting : enableColumnSetting ,
329
- } )
330
- ) {
331
- return [ ] ;
332
- }
333
- if (
334
- dynamicColumn &&
335
- dynamicColumnConfig . length > 0 &&
336
- ! dynamicColumnConfig . includes ( column . isCustom ? column . title : column . dataIndex )
337
- ) {
338
- return [ ] ;
495
+ const sortMap = computeSortMap ( sort ) ;
496
+ const sortedColumns = orderColumns ( columns , dynamicColumn , dynamicColumnConfig ) ;
497
+
498
+ const result : Array < CustomColumnType < RecordType > > = [ ] ;
499
+
500
+ sortedColumns . forEach ( ( column , mIndex ) => {
501
+ if ( ! shouldIncludeColumn ( column , enableColumnSetting , dynamicColumn , dynamicColumnConfig ) ) {
502
+ return ;
339
503
}
340
- const tags = ( ( columnsAggrData [ column . dataIndex ] ?? { } ) . uniqueTags ?? [ ] ) as string [ ] ;
341
- const status = ( ( columnsAggrData [ column . dataIndex ] ?? { } ) . uniqueStatus ?? [ ] ) as {
342
- text : string ;
343
- status : StatusType ;
344
- } [ ] ;
345
- const uniqueValues = ( columnsAggrData [ column . dataIndex ] as any ) ?. uniqueValues as any [ ] ?? [ ] ;
346
- const title = renderTitle ( { title : column . title , tooltip : column . titleTooltip } ) ;
347
504
348
- const filterProps = column . filterable
349
- ? {
350
- filters : ( Array . isArray ( tags ) && tags . length > 0
351
- ? tags
352
- : Array . isArray ( uniqueValues ) && uniqueValues . length > 0
353
- ? uniqueValues
354
- : [ ] )
355
- . slice ( 0 , 100 )
356
- . map ( ( v ) => ( { text : String ( v ) , value : v } ) ) ,
357
-
358
- onFilter : ( value : any , record : any ) => String ( record [ column . dataIndex ] ?? "" ) === String ( value ?? "" ) ,
359
- }
360
- : { } ;
505
+ const { candidateTags, candidateStatus, uniqueValues } = extractAggrForColumn ( column . dataIndex , columnsAggrData ) ;
506
+ const title = renderTitle ( { title : column . title , tooltip : column . titleTooltip } ) ;
507
+ const filterProps = buildFilterProps ( column . dataIndex , column . filterable , candidateTags , uniqueValues ) ;
508
+ const { style, linkStyle } = buildStyleProps ( column ) ;
509
+ const multiplePriority = ( sortedColumns . length - mIndex ) + 1 ;
510
+ const sorterProps = buildSorterProps ( column , sortMap . get ( column . dataIndex ) , multiplePriority ) ;
361
511
362
- return {
363
- key : `${ column . dataIndex } - ${ mIndex } ` ,
512
+ const antdColumn : CustomColumnType < RecordType > = {
513
+ key : `${ column . dataIndex } ` ,
364
514
title : column . showTitle ? title : '' ,
365
515
titleText : column . title ,
366
516
dataIndex : column . dataIndex ,
367
517
align : column . align ,
368
518
width : column . autoWidth === "auto" ? 0 : column . width ,
369
519
fixed : column . fixed === "close" ? false : column . fixed ,
370
- style : {
371
- background : column . background ,
372
- margin : column . margin ,
373
- text : column . text ,
374
- border : column . border ,
375
- radius : column . radius ,
376
- textSize : column . textSize ,
377
- textWeight : column . textWeight ,
378
- fontStyle :column . fontStyle ,
379
- fontFamily : column . fontFamily ,
380
- borderWidth : column . borderWidth ,
381
- } ,
382
- linkStyle : {
383
- text : column . linkColor ,
384
- hoverText : column . linkHoverColor ,
385
- activeText : column . linkActiveColor ,
386
- } ,
520
+ style,
521
+ linkStyle,
387
522
cellColorFn : column . cellColor ,
388
523
onWidthResize : column . onWidthResize ,
389
- render : ( value : any , record : RecordType , index : number ) => {
390
- const row = _ . omit ( record , OB_ROW_ORI_INDEX ) ;
391
- return column
392
- . render (
393
- {
394
- currentCell : value ,
395
- currentRow : row ,
396
- currentIndex : index ,
397
- currentOriginalIndex : tryToNumber ( record [ OB_ROW_ORI_INDEX ] ) ,
398
- initialColumns,
399
- } ,
400
- String ( record [ OB_ROW_ORI_INDEX ] )
401
- )
402
- . getView ( )
403
- . view ( {
404
- tableSize : size ,
405
- candidateTags : tags ,
406
- candidateStatus : status ,
407
- textOverflow : column . textOverflow ,
408
- cellTooltip : column . cellTooltip ( {
409
- currentCell : value ,
410
- currentRow : row ,
411
- currentIndex : index ,
412
- } ) ,
413
- onTableEvent,
414
- cellIndex : `${ column . dataIndex } -${ index } ` ,
415
- } ) ;
416
- } ,
417
- ...( column . sortable
418
- ? {
419
- sorter : {
420
- multiple : ( sortedColumns . length - mIndex ) + 1 ,
421
- compare : column . columnType === 'date' || column . columnType === 'dateTime'
422
- ? ( a : any , b : any ) => {
423
- return dayjs ( a [ column . dataIndex ] as string ) . unix ( ) - dayjs ( b [ column . dataIndex ] as string ) . unix ( ) ;
424
- }
425
- : undefined
426
- } ,
427
- sortOrder : sortMap . get ( column . dataIndex ) ,
428
- showSorterTooltip : false ,
429
- }
430
- : { } ) ,
431
- ...filterProps ,
524
+ render : buildRenderFn (
525
+ column ,
526
+ size ,
527
+ candidateTags ,
528
+ candidateStatus ,
529
+ onTableEvent ,
530
+ initialColumns ,
531
+ ) ,
532
+ ...( sorterProps as any ) ,
533
+ ...( filterProps as any ) ,
432
534
} as any ;
535
+
536
+ result . push ( antdColumn ) ;
433
537
} ) ;
538
+
539
+ return result ;
434
540
}
435
541
436
542
function getSortValue ( sortResult : SorterResult < RecordType > ) {
0 commit comments