mirror of https://github.com/grafana/grafana.git
				
				
				
			TableNG [Bug Bash]: Cell inspect and filter on the field level (#103004)
* fix: cell inspect + filter at the field level, not defaults * chore: defensive against missing custom config * chore: reconfigure tests * hide inspect block if nothing to show --------- Co-authored-by: Adela Almasan <adela.almasan@grafana.com> Co-authored-by: Ihor Yeromin <yeryomin.igor@gmail.com>
This commit is contained in:
		
							parent
							
								
									413378dd3a
								
							
						
					
					
						commit
						d6ec8ab8b1
					
				|  | @ -20,7 +20,6 @@ interface HeaderCellProps { | |||
|   justifyContent: Property.JustifyContent; | ||||
|   filter: FilterType; | ||||
|   setFilter: React.Dispatch<React.SetStateAction<FilterType>>; | ||||
|   filterable: boolean; | ||||
|   onColumnResize?: TableColumnResizeActionCallback; | ||||
|   headerCellRefs: React.MutableRefObject<Record<string, HTMLDivElement>>; | ||||
|   crossFilterOrder: React.MutableRefObject<string[]>; | ||||
|  | @ -37,7 +36,6 @@ const HeaderCell: React.FC<HeaderCellProps> = ({ | |||
|   justifyContent, | ||||
|   filter, | ||||
|   setFilter, | ||||
|   filterable, | ||||
|   onColumnResize, | ||||
|   headerCellRefs, | ||||
|   crossFilterOrder, | ||||
|  | @ -47,6 +45,8 @@ const HeaderCell: React.FC<HeaderCellProps> = ({ | |||
|   const styles = useStyles2(getStyles, justifyContent); | ||||
|   const headerRef = useRef<HTMLDivElement>(null); | ||||
| 
 | ||||
|   const filterable = field.config?.custom?.filterable ?? false; | ||||
| 
 | ||||
|   let isColumnFilterable = filterable; | ||||
|   if (field.config.custom?.filterable !== filterable) { | ||||
|     isColumnFilterable = field.config.custom?.filterable || false; | ||||
|  |  | |||
|  | @ -32,12 +32,13 @@ export function TableCellNG(props: TableCellNGProps) { | |||
|     shouldTextOverflow, | ||||
|     setIsInspecting, | ||||
|     setContextMenuProps, | ||||
|     cellInspect, | ||||
|     getActions, | ||||
|     rowBg, | ||||
|     onCellFilterAdded, | ||||
|   } = props; | ||||
| 
 | ||||
|   const cellInspect = field.config?.custom?.inspect ?? false; | ||||
| 
 | ||||
|   const { config: fieldConfig } = field; | ||||
|   const defaultCellOptions: TableAutoCellOptions = { type: TableCellDisplayMode.Auto }; | ||||
|   const cellOptions = fieldConfig.custom?.cellOptions ?? defaultCellOptions; | ||||
|  | @ -148,6 +149,7 @@ export function TableCellNG(props: TableCellNGProps) { | |||
|       tableCellDiv?.style.setProperty('z-index', String(theme.zIndex.tooltip)); | ||||
|       tableCellDiv?.style.setProperty('white-space', 'normal'); | ||||
|       tableCellDiv?.style.setProperty('min-height', `${height}px`); | ||||
|       tableCellDiv?.style.setProperty('width', `${divWidth}px`); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|  | @ -179,7 +181,7 @@ export function TableCellNG(props: TableCellNGProps) { | |||
|   return ( | ||||
|     <div ref={divWidthRef} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} className={styles.cell}> | ||||
|       {cell} | ||||
|       {isHovered && ( | ||||
|       {isHovered && (cellInspect || showFilters) && ( | ||||
|         <div className={styles.cellActions}> | ||||
|           {cellInspect && ( | ||||
|             <IconButton | ||||
|  |  | |||
|  | @ -1249,24 +1249,26 @@ describe('TableNG', () => { | |||
| 
 | ||||
|   describe('Cell inspection', () => { | ||||
|     it('shows inspect icon when hovering over a cell with inspection enabled', () => { | ||||
|       const fieldConfig = { | ||||
|         defaults: { | ||||
|       const inspectDataFrame = { | ||||
|         ...createBasicDataFrame(), | ||||
|         fields: createBasicDataFrame().fields.map((field) => ({ | ||||
|           ...field, | ||||
|           config: { | ||||
|             ...field.config, | ||||
|             custom: { | ||||
|               ...field.config.custom, | ||||
|               inspect: true, | ||||
|             cellOptions: { | ||||
|               wrapText: false, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         overrides: [], | ||||
|         })), | ||||
|       }; | ||||
| 
 | ||||
|       // Render the component
 | ||||
|       const { container } = render( | ||||
|         <TableNG | ||||
|           enableVirtualization={false} | ||||
|           fieldConfig={fieldConfig} | ||||
|           data={createBasicDataFrame()} | ||||
|           // fieldConfig={inspectDataFrame.fields[0].config}
 | ||||
|           data={inspectDataFrame} | ||||
|           width={800} | ||||
|           height={600} | ||||
|         /> | ||||
|  |  | |||
|  | @ -610,7 +610,6 @@ export function mapFrameToDataGrid({ | |||
|     sortColumnsRef, | ||||
|     styles, | ||||
|     textWrap, | ||||
|     fieldConfig, | ||||
|     theme, | ||||
|     timeRange, | ||||
|     getActions, | ||||
|  | @ -621,9 +620,6 @@ export function mapFrameToDataGrid({ | |||
|   const columns: TableColumn[] = []; | ||||
|   const hasNestedFrames = getIsNestedTable(frame); | ||||
| 
 | ||||
|   const cellInspect = fieldConfig?.defaults?.custom?.inspect ?? false; | ||||
|   const filterable = fieldConfig?.defaults?.custom?.filterable ?? false; | ||||
| 
 | ||||
|   // If nested frames, add expansion control column
 | ||||
|   if (hasNestedFrames) { | ||||
|     const expanderField: Field = { | ||||
|  | @ -756,13 +752,12 @@ export function mapFrameToDataGrid({ | |||
|                 defaultRowHeight, | ||||
|                 TABLE.CELL_PADDING, | ||||
|                 textWrap, | ||||
|                 cellInspect, | ||||
|                 field, | ||||
|                 cellType | ||||
|               ) | ||||
|             } | ||||
|             setIsInspecting={setIsInspecting} | ||||
|             setContextMenuProps={setContextMenuProps} | ||||
|             cellInspect={cellInspect} | ||||
|             getActions={getActions} | ||||
|             rowBg={rowBg} | ||||
|             onCellFilterAdded={onCellFilterAdded} | ||||
|  | @ -803,7 +798,6 @@ export function mapFrameToDataGrid({ | |||
|           justifyContent={justifyColumnContent} | ||||
|           filter={filter} | ||||
|           setFilter={setFilter} | ||||
|           filterable={filterable} | ||||
|           onColumnResize={onColumnResize} | ||||
|           headerCellRefs={headerCellRefs} | ||||
|           crossFilterOrder={crossFilterOrder} | ||||
|  |  | |||
|  | @ -134,7 +134,6 @@ export interface BaseTableProps { | |||
| export interface TableNGProps extends BaseTableProps {} | ||||
| 
 | ||||
| export interface TableCellNGProps { | ||||
|   cellInspect: boolean; | ||||
|   field: Field; | ||||
|   frame: DataFrame; | ||||
|   getActions?: GetActionsFunction; | ||||
|  |  | |||
|  | @ -1047,7 +1047,13 @@ describe('TableNG utils', () => { | |||
|         40, // defaultRowHeight
 | ||||
|         8, // padding
 | ||||
|         false, // textWrap
 | ||||
|         false, // cellInspect
 | ||||
|         { | ||||
|           config: { | ||||
|             custom: { | ||||
|               inspect: false, | ||||
|             }, | ||||
|           }, | ||||
|         } as Field, | ||||
|         TableCellDisplayMode.Auto // cellType
 | ||||
|       ); | ||||
| 
 | ||||
|  | @ -1073,7 +1079,13 @@ describe('TableNG utils', () => { | |||
|         40, // defaultRowHeight
 | ||||
|         8, // padding
 | ||||
|         false, // textWrap
 | ||||
|         false, // cellInspect
 | ||||
|         { | ||||
|           config: { | ||||
|             custom: { | ||||
|               inspect: false, | ||||
|             }, | ||||
|           }, | ||||
|         } as Field, | ||||
|         TableCellDisplayMode.Auto // cellType
 | ||||
|       ); | ||||
| 
 | ||||
|  | @ -1098,7 +1110,13 @@ describe('TableNG utils', () => { | |||
|         40, // defaultRowHeight
 | ||||
|         8, // padding
 | ||||
|         true, // textWrap ENABLED
 | ||||
|         false, // cellInspect
 | ||||
|         { | ||||
|           config: { | ||||
|             custom: { | ||||
|               inspect: true, | ||||
|             }, | ||||
|           }, | ||||
|         } as Field, | ||||
|         TableCellDisplayMode.Auto // cellType
 | ||||
|       ); | ||||
| 
 | ||||
|  | @ -1123,7 +1141,13 @@ describe('TableNG utils', () => { | |||
|         40, // defaultRowHeight
 | ||||
|         8, // padding
 | ||||
|         false, // textWrap
 | ||||
|         true, // cellInspect ENABLED
 | ||||
|         { | ||||
|           config: { | ||||
|             custom: { | ||||
|               inspect: true, | ||||
|             }, | ||||
|           }, | ||||
|         } as Field, | ||||
|         TableCellDisplayMode.Auto // cellType
 | ||||
|       ); | ||||
| 
 | ||||
|  |  | |||
|  | @ -169,9 +169,11 @@ export function shouldTextOverflow( | |||
|   defaultRowHeight: number, | ||||
|   padding: number, | ||||
|   textWrap: boolean, | ||||
|   cellInspect: boolean, | ||||
|   field: Field, | ||||
|   cellType: TableCellDisplayMode | ||||
| ): boolean { | ||||
|   const cellInspect = field.config?.custom?.inspect ?? false; | ||||
| 
 | ||||
|   // Tech debt: Technically image cells are of type string, which is misleading (kinda?)
 | ||||
|   // so we need to ensure we don't apply overflow hover states fo type image
 | ||||
|   if (textWrap || cellInspect || cellType === TableCellDisplayMode.Image || !isTextCell(key, columnTypes)) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue