Fix/check the flows of toggling logs timestamp and body columns (#6992)

* fix: add default timestamp and body columns to live logs

* refactor: use convertKeysToColumnFields instead of re-modifying the default columns

* fix: remove the local storage selectColumns when clear view is clicked

* fix: improve selectColumns migration handling
This commit is contained in:
Shaheer Kochai 2025-01-31 10:25:47 +04:30 committed by GitHub
parent d910d99689
commit a84e462a65
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 92 additions and 29 deletions

View File

@ -25,7 +25,10 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import ExportPanelContainer from 'container/ExportPanel/ExportPanelContainer';
import { useOptionsMenu } from 'container/OptionsMenu';
import { defaultTraceSelectedColumns } from 'container/OptionsMenu/constants';
import {
defaultLogsSelectedColumns,
defaultTraceSelectedColumns,
} from 'container/OptionsMenu/constants';
import { OptionsQuery } from 'container/OptionsMenu/types';
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
@ -408,6 +411,14 @@ function ExplorerOptions({
const handleClearSelect = (): void => {
removeCurrentViewFromLocalStorage();
handleOptionsChange({
...options,
selectColumns:
sourcepage === DataSource.TRACES
? defaultTraceSelectedColumns
: defaultLogsSelectedColumns,
});
history.replace(DATASOURCE_VS_ROUTES[sourcepage]);
};

View File

@ -13,6 +13,7 @@ import { InfinityWrapperStyled } from 'container/LogsExplorerList/styles';
import { convertKeysToColumnFields } from 'container/LogsExplorerList/utils';
import { Heading } from 'container/LogsTable/styles';
import { useOptionsMenu } from 'container/OptionsMenu';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import { useActiveLog } from 'hooks/logs/useActiveLog';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import { useEventSource } from 'providers/EventSource';
@ -53,7 +54,10 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
[logs, activeLogId],
);
const selectedFields = convertKeysToColumnFields(options.selectColumns);
const selectedFields = convertKeysToColumnFields([
...defaultLogsSelectedColumns,
...options.selectColumns,
]);
const getItemContent = useCallback(
(_: number, log: ILog): JSX.Element => {

View File

@ -5,6 +5,7 @@ import RawLogView from 'components/Logs/RawLogView';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import { LOCALSTORAGE } from 'constants/localStorage';
import ShowButton from 'container/LogsContextList/ShowButton';
import { convertKeysToColumnFields } from 'container/LogsExplorerList/utils';
import { useOptionsMenu } from 'container/OptionsMenu';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import { FontSize } from 'container/OptionsMenu/types';
@ -12,21 +13,12 @@ import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/co
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { IField } from 'types/api/logs/fields';
import { ILog } from 'types/api/logs/log';
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, StringOperators } from 'types/common/queryBuilder';
import { useContextLogData } from './useContextLogData';
const defaultLogsSelectedFields: IField[] = defaultLogsSelectedColumns.map(
(item) => ({
name: item.key,
type: item.type,
dataType: item.dataType,
}),
);
function ContextLogRenderer({
isEdit,
query,
@ -119,7 +111,7 @@ function ContextLogRenderer({
data={logTorender}
linesPerRow={1}
fontSize={options.fontSize}
selectedFields={defaultLogsSelectedFields}
selectedFields={convertKeysToColumnFields(defaultLogsSelectedColumns)}
/>
),
[log.id, options.fontSize],

View File

@ -23,7 +23,8 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { isEqual, isNull } from 'lodash-es';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { DataSource } from 'types/common/queryBuilder';
import { WrapperStyled } from './styles';
@ -86,25 +87,80 @@ function LogsExplorer(): JSX.Element {
redirectWithQuery: redirectWithOptionsData,
} = useUrlQueryData<OptionsQuery>(URL_OPTIONS, defaultOptionsQuery);
const migrateOptionsQuery = (query: OptionsQuery): OptionsQuery => {
// If version is missing AND timestamp/body are not in selectColumns, this is an old URL
if (
!query.version &&
!query.selectColumns.some((col) => col.key === 'timestamp') &&
!query.selectColumns.some((col) => col.key === 'body')
) {
// Get and parse stored columns from localStorage
const logListOptionsFromLocalStorage = useMemo(() => {
const data = getLocalStorageKey(LOCALSTORAGE.LOGS_LIST_OPTIONS);
if (!data) return null;
try {
const parsed = JSON.parse(data);
const hasValidColumns = Array.isArray(parsed?.selectColumns);
return hasValidColumns ? parsed.selectColumns : null;
} catch {
return null;
}
}, []);
// Check if the columns have the required columns (timestamp, body)
const hasRequiredColumns = useCallback(
(columns?: Array<{ key: string }> | null): boolean => {
if (!columns?.length) return false;
const hasTimestamp = columns.some((col) => col.key === 'timestamp');
const hasBody = columns.some((col) => col.key === 'body');
return hasTimestamp && hasBody;
},
[],
);
// Merge the columns with the required columns (timestamp, body) if missing
const mergeWithRequiredColumns = useCallback(
(columns: BaseAutocompleteData[]): BaseAutocompleteData[] => [
// Add required columns (timestamp, body) if missing
...(!hasRequiredColumns(columns) ? defaultLogsSelectedColumns : []),
...columns,
],
[hasRequiredColumns],
);
// Migrate the options query to the new format
const migrateOptionsQuery = useCallback(
(query: OptionsQuery): OptionsQuery => {
// Skip if already migrated
if (query.version) return query;
// Case 1: query has columns
if (query.selectColumns.length > 0) {
return {
...query,
version: 1,
selectColumns: mergeWithRequiredColumns(query.selectColumns),
};
}
// Case 2: No query columns in but we have localStorage columns
if (logListOptionsFromLocalStorage?.selectColumns?.length > 0) {
return {
...query,
version: 1,
selectColumns: mergeWithRequiredColumns(
logListOptionsFromLocalStorage.selectColumns,
),
};
}
// Case 3: No columns anywhere, use defaults
return {
...query,
version: 1,
selectColumns: [
// Add default timestamp and body columns
...defaultLogsSelectedColumns,
...query.selectColumns,
],
selectColumns: defaultLogsSelectedColumns,
};
}
return query;
};
},
[mergeWithRequiredColumns, logListOptionsFromLocalStorage?.selectColumns],
);
useEffect(() => {
const migratedQuery = migrateOptionsQuery(optionsQueryData);
@ -112,7 +168,7 @@ function LogsExplorer(): JSX.Element {
if (!isEqual(migratedQuery, optionsQueryData)) {
redirectWithOptionsData(migratedQuery);
}
}, [optionsQueryData, redirectWithOptionsData]);
}, [migrateOptionsQuery, optionsQueryData, redirectWithOptionsData]);
const isMultipleQueries = useMemo(
() =>