@@ -13,11 +13,35 @@ import {
1313 TableHeader ,
1414 TableRow ,
1515} from "@carbon/react" ;
16+ import { useQuery } from "@tanstack/react-query" ;
1617
18+ import { api } from "@/api" ;
1719import { cn } from "@/lib/utils.ts" ;
18- import { Check } from "@/types/upload" ;
20+ import { Check , DataQualityCheckLabel } from "@/types/upload" ;
1921import { commaNumber } from "@/utils/number.ts" ;
2022
23+ const getLabelKey = ( assertion : string , columnKey = "" ) =>
24+ `${ assertion } -${ columnKey } ` ;
25+
26+ const buildAssertionLabelMap = ( labels : DataQualityCheckLabel [ ] ) =>
27+ labels . reduce < Record < string , string > > ( ( acc , label ) => {
28+ acc [ getLabelKey ( label . assertion , label . column_key ) ] =
29+ label . ui_error_description ;
30+ return acc ;
31+ } , { } ) ;
32+
33+ export const formatAssertion = (
34+ assertion : string ,
35+ columnKey : string ,
36+ assertionLabels : Record < string , string > ,
37+ ) => {
38+ return (
39+ assertionLabels [ getLabelKey ( assertion , columnKey ) ] ??
40+ assertionLabels [ getLabelKey ( assertion ) ] ??
41+ assertion . replace ( / _ / g, " " )
42+ ) ;
43+ } ;
44+
2145interface ExtendedDataTableHeader extends DataTableHeader {
2246 sortable ?: boolean ;
2347}
@@ -33,6 +57,16 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
3357 direction : "ascending" | "descending" ;
3458 } > ( { key : "" , direction : "ascending" } ) ;
3559
60+ const { data : dataQualityCheckLabelsQuery } = useQuery ( {
61+ queryKey : [ "data_quality_check_labels" ] ,
62+ queryFn : api . uploads . list_data_quality_check_labels ,
63+ } ) ;
64+
65+ const assertionLabels = useMemo (
66+ ( ) => buildAssertionLabelMap ( dataQualityCheckLabelsQuery ?. data ?? [ ] ) ,
67+ [ dataQualityCheckLabelsQuery ] ,
68+ ) ;
69+
3670 const handleUpSort = ( key : string ) => {
3771 setSortConfig ( { key, direction : "ascending" } ) ;
3872 } ;
@@ -44,9 +78,19 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
4478 const filteredAndSortedRows = useMemo ( ( ) => {
4579 const result = data . filter ( check => {
4680 const searchString = searchTerm . toLowerCase ( ) ;
81+ const columnKey = check . column === "" ? "NO_COLUMN" : check . column ;
82+ const columnDisplay =
83+ columnKey === "NO_COLUMN" ? "Entire row" : columnKey ;
84+ const assertionLabel = formatAssertion (
85+ check . assertion ,
86+ check . column ,
87+ assertionLabels ,
88+ ) ;
4789 return (
4890 check . column . toLowerCase ( ) . includes ( searchString ) ||
49- check . assertion . toLowerCase ( ) . includes ( searchString )
91+ check . assertion . toLowerCase ( ) . includes ( searchString ) ||
92+ columnDisplay . toLowerCase ( ) . includes ( searchString ) ||
93+ assertionLabel . toLowerCase ( ) . includes ( searchString )
5094 ) ;
5195 } ) ;
5296
@@ -78,13 +122,13 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
78122 }
79123
80124 return result ;
81- } , [ data , searchTerm , sortConfig ] ) ;
125+ } , [ assertionLabels , data , searchTerm , sortConfig ] ) ;
82126
83127 const renderSortControls = ( key : string ) => {
84128 const isActive = sortConfig . key === key ;
85129
86130 return (
87- < div className = "absolute right-1 top-1/ 2 flex -translate-y-1/2 flex-col" >
131+ < div className = "ml- 2 flex shrink-0 flex-col" >
88132 < ChevronUp
89133 className = { cn (
90134 "cursor-pointer transition-colors duration-150" ,
@@ -112,18 +156,19 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
112156 const rows = filteredAndSortedRows . map ( check => {
113157 const {
114158 assertion,
115- column = "NO_COLUMN " ,
159+ column = "" ,
116160 count_failed,
117161 count_passed,
118162 percent_passed,
119163 } = check ;
120164
121165 const columnKey = column === "" ? "NO_COLUMN" : column ;
166+ const columnDisplay = columnKey === "NO_COLUMN" ? "Entire row" : columnKey ;
122167
123168 return {
124169 id : `${ assertion } -${ columnKey } ` ,
125- column : columnKey ,
126- assertion,
170+ column : columnDisplay ,
171+ assertion : formatAssertion ( assertion , column , assertionLabels ) ,
127172 result_with_errors : (
128173 < div className = "flex items-center" >
129174 { count_failed > 0 ? (
@@ -152,12 +197,12 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
152197 const dqResultHeaders : ExtendedDataTableHeader [ ] = [
153198 {
154199 key : "column" ,
155- header : "Column(s) " ,
200+ header : "Column" ,
156201 sortable : false ,
157202 } ,
158203 {
159204 key : "assertion" ,
160- header : "Validation Rule " ,
205+ header : "Check Description " ,
161206 sortable : false ,
162207 } ,
163208 {
@@ -185,7 +230,7 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
185230 < div className = "rounded-lg border bg-white shadow-sm" >
186231 < div className = "border-b px-4 py-3" >
187232 < h3 className = "text-lg font-semibold text-gray-800" >
188- Overview of all fields sorted by type
233+ Overview of all checks sorted by type
189234 </ h3 >
190235 </ div >
191236
@@ -199,9 +244,9 @@ const DataQualityChecks = ({ data }: DataQualityChecksProps) => {
199244 < TableHeader
200245 key = { header . key }
201246 isSortable = { false }
202- className = { cn ( "relative bg-blue-50 text-gray-700" ) }
247+ className = { cn ( "bg-blue-50 text-gray-700" ) }
203248 >
204- < div className = "flex w-full items-center justify-between" >
249+ < div className = "flex w-full items-center justify-between gap-2 " >
205250 < span > { header . header } </ span >
206251 { ( header as ExtendedDataTableHeader ) . sortable &&
207252 renderSortControls ( header . key ) }
0 commit comments