@@ -2,14 +2,36 @@ import { Table, Text } from '@components';
22import React , { useEffect , useMemo , useRef , useState } from 'react' ;
33import styled from 'styled-components' ;
44
5+ import { ExtendedSchemaFields } from '@app/entityV2/dataset/profile/schema/utils/types' ;
56import SchemaFieldDrawer from '@app/entityV2/shared/tabs/Dataset/Schema/components/SchemaFieldDrawer/SchemaFieldDrawer' ;
67import { useGetEntityWithSchema } from '@app/entityV2/shared/tabs/Dataset/Schema/useGetEntitySchema' ;
78import useKeyboardControls from '@app/entityV2/shared/tabs/Dataset/Schema/useKeyboardControls' ;
89import { decimalToPercentStr } from '@app/entityV2/shared/tabs/Dataset/Schema/utils/statsUtil' ;
10+ import {
11+ createStatsOnlyField ,
12+ filterColumnStatsByQuery ,
13+ flattenFields ,
14+ handleRowScrollIntoView ,
15+ mapToSchemaFields ,
16+ } from '@app/entityV2/shared/tabs/Dataset/Stats/StatsTabV2/columnStats/ColumnStatsTable.utils' ;
917import { useGetColumnStatsColumns } from '@app/entityV2/shared/tabs/Dataset/Stats/StatsTabV2/columnStats/useGetColumnStatsColumns' ;
1018import { isPresent } from '@app/entityV2/shared/tabs/Dataset/Stats/StatsTabV2/utils' ;
1119import { downgradeV2FieldPath , groupByFieldPath } from '@src/app/entityV2/dataset/profile/schema/utils/utils' ;
12- import { DatasetFieldProfile } from '@src/types.generated' ;
20+
21+ // Local type definitions since generated types aren't available
22+ interface DatasetFieldProfile {
23+ fieldPath : string ;
24+ nullCount ?: number | null ;
25+ nullProportion ?: number | null ;
26+ uniqueCount ?: number | null ;
27+ min ?: string | null ;
28+ max ?: string | null ;
29+ }
30+
31+ // Extended type that includes the fieldPath property we know exists
32+ interface ExtendedSchemaFieldsWithFieldPath extends ExtendedSchemaFields {
33+ fieldPath : string ;
34+ }
1335
1436const EmptyContainer = styled . div `
1537 display: flex;
@@ -22,38 +44,49 @@ const EmptyContainer = styled.div`
2244` ;
2345
2446interface Props {
25- columnStats : Array < DatasetFieldProfile > ;
47+ columnStats : DatasetFieldProfile [ ] ;
2648 searchQuery : string ;
2749}
2850
29- const ColumnStatsTable = ( { columnStats, searchQuery } : Props ) => {
51+ function ColumnStatsTable ( { columnStats, searchQuery } : Props ) {
3052 const { entityWithSchema } = useGetEntityWithSchema ( ) ;
31- const schemaMetadata : any = entityWithSchema ?. schemaMetadata || undefined ;
32- const editableSchemaMetadata : any = entityWithSchema ?. editableSchemaMetadata || undefined ;
33- const fields = schemaMetadata ?. fields ;
53+ const rawFields = entityWithSchema ?. schemaMetadata ?. fields ;
54+
55+ const fields = useMemo ( ( ) => {
56+ return rawFields ? mapToSchemaFields ( rawFields ) : [ ] ;
57+ } , [ rawFields ] ) ;
3458
3559 const columnStatsTableData = useMemo (
3660 ( ) =>
37- columnStats . map ( ( doc ) => ( {
38- column : downgradeV2FieldPath ( doc . fieldPath ) ,
39- type : fields ?. find ( ( field ) => field . fieldPath === doc . fieldPath ) ?. type ,
40- nullPercentage : isPresent ( doc . nullProportion ) && decimalToPercentStr ( doc . nullProportion , 2 ) ,
41- uniqueValues : isPresent ( doc . uniqueCount ) && doc . uniqueCount . toString ( ) ,
42- min : doc . min ,
43- max : doc . max ,
61+ columnStats . map ( ( stat ) => ( {
62+ column : downgradeV2FieldPath ( stat . fieldPath ) ,
63+ originalFieldPath : stat . fieldPath ,
64+ type : fields . find ( ( field ) => field . fieldPath === stat . fieldPath ) ?. type ,
65+ nullPercentage : isPresent ( stat . nullProportion ) && decimalToPercentStr ( stat . nullProportion , 2 ) ,
66+ uniqueValues : isPresent ( stat . uniqueCount ) && stat . uniqueCount . toString ( ) ,
67+ min : stat . min ,
68+ max : stat . max ,
4469 } ) ) || [ ] ,
4570 [ columnStats , fields ] ,
4671 ) ;
4772
4873 const [ expandedDrawerFieldPath , setExpandedDrawerFieldPath ] = useState < string | null > ( null ) ;
4974
5075 const rows = useMemo ( ( ) => {
51- return groupByFieldPath ( fields ) ;
52- } , [ fields ] ) ;
76+ const schemaFields = fields ;
5377
54- const filteredData = columnStatsTableData . filter ( ( columnStat ) =>
55- columnStat . column ?. toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ,
56- ) ;
78+ // Add fields from column stats that don't exist in schema
79+ const statsOnlyFields = columnStats
80+ . filter ( ( stat ) => ! schemaFields . find ( ( field ) => field . fieldPath === stat . fieldPath ) )
81+ . map ( createStatsOnlyField ) ;
82+
83+ const combinedFields = [ ...schemaFields , ...statsOnlyFields ] ;
84+ const groupedFields = groupByFieldPath ( combinedFields as any ) ;
85+
86+ return flattenFields ( groupedFields ) ;
87+ } , [ fields , columnStats ] ) ;
88+
89+ const filteredData = filterColumnStatsByQuery ( columnStatsTableData , searchQuery ) ;
5790
5891 const columnStatsColumns = useGetColumnStatsColumns ( {
5992 tableData : columnStatsTableData ,
@@ -72,7 +105,9 @@ const ColumnStatsTable = ({ columnStats, searchQuery }: Props) => {
72105
73106 useEffect ( ( ) => {
74107 if ( expandedDrawerFieldPath ) {
75- const selectedIndex = rows . findIndex ( ( row ) => row . fieldPath === expandedDrawerFieldPath ) ;
108+ const selectedIndex = rows . findIndex (
109+ ( row ) => ( row as ExtendedSchemaFieldsWithFieldPath ) . fieldPath === expandedDrawerFieldPath ,
110+ ) ;
76111 const row = rowRefs . current [ selectedIndex ] ;
77112 const header = headerRef . current ;
78113
@@ -83,20 +118,9 @@ const ColumnStatsTable = ({ columnStats, searchQuery }: Props) => {
83118 block : 'nearest' ,
84119 } ) ;
85120 }
86- // To bring the row hidden behind the fixed header into view fully
121+ // Adjust scroll position to account for fixed header
87122 setTimeout ( ( ) => {
88- if ( row && header ) {
89- const rowRect = row . getBoundingClientRect ( ) ;
90- const headerRect = header . getBoundingClientRect ( ) ;
91- const rowTop = rowRect . top ;
92- const headerBottom = headerRect . bottom ;
93- const scrollContainer = row . closest ( 'table' ) ?. parentElement ;
94-
95- if ( scrollContainer && rowTop < headerBottom ) {
96- const scrollAmount = headerBottom - rowTop ;
97- scrollContainer . scrollTop -= scrollAmount ;
98- }
99- }
123+ handleRowScrollIntoView ( row , header ) ;
100124 } , 100 ) ;
101125 }
102126 } , [ expandedDrawerFieldPath , rows ] ) ;
@@ -112,11 +136,13 @@ const ColumnStatsTable = ({ columnStats, searchQuery }: Props) => {
112136 }
113137
114138 const getRowClassName = ( record ) => {
115- return expandedDrawerFieldPath === record . column ? 'selected-row' : '' ;
139+ return expandedDrawerFieldPath === record . originalFieldPath ? 'selected-row' : '' ;
116140 } ;
117141
118142 const onRowClick = ( record ) => {
119- setExpandedDrawerFieldPath ( expandedDrawerFieldPath === record . column ? null : record . column ) ;
143+ setExpandedDrawerFieldPath (
144+ expandedDrawerFieldPath === record . originalFieldPath ? null : record . originalFieldPath ,
145+ ) ;
120146 } ;
121147
122148 return (
@@ -132,11 +158,11 @@ const ColumnStatsTable = ({ columnStats, searchQuery }: Props) => {
132158 rowRefs = { rowRefs }
133159 headerRef = { headerRef }
134160 />
135- { ! ! fields && (
161+ { fields . length > 0 && (
136162 < SchemaFieldDrawer
137- schemaFields = { fields }
163+ schemaFields = { fields as any }
138164 expandedDrawerFieldPath = { expandedDrawerFieldPath }
139- editableSchemaMetadata = { editableSchemaMetadata }
165+ editableSchemaMetadata = { entityWithSchema ?. editableSchemaMetadata as any }
140166 setExpandedDrawerFieldPath = { setExpandedDrawerFieldPath }
141167 displayedRows = { rows }
142168 defaultSelectedTabName = "Statistics"
@@ -146,6 +172,6 @@ const ColumnStatsTable = ({ columnStats, searchQuery }: Props) => {
146172 ) }
147173 </ >
148174 ) ;
149- } ;
175+ }
150176
151177export default ColumnStatsTable ;
0 commit comments