From 1aa0a5e7bf5f4a517549b6a142f8ab5bdc53b84b Mon Sep 17 00:00:00 2001 From: Develer Date: Tue, 2 Dec 2025 18:42:52 +0100 Subject: [PATCH] update options footer --- .../PanelDataPane/QueryDetailView.tsx | 146 ++++++++++++++++-- 1 file changed, 129 insertions(+), 17 deletions(-) diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryDetailView.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryDetailView.tsx index dcc2165e90f..357ae185c4c 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryDetailView.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/QueryDetailView.tsx @@ -217,27 +217,119 @@ export function QueryDetailView({ panel, query, queryIndex }: QueryDetailViewPro return undefined; } - let mdDesc = queryOptions.maxDataPoints ?? ''; - if (mdDesc === '' && panelData.request) { - mdDesc = `auto = ${panelData.request.maxDataPoints}`; + const optionItems: React.ReactNode[] = []; + + // Helper to render value with appropriate styling + const renderValue = (value: string | number, isCustom: boolean) => ( + {value} + ); + + // Helper to render the custom indicator (green circle) + const renderCustomIndicator = (isCustom: boolean) => + isCustom ? : null; + + // Max data points - custom if explicitly set + const hasCustomMaxDataPoints = queryOptions.maxDataPoints !== undefined && queryOptions.maxDataPoints !== null; + const mdDesc = queryOptions.maxDataPoints ?? panelData.request?.maxDataPoints ?? '-'; + optionItems.push( + + {renderCustomIndicator(hasCustomMaxDataPoints)} + + Max data points + + {' = '} + {renderValue(mdDesc, hasCustomMaxDataPoints)} + + ); + + // Min interval - custom if explicitly set (not falling back to datasource default) + const hasCustomMinInterval = !!queryOptions.minInterval; + const minIntervalDesc = queryOptions.minInterval ?? datasource?.interval ?? 'No limit'; + optionItems.push( + + {renderCustomIndicator(hasCustomMinInterval)} + + Min interval + + {' = '} + {renderValue(minIntervalDesc, hasCustomMinInterval)} + + ); + + // Interval - read-only, never custom (computed value) + const intervalDesc = panelData.request?.interval ?? '-'; + optionItems.push( + + {renderCustomIndicator(false)} + + Interval + + {' = '} + {renderValue(intervalDesc, false)} + + ); + + // Cache timeout - custom if explicitly set (not using default "60") + if (dsSettings?.meta.queryOptions?.cacheTimeout) { + const hasCustomCacheTimeout = !!queryOptions.cacheTimeout; + const cacheTimeoutDesc = queryOptions.cacheTimeout ?? '60'; + optionItems.push( + + {renderCustomIndicator(hasCustomCacheTimeout)} + + Cache timeout + + {' = '} + {renderValue(cacheTimeoutDesc, hasCustomCacheTimeout)} + + ); } - const intervalDesc = panelData.request?.interval ?? queryOptions.minInterval; + // Cache TTL - custom if explicitly set (not using datasource default) + if (datasource?.cachingConfig?.enabled) { + const hasCustomCacheTTL = queryOptions.queryCachingTTL !== undefined && queryOptions.queryCachingTTL !== null; + const cacheTTLDesc = queryOptions.queryCachingTTL ?? datasource.cachingConfig.TTLMs ?? '-'; + optionItems.push( + + {renderCustomIndicator(hasCustomCacheTTL)} + + Cache TTL + + {' = '} + {renderValue(cacheTTLDesc, hasCustomCacheTTL)} + + ); + } - return ( - <> - { - - MD = {{ mdDesc }} - - } - { - - Interval = {{ intervalDesc }} - - } - + // Relative time - custom if explicitly set + const hasCustomRelativeTime = !!queryOptions.timeRange?.from; + const relativeTime = queryOptions.timeRange?.from ?? '1h'; + optionItems.push( + + {renderCustomIndicator(hasCustomRelativeTime)} + + Relative time + + {' = '} + {renderValue(relativeTime, hasCustomRelativeTime)} + ); + + // Time shift - custom if explicitly set + const hasCustomTimeShift = !!queryOptions.timeRange?.shift; + const timeShift = queryOptions.timeRange?.shift ?? '1h'; + optionItems.push( + + {renderCustomIndicator(hasCustomTimeShift)} + + Time shift + + {' = '} + {renderValue(timeShift, hasCustomTimeShift)} + + ); + + return <>{optionItems}; }; return ( @@ -324,6 +416,7 @@ const getStyles = (theme: GrafanaTheme2) => { color: theme.colors.text.link, cursor: 'pointer', fontSize: theme.typography.bodySmall.fontSize, + marginLeft: 'auto', padding: 0, textDecoration: 'none', '&:hover': { @@ -347,6 +440,25 @@ const getStyles = (theme: GrafanaTheme2) => { marginInline: theme.spacing(1), fontSize: theme.typography.size.sm, color: theme.colors.text.secondary, + display: 'inline-flex', + alignItems: 'center', + gap: theme.spacing(0.5), + }), + collapsedTextLabel: css({ + color: theme.colors.text.primary, + }), + collapsedTextValue: css({ + color: theme.colors.text.secondary, + }), + collapsedTextValueCustom: css({ + color: theme.visualization.getColorByName('green'), + }), + customIndicator: css({ + width: 6, + height: 6, + borderRadius: theme.shape.radius.circle, + backgroundColor: theme.visualization.getColorByName('green'), + flexShrink: 0, }), }; };