From a196cc1adb636e14c9c0fade4c090777b39afc2c Mon Sep 17 00:00:00 2001 From: L2D2Grafana Date: Fri, 12 Dec 2025 07:36:45 -0800 Subject: [PATCH] Logs: displayFields migration us columns for vistype table --- public/app/features/explore/Logs/Logs.tsx | 2 +- .../explore/Logs/utils/columnMigration.ts | 82 +++++++++++++++---- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/public/app/features/explore/Logs/Logs.tsx b/public/app/features/explore/Logs/Logs.tsx index 86934cf59d9..54de3fd1de3 100644 --- a/public/app/features/explore/Logs/Logs.tsx +++ b/public/app/features/explore/Logs/Logs.tsx @@ -364,7 +364,7 @@ const UnthemedLogs: React.FunctionComponent = (props: Props) => { const currentDisplayedFields = displayedFields; // Use migration utility to parse and transform legacy columns - const mergedFields = migrateLegacyColumns(urlPane.panelsState.logs, currentDisplayedFields); + const mergedFields = migrateLegacyColumns(urlPane.panelsState.logs, currentDisplayedFields, visualisationType); if (!mergedFields) { return; } diff --git a/public/app/features/explore/Logs/utils/columnMigration.ts b/public/app/features/explore/Logs/utils/columnMigration.ts index a40a60687f5..91658925f0d 100644 --- a/public/app/features/explore/Logs/utils/columnMigration.ts +++ b/public/app/features/explore/Logs/utils/columnMigration.ts @@ -1,4 +1,8 @@ -import { LOG_LINE_BODY_FIELD_NAME, TABLE_LINE_FIELD_NAME } from 'app/features/logs/components/LogDetailsBody'; +import { + LOG_LINE_BODY_FIELD_NAME, + TABLE_LINE_FIELD_NAME, + TABLE_TIME_FIELD_NAME, +} from 'app/features/logs/components/LogDetailsBody'; /** * Migration utility for converting legacy 'columns' URL parameter to 'displayedFields'. @@ -45,17 +49,25 @@ export function parseLegacyColumns(columnsValue: unknown): string[] | null { /** * Maps legacy field names to their new equivalents. - * Currently maps 'Line' to the LOG_LINE_BODY_FIELD_NAME constant. + * Maps: 'Line' -> LOG_LINE_BODY_FIELD_NAME, 'timestamp' -> 'Time', 'body' -> LOG_LINE_BODY_FIELD_NAME * * @param columns - Array of column names * @returns Array with mapped column names */ export function mapLegacyFieldNames(columns: string[]): string[] { return columns.map((column) => { - // Map 'Line' to LOG_LINE_BODY_FIELD_NAME (typically 'body') + // Map 'Line' to LOG_LINE_BODY_FIELD_NAME if (column === TABLE_LINE_FIELD_NAME) { return LOG_LINE_BODY_FIELD_NAME; } + // Map 'timestamp' to TABLE_TIME_FIELD_NAME ('Time') + if (column === 'timestamp') { + return TABLE_TIME_FIELD_NAME; + } + // Map 'body' to LOG_LINE_BODY_FIELD_NAME + if (column === 'body') { + return LOG_LINE_BODY_FIELD_NAME; + } return column; }); } @@ -105,31 +117,71 @@ export function extractColumnsValue(logsState: object): unknown { return descriptor?.value; } +/** + * Extracts the displayedFields value from logs state using safe property access. + * + * @param logsState - The logs panel state from URL + * @returns The displayedFields value, or undefined if not present + */ +export function extractDisplayedFields(logsState: object): unknown { + const descriptor = Object.getOwnPropertyDescriptor(logsState, 'displayedFields'); + return descriptor?.value; +} + /** * Main migration function - orchestrates the full migration process. * Returns the migrated and merged fields, or null if no migration is needed. * + * For table visualization: merges defaults with legacy 'columns' from URL + * For logs visualization: merges defaults with 'displayedFields' from URL + * * @param logsState - The logs panel state from URL * @param defaultDisplayedFields - Default fields to merge with + * @param visualisationType - The current visualization type ('table' or 'logs') * @returns Merged displayed fields array, or null if no migration needed */ -export function migrateLegacyColumns(logsState: unknown, defaultDisplayedFields: string[]): string[] | null { - // Check if migration is needed (type guard narrows logsState to object) - if (!hasLegacyColumns(logsState)) { +export function migrateLegacyColumns( + logsState: unknown, + defaultDisplayedFields: string[], + visualisationType?: string +): string[] | null { + console.log('logsState', logsState); + // Ensure logsState is an object + if (!logsState || typeof logsState !== 'object') { return null; } - // Extract and parse the columns value - const columnsValue = extractColumnsValue(logsState); - const parsedColumns = parseLegacyColumns(columnsValue); + // For table visualization: only use columns from URL and map the old field names to the new ones + if (visualisationType === 'table') { + if (!hasLegacyColumns(logsState)) { + return null; + } - if (!parsedColumns) { - return null; + const columnsValue = extractColumnsValue(logsState); + const parsedColumns = parseLegacyColumns(columnsValue); + + if (!parsedColumns) { + return null; + } + + // Map legacy field names to new names + const mappedColumns = mapLegacyFieldNames(parsedColumns); + + return mappedColumns; } - // Map legacy field names to new names - const mappedColumns = mapLegacyFieldNames(parsedColumns); + // For logs visualization only use displayedFields from URL + if (visualisationType === 'logs') { + const displayedFieldsValue = extractDisplayedFields(logsState); - // Merge with defaults - return mergeWithDefaults(mappedColumns, defaultDisplayedFields); + // displayedFields should already be an array of strings + if (!Array.isArray(displayedFieldsValue) || displayedFieldsValue.length === 0) { + return null; + } + + return displayedFieldsValue; + } + + // No visualisationType specified or unknown type - return null + return null; }