{"version":3,"file":"1828.0dfd49f78dc93c695e30.js","mappings":"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","sources":["webpack://grafana/./public/app/plugins/datasource/loki/language_utils.ts","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiQueryField.tsx"],"sourcesContent":["import { TimeRange } from '@grafana/data';\n\nfunction roundMsToMin(milliseconds: number): number {\n  return roundSecToMin(milliseconds / 1000);\n}\n\nfunction roundSecToMin(seconds: number): number {\n  return Math.floor(seconds / 60);\n}\n\nexport function shouldRefreshLabels(range?: TimeRange, prevRange?: TimeRange): boolean {\n  if (range && prevRange) {\n    const sameMinuteFrom = roundMsToMin(range.from.valueOf()) === roundMsToMin(prevRange.from.valueOf());\n    const sameMinuteTo = roundMsToMin(range.to.valueOf()) === roundMsToMin(prevRange.to.valueOf());\n    // If both are same, don't need to refresh\n    return !(sameMinuteFrom && sameMinuteTo);\n  }\n  return false;\n}\n","import { css, cx } from '@emotion/css';\nimport { sortBy } from 'lodash';\nimport React, { ChangeEvent } from 'react';\nimport { FixedSizeList } from 'react-window';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport {\n  Button,\n  HighlightPart,\n  HorizontalGroup,\n  Input,\n  Label,\n  LoadingPlaceholder,\n  withTheme2,\n  BrowserLabel as LokiLabel,\n  fuzzyMatch,\n} from '@grafana/ui';\n\nimport PromQlLanguageProvider from '../../prometheus/language_provider';\nimport LokiLanguageProvider from '../language_provider';\n\n// Hard limit on labels to render\nconst MAX_LABEL_COUNT = 1000;\nconst MAX_VALUE_COUNT = 10000;\nconst MAX_AUTO_SELECT = 4;\nconst EMPTY_SELECTOR = '{}';\n\nexport interface BrowserProps {\n  // TODO #33976: Is it possible to use a common interface here? For example: LabelsLanguageProvider\n  languageProvider: LokiLanguageProvider | PromQlLanguageProvider;\n  onChange: (selector: string) => void;\n  theme: GrafanaTheme2;\n  autoSelect?: number;\n  hide?: () => void;\n  lastUsedLabels: string[];\n  storeLastUsedLabels: (labels: string[]) => void;\n  deleteLastUsedLabels: () => void;\n}\n\ninterface BrowserState {\n  labels: SelectableLabel[];\n  searchTerm: string;\n  status: string;\n  error: string;\n  validationStatus: string;\n}\n\ninterface FacettableValue {\n  name: string;\n  selected?: boolean;\n  highlightParts?: HighlightPart[];\n  order?: number;\n}\n\nexport interface SelectableLabel {\n  name: string;\n  selected?: boolean;\n  loading?: boolean;\n  values?: FacettableValue[];\n  hidden?: boolean;\n  facets?: number;\n}\n\nexport function buildSelector(labels: SelectableLabel[]): string {\n  const selectedLabels = [];\n  for (const label of labels) {\n    if (label.selected && label.values && label.values.length > 0) {\n      const selectedValues = label.values.filter((value) => value.selected).map((value) => value.name);\n      if (selectedValues.length > 1) {\n        selectedLabels.push(`${label.name}=~\"${selectedValues.join('|')}\"`);\n      } else if (selectedValues.length === 1) {\n        selectedLabels.push(`${label.name}=\"${selectedValues[0]}\"`);\n      }\n    }\n  }\n  return ['{', selectedLabels.join(','), '}'].join('');\n}\n\nexport function facetLabels(\n  labels: SelectableLabel[],\n  possibleLabels: Record<string, string[]>,\n  lastFacetted?: string\n): SelectableLabel[] {\n  return labels.map((label) => {\n    const possibleValues = possibleLabels[label.name];\n    if (possibleValues) {\n      let existingValues: FacettableValue[];\n      if (label.name === lastFacetted && label.values) {\n        // Facetting this label, show all values\n        existingValues = label.values;\n      } else {\n        // Keep selection in other facets\n        const selectedValues: Set<string> = new Set(\n          label.values?.filter((value) => value.selected).map((value) => value.name) || []\n        );\n        // Values for this label have not been requested yet, let's use the facetted ones as the initial values\n        existingValues = possibleValues.map((value) => ({ name: value, selected: selectedValues.has(value) }));\n      }\n      return { ...label, loading: false, values: existingValues, facets: existingValues.length };\n    }\n\n    // Label is facetted out, hide all values\n    return { ...label, loading: false, hidden: !possibleValues, values: undefined, facets: 0 };\n  });\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n  wrapper: css`\n    background-color: ${theme.colors.background.secondary};\n    padding: ${theme.spacing(2)};\n    width: 100%;\n  `,\n  list: css`\n    margin-top: ${theme.spacing(1)};\n    display: flex;\n    flex-wrap: wrap;\n    max-height: 200px;\n    overflow: auto;\n  `,\n  section: css`\n    & + & {\n      margin: ${theme.spacing(2, 0)};\n    }\n    position: relative;\n  `,\n  selector: css`\n    font-family: ${theme.typography.fontFamilyMonospace};\n    margin-bottom: ${theme.spacing(1)};\n  `,\n  status: css`\n    padding: ${theme.spacing(0.5)};\n    color: ${theme.colors.text.secondary};\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    /* using absolute positioning because flex interferes with ellipsis */\n    position: absolute;\n    width: 50%;\n    right: 0;\n    text-align: right;\n    transition: opacity 100ms linear;\n    opacity: 0;\n  `,\n  statusShowing: css`\n    opacity: 1;\n  `,\n  error: css`\n    color: ${theme.colors.error.main};\n  `,\n  valueList: css`\n    margin-right: ${theme.spacing(1)};\n  `,\n  valueListWrapper: css`\n    border-left: 1px solid ${theme.colors.border.medium};\n    margin: ${theme.spacing(1, 0)};\n    padding: ${theme.spacing(1, 0, 1, 1)};\n  `,\n  valueListArea: css`\n    display: flex;\n    flex-wrap: wrap;\n    margin-top: ${theme.spacing(1)};\n  `,\n  valueTitle: css`\n    margin-left: -${theme.spacing(0.5)};\n    margin-bottom: ${theme.spacing(1)};\n  `,\n  validationStatus: css`\n    padding: ${theme.spacing(0.5)};\n    margin-bottom: ${theme.spacing(1)};\n    color: ${theme.colors.text.maxContrast};\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n  `,\n});\n\nexport class UnthemedLokiLabelBrowser extends React.Component<BrowserProps, BrowserState> {\n  state: BrowserState = {\n    labels: [] as SelectableLabel[],\n    searchTerm: '',\n    status: 'Ready',\n    error: '',\n    validationStatus: '',\n  };\n\n  onChangeSearch = (event: ChangeEvent<HTMLInputElement>) => {\n    this.setState({ searchTerm: event.target.value });\n  };\n\n  onClickRunLogsQuery = () => {\n    const selector = buildSelector(this.state.labels);\n    this.props.onChange(selector);\n  };\n\n  onClickRunMetricsQuery = () => {\n    const selector = buildSelector(this.state.labels);\n    const query = `rate(${selector}[$__interval])`;\n    this.props.onChange(query);\n  };\n\n  onClickClear = () => {\n    this.setState((state) => {\n      const labels: SelectableLabel[] = state.labels.map((label) => ({\n        ...label,\n        values: undefined,\n        selected: false,\n        loading: false,\n        hidden: false,\n        facets: undefined,\n      }));\n      return { labels, searchTerm: '', status: '', error: '', validationStatus: '' };\n    });\n    this.props.deleteLastUsedLabels();\n  };\n\n  onClickLabel = (name: string, value: string | undefined, event: React.MouseEvent<HTMLElement>) => {\n    const label = this.state.labels.find((l) => l.name === name);\n    if (!label) {\n      return;\n    }\n    // Toggle selected state\n    const selected = !label.selected;\n    let nextValue: Partial<SelectableLabel> = { selected };\n    if (label.values && !selected) {\n      // Deselect all values if label was deselected\n      const values = label.values.map((value) => ({ ...value, selected: false }));\n      nextValue = { ...nextValue, facets: 0, values };\n    }\n    // Resetting search to prevent empty results\n    this.setState({ searchTerm: '' });\n    this.updateLabelState(name, nextValue, '', () => this.doFacettingForLabel(name));\n  };\n\n  onClickValue = (name: string, value: string | undefined, event: React.MouseEvent<HTMLElement>) => {\n    const label = this.state.labels.find((l) => l.name === name);\n    if (!label || !label.values) {\n      return;\n    }\n    // Resetting search to prevent empty results\n    this.setState({ searchTerm: '' });\n    // Toggling value for selected label, leaving other values intact\n    const values = label.values.map((v) => ({ ...v, selected: v.name === value ? !v.selected : v.selected }));\n    this.updateLabelState(name, { values }, '', () => this.doFacetting(name));\n  };\n\n  onClickValidate = () => {\n    const selector = buildSelector(this.state.labels);\n    this.validateSelector(selector);\n  };\n\n  updateLabelState(name: string, updatedFields: Partial<SelectableLabel>, status = '', cb?: () => void) {\n    this.setState((state) => {\n      const labels: SelectableLabel[] = state.labels.map((label) => {\n        if (label.name === name) {\n          return { ...label, ...updatedFields };\n        }\n        return label;\n      });\n      // New status overrides errors\n      const error = status ? '' : state.error;\n      return { labels, status, error, validationStatus: '' };\n    }, cb);\n  }\n\n  componentDidMount() {\n    const { languageProvider, autoSelect = MAX_AUTO_SELECT, lastUsedLabels } = this.props;\n    if (languageProvider) {\n      const selectedLabels: string[] = lastUsedLabels;\n      languageProvider.start().then(() => {\n        let rawLabels: string[] = languageProvider.getLabelKeys();\n        if (rawLabels.length > MAX_LABEL_COUNT) {\n          const error = `Too many labels found (showing only ${MAX_LABEL_COUNT} of ${rawLabels.length})`;\n          rawLabels = rawLabels.slice(0, MAX_LABEL_COUNT);\n          this.setState({ error });\n        }\n        // Auto-select all labels if label list is small enough\n        const labels: SelectableLabel[] = rawLabels.map((label, i, arr) => ({\n          name: label,\n          selected: (arr.length <= autoSelect && selectedLabels.length === 0) || selectedLabels.includes(label),\n          loading: false,\n        }));\n        // Pre-fetch values for selected labels\n        this.setState({ labels }, () => {\n          this.state.labels.forEach((label) => {\n            if (label.selected) {\n              this.fetchValues(label.name, EMPTY_SELECTOR);\n            }\n          });\n        });\n      });\n    }\n  }\n\n  doFacettingForLabel(name: string) {\n    const label = this.state.labels.find((l) => l.name === name);\n    if (!label) {\n      return;\n    }\n    const selectedLabels = this.state.labels.filter((label) => label.selected).map((label) => label.name);\n    this.props.storeLastUsedLabels(selectedLabels);\n    if (label.selected) {\n      // Refetch values for newly selected label...\n      if (!label.values) {\n        this.fetchValues(name, buildSelector(this.state.labels));\n      }\n    } else {\n      // Only need to facet when deselecting labels\n      this.doFacetting();\n    }\n  }\n\n  doFacetting = (lastFacetted?: string) => {\n    const selector = buildSelector(this.state.labels);\n    if (selector === EMPTY_SELECTOR) {\n      // Clear up facetting\n      const labels: SelectableLabel[] = this.state.labels.map((label) => {\n        return { ...label, facets: 0, values: undefined, hidden: false };\n      });\n      this.setState({ labels }, () => {\n        // Get fresh set of values\n        this.state.labels.forEach((label) => label.selected && this.fetchValues(label.name, selector));\n      });\n    } else {\n      // Do facetting\n      this.fetchSeries(selector, lastFacetted);\n    }\n  };\n\n  async fetchValues(name: string, selector: string) {\n    const { languageProvider } = this.props;\n    this.updateLabelState(name, { loading: true }, `Fetching values for ${name}`);\n    try {\n      let rawValues = await languageProvider.getLabelValues(name);\n      // If selector changed, clear loading state and discard result by returning early\n      if (selector !== buildSelector(this.state.labels)) {\n        this.updateLabelState(name, { loading: false }, '');\n        return;\n      }\n      if (rawValues.length > MAX_VALUE_COUNT) {\n        const error = `Too many values for ${name} (showing only ${MAX_VALUE_COUNT} of ${rawValues.length})`;\n        rawValues = rawValues.slice(0, MAX_VALUE_COUNT);\n        this.setState({ error });\n      }\n      const values: FacettableValue[] = rawValues.map((value) => ({ name: value }));\n      this.updateLabelState(name, { values, loading: false });\n    } catch (error) {\n      console.error(error);\n    }\n  }\n\n  async fetchSeries(selector: string, lastFacetted?: string) {\n    const { languageProvider } = this.props;\n    if (lastFacetted) {\n      this.updateLabelState(lastFacetted, { loading: true }, `Facetting labels for ${selector}`);\n    }\n    try {\n      const possibleLabels = await languageProvider.fetchSeriesLabels(selector, true);\n      // If selector changed, clear loading state and discard result by returning early\n      if (selector !== buildSelector(this.state.labels)) {\n        if (lastFacetted) {\n          this.updateLabelState(lastFacetted, { loading: false });\n        }\n        return;\n      }\n      if (Object.keys(possibleLabels).length === 0) {\n        this.setState({ error: `Empty results, no matching label for ${selector}` });\n        return;\n      }\n      const labels: SelectableLabel[] = facetLabels(this.state.labels, possibleLabels, lastFacetted);\n      this.setState({ labels, error: '' });\n      if (lastFacetted) {\n        this.updateLabelState(lastFacetted, { loading: false });\n      }\n    } catch (error) {\n      console.error(error);\n    }\n  }\n\n  async validateSelector(selector: string) {\n    const { languageProvider } = this.props;\n    this.setState({ validationStatus: `Validating selector ${selector}`, error: '' });\n    const streams = await languageProvider.fetchSeries(selector);\n    this.setState({ validationStatus: `Selector is valid (${streams.length} streams found)` });\n  }\n\n  render() {\n    const { theme } = this.props;\n    const { labels, searchTerm, status, error, validationStatus } = this.state;\n    if (labels.length === 0) {\n      return <LoadingPlaceholder text=\"Loading labels...\" />;\n    }\n    const styles = getStyles(theme);\n    const selector = buildSelector(this.state.labels);\n    const empty = selector === EMPTY_SELECTOR;\n\n    let selectedLabels = labels.filter((label) => label.selected && label.values);\n    if (searchTerm) {\n      selectedLabels = selectedLabels.map((label) => {\n        const searchResults = label.values!.filter((value) => {\n          // Always return selected values\n          if (value.selected) {\n            value.highlightParts = undefined;\n            return true;\n          }\n          const fuzzyMatchResult = fuzzyMatch(value.name.toLowerCase(), searchTerm.toLowerCase());\n          if (fuzzyMatchResult.found) {\n            value.highlightParts = fuzzyMatchResult.ranges;\n            value.order = fuzzyMatchResult.distance;\n            return true;\n          } else {\n            return false;\n          }\n        });\n        return {\n          ...label,\n          values: sortBy(searchResults, (value) => (value.selected ? -Infinity : value.order)),\n        };\n      });\n    } else {\n      // Clear highlight parts when searchTerm is cleared\n      selectedLabels = this.state.labels\n        .filter((label) => label.selected && label.values)\n        .map((label) => ({\n          ...label,\n          values: label?.values ? label.values.map((value) => ({ ...value, highlightParts: undefined })) : [],\n        }));\n    }\n\n    return (\n      <div className={styles.wrapper}>\n        <div className={styles.section}>\n          <Label description=\"Which labels would you like to consider for your search?\">\n            1. Select labels to search in\n          </Label>\n          <div className={styles.list}>\n            {labels.map((label) => (\n              <LokiLabel\n                key={label.name}\n                name={label.name}\n                loading={label.loading}\n                active={label.selected}\n                hidden={label.hidden}\n                facets={label.facets}\n                onClick={this.onClickLabel}\n              />\n            ))}\n          </div>\n        </div>\n        <div className={styles.section}>\n          <Label description=\"Choose the label values that you would like to use for the query. Use the search field to find values across selected labels.\">\n            2. Find values for the selected labels\n          </Label>\n          <div>\n            <Input onChange={this.onChangeSearch} aria-label=\"Filter expression for values\" value={searchTerm} />\n          </div>\n          <div className={styles.valueListArea}>\n            {selectedLabels.map((label) => (\n              <div role=\"list\" key={label.name} className={styles.valueListWrapper}>\n                <div className={styles.valueTitle} aria-label={`Values for ${label.name}`}>\n                  <LokiLabel\n                    name={label.name}\n                    loading={label.loading}\n                    active={label.selected}\n                    hidden={label.hidden}\n                    //If no facets, we want to show number of all label values\n                    facets={label.facets || label.values?.length}\n                    onClick={this.onClickLabel}\n                  />\n                </div>\n                <FixedSizeList\n                  height={200}\n                  itemCount={label.values?.length || 0}\n                  itemSize={28}\n                  itemKey={(i) => (label.values as FacettableValue[])[i].name}\n                  width={200}\n                  className={styles.valueList}\n                >\n                  {({ index, style }) => {\n                    const value = label.values?.[index];\n                    if (!value) {\n                      return null;\n                    }\n                    return (\n                      <div style={style}>\n                        <LokiLabel\n                          name={label.name}\n                          value={value?.name}\n                          active={value?.selected}\n                          highlightParts={value?.highlightParts}\n                          onClick={this.onClickValue}\n                          searchTerm={searchTerm}\n                        />\n                      </div>\n                    );\n                  }}\n                </FixedSizeList>\n              </div>\n            ))}\n          </div>\n        </div>\n        <div className={styles.section}>\n          <Label>3. Resulting selector</Label>\n          <div aria-label=\"selector\" className={styles.selector}>\n            {selector}\n          </div>\n          {validationStatus && <div className={styles.validationStatus}>{validationStatus}</div>}\n          <HorizontalGroup>\n            <Button aria-label=\"Use selector as logs button\" disabled={empty} onClick={this.onClickRunLogsQuery}>\n              Show logs\n            </Button>\n            <Button\n              aria-label=\"Use selector as metrics button\"\n              variant=\"secondary\"\n              disabled={empty}\n              onClick={this.onClickRunMetricsQuery}\n            >\n              Show logs rate\n            </Button>\n            <Button\n              aria-label=\"Validate submit button\"\n              variant=\"secondary\"\n              disabled={empty}\n              onClick={this.onClickValidate}\n            >\n              Validate selector\n            </Button>\n            <Button aria-label=\"Selector clear button\" variant=\"secondary\" onClick={this.onClickClear}>\n              Clear\n            </Button>\n            <div className={cx(styles.status, (status || error) && styles.statusShowing)}>\n              <span className={error ? styles.error : ''}>{error || status}</span>\n            </div>\n          </HorizontalGroup>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport const LokiLabelBrowser = withTheme2(UnthemedLokiLabelBrowser);\n","import { LanguageMap, languages as prismLanguages } from 'prismjs';\nimport React, { ReactNode } from 'react';\nimport { Plugin, Node } from 'slate';\nimport { Editor } from 'slate-react';\n\nimport { QueryEditorProps } from '@grafana/data';\nimport {\n  SlatePrism,\n  TypeaheadOutput,\n  SuggestionsState,\n  QueryField,\n  TypeaheadInput,\n  BracesPlugin,\n  DOMUtil,\n  Icon,\n} from '@grafana/ui';\nimport { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider';\n\nimport { LokiDatasource } from '../datasource';\nimport LokiLanguageProvider from '../language_provider';\nimport { shouldRefreshLabels } from '../language_utils';\nimport { LokiQuery, LokiOptions } from '../types';\n\nimport { LokiLabelBrowser } from './LokiLabelBrowser';\n\nconst LAST_USED_LABELS_KEY = 'grafana.datasources.loki.browser.labels';\n\nfunction getChooserText(hasSyntax: boolean, hasLogLabels: boolean) {\n  if (!hasSyntax) {\n    return 'Loading labels...';\n  }\n  if (!hasLogLabels) {\n    return '(No logs found)';\n  }\n  return 'Log browser';\n}\n\nfunction willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadText }: SuggestionsState): string {\n  // Modify suggestion based on context\n  switch (typeaheadContext) {\n    case 'context-labels': {\n      const nextChar = DOMUtil.getNextCharacter();\n      if (!nextChar || nextChar === '}' || nextChar === ',') {\n        suggestion += '=';\n      }\n      break;\n    }\n\n    case 'context-label-values': {\n      // Always add quotes and remove existing ones instead\n      if (!typeaheadText.match(/^(!?=~?\"|\")/)) {\n        suggestion = `\"${suggestion}`;\n      }\n      if (DOMUtil.getNextCharacter() !== '\"') {\n        suggestion = `${suggestion}\"`;\n      }\n      break;\n    }\n\n    default:\n  }\n  return suggestion;\n}\n\nexport interface LokiQueryFieldProps extends QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions> {\n  ExtraFieldElement?: ReactNode;\n  placeholder?: string;\n  'data-testid'?: string;\n}\n\ninterface LokiQueryFieldState {\n  labelsLoaded: boolean;\n  labelBrowserVisible: boolean;\n}\n\nexport class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryFieldState> {\n  plugins: Array<Plugin<Editor>>;\n  _isMounted = false;\n\n  constructor(props: LokiQueryFieldProps) {\n    super(props);\n\n    this.state = { labelsLoaded: false, labelBrowserVisible: false };\n\n    this.plugins = [\n      BracesPlugin(),\n      SlatePrism(\n        {\n          onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block',\n          getSyntax: (node: Node) => 'logql',\n        },\n        { ...(prismLanguages as LanguageMap), logql: this.props.datasource.languageProvider.getSyntax() }\n      ),\n    ];\n  }\n\n  async componentDidMount() {\n    this._isMounted = true;\n    await this.props.datasource.languageProvider.start();\n    if (this._isMounted) {\n      this.setState({ labelsLoaded: true });\n    }\n  }\n\n  componentWillUnmount() {\n    this._isMounted = false;\n  }\n\n  componentDidUpdate(prevProps: LokiQueryFieldProps) {\n    const {\n      range,\n      datasource: { languageProvider },\n    } = this.props;\n    const refreshLabels = shouldRefreshLabels(range, prevProps.range);\n    // We want to refresh labels when range changes (we round up intervals to a minute)\n    if (refreshLabels) {\n      languageProvider.fetchLabels();\n    }\n  }\n\n  onChangeLabelBrowser = (selector: string) => {\n    this.onChangeQuery(selector, true);\n    this.setState({ labelBrowserVisible: false });\n  };\n\n  onChangeQuery = (value: string, override?: boolean) => {\n    // Send text change to parent\n    const { query, onChange, onRunQuery } = this.props;\n    if (onChange) {\n      const nextQuery = { ...query, expr: value };\n      onChange(nextQuery);\n\n      if (override && onRunQuery) {\n        onRunQuery();\n      }\n    }\n  };\n\n  onClickChooserButton = () => {\n    this.setState((state) => ({ labelBrowserVisible: !state.labelBrowserVisible }));\n  };\n\n  onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {\n    const { datasource } = this.props;\n\n    if (!datasource.languageProvider) {\n      return { suggestions: [] };\n    }\n\n    const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;\n    const { history } = this.props;\n    const { prefix, text, value, wrapperClasses, labelKey } = typeahead;\n\n    const result = await lokiLanguageProvider.provideCompletionItems(\n      { text, value, prefix, wrapperClasses, labelKey },\n      { history }\n    );\n    return result;\n  };\n\n  render() {\n    const {\n      ExtraFieldElement,\n      query,\n      datasource,\n      placeholder = 'Enter a Loki query (run with Shift+Enter)',\n    } = this.props;\n\n    const { labelsLoaded, labelBrowserVisible } = this.state;\n    const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;\n    const cleanText = datasource.languageProvider ? lokiLanguageProvider.cleanText : undefined;\n    const hasLogLabels = lokiLanguageProvider.getLabelKeys().length > 0;\n    const chooserText = getChooserText(labelsLoaded, hasLogLabels);\n    const buttonDisabled = !(labelsLoaded && hasLogLabels);\n\n    return (\n      <LocalStorageValueProvider<string[]> storageKey={LAST_USED_LABELS_KEY} defaultValue={[]}>\n        {(lastUsedLabels, onLastUsedLabelsSave, onLastUsedLabelsDelete) => {\n          return (\n            <>\n              <div\n                className=\"gf-form-inline gf-form-inline--xs-view-flex-column flex-grow-1\"\n                data-testid={this.props['data-testid']}\n              >\n                <button\n                  className=\"gf-form-label query-keyword pointer\"\n                  onClick={this.onClickChooserButton}\n                  disabled={buttonDisabled}\n                >\n                  {chooserText}\n                  <Icon name={labelBrowserVisible ? 'angle-down' : 'angle-right'} />\n                </button>\n                <div className=\"gf-form gf-form--grow flex-shrink-1 min-width-15\">\n                  <QueryField\n                    additionalPlugins={this.plugins}\n                    cleanText={cleanText}\n                    query={query.expr}\n                    onTypeahead={this.onTypeahead}\n                    onWillApplySuggestion={willApplySuggestion}\n                    onChange={this.onChangeQuery}\n                    onBlur={this.props.onBlur}\n                    onRunQuery={this.props.onRunQuery}\n                    placeholder={placeholder}\n                    portalOrigin=\"loki\"\n                  />\n                </div>\n              </div>\n              {labelBrowserVisible && (\n                <div className=\"gf-form\">\n                  <LokiLabelBrowser\n                    languageProvider={lokiLanguageProvider}\n                    onChange={this.onChangeLabelBrowser}\n                    lastUsedLabels={lastUsedLabels || []}\n                    storeLastUsedLabels={onLastUsedLabelsSave}\n                    deleteLastUsedLabels={onLastUsedLabelsDelete}\n                  />\n                </div>\n              )}\n\n              {ExtraFieldElement}\n            </>\n          );\n        }}\n      </LocalStorageValueProvider>\n    );\n  }\n}\n"],"names":["roundMsToMin","milliseconds","seconds","Math","floor","MAX_LABEL_COUNT","MAX_VALUE_COUNT","MAX_AUTO_SELECT","EMPTY_SELECTOR","buildSelector","labels","selectedLabels","label","selected","values","length","selectedValues","filter","value","map","name","push","join","UnthemedLokiLabelBrowser","React","searchTerm","status","error","validationStatus","event","this","setState","target","selector","state","props","onChange","query","undefined","loading","hidden","facets","deleteLastUsedLabels","find","l","nextValue","updateLabelState","doFacettingForLabel","v","doFacetting","validateSelector","lastFacetted","forEach","fetchValues","fetchSeries","updatedFields","cb","componentDidMount","languageProvider","autoSelect","lastUsedLabels","start","then","rawLabels","getLabelKeys","slice","i","arr","includes","storeLastUsedLabels","rawValues","getLabelValues","console","possibleLabels","fetchSeriesLabels","Object","keys","possibleValues","existingValues","Set","has","facetLabels","streams","render","theme","LoadingPlaceholder","text","styles","wrapper","css","colors","background","secondary","spacing","list","section","typography","fontFamilyMonospace","statusShowing","main","valueList","valueListWrapper","border","medium","valueListArea","valueTitle","maxContrast","getStyles","empty","searchResults","highlightParts","fuzzyMatchResult","fuzzyMatch","toLowerCase","found","ranges","order","distance","sortBy","Infinity","className","Label","description","active","onClick","onClickLabel","Input","onChangeSearch","role","height","itemCount","itemSize","itemKey","width","index","style","onClickValue","HorizontalGroup","Button","disabled","onClickRunLogsQuery","variant","onClickRunMetricsQuery","onClickValidate","onClickClear","cx","LokiLabelBrowser","withTheme2","willApplySuggestion","suggestion","typeaheadContext","typeaheadText","nextChar","DOMUtil","match","LokiQueryField","constructor","super","onChangeQuery","labelBrowserVisible","override","onRunQuery","expr","async","datasource","suggestions","lokiLanguageProvider","history","prefix","wrapperClasses","labelKey","typeahead","provideCompletionItems","labelsLoaded","plugins","BracesPlugin","SlatePrism","onlyIn","node","object","type","getSyntax","prismLanguages","logql","_isMounted","componentWillUnmount","componentDidUpdate","prevProps","range","refreshLabels","prevRange","sameMinuteFrom","from","valueOf","sameMinuteTo","to","shouldRefreshLabels","fetchLabels","ExtraFieldElement","placeholder","cleanText","hasLogLabels","chooserText","hasSyntax","getChooserText","buttonDisabled","LocalStorageValueProvider","storageKey","defaultValue","onLastUsedLabelsSave","onLastUsedLabelsDelete","onClickChooserButton","Icon","QueryField","additionalPlugins","onTypeahead","onWillApplySuggestion","onBlur","portalOrigin","onChangeLabelBrowser"],"sourceRoot":""}