From 97beb26f0ca9825d049363d5486ade79b45b5cd6 Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Wed, 25 Sep 2019 12:46:37 +0200 Subject: [PATCH] DataLinks: suggestions menu improvements (#19396) * Deduplicate series labels in datalinks variables suggestions * Allways show all variables available in datalinks suggestions --- .../components/DataLinks/DataLinkInput.tsx | 36 ++++--------------- .../app/features/panel/panellinks/link_srv.ts | 5 ++- 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 3b72d409fc6..d6938ac3848 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -8,7 +8,6 @@ import { Editor } from '@grafana/slate-react'; import { Value, Editor as CoreEditor } from 'slate'; import Plain from 'slate-plain-serializer'; import { Popper as ReactPopper } from 'react-popper'; -import useDebounce from 'react-use/lib/useDebounce'; import { css, cx } from 'emotion'; import { SlatePrism } from '../../slate-plugins'; @@ -33,12 +32,7 @@ export const DataLinkInput: React.FC = ({ value, onChange, s const editorRef = useRef() as RefObject; const theme = useContext(ThemeContext); const [showingSuggestions, setShowingSuggestions] = useState(false); - const [suggestionsIndex, setSuggestionsIndex] = useState(0); - const [usedSuggestions, setUsedSuggestions] = useState( - suggestions.filter(suggestion => value.includes(suggestion.value)) - ); - const [linkUrl, setLinkUrl] = useState(makeValue(value)); const getStyles = useCallback(() => { @@ -54,29 +48,13 @@ export const DataLinkInput: React.FC = ({ value, onChange, s }; }, [theme]); - const currentSuggestions = useMemo( - () => suggestions.filter(suggestion => !usedSuggestions.map(s => s.value).includes(suggestion.value)), - [usedSuggestions, suggestions] - ); - // Workaround for https://github.com/ianstormtaylor/slate/issues/2927 - const stateRef = useRef({ showingSuggestions, currentSuggestions, suggestionsIndex, linkUrl, onChange }); - stateRef.current = { showingSuggestions, currentSuggestions, suggestionsIndex, linkUrl, onChange }; + const stateRef = useRef({ showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }); + stateRef.current = { showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }; // SelectionReference is used to position the variables suggestion relatively to current DOM selection const selectionRef = useMemo(() => new SelectionReference(), [setShowingSuggestions, linkUrl]); - // Keep track of variables that has been used already - const updateUsedSuggestions = () => { - const currentLink = Plain.serialize(linkUrl); - const next = usedSuggestions.filter(suggestion => currentLink.includes(suggestion.value)); - if (next.length !== usedSuggestions.length) { - setUsedSuggestions(next); - } - }; - - useDebounce(updateUsedSuggestions, 250, [linkUrl]); - const onKeyDown = React.useCallback((event: KeyboardEvent, next: () => any) => { if (!stateRef.current.showingSuggestions) { if (event.key === '=' || event.key === '$' || (event.keyCode === 32 && event.ctrlKey)) { @@ -93,13 +71,13 @@ export const DataLinkInput: React.FC = ({ value, onChange, s case 'Enter': event.preventDefault(); - return onVariableSelect(stateRef.current.currentSuggestions[stateRef.current.suggestionsIndex]); + return onVariableSelect(stateRef.current.suggestions[stateRef.current.suggestionsIndex]); case 'ArrowDown': case 'ArrowUp': event.preventDefault(); const direction = event.key === 'ArrowDown' ? 1 : -1; - return setSuggestionsIndex(index => modulo(index + direction, stateRef.current.currentSuggestions.length)); + return setSuggestionsIndex(index => modulo(index + direction, stateRef.current.suggestions.length)); default: return next(); } @@ -126,9 +104,7 @@ export const DataLinkInput: React.FC = ({ value, onChange, s setLinkUrl(editor.value); setShowingSuggestions(false); - setUsedSuggestions((previous: VariableSuggestion[]) => { - return [...previous, item]; - }); + setSuggestionsIndex(0); onChange(Plain.serialize(editor.value)); }; @@ -159,7 +135,7 @@ export const DataLinkInput: React.FC = ({ value, onChange, s return (
setShowingSuggestions(false)} activeIndex={suggestionsIndex} diff --git a/public/app/features/panel/panellinks/link_srv.ts b/public/app/features/panel/panellinks/link_srv.ts index c586d55fe1d..de53df74825 100644 --- a/public/app/features/panel/panellinks/link_srv.ts +++ b/public/app/features/panel/panellinks/link_srv.ts @@ -77,7 +77,10 @@ export const getPanelLinksVariableSuggestions = (): VariableSuggestion[] => [ ]; const getSeriesVars = (dataFrames: DataFrame[]) => { - const labels = _.flatten(dataFrames.map(df => Object.keys(df.labels || {}))); + const labels = _.chain(dataFrames.map(df => Object.keys(df.labels || {}))) + .flatten() + .uniq() + .value(); return [ {