grafana/public/app/features/variables/pickers/shared/VariableLink.tsx
Hugo Häggmark 112a755e18
Variables: Adds new Api that allows proper QueryEditors for Query variables (#28217)
* Initial

* WIP

* wip

* Refactor: fixing types

* Refactor: Fixed more typings

* Feature: Moves TestData to new API

* Feature: Moves CloudMonitoringDatasource to new API

* Feature: Moves PrometheusDatasource to new Variables API

* Refactor: Clean up comments

* Refactor: changes to QueryEditorProps instead

* Refactor: cleans up testdata, prometheus and cloud monitoring variable support

* Refactor: adds variableQueryRunner

* Refactor: adds props to VariableQueryEditor

* Refactor: reverted Loki editor

* Refactor: refactor queryrunner into smaller pieces

* Refactor: adds upgrade query thunk

* Tests: Updates old tests

* Docs: fixes build errors for exported api

* Tests: adds guard tests

* Tests: adds QueryRunner tests

* Tests: fixes broken tests

* Tests: adds variableQueryObserver tests

* Test: adds tests for operator functions

* Test: adds VariableQueryRunner tests

* Refactor: renames dataSource

* Refactor: adds definition for standard variable support

* Refactor: adds cancellation to OptionPicker

* Refactor: changes according to Dominiks suggestion

* Refactor:tt

* Refactor: adds tests for factories

* Refactor: restructuring a bit

* Refactor: renames variableQueryRunner.ts

* Refactor: adds quick exit when runRequest returns errors

* Refactor: using TextArea from grafana/ui

* Refactor: changed from interfaces to classes instead

* Tests: fixes broken test

* Docs: fixes doc issue count

* Docs: fixes doc issue count

* Refactor: Adds check for self referencing queries

* Tests: fixed unused variable

* Refactor: Changes comments
2020-11-18 15:10:32 +01:00

116 lines
3.0 KiB
TypeScript

import React, { FC, MouseEvent, useCallback } from 'react';
import { css } from 'emotion';
import { getTagColorsFromName, Icon, Tooltip, useStyles } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
import { GrafanaTheme } from '@grafana/data';
import { VariableTag } from '../../types';
interface Props {
onClick: () => void;
text: string;
tags: VariableTag[];
loading: boolean;
onCancel: () => void;
}
export const VariableLink: FC<Props> = ({ loading, onClick: propsOnClick, tags, text, onCancel }) => {
const styles = useStyles(getStyles);
const onClick = useCallback(
(event: MouseEvent<HTMLAnchorElement>) => {
event.stopPropagation();
event.preventDefault();
propsOnClick();
},
[propsOnClick]
);
if (loading) {
return (
<div
className={styles.container}
aria-label={selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(`${text}`)}
title={text}
>
<VariableLinkText tags={tags} text={text} />
<LoadingIndicator onCancel={onCancel} />
</div>
);
}
return (
<a
onClick={onClick}
className={styles.container}
aria-label={selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(`${text}`)}
title={text}
>
<VariableLinkText tags={tags} text={text} />
<Icon name="angle-down" size="sm" />
</a>
);
};
const VariableLinkText: FC<Pick<Props, 'tags' | 'text'>> = ({ tags, text }) => {
const styles = useStyles(getStyles);
return (
<span className={styles.textAndTags}>
{text}
{tags.map(tag => {
const { color, borderColor } = getTagColorsFromName(tag.text.toString());
return (
<span key={`${tag.text}`}>
<span className="label-tag" style={{ backgroundColor: color, borderColor }}>
&nbsp;&nbsp;
<Icon name="tag-alt" />
&nbsp; {tag.text}
</span>
</span>
);
})}
</span>
);
};
const LoadingIndicator: FC<Pick<Props, 'onCancel'>> = ({ onCancel }) => {
const onClick = useCallback(
(event: MouseEvent) => {
event.preventDefault();
onCancel();
},
[onCancel]
);
return (
<Tooltip content="Cancel query">
<Icon className="spin-clockwise" name="sync" size="xs" onClick={onClick} />
</Tooltip>
);
};
const getStyles = (theme: GrafanaTheme) => ({
container: css`
max-width: 500px;
padding-right: 10px;
padding: 0 ${theme.spacing.sm};
background-color: ${theme.colors.formInputBg};
border: 1px solid ${theme.colors.formInputBorder};
border-radius: ${theme.border.radius.sm};
display: flex;
align-items: center;
color: ${theme.colors.text};
height: ${theme.height.md}px;
.label-tag {
margin: 0 5px;
}
`,
textAndTags: css`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: ${theme.spacing.xxs};
user-select: none;
`,
});