<commit_before>import React, { FC, memo } from 'react';
import { useLocalStorage } from 'react-use';
import { css } from '@emotion/css';
import { useTheme2, CustomScrollbar, stylesFactory, IconButton } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { useSearchQuery } from '../hooks/useSearchQuery';
import { useDashboardSearch } from '../hooks/useDashboardSearch';
import { SearchField } from './SearchField';
import { SearchResults } from './SearchResults';
import { ActionRow } from './ActionRow';
import { PREVIEWS_LOCAL_STORAGE_KEY } from '../constants';

export interface Props {
  onCloseSearch: () => void;
}

export const DashboardSearch: FC<Props> = memo(({ onCloseSearch }) => {
  const { query, onQueryChange, onTagFilterChange, onTagAdd, onSortChange, onLayoutChange } = useSearchQuery({});
  const { results, loading, onToggleSection, onKeyDown } = useDashboardSearch(query, onCloseSearch);
  const theme = useTheme2();
  const styles = getStyles(theme);
  const previewsEnabled = config.featureToggles.dashboardPreviews;
  const [showPreviews, setShowPreviews] = useLocalStorage<boolean>(PREVIEWS_LOCAL_STORAGE_KEY, previewsEnabled);
  const onShowPreviewsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setShowPreviews(event.target.checked);
  };

  return (
    <div tabIndex={0} className={styles.overlay}>
      <div className={styles.container}>
        <div className={styles.searchField}>
          <SearchField query={query} onChange={onQueryChange} onKeyDown={onKeyDown} autoFocus clearable />
          <div className={styles.closeBtn}>
            <IconButton name="times" surface="panel" onClick={onCloseSearch} size="xxl" tooltip="Close search" />
          </div>
        </div>
        <div className={styles.search}>
          <ActionRow
            {...{
              onLayoutChange,
              onShowPreviewsChange,
              onSortChange,
              onTagFilterChange,
              query,
              showPreviews,
            }}
          />
          <CustomScrollbar>
            <SearchResults
              results={results}
              loading={loading}
              onTagSelected={onTagAdd}
              editable={false}
              onToggleSection={onToggleSection}
              layout={query.layout}
              showPreviews={showPreviews}
            />
          </CustomScrollbar>
        </div>
      </div>
    </div>
  );
});

DashboardSearch.displayName = 'DashboardSearch';

export default DashboardSearch;
<commit_msg>Hide previews behind toggle properly (#43704)<commit_after>import React, { FC, memo } from 'react';
import { useLocalStorage } from 'react-use';
import { css } from '@emotion/css';
import { useTheme2, CustomScrollbar, stylesFactory, IconButton } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { useSearchQuery } from '../hooks/useSearchQuery';
import { useDashboardSearch } from '../hooks/useDashboardSearch';
import { SearchField } from './SearchField';
import { SearchResults } from './SearchResults';
import { ActionRow } from './ActionRow';
import { PREVIEWS_LOCAL_STORAGE_KEY } from '../constants';

export interface Props {
  onCloseSearch: () => void;
}

export const DashboardSearch: FC<Props> = memo(({ onCloseSearch }) => {
  const { query, onQueryChange, onTagFilterChange, onTagAdd, onSortChange, onLayoutChange } = useSearchQuery({});
  const { results, loading, onToggleSection, onKeyDown } = useDashboardSearch(query, onCloseSearch);
  const theme = useTheme2();
  const styles = getStyles(theme);
  const previewsEnabled = config.featureToggles.dashboardPreviews;
  const [showPreviews, setShowPreviews] = useLocalStorage<boolean>(PREVIEWS_LOCAL_STORAGE_KEY, previewsEnabled);
  const onShowPreviewsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setShowPreviews(event.target.checked);
  };

  return (
    <div tabIndex={0} className={styles.overlay}>
      <div className={styles.container}>
        <div className={styles.searchField}>
          <SearchField query={query} onChange={onQueryChange} onKeyDown={onKeyDown} autoFocus clearable />
          <div className={styles.closeBtn}>
            <IconButton name="times" surface="panel" onClick={onCloseSearch} size="xxl" tooltip="Close search" />
          </div>
        </div>
        <div className={styles.search}>
          <ActionRow
            {...{
              onLayoutChange,
              onShowPreviewsChange,
              onSortChange,
              onTagFilterChange,
              query,
              showPreviews,
            }}
          />
          <CustomScrollbar>
            <SearchResults
              results={results}
              loading={loading}
              onTagSelected={onTagAdd}
              editable={false}
              onToggleSection={onToggleSection}
              layout={query.layout}
              showPreviews={previewsEnabled && showPreviews}
            />
          </CustomScrollbar>
        </div>
      </div>
    </div>
  );
});

DashboardSearch.displayName = 'DashboardSearch';

export default DashboardSearch;

{'fraction_non_alphanumeric': 0.12079892452467832, 'fraction_numerical': 0.0024966391396197426, 'mean_word_length': 2.9938650306748467, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1788787', 'n_tokens_mistral': 1430, 'n_tokens_neox': 1444, 'n_words': 306}