mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tracing: Upgrade tracing data source configuration editors (#68764)
* Add tracing config sub sections * Export common sections and update divider in additional settings section * Max width and margin bottom * Add feature name to config link * Update SpanBarSettings * remove import
This commit is contained in:
@@ -254,7 +254,7 @@
|
|||||||
"@grafana/aws-sdk": "0.0.44",
|
"@grafana/aws-sdk": "0.0.44",
|
||||||
"@grafana/data": "workspace:*",
|
"@grafana/data": "workspace:*",
|
||||||
"@grafana/e2e-selectors": "workspace:*",
|
"@grafana/e2e-selectors": "workspace:*",
|
||||||
"@grafana/experimental": "1.1.0",
|
"@grafana/experimental": "1.4.2",
|
||||||
"@grafana/faro-core": "1.0.2",
|
"@grafana/faro-core": "1.0.2",
|
||||||
"@grafana/faro-web-sdk": "1.0.2",
|
"@grafana/faro-web-sdk": "1.0.2",
|
||||||
"@grafana/google-sdk": "0.1.1",
|
"@grafana/google-sdk": "0.1.1",
|
||||||
|
|||||||
47
public/app/core/components/ConfigDescriptionLink.tsx
Normal file
47
public/app/core/components/ConfigDescriptionLink.tsx
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
description: string;
|
||||||
|
suffix: string;
|
||||||
|
feature: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ConfigDescriptionLink(props: Props) {
|
||||||
|
const { description, suffix, feature } = props;
|
||||||
|
const text = `Learn more about ${feature}`;
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={styles.container}>
|
||||||
|
{description}
|
||||||
|
<a
|
||||||
|
aria-label={text}
|
||||||
|
href={`https://grafana.com/docs/grafana/next/datasources/${suffix}`}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => {
|
||||||
|
return {
|
||||||
|
container: css({
|
||||||
|
color: theme.colors.text.secondary,
|
||||||
|
a: css({
|
||||||
|
color: theme.colors.text.link,
|
||||||
|
textDecoration: 'underline',
|
||||||
|
marginLeft: '5px',
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'none',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
};
|
||||||
25
public/app/core/components/Divider.tsx
Normal file
25
public/app/core/components/Divider.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
|
export const Divider = ({ hideLine = false }) => {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
|
if (hideLine) {
|
||||||
|
return <hr className={styles.dividerHideLine} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <hr className={styles.divider} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
|
divider: css`
|
||||||
|
margin: ${theme.spacing(4, 0)};
|
||||||
|
`,
|
||||||
|
dividerHideLine: css`
|
||||||
|
border: none;
|
||||||
|
margin: ${theme.spacing(3, 0)};
|
||||||
|
`,
|
||||||
|
});
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { LinkButton } from '@grafana/ui';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
hrefSuffix: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function DocsLinkButton(props: Props) {
|
|
||||||
const { hrefSuffix } = props;
|
|
||||||
const tooltip = 'Learn more in the Grafana docs';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LinkButton
|
|
||||||
aria-label={tooltip}
|
|
||||||
icon="external-link-alt"
|
|
||||||
fill="text"
|
|
||||||
href={`https://grafana.com/docs/grafana/next/datasources/${hrefSuffix}`}
|
|
||||||
variant="secondary"
|
|
||||||
size="md"
|
|
||||||
target="_blank"
|
|
||||||
tooltip={tooltip}
|
|
||||||
tooltipPlacement="top"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,10 @@ import {
|
|||||||
GrafanaTheme2,
|
GrafanaTheme2,
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { ConfigSubSection } from '@grafana/experimental';
|
||||||
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { DocsLinkButton } from './DocsLinkButton';
|
import { ConfigDescriptionLink } from './ConfigDescriptionLink';
|
||||||
|
|
||||||
export interface NodeGraphOptions {
|
export interface NodeGraphOptions {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
@@ -26,13 +27,6 @@ export function NodeGraphSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">Node graph</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
{`Show or hide the node graph visualization`}
|
|
||||||
<DocsLinkButton hrefSuffix={`${options.type}/#node-graph`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField
|
<InlineField
|
||||||
tooltip="Displays the node graph above the trace view. Default: disabled"
|
tooltip="Displays the node graph above the trace view. Default: disabled"
|
||||||
@@ -55,6 +49,23 @@ export function NodeGraphSettings({ options, onOptionsChange }: Props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const NodeGraphSection = ({ options, onOptionsChange }: DataSourcePluginOptionsEditorProps) => {
|
||||||
|
return (
|
||||||
|
<ConfigSubSection
|
||||||
|
title="Node graph"
|
||||||
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Show or hide the node graph visualization."
|
||||||
|
suffix={`${options.type}/#node-graph`}
|
||||||
|
feature="the node graph"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSubSection>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => ({
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
infoText: css`
|
infoText: css`
|
||||||
label: infoText;
|
label: infoText;
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import {
|
import { DataSourceJsonData, DataSourceInstanceSettings, DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||||
DataSourceJsonData,
|
import { ConfigSection } from '@grafana/experimental';
|
||||||
DataSourceInstanceSettings,
|
|
||||||
DataSourcePluginOptionsEditorProps,
|
|
||||||
GrafanaTheme2,
|
|
||||||
} from '@grafana/data';
|
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { InlineField, InlineFieldRow, Input, useStyles2, InlineSwitch } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, Input, InlineSwitch } from '@grafana/ui';
|
||||||
|
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||||
import { DocsLinkButton } from '../DocsLinkButton';
|
|
||||||
|
|
||||||
import { TagMappingInput } from './TagMappingInput';
|
import { TagMappingInput } from './TagMappingInput';
|
||||||
|
|
||||||
@@ -71,7 +66,6 @@ export function getTraceToLogsOptions(data?: TraceToLogsData): TraceToLogsOption
|
|||||||
interface Props extends DataSourcePluginOptionsEditorProps<TraceToLogsData> {}
|
interface Props extends DataSourcePluginOptionsEditorProps<TraceToLogsData> {}
|
||||||
|
|
||||||
export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
|
export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
|
||||||
const styles = useStyles2(getStyles);
|
|
||||||
const supportedDataSourceTypes = [
|
const supportedDataSourceTypes = [
|
||||||
'loki',
|
'loki',
|
||||||
'elasticsearch',
|
'elasticsearch',
|
||||||
@@ -108,13 +102,6 @@ export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css({ width: '100%' })}>
|
<div className={css({ width: '100%' })}>
|
||||||
<h3 className="page-heading">Trace to logs</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Navigate from a trace span to the selected data source's logs
|
|
||||||
<DocsLinkButton hrefSuffix={`${options.type}/#trace-to-logs`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField
|
<InlineField
|
||||||
tooltip="The logs data source the trace is going to navigate to"
|
tooltip="The logs data source the trace is going to navigate to"
|
||||||
@@ -261,9 +248,21 @@ function TimeRangeShift(props: TimeRangeShiftProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => ({
|
export const TraceToLogsSection = ({ options, onOptionsChange }: DataSourcePluginOptionsEditorProps) => {
|
||||||
infoText: css`
|
return (
|
||||||
padding-bottom: ${theme.spacing(2)};
|
<ConfigSection
|
||||||
color: ${theme.colors.text.secondary};
|
title="Trace to logs"
|
||||||
`,
|
description={
|
||||||
});
|
<ConfigDescriptionLink
|
||||||
|
description="Navigate from a trace span to the selected data source's logs."
|
||||||
|
suffix={`${options.type}/#trace-to-logs`}
|
||||||
|
feature="trace to logs"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
isCollapsible={true}
|
||||||
|
isInitiallyOpen={true}
|
||||||
|
>
|
||||||
|
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSection>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import {
|
|||||||
GrafanaTheme2,
|
GrafanaTheme2,
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { ConfigSection } from '@grafana/experimental';
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { Button, InlineField, InlineFieldRow, Input, useStyles2 } from '@grafana/ui';
|
import { Button, InlineField, InlineFieldRow, Input, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { DocsLinkButton } from '../DocsLinkButton';
|
import { ConfigDescriptionLink } from '../ConfigDescriptionLink';
|
||||||
import { TagMappingInput } from '../TraceToLogs/TagMappingInput';
|
import { TagMappingInput } from '../TraceToLogs/TagMappingInput';
|
||||||
|
|
||||||
export interface TraceToMetricsOptions {
|
export interface TraceToMetricsOptions {
|
||||||
@@ -37,13 +38,6 @@ export function TraceToMetricsSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css({ width: '100%' })}>
|
<div className={css({ width: '100%' })}>
|
||||||
<h3 className="page-heading">Trace to metrics</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Navigate from a trace span to the selected data source's metrics
|
|
||||||
<DocsLinkButton hrefSuffix={`${options.type}/#trace-to-metrics`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField
|
<InlineField
|
||||||
tooltip="The Prometheus data source the trace is going to navigate to"
|
tooltip="The Prometheus data source the trace is going to navigate to"
|
||||||
@@ -216,6 +210,25 @@ export function TraceToMetricsSettings({ options, onOptionsChange }: Props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const TraceToMetricsSection = ({ options, onOptionsChange }: DataSourcePluginOptionsEditorProps) => {
|
||||||
|
return (
|
||||||
|
<ConfigSection
|
||||||
|
title="Trace to metrics"
|
||||||
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Navigate from a trace span to the selected data source's metrics."
|
||||||
|
suffix={`${options.type}/#trace-to-metrics`}
|
||||||
|
feature="trace to metrics"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
isCollapsible={true}
|
||||||
|
isInitiallyOpen={true}
|
||||||
|
>
|
||||||
|
<TraceToMetricsSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSection>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => ({
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
infoText: css`
|
infoText: css`
|
||||||
padding-bottom: ${theme.spacing(2)};
|
padding-bottom: ${theme.spacing(2)};
|
||||||
@@ -226,6 +239,8 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
`,
|
`,
|
||||||
queryRow: css`
|
queryRow: css`
|
||||||
|
label: queryRow;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-flow: wrap;
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import {
|
|||||||
toOption,
|
toOption,
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { ConfigSubSection } from '@grafana/experimental';
|
||||||
import { InlineField, InlineFieldRow, Input, Select, useStyles2 } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, Input, Select, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||||
|
|
||||||
export interface SpanBarOptions {
|
export interface SpanBarOptions {
|
||||||
type?: string;
|
type?: string;
|
||||||
@@ -32,13 +33,6 @@ export default function SpanBarSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css({ width: '100%' })}>
|
<div className={css({ width: '100%' })}>
|
||||||
<h3 className="page-heading">Span bar</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Add additional info next to the service and operation on a span bar row in the trace view
|
|
||||||
<DocsLinkButton hrefSuffix={`${options.type}/#span-bar`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField label="Label" labelWidth={26} tooltip="Default: duration" grow>
|
<InlineField label="Label" labelWidth={26} tooltip="Default: duration" grow>
|
||||||
<Select
|
<Select
|
||||||
@@ -84,6 +78,23 @@ export default function SpanBarSettings({ options, onOptionsChange }: Props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SpanBarSection = ({ options, onOptionsChange }: DataSourcePluginOptionsEditorProps) => {
|
||||||
|
return (
|
||||||
|
<ConfigSubSection
|
||||||
|
title="Span bar"
|
||||||
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Add additional info next to the service and operation on a span bar row in the trace view."
|
||||||
|
suffix={`${options.type}/#span-bar`}
|
||||||
|
feature="the span bar"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSubSection>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => ({
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
infoText: css`
|
infoText: css`
|
||||||
label: infoText;
|
label: infoText;
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { ConfigSection } from '@grafana/experimental';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings, useStyles2 } from '@grafana/ui';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { Divider } from 'app/core/components/Divider';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { NodeGraphSection } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToLogsSection } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { SpanBarSettings } from 'app/features/explore/TraceView/components';
|
import { TraceToMetricsSection } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
|
import { SpanBarSection } from 'app/features/explore/TraceView/components/settings/SpanBarSettings';
|
||||||
|
|
||||||
export type Props = DataSourcePluginOptionsEditorProps;
|
export type Props = DataSourcePluginOptionsEditorProps;
|
||||||
|
|
||||||
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.container}>
|
||||||
<DataSourceHttpSettings
|
<DataSourceHttpSettings
|
||||||
defaultUrl="http://localhost:16686"
|
defaultUrl="http://localhost:16686"
|
||||||
dataSourceConfig={options}
|
dataSourceConfig={options}
|
||||||
@@ -21,23 +26,35 @@ export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
|||||||
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<TraceToLogsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
</div>
|
<Divider />
|
||||||
|
|
||||||
{config.featureToggles.traceToMetrics ? (
|
{config.featureToggles.traceToMetrics ? (
|
||||||
<div className="gf-form-group">
|
<>
|
||||||
<TraceToMetricsSettings options={options} onOptionsChange={onOptionsChange} />
|
<TraceToMetricsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
<Divider />
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<ConfigSection
|
||||||
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
title="Additional settings"
|
||||||
</div>
|
description="Additional settings are optional settings that can be configured for more control over your data source."
|
||||||
|
isCollapsible={true}
|
||||||
<div className="gf-form-group">
|
isInitiallyOpen={false}
|
||||||
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
>
|
||||||
</div>
|
<NodeGraphSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
</>
|
<Divider hideLine={true} />
|
||||||
|
<SpanBarSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSection>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
|
container: css`
|
||||||
|
label: container;
|
||||||
|
margin-bottom: ${theme.spacing(2)};
|
||||||
|
max-width: '578px';
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { ConfigSection, ConfigSubSection } from '@grafana/experimental';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings, useStyles2 } from '@grafana/ui';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { Divider } from 'app/core/components/Divider';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { NodeGraphSection } from 'app/core/components/NodeGraphSettings';
|
||||||
import { SpanBarSettings } from 'app/features/explore/TraceView/components';
|
import { TraceToLogsSection } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
|
import { TraceToMetricsSection } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
|
import { SpanBarSection } from 'app/features/explore/TraceView/components/settings/SpanBarSettings';
|
||||||
|
|
||||||
import { LokiSearchSettings } from './LokiSearchSettings';
|
import { LokiSearchSettings } from './LokiSearchSettings';
|
||||||
import { QuerySettings } from './QuerySettings';
|
import { QuerySettings } from './QuerySettings';
|
||||||
@@ -17,8 +21,10 @@ import { TraceQLSearchSettings } from './TraceQLSearchSettings';
|
|||||||
export type Props = DataSourcePluginOptionsEditorProps;
|
export type Props = DataSourcePluginOptionsEditorProps;
|
||||||
|
|
||||||
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.container}>
|
||||||
<DataSourceHttpSettings
|
<DataSourceHttpSettings
|
||||||
defaultUrl="http://tempo"
|
defaultUrl="http://tempo"
|
||||||
dataSourceConfig={options}
|
dataSourceConfig={options}
|
||||||
@@ -27,43 +33,102 @@ export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
|||||||
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<Divider />
|
||||||
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
</div>
|
<TraceToLogsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
{config.featureToggles.traceToMetrics ? (
|
{config.featureToggles.traceToMetrics ? (
|
||||||
<div className="gf-form-group">
|
<>
|
||||||
<TraceToMetricsSettings options={options} onOptionsChange={onOptionsChange} />
|
<TraceToMetricsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
<Divider />
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<ConfigSection
|
||||||
<ServiceGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
title="Additional settings"
|
||||||
</div>
|
description="Additional settings are optional settings that can be configured for more control over your data source."
|
||||||
|
isCollapsible={true}
|
||||||
|
isInitiallyOpen={false}
|
||||||
|
>
|
||||||
|
<ConfigSubSection
|
||||||
|
title="Service graph"
|
||||||
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Select a Prometheus data source that contains the service graph data."
|
||||||
|
suffix="tempo/#service-graph"
|
||||||
|
feature="the service graph"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ServiceGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSubSection>
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<Divider hideLine={true} />
|
||||||
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<NodeGraphSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
{config.featureToggles.traceqlSearch ? (
|
<Divider hideLine={true} />
|
||||||
<TraceQLSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
) : (
|
|
||||||
<SearchSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<ConfigSubSection
|
||||||
<LokiSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
title="Tempo search"
|
||||||
</div>
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Modify how traces are searched."
|
||||||
|
suffix="tempo/#tempo-search"
|
||||||
|
feature="Tempo search"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{config.featureToggles.traceqlSearch ? (
|
||||||
|
<TraceQLSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
) : (
|
||||||
|
<SearchSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
)}
|
||||||
|
</ConfigSubSection>
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<Divider hideLine={true} />
|
||||||
<QuerySettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<ConfigSubSection
|
||||||
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
title="Loki search"
|
||||||
</div>
|
description={
|
||||||
</>
|
<ConfigDescriptionLink
|
||||||
|
description="Select a Loki data source to search for traces. Derived fields must be configured in the Loki data source."
|
||||||
|
suffix="tempo/#loki-search"
|
||||||
|
feature="Loki search"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<LokiSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSubSection>
|
||||||
|
|
||||||
|
<Divider hideLine={true} />
|
||||||
|
|
||||||
|
<ConfigSubSection
|
||||||
|
title="TraceID query"
|
||||||
|
description={
|
||||||
|
<ConfigDescriptionLink
|
||||||
|
description="Modify how TraceID queries are run."
|
||||||
|
suffix="tempo/#traceid-query"
|
||||||
|
feature="the TraceID query"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<QuerySettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSubSection>
|
||||||
|
|
||||||
|
<Divider hideLine={true} />
|
||||||
|
|
||||||
|
<SpanBarSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSection>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
|
container: css`
|
||||||
|
label: container;
|
||||||
|
margin-bottom: ${theme.spacing(2)};
|
||||||
|
max-width: '578px';
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import React from 'react';
|
|||||||
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { Button, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';
|
import { Button, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
|
||||||
|
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
|
|
||||||
@@ -26,13 +25,6 @@ export function LokiSearchSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">Loki search</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Select a Loki data source to search for traces. Derived fields must be configured in the Loki data source
|
|
||||||
<DocsLinkButton hrefSuffix="tempo/#loki-search" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField tooltip="The Loki data source with the service graph data" label="Data source" labelWidth={26}>
|
<InlineField tooltip="The Loki data source with the service graph data" label="Data source" labelWidth={26}>
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import React from 'react';
|
|||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps, GrafanaTheme2, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, GrafanaTheme2, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
||||||
import { InlineField, InlineFieldRow, InlineSwitch, Input, useStyles2 } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, InlineSwitch, Input, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
|
||||||
|
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
|
|
||||||
@@ -14,13 +13,6 @@ export function QuerySettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">TraceID query</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Modify how TraceID queries are run
|
|
||||||
<DocsLinkButton hrefSuffix="tempo/#traceid-query" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineField
|
<InlineField
|
||||||
label="Use time range in query"
|
label="Use time range in query"
|
||||||
tooltip="The time range can be used when there are performance issues or timeouts since it will narrow down the search to the defined range. Default: disabled"
|
tooltip="The time range can be used when there are performance issues or timeouts since it will narrow down the search to the defined range. Default: disabled"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React from 'react';
|
|||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
||||||
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
|
||||||
|
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
|
|
||||||
@@ -15,13 +14,6 @@ export function SearchSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">Tempo search</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Modify how traces are searched
|
|
||||||
<DocsLinkButton hrefSuffix="tempo/#tempo-search" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField tooltip="Removes the search tab from the query editor" label="Hide search" labelWidth={26}>
|
<InlineField tooltip="Removes the search tab from the query editor" label="Hide search" labelWidth={26}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import React from 'react';
|
|||||||
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { Button, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';
|
import { Button, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
|
||||||
|
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
|
|
||||||
@@ -16,13 +15,6 @@ export function ServiceGraphSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">Service graph</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Select a Prometheus data source that contains the service graph data
|
|
||||||
<DocsLinkButton hrefSuffix="tempo/#service-graph" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField
|
<InlineField
|
||||||
tooltip="The Prometheus data source with the service graph data"
|
tooltip="The Prometheus data source with the service graph data"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import useAsync from 'react-use/lib/useAsync';
|
|||||||
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption } from '@grafana/data';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui';
|
||||||
import { DocsLinkButton } from 'app/core/components/DocsLinkButton';
|
|
||||||
|
|
||||||
import { TempoDatasource } from '../datasource';
|
import { TempoDatasource } from '../datasource';
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
@@ -25,13 +24,6 @@ export function TraceQLSearchSettings({ options, onOptionsChange }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<h3 className="page-heading">Tempo search</h3>
|
|
||||||
|
|
||||||
<div className={styles.infoText}>
|
|
||||||
Modify how traces are searched
|
|
||||||
<DocsLinkButton hrefSuffix="tempo/#tempo-search" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InlineFieldRow className={styles.row}>
|
<InlineFieldRow className={styles.row}>
|
||||||
<InlineField tooltip="Removes the search tab from the query editor" label="Hide search" labelWidth={26}>
|
<InlineField tooltip="Removes the search tab from the query editor" label="Hide search" labelWidth={26}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { ConfigSection } from '@grafana/experimental';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings, useStyles2 } from '@grafana/ui';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { Divider } from 'app/core/components/Divider';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { NodeGraphSection } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToLogsSection } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { SpanBarSettings } from 'app/features/explore/TraceView/components';
|
import { TraceToMetricsSection } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
|
import { SpanBarSection } from 'app/features/explore/TraceView/components/settings/SpanBarSettings';
|
||||||
|
|
||||||
export type Props = DataSourcePluginOptionsEditorProps;
|
export type Props = DataSourcePluginOptionsEditorProps;
|
||||||
|
|
||||||
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.container}>
|
||||||
<DataSourceHttpSettings
|
<DataSourceHttpSettings
|
||||||
defaultUrl="http://localhost:9411"
|
defaultUrl="http://localhost:9411"
|
||||||
dataSourceConfig={options}
|
dataSourceConfig={options}
|
||||||
@@ -21,23 +26,35 @@ export const ConfigEditor = ({ options, onOptionsChange }: Props) => {
|
|||||||
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<TraceToLogsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
|
|
||||||
</div>
|
<Divider />
|
||||||
|
|
||||||
{config.featureToggles.traceToMetrics ? (
|
{config.featureToggles.traceToMetrics ? (
|
||||||
<div className="gf-form-group">
|
<>
|
||||||
<TraceToMetricsSettings options={options} onOptionsChange={onOptionsChange} />
|
<TraceToMetricsSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
<Divider />
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="gf-form-group">
|
<ConfigSection
|
||||||
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
title="Additional settings"
|
||||||
</div>
|
description="Additional settings are optional settings that can be configured for more control over your data source."
|
||||||
|
isCollapsible={true}
|
||||||
<div className="gf-form-group">
|
isInitiallyOpen={false}
|
||||||
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
>
|
||||||
</div>
|
<NodeGraphSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
</>
|
<Divider hideLine={true} />
|
||||||
|
<SpanBarSection options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</ConfigSection>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
|
container: css`
|
||||||
|
label: container;
|
||||||
|
margin-bottom: ${theme.spacing(2)};
|
||||||
|
max-width: '578px';
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|||||||
20
yarn.lock
20
yarn.lock
@@ -3374,6 +3374,24 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@grafana/experimental@npm:1.4.2":
|
||||||
|
version: 1.4.2
|
||||||
|
resolution: "@grafana/experimental@npm:1.4.2"
|
||||||
|
dependencies:
|
||||||
|
"@types/uuid": ^8.3.3
|
||||||
|
uuid: ^8.3.2
|
||||||
|
peerDependencies:
|
||||||
|
"@emotion/css": 11.1.3
|
||||||
|
"@grafana/data": ^9.2.0
|
||||||
|
"@grafana/runtime": ^9.2.0
|
||||||
|
"@grafana/ui": ^9.2.0
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2
|
||||||
|
react-select: ^5.2.1
|
||||||
|
checksum: 6e4d7f162ebc4c1a2746f7d0301e98a1634486d8e4c8adccdbab993139b06f46ccc85ab7233fdaaa93981b8b9ad8d68fb1b8542a0e6bba4f89e51707971a05db
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@grafana/faro-core@npm:1.0.2, @grafana/faro-core@npm:^1.0.2":
|
"@grafana/faro-core@npm:1.0.2, @grafana/faro-core@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "@grafana/faro-core@npm:1.0.2"
|
resolution: "@grafana/faro-core@npm:1.0.2"
|
||||||
@@ -18058,7 +18076,7 @@ __metadata:
|
|||||||
"@grafana/e2e-selectors": "workspace:*"
|
"@grafana/e2e-selectors": "workspace:*"
|
||||||
"@grafana/eslint-config": 5.1.0
|
"@grafana/eslint-config": 5.1.0
|
||||||
"@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules"
|
"@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules"
|
||||||
"@grafana/experimental": 1.1.0
|
"@grafana/experimental": 1.4.2
|
||||||
"@grafana/faro-core": 1.0.2
|
"@grafana/faro-core": 1.0.2
|
||||||
"@grafana/faro-web-sdk": 1.0.2
|
"@grafana/faro-web-sdk": 1.0.2
|
||||||
"@grafana/google-sdk": 0.1.1
|
"@grafana/google-sdk": 0.1.1
|
||||||
|
|||||||
Reference in New Issue
Block a user