bug fixes
This commit is contained in:
@@ -54,7 +54,7 @@ export interface ThemeTypographyInput {
|
||||
}
|
||||
|
||||
const defaultFontFamily = "'Inter', 'Helvetica', 'Arial', sans-serif";
|
||||
const defaultFontFamilyMonospace = "'Roboto Mono', monospace";
|
||||
const defaultFontFamilyMonospace = "'CommitMono', monospace";
|
||||
|
||||
export function createTypography(colors: ThemeColors, typographyInput: ThemeTypographyInput = {}): ThemeTypography {
|
||||
const {
|
||||
|
||||
@@ -32,7 +32,7 @@ const theme: GrafanaThemeCommons = {
|
||||
typography: {
|
||||
fontFamily: {
|
||||
sansSerif: '"Inter", "Helvetica", "Arial", sans-serif',
|
||||
monospace: "'Roboto Mono', monospace",
|
||||
monospace: "'CommitMono', monospace",
|
||||
},
|
||||
size: {
|
||||
base: '14px',
|
||||
|
||||
@@ -90,11 +90,7 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
return undefined;
|
||||
}, [selectedItem]);
|
||||
|
||||
// Get all queries for validation
|
||||
const allQueries = useMemo(() => {
|
||||
const queryRunner = getQueryRunnerFor(panel);
|
||||
return queryRunner?.state.queries || [];
|
||||
}, [panel]);
|
||||
const queryRunner = getQueryRunnerFor(panel);
|
||||
|
||||
// Handle datasource change for queries
|
||||
const handleDataSourceChange = useCallback(
|
||||
@@ -177,7 +173,7 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
return;
|
||||
}
|
||||
|
||||
for (const otherQuery of allQueries) {
|
||||
for (const otherQuery of queryRunner?.state.queries || []) {
|
||||
if (otherQuery !== selectedItem.data && newName === otherQuery.refId) {
|
||||
setValidationError('Query name already exists');
|
||||
return;
|
||||
@@ -188,7 +184,7 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
setValidationError(null);
|
||||
}
|
||||
},
|
||||
[allQueries, selectedItem.data, validationError]
|
||||
[queryRunner, selectedItem.data, validationError]
|
||||
);
|
||||
|
||||
const onEditQueryBlur = useCallback(
|
||||
@@ -290,7 +286,7 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
<>
|
||||
{!isEditing ? (
|
||||
<button
|
||||
className={styles.queryNameWrapper}
|
||||
className={cx(styles.queryNameWrapper, styles.monospace)}
|
||||
title={t('dashboard-scene.detail-view-header.edit-query-name', 'Edit query name')}
|
||||
onClick={onEditQueryName}
|
||||
type="button"
|
||||
@@ -321,7 +317,14 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
{/* Right side: Run Query + Actions Menu */}
|
||||
{(selectedItem.type === 'query' || selectedItem.type === 'expression') && (
|
||||
<Stack gap={0.5} alignItems="center">
|
||||
<Button variant="primary" fill="text" size="sm" onClick={onRunQuery} icon="play">
|
||||
<Button
|
||||
className={styles.monospace}
|
||||
variant="primary"
|
||||
fill="text"
|
||||
size="sm"
|
||||
onClick={onRunQuery}
|
||||
icon="play"
|
||||
>
|
||||
{t('dashboard-scene.detail-view-header.run-query', 'RUN QUERY')}
|
||||
</Button>
|
||||
<Dropdown
|
||||
@@ -365,6 +368,9 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps)
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2, config: { color: string }) => {
|
||||
return {
|
||||
monospace: css({
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
}),
|
||||
header: css({
|
||||
padding: theme.spacing(0.5),
|
||||
borderLeft: `4px solid ${config.color}`,
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { SceneDataQuery, VizPanel, sceneGraph, SceneQueryRunner } from '@grafana/scenes';
|
||||
import { Button, ErrorBoundaryAlert, useStyles2 } from '@grafana/ui';
|
||||
import { Button, ErrorBoundaryAlert, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow';
|
||||
import { QueryErrorAlert } from 'app/features/query/components/QueryErrorAlert';
|
||||
import { QueryGroupOptionsEditor } from 'app/features/query/components/QueryGroupOptions';
|
||||
@@ -334,45 +334,58 @@ export function QueryDetailView({ panel, query, queryIndex }: QueryDetailViewPro
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={cx(styles.contentWrapper, showOptions && styles.contentWrapperTwoColumn)}>
|
||||
<div className={styles.mainContent}>
|
||||
<QueryOperationRow
|
||||
id={`query-${query.refId}`}
|
||||
index={queryIndex}
|
||||
draggable={false}
|
||||
collapsable={false}
|
||||
isOpen={true}
|
||||
hideHeader={true}
|
||||
className={styles.queryOperationRow}
|
||||
>
|
||||
<div className={styles.queryContent}>
|
||||
{error && <QueryErrorAlert error={error} />}
|
||||
{renderQueryEditor()}
|
||||
</div>
|
||||
</QueryOperationRow>
|
||||
<div className={styles.footer}>
|
||||
{renderCollapsedText()}
|
||||
<div className={cx(styles.content, showOptions && styles.contentOptionsVisible)}>
|
||||
<QueryOperationRow
|
||||
id={`query-${query.refId}`}
|
||||
index={queryIndex}
|
||||
draggable={false}
|
||||
collapsable={false}
|
||||
isOpen={true}
|
||||
hideHeader={true}
|
||||
className={styles.queryOperationRow}
|
||||
>
|
||||
<div className={styles.queryContent}>
|
||||
{error && <QueryErrorAlert error={error} />}
|
||||
{renderQueryEditor()}
|
||||
</div>
|
||||
</QueryOperationRow>
|
||||
<div className={styles.optionsColumn}>
|
||||
<Stack gap={1} direction="column">
|
||||
<Button
|
||||
size="sm"
|
||||
icon={showOptions ? 'angle-right' : 'angle-left'}
|
||||
size="md"
|
||||
icon="angle-right"
|
||||
fill="text"
|
||||
variant="secondary"
|
||||
onClick={() => setShowOptions(!showOptions)}
|
||||
className={styles.optionsButton}
|
||||
>
|
||||
<Trans i18nKey="dashboard-scene.query-detail-view.options">Options</Trans>
|
||||
<Trans i18nKey="dashboard-scene.query-detail-view.query-options">Query Options</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
{datasource && panelData && (
|
||||
<QueryGroupOptionsEditor
|
||||
options={queryOptions}
|
||||
dataSource={datasource}
|
||||
data={panelData}
|
||||
onChange={handleQueryOptionsChange}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
{showOptions && datasource && panelData && (
|
||||
<div className={styles.optionsColumn}>
|
||||
<QueryGroupOptionsEditor
|
||||
options={queryOptions}
|
||||
dataSource={datasource}
|
||||
data={panelData}
|
||||
onChange={handleQueryOptionsChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{datasource && panelData && !showOptions && (
|
||||
<div className={styles.optionsFooter}>
|
||||
{renderCollapsedText()}
|
||||
<Button
|
||||
size="sm"
|
||||
icon="angle-left"
|
||||
fill="text"
|
||||
onClick={() => setShowOptions(!showOptions)}
|
||||
className={styles.optionsButton}
|
||||
>
|
||||
<Trans i18nKey="dashboard-scene.query-detail-view.options">Options</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -382,36 +395,34 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
container: css({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}),
|
||||
contentWrapper: css({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}),
|
||||
contentWrapperTwoColumn: css({
|
||||
gridTemplateColumns: '1fr 0.5fr',
|
||||
}),
|
||||
mainContent: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
position: 'relative',
|
||||
overflow: 'scroll',
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
content: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: '100%',
|
||||
width: 'calc(100% + 300px)',
|
||||
[theme.transitions.handleMotion('no-preference', 'reduce')]: {
|
||||
transition: theme.transitions.create(['width'], {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
contentOptionsVisible: css({
|
||||
width: '100%',
|
||||
}),
|
||||
queryContent: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: theme.spacing(1),
|
||||
padding: theme.spacing(2),
|
||||
height: '100%',
|
||||
overflow: 'scroll',
|
||||
}),
|
||||
queryOperationRow: css({
|
||||
marginBottom: '0 !important', // need to beat specificty in the underling component
|
||||
minHeight: 'calc(100% - 32px)', // 32px for the footer
|
||||
overflow: 'scroll',
|
||||
maxHeight: 'calc(100% - 32px)', // 32px for the footer
|
||||
width: 'calc(100% - 300px)',
|
||||
overflowY: 'auto',
|
||||
}),
|
||||
footer: css({
|
||||
optionsFooter: css({
|
||||
height: '32px',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
@@ -424,12 +435,18 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
background: theme.colors.background.secondary,
|
||||
}),
|
||||
optionsColumn: css({
|
||||
width: '300px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
borderLeft: `1px solid ${theme.colors.border.weak}`,
|
||||
background: theme.colors.background.secondary,
|
||||
padding: theme.spacing(2),
|
||||
}),
|
||||
optionsButton: css({
|
||||
paddingLeft: 0,
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
textTransform: 'uppercase',
|
||||
}),
|
||||
noEditor: css({
|
||||
padding: theme.spacing(2),
|
||||
textAlign: 'center',
|
||||
|
||||
@@ -224,7 +224,7 @@ const getStyles = (theme: GrafanaTheme2, colors: ReturnType<typeof usePanelDataP
|
||||
flexShrink: 0,
|
||||
}),
|
||||
typeLabel: css({
|
||||
fontFamily: "'CommitMono', monospace",
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
fontSize: theme.typography.bodySmall.fontSize,
|
||||
color: 'inherit',
|
||||
textTransform: 'uppercase',
|
||||
@@ -243,7 +243,7 @@ const getStyles = (theme: GrafanaTheme2, colors: ReturnType<typeof usePanelDataP
|
||||
flexShrink: 0,
|
||||
}),
|
||||
name: css({
|
||||
fontFamily: "'CommitMono', monospace",
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
fontSize: theme.typography.bodySmall.fontSize,
|
||||
color: theme.colors.text.maxContrast,
|
||||
overflow: 'hidden',
|
||||
|
||||
@@ -231,7 +231,6 @@ QueryTransformList.displayName = 'QueryTransformList';
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
const headerHeight = 41;
|
||||
const footerHeight = 32;
|
||||
const monoFont = "'CommitMono', monospace";
|
||||
const barBase = {
|
||||
padding: theme.spacing(0.5, 2),
|
||||
background: theme.colors.background.secondary,
|
||||
@@ -257,12 +256,12 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||
}),
|
||||
headerTitle: css({
|
||||
fontFamily: monoFont,
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
textTransform: 'uppercase',
|
||||
color: theme.colors.text.primary,
|
||||
}),
|
||||
sectionLabel: css({
|
||||
fontFamily: "'CommitMono', monospace",
|
||||
fontFamily: theme.typography.fontFamilyMonospace
|
||||
fontSize: theme.typography.bodySmall.fontSize,
|
||||
color: theme.colors.text.maxContrast,
|
||||
textTransform: 'uppercase',
|
||||
@@ -295,7 +294,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
zIndex: 20,
|
||||
}),
|
||||
footerStat: css({
|
||||
fontFamily: monoFont,
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
fontSize: theme.typography.bodySmall.fontSize,
|
||||
color: theme.colors.text.primary,
|
||||
textTransform: 'uppercase',
|
||||
|
||||
@@ -194,7 +194,7 @@ export const QueryGroupOptionsEditor = React.memo(({ options, dataSource, data,
|
||||
const renderMaxDataPointsOption = () => {
|
||||
const realMd = data.request?.maxDataPoints;
|
||||
const value = options.maxDataPoints ?? '';
|
||||
const isAuto = value === '';
|
||||
// const isAuto = value === '';
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -220,7 +220,7 @@ export const QueryGroupOptionsEditor = React.memo(({ options, dataSource, data,
|
||||
onBlur={onMaxDataPointsBlur}
|
||||
defaultValue={value}
|
||||
/>
|
||||
{isAuto && (
|
||||
{/* {isAuto && (
|
||||
<>
|
||||
<span className={cx(styles.noSquish, styles.operator)}>=</span>
|
||||
<span className={cx(styles.noSquish, styles.left)}>
|
||||
@@ -229,7 +229,7 @@ export const QueryGroupOptionsEditor = React.memo(({ options, dataSource, data,
|
||||
</Trans>
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
)} */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -274,12 +274,12 @@ export const QueryGroupOptionsEditor = React.memo(({ options, dataSource, data,
|
||||
<Trans i18nKey="query.query-group-options-editor.render-interval-option.interval">Interval</Trans>
|
||||
</InlineLabel>
|
||||
<span className={styles.noSquish}>{realInterval}</span>
|
||||
<span className={cx(styles.noSquish, styles.operator)}>=</span>
|
||||
{/* <span className={cx(styles.noSquish, styles.operator)}>=</span>
|
||||
<span className={cx(styles.noSquish, styles.left)}>
|
||||
<Trans i18nKey="query.query-group-options-editor.render-interval-option.time-range-max-data-points">
|
||||
Time range / max data points
|
||||
</Trans>
|
||||
</span>
|
||||
</span> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -374,10 +374,11 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
grid: css({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: `auto minmax(5em, 1fr) auto 1fr`,
|
||||
gridTemplateColumns: `auto 8em`,
|
||||
gap: theme.spacing(0.5),
|
||||
gridAutoRows: theme.spacing(4),
|
||||
whiteSpace: 'nowrap',
|
||||
minWidth: '100%',
|
||||
}),
|
||||
firstColumn: css({
|
||||
gridColumn: 1,
|
||||
|
||||
Reference in New Issue
Block a user