diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx index 043eda4d07d..a4d629a75c8 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx @@ -1,11 +1,11 @@ import React, { ChangeEvent, useContext } from 'react'; import { DataLink, VariableSuggestion, GrafanaTheme } from '@grafana/data'; -import { FormField } from '../FormField/FormField'; -import { Switch } from '../Forms/Legacy/Switch/Switch'; +import { Switch } from '../Switch/Switch'; import { css } from 'emotion'; import { ThemeContext, stylesFactory } from '../../themes/index'; import { DataLinkInput } from './DataLinkInput'; -import { Icon } from '../Icon/Icon'; +import { Field } from '../Forms/Field'; +import { Input } from '../Input/Input'; interface DataLinkEditorProps { index: number; @@ -13,7 +13,6 @@ interface DataLinkEditorProps { value: DataLink; suggestions: VariableSuggestion[]; onChange: (index: number, link: DataLink, callback?: () => void) => void; - onRemove: (link: DataLink) => void; } const getStyles = stylesFactory((theme: GrafanaTheme) => ({ @@ -28,7 +27,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ })); export const DataLinkEditor: React.FC = React.memo( - ({ index, value, onChange, onRemove, suggestions, isLast }) => { + ({ index, value, onChange, suggestions, isLast }) => { const theme = useContext(ThemeContext); const styles = getStyles(theme); @@ -39,39 +38,24 @@ export const DataLinkEditor: React.FC = React.memo( onChange(index, { ...value, title: event.target.value }); }; - const onRemoveClick = () => { - onRemove(value); - }; - const onOpenInNewTabChanged = () => { onChange(index, { ...value, targetBlank: !value.targetBlank }); }; return (
-
- - - -
- } - className={css` - width: 100%; - `} - /> + + + + + + + + + + + + {isLast && (
With data links you can reference data variables like series name, labels and values. Type CMD+Space, diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 9109ce4d210..58ef2f98b5b 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -3,13 +3,15 @@ import usePrevious from 'react-use/lib/usePrevious'; import { DataLinkSuggestions } from './DataLinkSuggestions'; import { ThemeContext, makeValue } from '../../index'; import { SelectionReference } from './SelectionReference'; -import { Portal } from '../index'; +import { Portal, getFormStyles } from '../index'; +// @ts-ignore +import Prism from 'prismjs'; import { Editor } from '@grafana/slate-react'; import { Value } from 'slate'; import Plain from 'slate-plain-serializer'; import { Popper as ReactPopper } from 'react-popper'; -import { css } from 'emotion'; +import { css, cx } from 'emotion'; import { SlatePrism } from '../../slate-plugins'; import { SCHEMA } from '../../utils/slate'; @@ -33,6 +35,7 @@ const plugins = [ ]; const getStyles = stylesFactory((theme: GrafanaTheme) => ({ + input: getFormStyles(theme, { variant: 'primary', size: 'md', invalid: false }).input.input, editor: css` .token.builtInVariable { color: ${theme.palette.queryGreen}; @@ -41,12 +44,31 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ color: ${theme.colors.textBlue}; } `, + // Wrapper with child selector needed. + // When classnames are appplied to the same element as the wrapper, it causes the suggestions to stop working + wrapperOverrides: css` + width: 100%; + > .slate-query-field__wrapper { + padding: 0; + background-color: transparent; + border: none; + } + `, })); +export const enableDatalinksPrismSyntax = () => { + Prism.languages['links'] = { + builtInVariable: { + pattern: /(\${\S+?})/, + }, + }; +}; + // This memoised also because rerendering the slate editor grabs focus which created problem in some cases this // was used and changes to different state were propagated here. export const DataLinkInput: React.FC = memo( ({ value, onChange, suggestions, placeholder = 'http://your-grafana.com/d/000000010/annotations' }) => { + enableDatalinksPrismSyntax(); const editorRef = useRef() as RefObject; const theme = useContext(ThemeContext); const styles = getStyles(theme); @@ -119,44 +141,52 @@ export const DataLinkInput: React.FC = memo( }; return ( -
-
- {showingSuggestions && ( - - - {({ ref, style, placement }) => { - return ( -
- setShowingSuggestions(false)} - activeIndex={suggestionsIndex} - /> -
- ); - }} -
-
- )} - onKeyDown(event as KeyboardEvent, next)} - plugins={plugins} - className={styles.editor} - /> +
+
+
+ {showingSuggestions && ( + + + {({ ref, style, placement }) => { + return ( +
+ setShowingSuggestions(false)} + activeIndex={suggestionsIndex} + /> +
+ ); + }} +
+
+ )} + onKeyDown(event as KeyboardEvent, next)} + plugins={plugins} + className={cx( + styles.editor, + styles.input, + css` + padding: 3px 8px; + ` + )} + /> +
); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksEditor.tsx deleted file mode 100644 index dfbfdda6644..00000000000 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksEditor.tsx +++ /dev/null @@ -1,85 +0,0 @@ -// Libraries -import React, { FC } from 'react'; -// @ts-ignore -import Prism from 'prismjs'; -// Components -import { css } from 'emotion'; -import { DataLink, VariableSuggestion } from '@grafana/data'; -import { Button } from '../index'; -import { DataLinkEditor } from './DataLinkEditor'; - -import { useTheme } from '../../themes/ThemeContext'; - -interface DataLinksEditorProps { - value?: DataLink[]; - onChange: (links: DataLink[], callback?: () => void) => void; - suggestions: VariableSuggestion[]; - maxLinks?: number; -} - -export const enableDatalinksPrismSyntax = () => { - Prism.languages['links'] = { - builtInVariable: { - pattern: /(\${\S+?})/, - }, - }; -}; - -export const DataLinksEditor: FC = React.memo( - ({ value = [], onChange, suggestions, maxLinks }) => { - const theme = useTheme(); - enableDatalinksPrismSyntax(); - - const onAdd = () => { - onChange(value ? [...value, { url: '', title: '' }] : [{ url: '', title: '' }]); - }; - - const onLinkChanged = (linkIndex: number, newLink: DataLink, callback?: () => void) => { - onChange( - value.map((item, listIndex) => { - if (linkIndex === listIndex) { - return newLink; - } - return item; - }), - callback - ); - }; - - const onRemove = (link: DataLink) => { - onChange(value.filter(item => item !== link)); - }; - - return ( - <> - {value && value.length > 0 && ( -
- {value.map((link, index) => ( - - ))} -
- )} - - {(!value || (value && value.length < (maxLinks || Infinity))) && ( - - )} - - ); - } -); - -DataLinksEditor.displayName = 'DataLinksEditor'; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx index 991aad7cbc5..48c2339e333 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx @@ -31,7 +31,6 @@ export const DataLinkEditorModalContent: FC = ( onChange={(index, link) => { setDirtyLink(link); }} - onRemove={() => {}} />