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:
Matias Chomicki 2025-09-17 12:13:13 +02:00 committed by GitHub
parent 8c284cbcba
commit a044f567a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 51 additions and 39 deletions

View File

@ -75,6 +75,7 @@ export interface Props {
permalinkedLogId?: string;
pinLineButtonTooltipTitle?: PopoverContent;
pinnedLogs?: string[];
prettifyJSON?: boolean;
setDisplayedFields?: (displayedFields: string[]) => void;
showControls: boolean;
showTime: boolean;
@ -88,7 +89,7 @@ export interface Props {
export type LogListFontSize = 'default' | 'small';
export type LogListControlOptions = keyof LogListState | 'wrapLogMessage' | 'prettifyJSON';
export type LogListControlOptions = keyof LogListState | 'wrapLogMessage' | 'prettifyLogMessage';
type LogListComponentProps = Omit<
Props,
@ -143,6 +144,7 @@ export const LogList = ({
permalinkedLogId,
pinLineButtonTooltipTitle,
pinnedLogs,
prettifyJSON = logOptionsStorageKey ? store.getBool(`${logOptionsStorageKey}.prettifyLogMessage`, true) : true,
setDisplayedFields,
showControls,
showTime,
@ -186,6 +188,7 @@ export const LogList = ({
permalinkedLogId={permalinkedLogId}
pinLineButtonTooltipTitle={pinLineButtonTooltipTitle}
pinnedLogs={pinnedLogs}
prettifyJSON={prettifyJSON}
setDisplayedFields={setDisplayedFields}
showControls={showControls}
showTime={showTime}

View File

@ -151,8 +151,6 @@ export type LogListState = Pick<
| 'timestampResolution'
>;
export type LogListOption = keyof LogListState | 'wrapLogMessage' | 'prettifyJSON';
export interface Props {
app: CoreApp;
children?: ReactNode;
@ -233,9 +231,7 @@ export const LogListContextProvider = ({
permalinkedLogId,
pinLineButtonTooltipTitle,
pinnedLogs,
prettifyJSON: prettifyJSONProp = logOptionsStorageKey
? store.getBool(`${logOptionsStorageKey}.prettifyLogMessage`, true)
: true,
prettifyJSON: prettifyJSONProp,
setDisplayedFields,
showControls,
showTime,
@ -280,8 +276,10 @@ export const LogListContextProvider = ({
fontSize,
forceEscape: logListState.forceEscape,
showTime,
showUniqueLabels,
syntaxHighlighting,
wrapLogMessage,
prettifyJSON,
detailsWidth,
detailsMode,
withDisplayedFields: displayedFields.length > 0,
@ -312,24 +310,14 @@ export const LogListContextProvider = ({
...logListState,
dedupStrategy,
showTime,
showUniqueLabels,
sortOrder,
syntaxHighlighting,
wrapLogMessage,
};
if (!shallowCompare(logListState, newState)) {
setLogListState(newState);
}
}, [
app,
dedupStrategy,
logListState,
pinnedLogs,
showControls,
showTime,
sortOrder,
syntaxHighlighting,
wrapLogMessage,
]);
}, [app, dedupStrategy, logListState, showControls, showTime, showUniqueLabels, sortOrder, syntaxHighlighting]);
// Sync filter levels
useEffect(() => {
@ -344,6 +332,11 @@ export const LogListContextProvider = ({
});
}, [filterLevels]);
// Sync details mode
useEffect(() => {
setDetailsMode(detailsModeProp);
}, [detailsModeProp]);
// Sync font size
useEffect(() => {
setLogListState((logListState) => ({ ...logListState, fontSize }));
@ -389,6 +382,18 @@ export const LogListContextProvider = ({
return () => observer.disconnect();
}, [containerElement, detailsMode, logOptionsStorageKey, showControls]);
// Sync prettifyJSON
useEffect(() => {
if (prettifyJSONProp !== undefined) {
setPrettifyJSONState(prettifyJSONProp);
}
}, [prettifyJSONProp]);
// Sync wrapLogMessage
useEffect(() => {
setWrapLogMessageState(wrapLogMessageProp);
}, [wrapLogMessageProp]);
// Sync timestamp resolution
useEffect(() => {
setLogListState((state) => ({
@ -485,7 +490,7 @@ export const LogListContextProvider = ({
if (logOptionsStorageKey) {
store.set(`${logOptionsStorageKey}.prettifyLogMessage`, prettifyJSON);
}
onLogOptionsChange?.('prettifyJSON', prettifyJSON);
onLogOptionsChange?.('prettifyLogMessage', prettifyJSON);
},
[logOptionsStorageKey, onLogOptionsChange]
);

View File

@ -303,19 +303,19 @@ describe('LogListControls', () => {
expect(onLogOptionsChange).toHaveBeenCalledTimes(2);
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.getByText(WRAP_JSON_TOOLTIP_COPY));
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.getByText(WRAP_DISABLE_LABEL_COPY));
expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', false);
expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', false);
expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyLogMessage', false);
expect(onLogOptionsChange).toHaveBeenCalledTimes(6);

View File

@ -735,7 +735,7 @@ const WrapLogMessageButton = ({ expanded }: LogSelectOptionProps) => {
tooltip={tooltip}
label={wrapStateText}
buttonAriaLabel={tooltip}
customTagText={'+'}
customTagText={prettifyJSON ? '+' : ''}
/>
);
};

View File

@ -69,7 +69,7 @@ export const LogListControlsSelectOption = React.forwardRef<SVGElement, SelectPr
className: iconButtonClassName,
name: iconButtonName,
dropdown,
isActive: isActive,
isActive,
customTagText,
buttonAriaLabel,
...iconButtonProps

View File

@ -606,6 +606,7 @@ export const LogsPanel = ({
onOpenContext={onOpenContext}
onPermalinkClick={showPermaLink() ? onPermalinkClick : undefined}
permalinkedLogId={getLogsPanelState()?.logs?.id ?? undefined}
prettifyJSON={prettifyLogMessage}
setDisplayedFields={setDisplayedFieldsFn}
showControls={Boolean(showControls)}
showTime={showTime}

View File

@ -60,17 +60,8 @@ export const plugin = new PanelPlugin<Options>(LogsPanel)
defaultValue: false,
});
if (config.featureToggles.newLogsPanel) {
builder.addBooleanSwitch({
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 {
// In the old panel this is an independent option, in the new panel is linked to wrapLogMessage
if (!config.featureToggles.newLogsPanel || context.options?.wrapLogMessage) {
builder.addBooleanSwitch({
path: 'prettifyLogMessage',
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({
path: 'enableLogDetails',
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) {
builder.addRadio({
path: 'detailsMode',
name: t('logs.name-details-mode', 'Log Details panel mode'),
name: t('logs.name-details-mode', 'Log details panel mode'),
category,
description: '',
settings: {

View File

@ -9439,7 +9439,7 @@
"label-signature": "Signature"
},
"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",
"fields": {
"type": {
@ -9711,14 +9711,14 @@
},
"name-common-labels": "Common labels",
"name-deduplication": "Deduplication",
"name-details-mode": "Log Details panel mode",
"name-details-mode": "Log details panel mode",
"name-details-options": {
"label-inline": "Inline",
"label-sidebar": "Sidebar"
},
"name-enable-infinite-scrolling": "Enable infinite scrolling",
"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-order": "Order",
"name-prettify-json": "Prettify JSON",