mirror of https://github.com/grafana/grafana.git
				
				
				
			Logs Panel: Sync visual options in panel editor (#111163)
* Logs panel: sync visual options in panel editor * LogListContext: sync uniqueLabels * Tranlations * Prettier * PrettifyJSON before syntax highlighting * Update LogListContext.tsx * LogListContext: fix prettify json option callback * LogListControls: fix third state for wrapping * Update test * chore: fix label capitalization
This commit is contained in:
		
							parent
							
								
									8c284cbcba
								
							
						
					
					
						commit
						a044f567a8
					
				|  | @ -75,6 +75,7 @@ export interface Props { | ||||||
|   permalinkedLogId?: string; |   permalinkedLogId?: string; | ||||||
|   pinLineButtonTooltipTitle?: PopoverContent; |   pinLineButtonTooltipTitle?: PopoverContent; | ||||||
|   pinnedLogs?: string[]; |   pinnedLogs?: string[]; | ||||||
|  |   prettifyJSON?: boolean; | ||||||
|   setDisplayedFields?: (displayedFields: string[]) => void; |   setDisplayedFields?: (displayedFields: string[]) => void; | ||||||
|   showControls: boolean; |   showControls: boolean; | ||||||
|   showTime: boolean; |   showTime: boolean; | ||||||
|  | @ -88,7 +89,7 @@ export interface Props { | ||||||
| 
 | 
 | ||||||
| export type LogListFontSize = 'default' | 'small'; | export type LogListFontSize = 'default' | 'small'; | ||||||
| 
 | 
 | ||||||
| export type LogListControlOptions = keyof LogListState | 'wrapLogMessage' | 'prettifyJSON'; | export type LogListControlOptions = keyof LogListState | 'wrapLogMessage' | 'prettifyLogMessage'; | ||||||
| 
 | 
 | ||||||
| type LogListComponentProps = Omit< | type LogListComponentProps = Omit< | ||||||
|   Props, |   Props, | ||||||
|  | @ -143,6 +144,7 @@ export const LogList = ({ | ||||||
|   permalinkedLogId, |   permalinkedLogId, | ||||||
|   pinLineButtonTooltipTitle, |   pinLineButtonTooltipTitle, | ||||||
|   pinnedLogs, |   pinnedLogs, | ||||||
|  |   prettifyJSON = logOptionsStorageKey ? store.getBool(`${logOptionsStorageKey}.prettifyLogMessage`, true) : true, | ||||||
|   setDisplayedFields, |   setDisplayedFields, | ||||||
|   showControls, |   showControls, | ||||||
|   showTime, |   showTime, | ||||||
|  | @ -186,6 +188,7 @@ export const LogList = ({ | ||||||
|       permalinkedLogId={permalinkedLogId} |       permalinkedLogId={permalinkedLogId} | ||||||
|       pinLineButtonTooltipTitle={pinLineButtonTooltipTitle} |       pinLineButtonTooltipTitle={pinLineButtonTooltipTitle} | ||||||
|       pinnedLogs={pinnedLogs} |       pinnedLogs={pinnedLogs} | ||||||
|  |       prettifyJSON={prettifyJSON} | ||||||
|       setDisplayedFields={setDisplayedFields} |       setDisplayedFields={setDisplayedFields} | ||||||
|       showControls={showControls} |       showControls={showControls} | ||||||
|       showTime={showTime} |       showTime={showTime} | ||||||
|  |  | ||||||
|  | @ -151,8 +151,6 @@ export type LogListState = Pick< | ||||||
|   | 'timestampResolution' |   | 'timestampResolution' | ||||||
| >; | >; | ||||||
| 
 | 
 | ||||||
| export type LogListOption = keyof LogListState | 'wrapLogMessage' | 'prettifyJSON'; |  | ||||||
| 
 |  | ||||||
| export interface Props { | export interface Props { | ||||||
|   app: CoreApp; |   app: CoreApp; | ||||||
|   children?: ReactNode; |   children?: ReactNode; | ||||||
|  | @ -233,9 +231,7 @@ export const LogListContextProvider = ({ | ||||||
|   permalinkedLogId, |   permalinkedLogId, | ||||||
|   pinLineButtonTooltipTitle, |   pinLineButtonTooltipTitle, | ||||||
|   pinnedLogs, |   pinnedLogs, | ||||||
|   prettifyJSON: prettifyJSONProp = logOptionsStorageKey |   prettifyJSON: prettifyJSONProp, | ||||||
|     ? store.getBool(`${logOptionsStorageKey}.prettifyLogMessage`, true) |  | ||||||
|     : true, |  | ||||||
|   setDisplayedFields, |   setDisplayedFields, | ||||||
|   showControls, |   showControls, | ||||||
|   showTime, |   showTime, | ||||||
|  | @ -280,8 +276,10 @@ export const LogListContextProvider = ({ | ||||||
|       fontSize, |       fontSize, | ||||||
|       forceEscape: logListState.forceEscape, |       forceEscape: logListState.forceEscape, | ||||||
|       showTime, |       showTime, | ||||||
|  |       showUniqueLabels, | ||||||
|       syntaxHighlighting, |       syntaxHighlighting, | ||||||
|       wrapLogMessage, |       wrapLogMessage, | ||||||
|  |       prettifyJSON, | ||||||
|       detailsWidth, |       detailsWidth, | ||||||
|       detailsMode, |       detailsMode, | ||||||
|       withDisplayedFields: displayedFields.length > 0, |       withDisplayedFields: displayedFields.length > 0, | ||||||
|  | @ -312,24 +310,14 @@ export const LogListContextProvider = ({ | ||||||
|       ...logListState, |       ...logListState, | ||||||
|       dedupStrategy, |       dedupStrategy, | ||||||
|       showTime, |       showTime, | ||||||
|  |       showUniqueLabels, | ||||||
|       sortOrder, |       sortOrder, | ||||||
|       syntaxHighlighting, |       syntaxHighlighting, | ||||||
|       wrapLogMessage, |  | ||||||
|     }; |     }; | ||||||
|     if (!shallowCompare(logListState, newState)) { |     if (!shallowCompare(logListState, newState)) { | ||||||
|       setLogListState(newState); |       setLogListState(newState); | ||||||
|     } |     } | ||||||
|   }, [ |   }, [app, dedupStrategy, logListState, showControls, showTime, showUniqueLabels, sortOrder, syntaxHighlighting]); | ||||||
|     app, |  | ||||||
|     dedupStrategy, |  | ||||||
|     logListState, |  | ||||||
|     pinnedLogs, |  | ||||||
|     showControls, |  | ||||||
|     showTime, |  | ||||||
|     sortOrder, |  | ||||||
|     syntaxHighlighting, |  | ||||||
|     wrapLogMessage, |  | ||||||
|   ]); |  | ||||||
| 
 | 
 | ||||||
|   // Sync filter levels
 |   // Sync filter levels
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|  | @ -344,6 +332,11 @@ export const LogListContextProvider = ({ | ||||||
|     }); |     }); | ||||||
|   }, [filterLevels]); |   }, [filterLevels]); | ||||||
| 
 | 
 | ||||||
|  |   // Sync details mode
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     setDetailsMode(detailsModeProp); | ||||||
|  |   }, [detailsModeProp]); | ||||||
|  | 
 | ||||||
|   // Sync font size
 |   // Sync font size
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     setLogListState((logListState) => ({ ...logListState, fontSize })); |     setLogListState((logListState) => ({ ...logListState, fontSize })); | ||||||
|  | @ -389,6 +382,18 @@ export const LogListContextProvider = ({ | ||||||
|     return () => observer.disconnect(); |     return () => observer.disconnect(); | ||||||
|   }, [containerElement, detailsMode, logOptionsStorageKey, showControls]); |   }, [containerElement, detailsMode, logOptionsStorageKey, showControls]); | ||||||
| 
 | 
 | ||||||
|  |   // Sync prettifyJSON
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     if (prettifyJSONProp !== undefined) { | ||||||
|  |       setPrettifyJSONState(prettifyJSONProp); | ||||||
|  |     } | ||||||
|  |   }, [prettifyJSONProp]); | ||||||
|  | 
 | ||||||
|  |   // Sync wrapLogMessage
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     setWrapLogMessageState(wrapLogMessageProp); | ||||||
|  |   }, [wrapLogMessageProp]); | ||||||
|  | 
 | ||||||
|   // Sync timestamp resolution
 |   // Sync timestamp resolution
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     setLogListState((state) => ({ |     setLogListState((state) => ({ | ||||||
|  | @ -485,7 +490,7 @@ export const LogListContextProvider = ({ | ||||||
|       if (logOptionsStorageKey) { |       if (logOptionsStorageKey) { | ||||||
|         store.set(`${logOptionsStorageKey}.prettifyLogMessage`, prettifyJSON); |         store.set(`${logOptionsStorageKey}.prettifyLogMessage`, prettifyJSON); | ||||||
|       } |       } | ||||||
|       onLogOptionsChange?.('prettifyJSON', prettifyJSON); |       onLogOptionsChange?.('prettifyLogMessage', prettifyJSON); | ||||||
|     }, |     }, | ||||||
|     [logOptionsStorageKey, onLogOptionsChange] |     [logOptionsStorageKey, onLogOptionsChange] | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  | @ -303,19 +303,19 @@ describe('LogListControls', () => { | ||||||
| 
 | 
 | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledTimes(2); |     expect(onLogOptionsChange).toHaveBeenCalledTimes(2); | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', true); |     expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', true); | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', false); |     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyLogMessage', false); | ||||||
| 
 | 
 | ||||||
|     await userEvent.click(screen.getByLabelText(WRAP_LINES_LABEL_COPY)); |     await userEvent.click(screen.getByLabelText(WRAP_LINES_LABEL_COPY)); | ||||||
|     await userEvent.click(screen.getByText(WRAP_JSON_TOOLTIP_COPY)); |     await userEvent.click(screen.getByText(WRAP_JSON_TOOLTIP_COPY)); | ||||||
| 
 | 
 | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledTimes(4); |     expect(onLogOptionsChange).toHaveBeenCalledTimes(4); | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', true); |     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyLogMessage', true); | ||||||
| 
 | 
 | ||||||
|     await userEvent.click(screen.getByLabelText(WRAP_JSON_LABEL_COPY)); |     await userEvent.click(screen.getByLabelText(WRAP_JSON_LABEL_COPY)); | ||||||
|     await userEvent.click(screen.getByText(WRAP_DISABLE_LABEL_COPY)); |     await userEvent.click(screen.getByText(WRAP_DISABLE_LABEL_COPY)); | ||||||
| 
 | 
 | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', false); |     expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', false); | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', false); |     expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyLogMessage', false); | ||||||
| 
 | 
 | ||||||
|     expect(onLogOptionsChange).toHaveBeenCalledTimes(6); |     expect(onLogOptionsChange).toHaveBeenCalledTimes(6); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -735,7 +735,7 @@ const WrapLogMessageButton = ({ expanded }: LogSelectOptionProps) => { | ||||||
|       tooltip={tooltip} |       tooltip={tooltip} | ||||||
|       label={wrapStateText} |       label={wrapStateText} | ||||||
|       buttonAriaLabel={tooltip} |       buttonAriaLabel={tooltip} | ||||||
|       customTagText={'+'} |       customTagText={prettifyJSON ? '+' : ''} | ||||||
|     /> |     /> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ export const LogListControlsSelectOption = React.forwardRef<SVGElement, SelectPr | ||||||
|       className: iconButtonClassName, |       className: iconButtonClassName, | ||||||
|       name: iconButtonName, |       name: iconButtonName, | ||||||
|       dropdown, |       dropdown, | ||||||
|       isActive: isActive, |       isActive, | ||||||
|       customTagText, |       customTagText, | ||||||
|       buttonAriaLabel, |       buttonAriaLabel, | ||||||
|       ...iconButtonProps |       ...iconButtonProps | ||||||
|  |  | ||||||
|  | @ -606,6 +606,7 @@ export const LogsPanel = ({ | ||||||
|               onOpenContext={onOpenContext} |               onOpenContext={onOpenContext} | ||||||
|               onPermalinkClick={showPermaLink() ? onPermalinkClick : undefined} |               onPermalinkClick={showPermaLink() ? onPermalinkClick : undefined} | ||||||
|               permalinkedLogId={getLogsPanelState()?.logs?.id ?? undefined} |               permalinkedLogId={getLogsPanelState()?.logs?.id ?? undefined} | ||||||
|  |               prettifyJSON={prettifyLogMessage} | ||||||
|               setDisplayedFields={setDisplayedFieldsFn} |               setDisplayedFields={setDisplayedFieldsFn} | ||||||
|               showControls={Boolean(showControls)} |               showControls={Boolean(showControls)} | ||||||
|               showTime={showTime} |               showTime={showTime} | ||||||
|  |  | ||||||
|  | @ -60,17 +60,8 @@ export const plugin = new PanelPlugin<Options>(LogsPanel) | ||||||
|       defaultValue: false, |       defaultValue: false, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     if (config.featureToggles.newLogsPanel) { |     // In the old panel this is an independent option, in the new panel is linked to wrapLogMessage
 | ||||||
|       builder.addBooleanSwitch({ |     if (!config.featureToggles.newLogsPanel || context.options?.wrapLogMessage) { | ||||||
|         path: 'syntaxHighlighting', |  | ||||||
|         name: t('logs.name-enable-syntax-highlighting', 'Enable syntax highlighting'), |  | ||||||
|         category, |  | ||||||
|         description: t( |  | ||||||
|           'logs.description-enable-syntax-highlighting', |  | ||||||
|           'Use a predefined syntax coloring grammar to highlight relevant parts of the log lines' |  | ||||||
|         ), |  | ||||||
|       }); |  | ||||||
|     } else { |  | ||||||
|       builder.addBooleanSwitch({ |       builder.addBooleanSwitch({ | ||||||
|         path: 'prettifyLogMessage', |         path: 'prettifyLogMessage', | ||||||
|         name: t('logs.name-prettify-json', 'Prettify JSON'), |         name: t('logs.name-prettify-json', 'Prettify JSON'), | ||||||
|  | @ -80,6 +71,18 @@ export const plugin = new PanelPlugin<Options>(LogsPanel) | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (config.featureToggles.newLogsPanel) { | ||||||
|  |       builder.addBooleanSwitch({ | ||||||
|  |         path: 'syntaxHighlighting', | ||||||
|  |         name: t('logs.name-enable-logs-highlighting', 'Enable logs highlighting'), | ||||||
|  |         category, | ||||||
|  |         description: t( | ||||||
|  |           'logs.description-enable-logs-highlighting', | ||||||
|  |           'Use a predefined coloring scheme to highlight relevant parts of the log lines' | ||||||
|  |         ), | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     builder.addBooleanSwitch({ |     builder.addBooleanSwitch({ | ||||||
|       path: 'enableLogDetails', |       path: 'enableLogDetails', | ||||||
|       name: t('logs.name-enable-log-details', 'Enable log details'), |       name: t('logs.name-enable-log-details', 'Enable log details'), | ||||||
|  | @ -91,7 +94,7 @@ export const plugin = new PanelPlugin<Options>(LogsPanel) | ||||||
|     if (config.featureToggles.newLogsPanel && context.options?.enableLogDetails) { |     if (config.featureToggles.newLogsPanel && context.options?.enableLogDetails) { | ||||||
|       builder.addRadio({ |       builder.addRadio({ | ||||||
|         path: 'detailsMode', |         path: 'detailsMode', | ||||||
|         name: t('logs.name-details-mode', 'Log Details panel mode'), |         name: t('logs.name-details-mode', 'Log details panel mode'), | ||||||
|         category, |         category, | ||||||
|         description: '', |         description: '', | ||||||
|         settings: { |         settings: { | ||||||
|  |  | ||||||
|  | @ -9439,7 +9439,7 @@ | ||||||
|       "label-signature": "Signature" |       "label-signature": "Signature" | ||||||
|     }, |     }, | ||||||
|     "description-enable-infinite-scrolling": "Experimental. Request more results by scrolling to the bottom of the logs list.", |     "description-enable-infinite-scrolling": "Experimental. Request more results by scrolling to the bottom of the logs list.", | ||||||
|     "description-enable-syntax-highlighting": "Use a predefined syntax coloring grammar to highlight relevant parts of the log lines", |     "description-enable-logs-highlighting": "Use a predefined coloring scheme to highlight relevant parts of the log lines", | ||||||
|     "description-show-controls": "Display controls to jump to the last or first log line, and filters by log level", |     "description-show-controls": "Display controls to jump to the last or first log line, and filters by log level", | ||||||
|     "fields": { |     "fields": { | ||||||
|       "type": { |       "type": { | ||||||
|  | @ -9711,14 +9711,14 @@ | ||||||
|     }, |     }, | ||||||
|     "name-common-labels": "Common labels", |     "name-common-labels": "Common labels", | ||||||
|     "name-deduplication": "Deduplication", |     "name-deduplication": "Deduplication", | ||||||
|     "name-details-mode": "Log Details panel mode", |     "name-details-mode": "Log details panel mode", | ||||||
|     "name-details-options": { |     "name-details-options": { | ||||||
|       "label-inline": "Inline", |       "label-inline": "Inline", | ||||||
|       "label-sidebar": "Sidebar" |       "label-sidebar": "Sidebar" | ||||||
|     }, |     }, | ||||||
|     "name-enable-infinite-scrolling": "Enable infinite scrolling", |     "name-enable-infinite-scrolling": "Enable infinite scrolling", | ||||||
|     "name-enable-log-details": "Enable log details", |     "name-enable-log-details": "Enable log details", | ||||||
|     "name-enable-syntax-highlighting": "Enable syntax highlighting", |     "name-enable-logs-highlighting": "Enable logs highlighting", | ||||||
|     "name-font-size": "Font size", |     "name-font-size": "Font size", | ||||||
|     "name-order": "Order", |     "name-order": "Order", | ||||||
|     "name-prettify-json": "Prettify JSON", |     "name-prettify-json": "Prettify JSON", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue