| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | import memoizeOne from 'memoize-one'; | 
					
						
							|  |  |  | import React, { PureComponent } from 'react'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 22:33:17 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   TimeZone, | 
					
						
							|  |  |  |   LogsDedupStrategy, | 
					
						
							|  |  |  |   LogRowModel, | 
					
						
							|  |  |  |   Field, | 
					
						
							|  |  |  |   LinkModel, | 
					
						
							|  |  |  |   LogsSortOrder, | 
					
						
							|  |  |  |   CoreApp, | 
					
						
							|  |  |  |   DataFrame, | 
					
						
							| 
									
										
										
										
											2023-01-27 22:12:01 +08:00
										 |  |  |   DataSourceWithLogsContextSupport, | 
					
						
							| 
									
										
										
										
											2023-04-11 18:19:28 +08:00
										 |  |  |   DataQueryResponse, | 
					
						
							| 
									
										
										
										
											2023-04-13 19:07:28 +08:00
										 |  |  |   LogRowContextOptions, | 
					
						
							| 
									
										
										
										
											2022-11-10 22:33:17 +08:00
										 |  |  | } from '@grafana/data'; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | import { withTheme2, Themeable2 } from '@grafana/ui'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 18:16:47 +08:00
										 |  |  | import { sortLogRows } from '../utils'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | //Components
 | 
					
						
							|  |  |  | import { LogRow } from './LogRow'; | 
					
						
							|  |  |  | import { getLogRowStyles } from './getLogRowStyles'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const PREVIEW_LIMIT = 100; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface Props extends Themeable2 { | 
					
						
							|  |  |  |   logRows?: LogRowModel[]; | 
					
						
							|  |  |  |   deduplicatedRows?: LogRowModel[]; | 
					
						
							|  |  |  |   dedupStrategy: LogsDedupStrategy; | 
					
						
							|  |  |  |   showLabels: boolean; | 
					
						
							|  |  |  |   showTime: boolean; | 
					
						
							|  |  |  |   wrapLogMessage: boolean; | 
					
						
							|  |  |  |   prettifyLogMessage: boolean; | 
					
						
							|  |  |  |   timeZone: TimeZone; | 
					
						
							|  |  |  |   enableLogDetails: boolean; | 
					
						
							|  |  |  |   logsSortOrder?: LogsSortOrder | null; | 
					
						
							|  |  |  |   previewLimit?: number; | 
					
						
							|  |  |  |   forceEscape?: boolean; | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |   displayedFields?: string[]; | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |   app?: CoreApp; | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |   scrollElement?: HTMLDivElement; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   showContextToggle?: (row?: LogRowModel) => boolean; | 
					
						
							|  |  |  |   onClickFilterLabel?: (key: string, value: string) => void; | 
					
						
							|  |  |  |   onClickFilterOutLabel?: (key: string, value: string) => void; | 
					
						
							| 
									
										
										
										
											2023-04-13 19:07:28 +08:00
										 |  |  |   getRowContext?: (row: LogRowModel, options?: LogRowContextOptions) => Promise<DataQueryResponse>; | 
					
						
							| 
									
										
										
										
											2023-01-27 22:12:01 +08:00
										 |  |  |   getLogRowContextUi?: DataSourceWithLogsContextSupport['getLogRowContextUi']; | 
					
						
							| 
									
										
										
										
											2022-11-10 22:33:17 +08:00
										 |  |  |   getFieldLinks?: (field: Field, rowIndex: number, dataFrame: DataFrame) => Array<LinkModel<Field>>; | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |   onClickShowField?: (key: string) => void; | 
					
						
							|  |  |  |   onClickHideField?: (key: string) => void; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   onLogRowHover?: (row?: LogRowModel) => void; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface State { | 
					
						
							|  |  |  |   renderAll: boolean; | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |   contextIsOpen: boolean; | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class UnThemedLogRows extends PureComponent<Props, State> { | 
					
						
							|  |  |  |   renderAllTimer: number | null = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static defaultProps = { | 
					
						
							|  |  |  |     previewLimit: PREVIEW_LIMIT, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   state: State = { | 
					
						
							|  |  |  |     renderAll: false, | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |     contextIsOpen: false, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Toggle the `contextIsOpen` state when a context of one LogRow is opened in order to not show the menu of the other log rows. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   toggleContextIsOpen = (): void => { | 
					
						
							|  |  |  |     this.setState((state) => { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         contextIsOpen: !state.contextIsOpen, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   componentDidMount() { | 
					
						
							|  |  |  |     // Staged rendering
 | 
					
						
							|  |  |  |     const { logRows, previewLimit } = this.props; | 
					
						
							|  |  |  |     const rowCount = logRows ? logRows.length : 0; | 
					
						
							|  |  |  |     // Render all right away if not too far over the limit
 | 
					
						
							|  |  |  |     const renderAll = rowCount <= previewLimit! * 2; | 
					
						
							|  |  |  |     if (renderAll) { | 
					
						
							|  |  |  |       this.setState({ renderAll }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this.renderAllTimer = window.setTimeout(() => this.setState({ renderAll: true }), 2000); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   componentWillUnmount() { | 
					
						
							|  |  |  |     if (this.renderAllTimer) { | 
					
						
							|  |  |  |       clearTimeout(this.renderAllTimer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   makeGetRows = memoizeOne((orderedRows: LogRowModel[]) => { | 
					
						
							|  |  |  |     return () => orderedRows; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sortLogs = memoizeOne((logRows: LogRowModel[], logsSortOrder: LogsSortOrder): LogRowModel[] => | 
					
						
							|  |  |  |     sortLogRows(logRows, logsSortOrder) | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   render() { | 
					
						
							|  |  |  |     const { | 
					
						
							|  |  |  |       dedupStrategy, | 
					
						
							|  |  |  |       showContextToggle, | 
					
						
							|  |  |  |       showLabels, | 
					
						
							|  |  |  |       showTime, | 
					
						
							|  |  |  |       wrapLogMessage, | 
					
						
							|  |  |  |       prettifyLogMessage, | 
					
						
							|  |  |  |       logRows, | 
					
						
							|  |  |  |       deduplicatedRows, | 
					
						
							|  |  |  |       timeZone, | 
					
						
							|  |  |  |       onClickFilterLabel, | 
					
						
							|  |  |  |       onClickFilterOutLabel, | 
					
						
							|  |  |  |       theme, | 
					
						
							|  |  |  |       enableLogDetails, | 
					
						
							|  |  |  |       previewLimit, | 
					
						
							|  |  |  |       getFieldLinks, | 
					
						
							|  |  |  |       logsSortOrder, | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |       displayedFields, | 
					
						
							|  |  |  |       onClickShowField, | 
					
						
							|  |  |  |       onClickHideField, | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |       forceEscape, | 
					
						
							|  |  |  |       onLogRowHover, | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |       app, | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |       scrollElement, | 
					
						
							| 
									
										
										
										
											2023-01-27 22:12:01 +08:00
										 |  |  |       getLogRowContextUi, | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |     } = this.props; | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |     const { renderAll, contextIsOpen } = this.state; | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |     const styles = getLogRowStyles(theme); | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |     const dedupedRows = deduplicatedRows ? deduplicatedRows : logRows; | 
					
						
							|  |  |  |     const hasData = logRows && logRows.length > 0; | 
					
						
							|  |  |  |     const dedupCount = dedupedRows | 
					
						
							|  |  |  |       ? dedupedRows.reduce((sum, row) => (row.duplicates ? sum + row.duplicates : sum), 0) | 
					
						
							|  |  |  |       : 0; | 
					
						
							|  |  |  |     const showDuplicates = dedupStrategy !== LogsDedupStrategy.none && dedupCount > 0; | 
					
						
							|  |  |  |     // Staged rendering
 | 
					
						
							|  |  |  |     const processedRows = dedupedRows ? dedupedRows : []; | 
					
						
							|  |  |  |     const orderedRows = logsSortOrder ? this.sortLogs(processedRows, logsSortOrder) : processedRows; | 
					
						
							|  |  |  |     const firstRows = orderedRows.slice(0, previewLimit!); | 
					
						
							|  |  |  |     const lastRows = orderedRows.slice(previewLimit!, orderedRows.length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // React profiler becomes unusable if we pass all rows to all rows and their labels, using getter instead
 | 
					
						
							|  |  |  |     const getRows = this.makeGetRows(orderedRows); | 
					
						
							| 
									
										
										
										
											2023-04-11 18:19:28 +08:00
										 |  |  |     const getRowContext = this.props.getRowContext ? this.props.getRowContext : () => Promise.resolve({ data: [] }); | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ( | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |       <table className={styles.logsRowsTable}> | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |         <tbody> | 
					
						
							|  |  |  |           {hasData && | 
					
						
							|  |  |  |             firstRows.map((row, index) => ( | 
					
						
							|  |  |  |               <LogRow | 
					
						
							|  |  |  |                 key={row.uid} | 
					
						
							|  |  |  |                 getRows={getRows} | 
					
						
							|  |  |  |                 getRowContext={getRowContext} | 
					
						
							| 
									
										
										
										
											2023-01-27 22:12:01 +08:00
										 |  |  |                 getLogRowContextUi={getLogRowContextUi} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 row={row} | 
					
						
							|  |  |  |                 showContextToggle={showContextToggle} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 showRowMenu={!contextIsOpen} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 showDuplicates={showDuplicates} | 
					
						
							|  |  |  |                 showLabels={showLabels} | 
					
						
							|  |  |  |                 showTime={showTime} | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |                 displayedFields={displayedFields} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 wrapLogMessage={wrapLogMessage} | 
					
						
							|  |  |  |                 prettifyLogMessage={prettifyLogMessage} | 
					
						
							|  |  |  |                 timeZone={timeZone} | 
					
						
							|  |  |  |                 enableLogDetails={enableLogDetails} | 
					
						
							|  |  |  |                 onClickFilterLabel={onClickFilterLabel} | 
					
						
							|  |  |  |                 onClickFilterOutLabel={onClickFilterOutLabel} | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |                 onClickShowField={onClickShowField} | 
					
						
							|  |  |  |                 onClickHideField={onClickHideField} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 getFieldLinks={getFieldLinks} | 
					
						
							|  |  |  |                 logsSortOrder={logsSortOrder} | 
					
						
							|  |  |  |                 forceEscape={forceEscape} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 toggleContextIsOpen={this.toggleContextIsOpen} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 onLogRowHover={onLogRowHover} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 app={app} | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |                 scrollElement={scrollElement} | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |                 styles={styles} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |               /> | 
					
						
							|  |  |  |             ))} | 
					
						
							|  |  |  |           {hasData && | 
					
						
							|  |  |  |             renderAll && | 
					
						
							|  |  |  |             lastRows.map((row, index) => ( | 
					
						
							|  |  |  |               <LogRow | 
					
						
							|  |  |  |                 key={row.uid} | 
					
						
							|  |  |  |                 getRows={getRows} | 
					
						
							|  |  |  |                 getRowContext={getRowContext} | 
					
						
							| 
									
										
										
										
											2023-01-27 22:12:01 +08:00
										 |  |  |                 getLogRowContextUi={getLogRowContextUi} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 row={row} | 
					
						
							|  |  |  |                 showContextToggle={showContextToggle} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 showRowMenu={!contextIsOpen} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 showDuplicates={showDuplicates} | 
					
						
							|  |  |  |                 showLabels={showLabels} | 
					
						
							|  |  |  |                 showTime={showTime} | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |                 displayedFields={displayedFields} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 wrapLogMessage={wrapLogMessage} | 
					
						
							|  |  |  |                 prettifyLogMessage={prettifyLogMessage} | 
					
						
							|  |  |  |                 timeZone={timeZone} | 
					
						
							|  |  |  |                 enableLogDetails={enableLogDetails} | 
					
						
							|  |  |  |                 onClickFilterLabel={onClickFilterLabel} | 
					
						
							|  |  |  |                 onClickFilterOutLabel={onClickFilterOutLabel} | 
					
						
							| 
									
										
										
										
											2023-01-12 02:20:11 +08:00
										 |  |  |                 onClickShowField={onClickShowField} | 
					
						
							|  |  |  |                 onClickHideField={onClickHideField} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 getFieldLinks={getFieldLinks} | 
					
						
							|  |  |  |                 logsSortOrder={logsSortOrder} | 
					
						
							|  |  |  |                 forceEscape={forceEscape} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 toggleContextIsOpen={this.toggleContextIsOpen} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |                 onLogRowHover={onLogRowHover} | 
					
						
							| 
									
										
										
										
											2022-09-29 16:00:01 +08:00
										 |  |  |                 app={app} | 
					
						
							| 
									
										
										
										
											2022-09-29 20:51:20 +08:00
										 |  |  |                 scrollElement={scrollElement} | 
					
						
							| 
									
										
										
										
											2023-02-01 22:28:10 +08:00
										 |  |  |                 styles={styles} | 
					
						
							| 
									
										
										
										
											2022-09-19 16:51:46 +08:00
										 |  |  |               /> | 
					
						
							|  |  |  |             ))} | 
					
						
							|  |  |  |           {hasData && !renderAll && ( | 
					
						
							|  |  |  |             <tr> | 
					
						
							|  |  |  |               <td colSpan={5}>Rendering {orderedRows.length - previewLimit!} rows...</td> | 
					
						
							|  |  |  |             </tr> | 
					
						
							|  |  |  |           )} | 
					
						
							|  |  |  |         </tbody> | 
					
						
							|  |  |  |       </table> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const LogRows = withTheme2(UnThemedLogRows); | 
					
						
							|  |  |  | LogRows.displayName = 'LogsRows'; |