mirror of https://github.com/grafana/grafana.git
Accessibility: Add lint rule to prevent text anchor usage (#109207)
* attempt at a lint rule * add comment * fix the specific alerting links * fix lint rule violations * update translations * fix unit tests * kick CI * add missing external
This commit is contained in:
parent
c91ad446ac
commit
797886e253
|
@ -157,6 +157,14 @@ module.exports = [
|
||||||
'@typescript-eslint/no-redeclare': ['error'],
|
'@typescript-eslint/no-redeclare': ['error'],
|
||||||
'unicorn/no-empty-file': 'error',
|
'unicorn/no-empty-file': 'error',
|
||||||
'no-constant-condition': 'error',
|
'no-constant-condition': 'error',
|
||||||
|
'no-restricted-syntax': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
// value regex is to filter out whitespace-only text nodes (e.g. new lines and spaces in the JSX)
|
||||||
|
selector: "JSXElement[openingElement.name.name='a'] > JSXText[value!=/^\\s*$/]",
|
||||||
|
message: 'No bare anchor nodes containing only text. Use `TextLink` instead.',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,24 +1,48 @@
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { TextLink } from '../Link/TextLink';
|
||||||
|
|
||||||
import { CallToActionCard } from './CallToActionCard';
|
import { CallToActionCard } from './CallToActionCard';
|
||||||
|
|
||||||
describe('CallToActionCard', () => {
|
describe('CallToActionCard', () => {
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
it('should render callToActionElement', () => {
|
it('should render callToActionElement', () => {
|
||||||
render(<CallToActionCard callToActionElement={<a href="http://dummy.link">Click me</a>} />);
|
render(
|
||||||
|
<CallToActionCard
|
||||||
|
callToActionElement={
|
||||||
|
<TextLink external href="http://dummy.link">
|
||||||
|
Click me
|
||||||
|
</TextLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
expect(screen.getByRole('link', { name: 'Click me' })).toBeInTheDocument();
|
expect(screen.getByRole('link', { name: 'Click me' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render message when provided', () => {
|
it('should render message when provided', () => {
|
||||||
render(
|
render(
|
||||||
<CallToActionCard message="Click button below" callToActionElement={<a href="http://dummy.link">Click me</a>} />
|
<CallToActionCard
|
||||||
|
message="Click button below"
|
||||||
|
callToActionElement={
|
||||||
|
<TextLink external href="http://dummy.link">
|
||||||
|
Click me
|
||||||
|
</TextLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('Click button below')).toBeInTheDocument();
|
expect(screen.getByText('Click button below')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render footer when provided', () => {
|
it('should render footer when provided', () => {
|
||||||
render(
|
render(
|
||||||
<CallToActionCard footer="footer content" callToActionElement={<a href="http://dummy.link">Click me</a>} />
|
<CallToActionCard
|
||||||
|
footer="footer content"
|
||||||
|
callToActionElement={
|
||||||
|
<TextLink external href="http://dummy.link">
|
||||||
|
Click me
|
||||||
|
</TextLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('footer content')).toBeInTheDocument();
|
expect(screen.getByText('footer content')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
@ -28,7 +52,11 @@ describe('CallToActionCard', () => {
|
||||||
<CallToActionCard
|
<CallToActionCard
|
||||||
message="Click button below"
|
message="Click button below"
|
||||||
footer="footer content"
|
footer="footer content"
|
||||||
callToActionElement={<a href="http://dummy.link">Click me</a>}
|
callToActionElement={
|
||||||
|
<TextLink external href="http://dummy.link">
|
||||||
|
Click me
|
||||||
|
</TextLink>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('Click button below')).toBeInTheDocument();
|
expect(screen.getByText('Click button below')).toBeInTheDocument();
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Meta, StoryFn } from '@storybook/react';
|
||||||
|
|
||||||
import { Button } from '../Button/Button';
|
import { Button } from '../Button/Button';
|
||||||
import { IconButton } from '../IconButton/IconButton';
|
import { IconButton } from '../IconButton/IconButton';
|
||||||
|
import { TextLink } from '../Link/TextLink';
|
||||||
import { TagList } from '../Tags/TagList';
|
import { TagList } from '../Tags/TagList';
|
||||||
|
|
||||||
import { Card } from './Card';
|
import { Card } from './Card';
|
||||||
|
@ -74,9 +75,9 @@ export const MultipleMetadataWithCustomSeparator: StoryFn<typeof Card> = (args)
|
||||||
<Card.Heading>Test dashboard</Card.Heading>
|
<Card.Heading>Test dashboard</Card.Heading>
|
||||||
<Card.Meta separator={'-'}>
|
<Card.Meta separator={'-'}>
|
||||||
Grafana
|
Grafana
|
||||||
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
|
<TextLink key="prom-link" href="https://ops-us-east4.grafana.net/api/prom" external>
|
||||||
https://ops-us-east4.grafana.net/api/prom
|
https://ops-us-east4.grafana.net/api/prom
|
||||||
</a>
|
</TextLink>
|
||||||
</Card.Meta>
|
</Card.Meta>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
@ -171,9 +172,9 @@ export const WithMediaElements: StoryFn<typeof Card> = (args) => {
|
||||||
</Card.Figure>
|
</Card.Figure>
|
||||||
<Card.Meta>
|
<Card.Meta>
|
||||||
Grafana
|
Grafana
|
||||||
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
|
<TextLink key="prom-link" href="https://ops-us-east4.grafana.net/api/prom" external>
|
||||||
https://ops-us-east4.grafana.net/api/prom
|
https://ops-us-east4.grafana.net/api/prom
|
||||||
</a>
|
</TextLink>
|
||||||
</Card.Meta>
|
</Card.Meta>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
@ -190,9 +191,9 @@ export const ActionCards: StoryFn<typeof Card> = (args) => {
|
||||||
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
|
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
|
||||||
<Card.Meta>
|
<Card.Meta>
|
||||||
Prometheus
|
Prometheus
|
||||||
<a key="link2" href="https://ops-us-east4.grafana.net/api/prom">
|
<TextLink key="link2" href="https://ops-us-east4.grafana.net/api/prom" external>
|
||||||
https://ops-us-east4.grafana.net/api/prom
|
https://ops-us-east4.grafana.net/api/prom
|
||||||
</a>
|
</TextLink>
|
||||||
</Card.Meta>
|
</Card.Meta>
|
||||||
<Card.Figure>
|
<Card.Figure>
|
||||||
<img src={logo} alt="Prometheus Logo" height="40" width="40" />
|
<img src={logo} alt="Prometheus Logo" height="40" width="40" />
|
||||||
|
@ -223,9 +224,9 @@ export const DisabledState: StoryFn<typeof Card> = (args) => {
|
||||||
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
|
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
|
||||||
<Card.Meta>
|
<Card.Meta>
|
||||||
Grafana
|
Grafana
|
||||||
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
|
<TextLink key="prom-link" href="https://ops-us-east4.grafana.net/api/prom" external>
|
||||||
https://ops-us-east4.grafana.net/api/prom
|
https://ops-us-east4.grafana.net/api/prom
|
||||||
</a>
|
</TextLink>
|
||||||
</Card.Meta>
|
</Card.Meta>
|
||||||
<Card.Figure>
|
<Card.Figure>
|
||||||
<img src={logo} alt="Grafana Logo" width="40" height="40" />
|
<img src={logo} alt="Grafana Logo" width="40" height="40" />
|
||||||
|
@ -269,9 +270,9 @@ export const Full: StoryFn<typeof Card> = (args) => {
|
||||||
</Card.Description>
|
</Card.Description>
|
||||||
<Card.Meta>
|
<Card.Meta>
|
||||||
{['Subtitle', 'Meta info 1', 'Meta info 2']}
|
{['Subtitle', 'Meta info 1', 'Meta info 2']}
|
||||||
<a key="link" href="https://ops-us-east4.grafana.net/api/prom">
|
<TextLink key="link" href="https://ops-us-east4.grafana.net/api/prom" external>
|
||||||
https://ops-us-east4.grafana.net/api/prom
|
https://ops-us-east4.grafana.net/api/prom
|
||||||
</a>
|
</TextLink>
|
||||||
</Card.Meta>
|
</Card.Meta>
|
||||||
<Card.Figure>
|
<Card.Figure>
|
||||||
<img src={logo} alt="Prometheus Logo" height="40" width="40" />
|
<img src={logo} alt="Prometheus Logo" height="40" width="40" />
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useStyles2, useTheme2 } from '../../../themes/ThemeContext';
|
||||||
import { getFocusStyles } from '../../../themes/mixins';
|
import { getFocusStyles } from '../../../themes/mixins';
|
||||||
import { FilterInput } from '../../FilterInput/FilterInput';
|
import { FilterInput } from '../../FilterInput/FilterInput';
|
||||||
import { Icon } from '../../Icon/Icon';
|
import { Icon } from '../../Icon/Icon';
|
||||||
|
import { TextLink } from '../../Link/TextLink';
|
||||||
import { WeekStart } from '../WeekStartPicker';
|
import { WeekStart } from '../WeekStartPicker';
|
||||||
|
|
||||||
import { TimePickerFooter } from './TimePickerFooter';
|
import { TimePickerFooter } from './TimePickerFooter';
|
||||||
|
@ -234,13 +235,9 @@ const EmptyRecentList = memo(() => {
|
||||||
</div>
|
</div>
|
||||||
<Trans i18nKey="time-picker.content.empty-recent-list-docs">
|
<Trans i18nKey="time-picker.content.empty-recent-list-docs">
|
||||||
<div>
|
<div>
|
||||||
<a
|
<TextLink href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls" external>
|
||||||
className={styles.link}
|
|
||||||
href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls"
|
|
||||||
target="_new"
|
|
||||||
>
|
|
||||||
Read the documentation
|
Read the documentation
|
||||||
</a>
|
</TextLink>
|
||||||
<span> to find out more about how to enter custom time ranges.</span>
|
<span> to find out more about how to enter custom time ranges.</span>
|
||||||
</div>
|
</div>
|
||||||
</Trans>
|
</Trans>
|
||||||
|
@ -371,7 +368,4 @@ const getEmptyListStyles = (theme: GrafanaTheme2) => ({
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
link: css({
|
|
||||||
color: theme.colors.text.link,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { Button } from '../Button/Button';
|
||||||
import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup';
|
import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup';
|
||||||
import { Icon } from '../Icon/Icon';
|
import { Icon } from '../Icon/Icon';
|
||||||
import { Stack } from '../Layout/Stack/Stack';
|
import { Stack } from '../Layout/Stack/Stack';
|
||||||
|
import { TextLink } from '../Link/TextLink';
|
||||||
import { Menu } from '../Menu/Menu';
|
import { Menu } from '../Menu/Menu';
|
||||||
|
|
||||||
import { PanelChromeProps } from './PanelChrome';
|
import { PanelChromeProps } from './PanelChrome';
|
||||||
|
@ -252,10 +253,9 @@ export const Examples = () => {
|
||||||
{renderPanel('Panel with action link', {
|
{renderPanel('Panel with action link', {
|
||||||
title: 'Panel with action link',
|
title: 'Panel with action link',
|
||||||
actions: (
|
actions: (
|
||||||
<a className="external-link" href="/some/page">
|
<TextLink external href="http://www.example.com/some/page">
|
||||||
Error details
|
Error details
|
||||||
<Icon name="arrow-right" />
|
</TextLink>
|
||||||
</a>
|
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
{renderPanel('Action and menu (should be rare)', {
|
{renderPanel('Action and menu (should be rare)', {
|
||||||
|
@ -322,10 +322,9 @@ export const ExamplesHoverHeader = () => {
|
||||||
title: 'With link in hover header',
|
title: 'With link in hover header',
|
||||||
hoverHeader: true,
|
hoverHeader: true,
|
||||||
actions: (
|
actions: (
|
||||||
<a className="external-link" href="/some/page">
|
<TextLink external href="http://www.example.com/some/page">
|
||||||
Error details
|
Error details
|
||||||
<Icon name="arrow-right" />
|
</TextLink>
|
||||||
</a>
|
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { MutableRefObject } from 'react';
|
import { MutableRefObject } from 'react';
|
||||||
|
|
||||||
|
import { TextLink } from '../Link/TextLink';
|
||||||
|
|
||||||
import { Tooltip } from './Tooltip';
|
import { Tooltip } from './Tooltip';
|
||||||
|
|
||||||
describe('Tooltip', () => {
|
describe('Tooltip', () => {
|
||||||
it('renders correctly', () => {
|
it('renders correctly', () => {
|
||||||
render(
|
render(
|
||||||
<Tooltip placement="auto" content="Tooltip text">
|
<Tooltip placement="auto" content="Tooltip text">
|
||||||
<a className="test-class" href="http://www.grafana.com">
|
<TextLink external href="http://www.grafana.com">
|
||||||
Link with tooltip
|
Link with tooltip
|
||||||
</a>
|
</TextLink>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('Link with tooltip')).toBeInTheDocument();
|
expect(screen.getByText('Link with tooltip')).toBeInTheDocument();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useAsync } from 'react-use';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
import { useStyles2, Icon } from '@grafana/ui';
|
import { useStyles2, Icon, TextLink } from '@grafana/ui';
|
||||||
import { Page } from 'app/core/components/Page/Page';
|
import { Page } from 'app/core/components/Page/Page';
|
||||||
|
|
||||||
import { getTogglesAPI } from './AdminFeatureTogglesAPI';
|
import { getTogglesAPI } from './AdminFeatureTogglesAPI';
|
||||||
|
@ -45,13 +45,12 @@ export default function AdminFeatureTogglesPage() {
|
||||||
<div>
|
<div>
|
||||||
<Trans i18nKey="admin.feature-toggles.sub-title">
|
<Trans i18nKey="admin.feature-toggles.sub-title">
|
||||||
View and edit feature toggles. Read more about feature toggles at{' '}
|
View and edit feature toggles. Read more about feature toggles at{' '}
|
||||||
<a
|
<TextLink
|
||||||
className="external-link"
|
|
||||||
target="_new"
|
|
||||||
href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/"
|
href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/"
|
||||||
|
external
|
||||||
>
|
>
|
||||||
grafana.com
|
grafana.com
|
||||||
</a>
|
</TextLink>
|
||||||
.
|
.
|
||||||
</Trans>
|
</Trans>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
useStyles2,
|
useStyles2,
|
||||||
withTheme2,
|
withTheme2,
|
||||||
Stack,
|
Stack,
|
||||||
|
TextLink,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker';
|
import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker';
|
||||||
import { fetchRoleOptions, updateUserRoles } from 'app/core/components/RolePicker/api';
|
import { fetchRoleOptions, updateUserRoles } from 'app/core/components/RolePicker/api';
|
||||||
|
@ -446,14 +447,9 @@ export function ChangeOrgButton({
|
||||||
<Trans i18nKey="admin.user-orgs.role-not-editable">
|
<Trans i18nKey="admin.user-orgs.role-not-editable">
|
||||||
This user's role is not editable because it is synchronized from your auth provider. Refer to
|
This user's role is not editable because it is synchronized from your auth provider. Refer to
|
||||||
the
|
the
|
||||||
<a
|
<TextLink href={'https://grafana.com/docs/grafana/latest/auth'} external>
|
||||||
className={styles.tooltipItemLink}
|
|
||||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
|
||||||
rel="noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Grafana authentication docs
|
Grafana authentication docs
|
||||||
</a>
|
</TextLink>
|
||||||
for details.
|
for details.
|
||||||
</Trans>
|
</Trans>
|
||||||
</div>
|
</div>
|
||||||
|
@ -496,14 +492,9 @@ export const ExternalUserTooltip = ({ lockMessage }: ExternalUserTooltipProps) =
|
||||||
<Trans i18nKey="admin.user-orgs.external-user-tooltip">
|
<Trans i18nKey="admin.user-orgs.external-user-tooltip">
|
||||||
This user's built-in role is not editable because it is synchronized from your auth provider. Refer
|
This user's built-in role is not editable because it is synchronized from your auth provider. Refer
|
||||||
to the
|
to the
|
||||||
<a
|
<TextLink href={'https://grafana.com/docs/grafana/latest/auth'} external>
|
||||||
className={styles.tooltipItemLink}
|
|
||||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Grafana authentication docs
|
Grafana authentication docs
|
||||||
</a>
|
</TextLink>
|
||||||
for details.
|
for details.
|
||||||
</Trans>
|
</Trans>
|
||||||
</div>
|
</div>
|
||||||
|
@ -519,9 +510,6 @@ const getTooltipStyles = (theme: GrafanaTheme2) => ({
|
||||||
disabledTooltip: css({
|
disabledTooltip: css({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
}),
|
}),
|
||||||
tooltipItemLink: css({
|
|
||||||
color: theme.v1.palette.blue95,
|
|
||||||
}),
|
|
||||||
lockMessageClass: css({
|
lockMessageClass: css({
|
||||||
fontStyle: 'italic',
|
fontStyle: 'italic',
|
||||||
marginLeft: '1.8rem',
|
marginLeft: '1.8rem',
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
Stack,
|
Stack,
|
||||||
Tag,
|
Tag,
|
||||||
Text,
|
Text,
|
||||||
|
TextLink,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker';
|
import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker';
|
||||||
|
@ -189,15 +190,14 @@ export const OrgUsersTable = ({
|
||||||
<Trans i18nKey="admin.org-users.not-editable">
|
<Trans i18nKey="admin.org-users.not-editable">
|
||||||
This user's role is not editable because it is synchronized from your auth provider. Refer
|
This user's role is not editable because it is synchronized from your auth provider. Refer
|
||||||
to the
|
to the
|
||||||
<a
|
<TextLink
|
||||||
href={
|
href={
|
||||||
'https://grafana.com/docs/grafana/latest/administration/user-management/manage-org-users/#change-a-users-organization-permissions'
|
'https://grafana.com/docs/grafana/latest/administration/user-management/manage-org-users/#change-a-users-organization-permissions'
|
||||||
}
|
}
|
||||||
rel="noreferrer"
|
external
|
||||||
target="_blank"
|
|
||||||
>
|
>
|
||||||
Grafana authentication docs
|
Grafana authentication docs
|
||||||
</a>
|
</TextLink>
|
||||||
for details.
|
for details.
|
||||||
</Trans>
|
</Trans>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -196,9 +196,7 @@ function WelcomeCTABox({ title, description, href, hrefText }: WelcomeCTABoxProp
|
||||||
</Text>
|
</Text>
|
||||||
<div className={styles.desc}>{description}</div>
|
<div className={styles.desc}>{description}</div>
|
||||||
<div className={styles.actionRow}>
|
<div className={styles.actionRow}>
|
||||||
<TextLink href={href} inline={false}>
|
<TextLink href={href}>{hrefText}</TextLink>
|
||||||
{hrefText}
|
|
||||||
</TextLink>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -87,7 +87,7 @@ export function NoAccessModal({ item, isOpen, onDismiss }: NoAccessModalProps) {
|
||||||
<p>
|
<p>
|
||||||
<Trans i18nKey="connections.no-access-modal.editor-warning">
|
<Trans i18nKey="connections.no-access-modal.editor-warning">
|
||||||
Editors cannot add new connections. You may check to see if it is already configured in{' '}
|
Editors cannot add new connections. You may check to see if it is already configured in{' '}
|
||||||
<a href="/connections/datasources">Data sources</a>.
|
<TextLink href="/connections/datasources">Data sources</TextLink>.
|
||||||
</Trans>
|
</Trans>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
type CellProps,
|
type CellProps,
|
||||||
type SortByFn,
|
type SortByFn,
|
||||||
Pagination,
|
Pagination,
|
||||||
Icon,
|
TextLink,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import { Page } from 'app/core/components/Page/Page';
|
import { Page } from 'app/core/components/Page/Page';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
|
@ -160,14 +160,9 @@ export default function CorrelationsPage() {
|
||||||
<>
|
<>
|
||||||
<Trans i18nKey="correlations.sub-title">
|
<Trans i18nKey="correlations.sub-title">
|
||||||
Define how data living in different data sources relates to each other. Read more in the{' '}
|
Define how data living in different data sources relates to each other. Read more in the{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/docs/grafana/next/administration/correlations/" external>
|
||||||
href="https://grafana.com/docs/grafana/next/administration/correlations/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
documentation
|
documentation
|
||||||
<Icon name="external-link-alt" />
|
</TextLink>
|
||||||
</a>
|
|
||||||
</Trans>
|
</Trans>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useAsync } from 'react-use';
|
||||||
import { CoreApp } from '@grafana/data';
|
import { CoreApp } from '@grafana/data';
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { Field, LoadingPlaceholder, Alert } from '@grafana/ui';
|
import { Field, LoadingPlaceholder, Alert, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
dsUid?: string;
|
dsUid?: string;
|
||||||
|
@ -34,13 +34,12 @@ export const QueryEditorField = ({ dsUid, invalid, error, name }: Props) => {
|
||||||
<span>
|
<span>
|
||||||
<Trans i18nKey="correlations.query-editor.query-description">
|
<Trans i18nKey="correlations.query-editor.query-description">
|
||||||
Define the query that is run when the link is clicked. You can use{' '}
|
Define the query that is run when the link is clicked. You can use{' '}
|
||||||
<a
|
<TextLink
|
||||||
href="https://grafana.com/docs/grafana/latest/panels-visualizations/configure-data-links/"
|
href="https://grafana.com/docs/grafana/latest/panels-visualizations/configure-data-links/"
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
>
|
>
|
||||||
variables
|
variables
|
||||||
</a>{' '}
|
</TextLink>{' '}
|
||||||
to access specific field values.
|
to access specific field values.
|
||||||
</Trans>
|
</Trans>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { SceneComponentProps, SceneObjectBase } from '@grafana/scenes';
|
import { SceneComponentProps, SceneObjectBase } from '@grafana/scenes';
|
||||||
import { Alert, Button, useStyles2 } from '@grafana/ui';
|
import { Alert, Button, TextLink, useStyles2 } from '@grafana/ui';
|
||||||
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
|
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
|
||||||
import { getDashboardSceneFor } from 'app/features/dashboard-scene/utils/utils';
|
import { getDashboardSceneFor } from 'app/features/dashboard-scene/utils/utils';
|
||||||
|
|
||||||
|
@ -152,14 +152,9 @@ function RendererAlert() {
|
||||||
<div>
|
<div>
|
||||||
<Trans i18nKey="share-modal.link.render-instructions">
|
<Trans i18nKey="share-modal.link.render-instructions">
|
||||||
To render an image, you must install the{' '}
|
To render an image, you must install the{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/grafana/plugins/grafana-image-renderer" external>
|
||||||
href="https://grafana.com/grafana/plugins/grafana-image-renderer"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="external-link"
|
|
||||||
>
|
|
||||||
Grafana image renderer plugin
|
Grafana image renderer plugin
|
||||||
</a>
|
</TextLink>
|
||||||
. Please contact your Grafana administrator to install the plugin.
|
. Please contact your Grafana administrator to install the plugin.
|
||||||
</Trans>
|
</Trans>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Trans, t } from '@grafana/i18n';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { SceneComponentProps, sceneGraph, SceneObjectBase, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
import { SceneComponentProps, sceneGraph, SceneObjectBase, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||||
import { TimeZone } from '@grafana/schema';
|
import { TimeZone } from '@grafana/schema';
|
||||||
import { Alert, ClipboardButton, Field, FieldSet, Icon, Input, Switch } from '@grafana/ui';
|
import { Alert, ClipboardButton, Field, FieldSet, Icon, Input, Switch, TextLink } from '@grafana/ui';
|
||||||
import { createDashboardShareUrl, createShortLink, getShareUrlParams } from 'app/core/utils/shortLinks';
|
import { createDashboardShareUrl, createShortLink, getShareUrlParams } from 'app/core/utils/shortLinks';
|
||||||
import { ThemePicker } from 'app/features/dashboard/components/ShareModal/ThemePicker';
|
import { ThemePicker } from 'app/features/dashboard/components/ShareModal/ThemePicker';
|
||||||
import { getTrackingSource, shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils';
|
import { getTrackingSource, shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils';
|
||||||
|
@ -215,14 +215,9 @@ function ShareLinkTabRenderer({ model }: SceneComponentProps<ShareLinkTab>) {
|
||||||
>
|
>
|
||||||
<Trans i18nKey="share-modal.link.render-instructions">
|
<Trans i18nKey="share-modal.link.render-instructions">
|
||||||
To render an image, you must install the{' '}
|
To render an image, you must install the{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/grafana/plugins/grafana-image-renderer" external>
|
||||||
href="https://grafana.com/grafana/plugins/grafana-image-renderer"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="external-link"
|
|
||||||
>
|
|
||||||
Grafana image renderer plugin
|
Grafana image renderer plugin
|
||||||
</a>
|
</TextLink>
|
||||||
. Please contact your Grafana administrator to install the plugin.
|
. Please contact your Grafana administrator to install the plugin.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { SceneComponentProps } from '@grafana/scenes';
|
import { SceneComponentProps } from '@grafana/scenes';
|
||||||
import { Alert, ClipboardButton, Divider, Stack, Text, useStyles2 } from '@grafana/ui';
|
import { Alert, ClipboardButton, Divider, Stack, Text, TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { getDashboardSceneFor } from '../../utils/utils';
|
import { getDashboardSceneFor } from '../../utils/utils';
|
||||||
import ShareInternallyConfiguration from '../ShareInternallyConfiguration';
|
import ShareInternallyConfiguration from '../ShareInternallyConfiguration';
|
||||||
|
@ -79,14 +79,9 @@ function SharePanelInternallyRenderer({ model }: SceneComponentProps<SharePanelI
|
||||||
>
|
>
|
||||||
<Trans i18nKey="share-modal.link.render-instructions">
|
<Trans i18nKey="share-modal.link.render-instructions">
|
||||||
To render an image, you must install the{' '}
|
To render an image, you must install the{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/grafana/plugins/grafana-image-renderer" external>
|
||||||
href="https://grafana.com/grafana/plugins/grafana-image-renderer"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="external-link"
|
|
||||||
>
|
|
||||||
Grafana image renderer plugin
|
Grafana image renderer plugin
|
||||||
</a>
|
</TextLink>
|
||||||
. Please contact your Grafana administrator to install the plugin.
|
. Please contact your Grafana administrator to install the plugin.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
|
@ -89,7 +89,7 @@ export function HelpWizard({ panel, plugin, onClose }: Props) {
|
||||||
<span className="muted">
|
<span className="muted">
|
||||||
<Trans i18nKey="help-wizard.support-bundle">
|
<Trans i18nKey="help-wizard.support-bundle">
|
||||||
You can also retrieve a support bundle containing information concerning your Grafana instance and
|
You can also retrieve a support bundle containing information concerning your Grafana instance and
|
||||||
configured datasources in the <a href="/support-bundles">support bundles section</a>.
|
configured datasources in the <TextLink href="/support-bundles">support bundles section</TextLink>.
|
||||||
</Trans>
|
</Trans>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { Trans } from '@grafana/i18n';
|
import { Trans } from '@grafana/i18n';
|
||||||
import { locationService } from '@grafana/runtime';
|
import { locationService } from '@grafana/runtime';
|
||||||
import { Button, useStyles2, Text, Box, Stack } from '@grafana/ui';
|
import { Button, useStyles2, Text, Box, Stack, TextLink } from '@grafana/ui';
|
||||||
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
||||||
import {
|
import {
|
||||||
onAddLibraryPanel as onAddLibraryPanelImpl,
|
onAddLibraryPanel as onAddLibraryPanelImpl,
|
||||||
|
@ -115,7 +115,11 @@ const DashboardEmpty = ({ dashboard, canCreate }: Props) => {
|
||||||
<Box marginBottom={2}>
|
<Box marginBottom={2}>
|
||||||
<Text element="p" textAlignment="center" color="secondary">
|
<Text element="p" textAlignment="center" color="secondary">
|
||||||
<Trans i18nKey="dashboard.empty.import-a-dashboard-body">
|
<Trans i18nKey="dashboard.empty.import-a-dashboard-body">
|
||||||
Import dashboards from files or <a href="https://grafana.com/grafana/dashboards/">grafana.com</a>.
|
Import dashboards from files or{' '}
|
||||||
|
<TextLink external href="https://grafana.com/grafana/dashboards/">
|
||||||
|
grafana.com
|
||||||
|
</TextLink>
|
||||||
|
.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Prism from 'prismjs';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Collapse, useStyles2, Text } from '@grafana/ui';
|
import { Collapse, useStyles2, Text, TextLink } from '@grafana/ui';
|
||||||
import { flattenTokens } from '@grafana/ui/internal';
|
import { flattenTokens } from '@grafana/ui/internal';
|
||||||
|
|
||||||
import { trackSampleQuerySelection } from '../../tracking';
|
import { trackSampleQuerySelection } from '../../tracking';
|
||||||
|
@ -145,14 +145,12 @@ const LogsCheatSheet = (props: Props) => {
|
||||||
))}
|
))}
|
||||||
<div>
|
<div>
|
||||||
Note: If you are seeing masked data, you may have CloudWatch logs data protection enabled.{' '}
|
Note: If you are seeing masked data, you may have CloudWatch logs data protection enabled.{' '}
|
||||||
<a
|
<TextLink
|
||||||
className={styles.link}
|
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/#cloudwatch-logs-data-protection"
|
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/#cloudwatch-logs-data-protection"
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
>
|
>
|
||||||
See documentation for details
|
See documentation for details
|
||||||
</a>
|
</TextLink>
|
||||||
.
|
.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -165,9 +163,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
heading: css({
|
heading: css({
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
}),
|
}),
|
||||||
link: css({
|
|
||||||
textDecoration: 'underline',
|
|
||||||
}),
|
|
||||||
cheatSheetExample: css({
|
cheatSheetExample: css({
|
||||||
margin: theme.spacing(0.5, 0),
|
margin: theme.spacing(0.5, 0),
|
||||||
// element is interactive, clear button styles
|
// element is interactive, clear button styles
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
region: string;
|
region: string;
|
||||||
}
|
}
|
||||||
|
@ -5,23 +7,16 @@ export interface Props {
|
||||||
export const ThrottlingErrorMessage = ({ region }: Props) => (
|
export const ThrottlingErrorMessage = ({ region }: Props) => (
|
||||||
<p>
|
<p>
|
||||||
Please visit the
|
Please visit the
|
||||||
<a
|
<TextLink
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
className="text-link"
|
|
||||||
href={`https://${region}.console.aws.amazon.com/servicequotas/home?region=${region}#!/services/monitoring/quotas/L-5E141212`}
|
href={`https://${region}.console.aws.amazon.com/servicequotas/home?region=${region}#!/services/monitoring/quotas/L-5E141212`}
|
||||||
>
|
>
|
||||||
AWS Service Quotas console
|
AWS Service Quotas console
|
||||||
</a>
|
</TextLink>
|
||||||
to request a quota increase or see our
|
to request a quota increase or see our
|
||||||
<a
|
<TextLink external href="https://grafana.com/docs/grafana/latest/datasources/cloudwatch/#manage-service-quotas">
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="text-link"
|
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/cloudwatch/#manage-service-quotas"
|
|
||||||
>
|
|
||||||
documentation
|
documentation
|
||||||
</a>
|
</TextLink>
|
||||||
to learn more.
|
to learn more.
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { css } from '@emotion/css';
|
||||||
import { GrafanaTheme2, QueryEditorProps, SelectableValue, toOption } from '@grafana/data';
|
import { GrafanaTheme2, QueryEditorProps, SelectableValue, toOption } from '@grafana/data';
|
||||||
import { EditorField } from '@grafana/plugin-ui';
|
import { EditorField } from '@grafana/plugin-ui';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { useStyles2 } from '@grafana/ui';
|
import { TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { CloudWatchDatasource } from '../../datasource';
|
import { CloudWatchDatasource } from '../../datasource';
|
||||||
import {
|
import {
|
||||||
|
@ -257,13 +257,12 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||||
tooltip={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
{'Attribute or tag to query on. Tags should be formatted "Tags.<name>". '}
|
{'Attribute or tag to query on. Tags should be formatted "Tags.<name>". '}
|
||||||
<a
|
<TextLink
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/template-queries-cloudwatch/#selecting-attributes"
|
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/template-queries-cloudwatch/#selecting-attributes"
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
>
|
>
|
||||||
See the documentation for more details
|
See the documentation for more details
|
||||||
</a>
|
</TextLink>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -272,13 +271,12 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||||
tooltipInteractive
|
tooltipInteractive
|
||||||
tooltip={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
<a
|
<TextLink
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/template-queries-cloudwatch/#selecting-attributes"
|
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/template-queries-cloudwatch/#selecting-attributes"
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
>
|
>
|
||||||
Pre-defined ec2:DescribeInstances filters/tags
|
Pre-defined ec2:DescribeInstances filters/tags
|
||||||
</a>
|
</TextLink>
|
||||||
{' and the values to filter on. Tags should be formatted tag:<name>.'}
|
{' and the values to filter on. Tags should be formatted tag:<name>.'}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,18 @@ import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { SelectableValue } from '@grafana/data';
|
||||||
import { EditorField } from '@grafana/plugin-ui';
|
import { EditorField } from '@grafana/plugin-ui';
|
||||||
import { Button, Checkbox, Icon, Label, LoadingPlaceholder, Modal, Select, Space, useStyles2 } from '@grafana/ui';
|
import {
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Icon,
|
||||||
|
Label,
|
||||||
|
LoadingPlaceholder,
|
||||||
|
Modal,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
TextLink,
|
||||||
|
useStyles2,
|
||||||
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import { DescribeLogGroupsRequest, ResourceResponse, LogGroupResponse } from '../../../resources/types';
|
import { DescribeLogGroupsRequest, ResourceResponse, LogGroupResponse } from '../../../resources/types';
|
||||||
import { LogGroup } from '../../../types';
|
import { LogGroup } from '../../../types';
|
||||||
|
@ -146,13 +157,12 @@ export const LogGroupsSelector = ({
|
||||||
search.
|
search.
|
||||||
<p>
|
<p>
|
||||||
A{' '}
|
A{' '}
|
||||||
<a
|
<TextLink
|
||||||
target="_blank"
|
external
|
||||||
rel="noopener noreferrer"
|
|
||||||
href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html"
|
href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html"
|
||||||
>
|
>
|
||||||
maximum{' '}
|
maximum{' '}
|
||||||
</a>{' '}
|
</TextLink>{' '}
|
||||||
of 50 Cloudwatch log groups can be queried at one time.
|
of 50 Cloudwatch log groups can be queried at one time.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { SelectableValue } from '@grafana/data';
|
||||||
import { EditorField, EditorFieldGroup, EditorRow, EditorRows, EditorSwitch } from '@grafana/plugin-ui';
|
import { EditorField, EditorFieldGroup, EditorRow, EditorRows, EditorSwitch } from '@grafana/plugin-ui';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Select } from '@grafana/ui';
|
import { Select, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
import { CloudWatchDatasource } from '../../../datasource';
|
import { CloudWatchDatasource } from '../../../datasource';
|
||||||
import { useAccountOptions, useMetrics, useNamespaces } from '../../../hooks';
|
import { useAccountOptions, useMetrics, useNamespaces } from '../../../hooks';
|
||||||
|
@ -152,13 +152,12 @@ export const MetricStatEditor = ({
|
||||||
{
|
{
|
||||||
'Only show metrics that contain exactly the dimensions defined in the query and match the specified values. If this is enabled, all dimensions of the metric being queried must be specified so that the '
|
'Only show metrics that contain exactly the dimensions defined in the query and match the specified values. If this is enabled, all dimensions of the metric being queried must be specified so that the '
|
||||||
}
|
}
|
||||||
<a
|
<TextLink
|
||||||
href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/search-expression-syntax.html"
|
href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/search-expression-syntax.html"
|
||||||
target="_blank"
|
external
|
||||||
rel="noreferrer"
|
|
||||||
>
|
>
|
||||||
metric schema
|
metric schema
|
||||||
</a>
|
</TextLink>
|
||||||
{
|
{
|
||||||
' matches exactly. If this is disabled, metrics that match the schema and have additional dimensions will also be returned.'
|
' matches exactly. If this is disabled, metrics that match the schema and have additional dimensions will also be returned.'
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Icon, Tooltip, useStyles2, type PopoverContent } from '@grafana/ui';
|
import { Icon, TextLink, Tooltip, useStyles2, type PopoverContent } from '@grafana/ui';
|
||||||
|
|
||||||
import { FuncInstance } from '../gfunc';
|
import { FuncInstance } from '../gfunc';
|
||||||
|
|
||||||
|
@ -64,14 +64,9 @@ const TooltipContent = memo(() => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
This function is not supported. Check your function for typos and{' '}
|
This function is not supported. Check your function for typos and{' '}
|
||||||
<a
|
<TextLink external href="https://graphite.readthedocs.io/en/latest/functions.html">
|
||||||
target="_blank"
|
|
||||||
className="external-link"
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
href="https://graphite.readthedocs.io/en/latest/functions.html"
|
|
||||||
>
|
|
||||||
read the docs
|
read the docs
|
||||||
</a>{' '}
|
</TextLink>{' '}
|
||||||
to see whether you need to upgrade your data source’s version to make this function available.
|
to see whether you need to upgrade your data source’s version to make this function available.
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Alert, DataSourceHttpSettings, InlineField, Select, Field, Input, FieldSet } from '@grafana/ui';
|
import { Alert, DataSourceHttpSettings, InlineField, Select, Field, Input, FieldSet, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
import { BROWSER_MODE_DISABLED_MESSAGE } from '../../../constants';
|
import { BROWSER_MODE_DISABLED_MESSAGE } from '../../../constants';
|
||||||
import { InfluxOptions, InfluxOptionsV1, InfluxVersion } from '../../../types';
|
import { InfluxOptions, InfluxOptionsV1, InfluxVersion } from '../../../types';
|
||||||
|
@ -130,9 +130,9 @@ export class ConfigEditor extends PureComponent<Props, State> {
|
||||||
<Alert severity="info" title={this.versionNotice[options.jsonData.version!]}>
|
<Alert severity="info" title={this.versionNotice[options.jsonData.version!]}>
|
||||||
<p>
|
<p>
|
||||||
Please report any issues to: <br />
|
Please report any issues to: <br />
|
||||||
<a href="https://github.com/grafana/grafana/issues/new/choose">
|
<TextLink href="https://github.com/grafana/grafana/issues/new/choose" external>
|
||||||
https://github.com/grafana/grafana/issues
|
https://github.com/grafana/grafana/issues
|
||||||
</a>
|
</TextLink>
|
||||||
</p>
|
</p>
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { useStyles2 } from '@grafana/ui';
|
import { TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
export default function CheatSheet() {
|
export default function CheatSheet() {
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
|
@ -11,14 +11,9 @@ export default function CheatSheet() {
|
||||||
<p>
|
<p>
|
||||||
This cheat sheet provides a quick overview of the query types that are available. For more details about the
|
This cheat sheet provides a quick overview of the query types that are available. For more details about the
|
||||||
Jaeger data source, check out{' '}
|
Jaeger data source, check out{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/docs/grafana/latest/datasources/jaeger" external>
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/jaeger"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className={styles.anchorTag}
|
|
||||||
>
|
|
||||||
the documentation
|
the documentation
|
||||||
</a>
|
</TextLink>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -32,14 +27,9 @@ export default function CheatSheet() {
|
||||||
<li>
|
<li>
|
||||||
JSON File - you can upload a JSON file that contains a single trace to visualize it. If the file has multiple
|
JSON File - you can upload a JSON file that contains a single trace to visualize it. If the file has multiple
|
||||||
traces then the first trace is used for visualization. An example of a valid JSON file can be found in{' '}
|
traces then the first trace is used for visualization. An example of a valid JSON file can be found in{' '}
|
||||||
<a
|
<TextLink href="https://grafana.com/docs/grafana/latest/datasources/jaeger/#upload-json-trace-file" external>
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/jaeger/#upload-json-trace-file"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className={styles.anchorTag}
|
|
||||||
>
|
|
||||||
this section
|
this section
|
||||||
</a>{' '}
|
</TextLink>{' '}
|
||||||
of the documentation.
|
of the documentation.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -48,9 +38,6 @@ export default function CheatSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => ({
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
anchorTag: css({
|
|
||||||
color: theme.colors.text.link,
|
|
||||||
}),
|
|
||||||
unorderedList: css({
|
unorderedList: css({
|
||||||
listStyleType: 'none',
|
listStyleType: 'none',
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { PureComponent } from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2, QueryEditorHelpProps } from '@grafana/data';
|
import { GrafanaTheme2, QueryEditorHelpProps } from '@grafana/data';
|
||||||
import { reportInteraction } from '@grafana/runtime';
|
import { reportInteraction } from '@grafana/runtime';
|
||||||
import { Themeable2, withTheme2 } from '@grafana/ui';
|
import { TextLink, Themeable2, withTheme2 } from '@grafana/ui';
|
||||||
|
|
||||||
import LokiLanguageProvider from '../LanguageProvider';
|
import LokiLanguageProvider from '../LanguageProvider';
|
||||||
import { escapeLabelValueInExactSelector } from '../languageUtils';
|
import { escapeLabelValueInExactSelector } from '../languageUtils';
|
||||||
|
@ -135,9 +135,9 @@ class UnthemedLokiCheatSheet extends PureComponent<
|
||||||
{this.renderExpression('{app="cassandra"} |~ "(duration|latency)s*(=|is|of)s*[d.]+"')}
|
{this.renderExpression('{app="cassandra"} |~ "(duration|latency)s*(=|is|of)s*[d.]+"')}
|
||||||
{this.renderExpression('{app="cassandra"} |= "exact match"')}
|
{this.renderExpression('{app="cassandra"} |= "exact match"')}
|
||||||
{this.renderExpression('{app="cassandra"} != "do not match"')}
|
{this.renderExpression('{app="cassandra"} != "do not match"')}
|
||||||
<a href="https://grafana.com/docs/loki/latest/logql/#log-pipeline" target="logql">
|
<TextLink href="https://grafana.com/docs/loki/latest/logql/#log-pipeline" external>
|
||||||
LogQL
|
LogQL
|
||||||
</a>{' '}
|
</TextLink>{' '}
|
||||||
supports exact and regular expression filters.
|
supports exact and regular expression filters.
|
||||||
</div>
|
</div>
|
||||||
{LOGQL_EXAMPLES.map((item) => (
|
{LOGQL_EXAMPLES.map((item) => (
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { DataSourcePluginOptionsEditorProps, GrafanaTheme2 } from '@grafana/data
|
||||||
import { AdvancedHttpSettings, ConfigSection, DataSourceDescription } from '@grafana/plugin-ui';
|
import { AdvancedHttpSettings, ConfigSection, DataSourceDescription } from '@grafana/plugin-ui';
|
||||||
import { AlertingSettingsOverhaul, PromOptions, PromSettings } from '@grafana/prometheus';
|
import { AlertingSettingsOverhaul, PromOptions, PromSettings } from '@grafana/prometheus';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Alert, FieldValidationMessage, useTheme2 } from '@grafana/ui';
|
import { Alert, FieldValidationMessage, TextLink, useTheme2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { AzureAuthSettings } from './AzureAuthSettings';
|
import { AzureAuthSettings } from './AzureAuthSettings';
|
||||||
import { AzurePromDataSourceSettings, setDefaultCredentials, resetCredentials } from './AzureCredentialsConfig';
|
import { AzurePromDataSourceSettings, setDefaultCredentials, resetCredentials } from './AzureCredentialsConfig';
|
||||||
|
@ -78,9 +78,9 @@ export function docsTip(url?: string) {
|
||||||
const docsUrl = 'https://grafana.com/docs/grafana/latest/datasources/prometheus/#configure-the-data-source';
|
const docsUrl = 'https://grafana.com/docs/grafana/latest/datasources/prometheus/#configure-the-data-source';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href={url ? url : docsUrl} target="_blank" rel="noopener noreferrer">
|
<TextLink href={url ? url : docsUrl} external>
|
||||||
Visit docs for more details here.
|
Visit docs for more details here.
|
||||||
</a>
|
</TextLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useCallback, useEffect, useState } from 'react';
|
||||||
import { CoreApp, GrafanaTheme2, TimeRange } from '@grafana/data';
|
import { CoreApp, GrafanaTheme2, TimeRange } from '@grafana/data';
|
||||||
import { TemporaryAlert } from '@grafana/o11y-ds-frontend';
|
import { TemporaryAlert } from '@grafana/o11y-ds-frontend';
|
||||||
import { config, FetchError, getTemplateSrv, reportInteraction } from '@grafana/runtime';
|
import { config, FetchError, getTemplateSrv, reportInteraction } from '@grafana/runtime';
|
||||||
import { Alert, Button, Stack, Select, useStyles2 } from '@grafana/ui';
|
import { Alert, Button, Stack, Select, useStyles2, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
import { RawQuery } from '../_importedDependencies/datasources/prometheus/RawQuery';
|
import { RawQuery } from '../_importedDependencies/datasources/prometheus/RawQuery';
|
||||||
import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen';
|
import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen';
|
||||||
|
@ -304,7 +304,7 @@ const TraceQLSearch = ({
|
||||||
{error ? (
|
{error ? (
|
||||||
<Alert title="Unable to connect to Tempo search" severity="info" className={styles.alert}>
|
<Alert title="Unable to connect to Tempo search" severity="info" className={styles.alert}>
|
||||||
Please ensure that Tempo is configured with search enabled. If you would like to hide this tab, you can
|
Please ensure that Tempo is configured with search enabled. If you would like to hide this tab, you can
|
||||||
configure it in the <a href={`/datasources/edit/${datasource.uid}`}>datasource settings</a>.
|
configure it in the <TextLink href={`/datasources/edit/${datasource.uid}`}>datasource settings</TextLink>.
|
||||||
</Alert>
|
</Alert>
|
||||||
) : null}
|
) : null}
|
||||||
{alertText && <TemporaryAlert severity={'error'} text={alertText} />}
|
{alertText && <TemporaryAlert severity={'error'} text={alertText} />}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useEffect, useState } from 'react';
|
||||||
import useAsync from 'react-use/lib/useAsync';
|
import useAsync from 'react-use/lib/useAsync';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Alert, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';
|
import { Alert, InlineField, InlineFieldRow, TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { AdHocFilter } from './_importedDependencies/components/AdHocFilter/AdHocFilter';
|
import { AdHocFilter } from './_importedDependencies/components/AdHocFilter/AdHocFilter';
|
||||||
import { AdHocVariableFilter } from './_importedDependencies/components/AdHocFilter/types';
|
import { AdHocVariableFilter } from './_importedDependencies/components/AdHocFilter/types';
|
||||||
|
@ -116,18 +116,13 @@ export function ServiceGraphSection({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWarning(title: string, description: string, styles: { alert: string; link: string }) {
|
function getWarning(title: string, description: string, styles: { alert: string }) {
|
||||||
return (
|
return (
|
||||||
<Alert title={title} severity="info" className={styles.alert}>
|
<Alert title={title} severity="info" className={styles.alert}>
|
||||||
{description} according to the{' '}
|
{description} according to the{' '}
|
||||||
<a
|
<TextLink external href="https://grafana.com/docs/grafana/latest/datasources/tempo/service-graph/">
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
href="https://grafana.com/docs/grafana/latest/datasources/tempo/service-graph/"
|
|
||||||
className={styles.link}
|
|
||||||
>
|
|
||||||
Tempo documentation
|
Tempo documentation
|
||||||
</a>
|
</TextLink>
|
||||||
.
|
.
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
|
@ -157,8 +152,4 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
maxWidth: '75ch',
|
maxWidth: '75ch',
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
}),
|
}),
|
||||||
link: css({
|
|
||||||
color: theme.colors.text.link,
|
|
||||||
textDecoration: 'underline',
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { Button, InlineField, InlineFieldRow, useStyles2, Combobox } from '@grafana/ui';
|
import { Button, InlineField, InlineFieldRow, useStyles2, Combobox, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
import { TempoJsonData } from '../types';
|
import { TempoJsonData } from '../types';
|
||||||
|
|
||||||
|
@ -31,40 +31,28 @@ export function ServiceGraphSettings({ options, onOptionsChange }: Props) {
|
||||||
|
|
||||||
function metricsGeneratorDocsLink() {
|
function metricsGeneratorDocsLink() {
|
||||||
return (
|
return (
|
||||||
<a
|
<TextLink href="https://grafana.com/docs/tempo/latest/setup-and-configuration/metrics-generator/" external>
|
||||||
style={{ textDecoration: 'underline' }}
|
|
||||||
href="https://grafana.com/docs/tempo/latest/setup-and-configuration/metrics-generator/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Tempo metrics generator
|
Tempo metrics generator
|
||||||
</a>
|
</TextLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function prometheusNativeHistogramsDocsLink() {
|
function prometheusNativeHistogramsDocsLink() {
|
||||||
return (
|
return (
|
||||||
<a
|
<TextLink href="https://prometheus.io/docs/specs/native_histograms/#native-histograms" external>
|
||||||
style={{ textDecoration: 'underline' }}
|
|
||||||
href="https://prometheus.io/docs/specs/native_histograms/#native-histograms"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Prometheus
|
Prometheus
|
||||||
</a>
|
</TextLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mimirNativeHistogramsDocsLink() {
|
function mimirNativeHistogramsDocsLink() {
|
||||||
return (
|
return (
|
||||||
<a
|
<TextLink
|
||||||
style={{ textDecoration: 'underline' }}
|
|
||||||
href="https://grafana.com/docs/mimir/latest/configure/configure-native-histograms-ingestion/#configure-native-histograms-globally"
|
href="https://grafana.com/docs/mimir/latest/configure/configure-native-histograms-ingestion/#configure-native-histograms-globally"
|
||||||
target="_blank"
|
external
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
Mimir
|
Mimir
|
||||||
</a>
|
</TextLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import { css } from '@emotion/css';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataSourceJsonData,
|
DataSourceJsonData,
|
||||||
DataSourcePluginOptionsEditorProps,
|
DataSourcePluginOptionsEditorProps,
|
||||||
GrafanaTheme2,
|
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { ConfigSection } from '@grafana/plugin-ui';
|
import { ConfigSection } from '@grafana/plugin-ui';
|
||||||
import { InlineFieldRow, InlineField, InlineSwitch, Alert, Stack, useStyles2 } from '@grafana/ui';
|
import { InlineFieldRow, InlineField, InlineSwitch, Alert, Stack, TextLink } from '@grafana/ui';
|
||||||
|
|
||||||
import { FeatureName, featuresToTempoVersion } from '../datasource';
|
import { FeatureName, featuresToTempoVersion } from '../datasource';
|
||||||
|
|
||||||
|
@ -21,7 +19,6 @@ interface StreamingOptions extends DataSourceJsonData {
|
||||||
interface Props extends DataSourcePluginOptionsEditorProps<StreamingOptions> {}
|
interface Props extends DataSourcePluginOptionsEditorProps<StreamingOptions> {}
|
||||||
|
|
||||||
export const StreamingSection = ({ options, onOptionsChange }: Props) => {
|
export const StreamingSection = ({ options, onOptionsChange }: Props) => {
|
||||||
const styles = useStyles2(getStyles);
|
|
||||||
return (
|
return (
|
||||||
<ConfigSection
|
<ConfigSection
|
||||||
title="Streaming"
|
title="Streaming"
|
||||||
|
@ -29,14 +26,9 @@ export const StreamingSection = ({ options, onOptionsChange }: Props) => {
|
||||||
description={
|
description={
|
||||||
<Stack gap={0.5}>
|
<Stack gap={0.5}>
|
||||||
<div>Enable streaming for different Tempo features.</div>
|
<div>Enable streaming for different Tempo features.</div>
|
||||||
<a
|
<TextLink external href={'https://grafana.com/docs/tempo/latest/traceql/#stream-query-results'}>
|
||||||
href={'https://grafana.com/docs/tempo/latest/traceql/#stream-query-results'}
|
|
||||||
target={'_blank'}
|
|
||||||
rel="noreferrer"
|
|
||||||
className={styles.a}
|
|
||||||
>
|
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</TextLink>
|
||||||
</Stack>
|
</Stack>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -87,15 +79,3 @@ export const StreamingSection = ({ options, onOptionsChange }: Props) => {
|
||||||
</ConfigSection>
|
</ConfigSection>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const getStyles = (theme: GrafanaTheme2) => {
|
|
||||||
return {
|
|
||||||
a: css({
|
|
||||||
color: theme.colors.text.link,
|
|
||||||
textDecoration: 'underline',
|
|
||||||
marginLeft: '5px',
|
|
||||||
'&:hover': {
|
|
||||||
textDecoration: 'none',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useState } from 'react';
|
||||||
|
|
||||||
import { CoreApp, GrafanaTheme2, QueryEditorProps } from '@grafana/data';
|
import { CoreApp, GrafanaTheme2, QueryEditorProps } from '@grafana/data';
|
||||||
import { config, reportInteraction } from '@grafana/runtime';
|
import { config, reportInteraction } from '@grafana/runtime';
|
||||||
import { Alert, Button, Icon, InlineLabel, useStyles2 } from '@grafana/ui';
|
import { Alert, Button, InlineLabel, TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { TempoDatasource } from '../datasource';
|
import { TempoDatasource } from '../datasource';
|
||||||
import { defaultQuery, MyDataSourceOptions, TempoQuery } from '../types';
|
import { defaultQuery, MyDataSourceOptions, TempoQuery } from '../types';
|
||||||
|
@ -32,14 +32,9 @@ export function QueryEditor(props: Props) {
|
||||||
<Alert title="Tempo metrics is an experimental feature" severity="warning">
|
<Alert title="Tempo metrics is an experimental feature" severity="warning">
|
||||||
Please note that TraceQL metrics is an experimental feature and should not be used in production. Read more about
|
Please note that TraceQL metrics is an experimental feature and should not be used in production. Read more about
|
||||||
it in{' '}
|
it in{' '}
|
||||||
<a
|
<TextLink external href="https://grafana.com/docs/tempo/latest/operations/traceql-metrics/">
|
||||||
className={css({ textDecoration: 'underline' })}
|
|
||||||
href="https://grafana.com/docs/tempo/latest/operations/traceql-metrics/"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
documentation
|
documentation
|
||||||
<Icon name="external-link-alt" />
|
</TextLink>
|
||||||
</a>
|
|
||||||
.
|
.
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
|
@ -50,9 +45,9 @@ export function QueryEditor(props: Props) {
|
||||||
{inAlerting && alertingWarning}
|
{inAlerting && alertingWarning}
|
||||||
<InlineLabel>
|
<InlineLabel>
|
||||||
Build complex queries using TraceQL to select a list of traces.{' '}
|
Build complex queries using TraceQL to select a list of traces.{' '}
|
||||||
<a rel="noreferrer" target="_blank" href="https://grafana.com/docs/tempo/latest/traceql/">
|
<TextLink external href="https://grafana.com/docs/tempo/latest/traceql/">
|
||||||
Documentation
|
Documentation
|
||||||
</a>
|
</TextLink>
|
||||||
</InlineLabel>
|
</InlineLabel>
|
||||||
{!showCopyFromSearchButton && (
|
{!showCopyFromSearchButton && (
|
||||||
<div className={styles.copyContainer}>
|
<div className={styles.copyContainer}>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useToggle } from 'react-use';
|
||||||
|
|
||||||
import { CoreApp, GrafanaTheme2 } from '@grafana/data';
|
import { CoreApp, GrafanaTheme2 } from '@grafana/data';
|
||||||
import { EditorField, EditorRow } from '@grafana/plugin-ui';
|
import { EditorField, EditorRow } from '@grafana/plugin-ui';
|
||||||
import { AutoSizeInput, RadioButtonGroup, useStyles2 } from '@grafana/ui';
|
import { AutoSizeInput, RadioButtonGroup, TextLink, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { QueryOptionGroup } from '../_importedDependencies/datasources/prometheus/QueryOptionGroup';
|
import { QueryOptionGroup } from '../_importedDependencies/datasources/prometheus/QueryOptionGroup';
|
||||||
import { SearchTableType, MetricsQueryType } from '../dataquery.gen';
|
import { SearchTableType, MetricsQueryType } from '../dataquery.gen';
|
||||||
|
@ -209,15 +209,14 @@ const StreamingTooltip = () => {
|
||||||
Indicates if streaming is currently enabled. Streaming allows you to view partial query results before the
|
Indicates if streaming is currently enabled. Streaming allows you to view partial query results before the
|
||||||
entire query completes.
|
entire query completes.
|
||||||
</span>
|
</span>
|
||||||
<a
|
<TextLink
|
||||||
|
external
|
||||||
href={'https://grafana.com/docs/tempo/latest/traceql/#stream-query-results'}
|
href={'https://grafana.com/docs/tempo/latest/traceql/#stream-query-results'}
|
||||||
aria-label={'Learn more about streaming query results'}
|
aria-label={'Learn more about streaming query results'}
|
||||||
target={'_blank'}
|
|
||||||
rel="noreferrer"
|
|
||||||
style={{ textDecoration: 'underline' }}
|
style={{ textDecoration: 'underline' }}
|
||||||
>
|
>
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</TextLink>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4319,7 +4319,7 @@
|
||||||
"source-label": "Source",
|
"source-label": "Source",
|
||||||
"sub-text": "<0>Define what data source will display the correlation, and what data will replace previously defined variables.</0>"
|
"sub-text": "<0>Define what data source will display the correlation, and what data will replace previously defined variables.</0>"
|
||||||
},
|
},
|
||||||
"sub-title": "Define how data living in different data sources relates to each other. Read more in the <2>documentation<1></1></2>",
|
"sub-title": "Define how data living in different data sources relates to each other. Read more in the <2>documentation</2>",
|
||||||
"target-form": {
|
"target-form": {
|
||||||
"control-rules": "This field is required.",
|
"control-rules": "This field is required.",
|
||||||
"sub-text": "<0>Define what the correlation will link to. With the query type, a query will run when the correlation is clicked. With the external type, clicking the correlation will open a URL.</0>",
|
"sub-text": "<0>Define what the correlation will link to. With the query type, a query will run when the correlation is clicked. With the external type, clicking the correlation will open a URL.</0>",
|
||||||
|
@ -4722,7 +4722,7 @@
|
||||||
"add-visualization-body": "Select a data source and then query and visualize your data with charts, stats and tables or create lists, markdowns and other widgets.",
|
"add-visualization-body": "Select a data source and then query and visualize your data with charts, stats and tables or create lists, markdowns and other widgets.",
|
||||||
"add-visualization-button": "Add visualization",
|
"add-visualization-button": "Add visualization",
|
||||||
"add-visualization-header": "Start your new dashboard by adding a visualization",
|
"add-visualization-header": "Start your new dashboard by adding a visualization",
|
||||||
"import-a-dashboard-body": "Import dashboards from files or <1>grafana.com</1>.",
|
"import-a-dashboard-body": "Import dashboards from files or <2>grafana.com</2>.",
|
||||||
"import-a-dashboard-header": "Import a dashboard",
|
"import-a-dashboard-header": "Import a dashboard",
|
||||||
"import-dashboard-button": "Import dashboard"
|
"import-dashboard-button": "Import dashboard"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue