import React, { FC, memo } from 'react'; import { css } from '@emotion/css'; import { FixedSizeList } from 'react-window'; import AutoSizer from 'react-virtualized-auto-sizer'; import { GrafanaTheme } from '@grafana/data'; import { stylesFactory, useTheme, Spinner } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; import { DashboardSection, OnToggleChecked, SearchLayout } from '../types'; import { SEARCH_ITEM_HEIGHT, SEARCH_ITEM_MARGIN } from '../constants'; import { SearchItem } from './SearchItem'; import { SectionHeader } from './SectionHeader'; export interface Props { editable?: boolean; loading?: boolean; onTagSelected: (name: string) => any; onToggleChecked?: OnToggleChecked; onToggleSection: (section: DashboardSection) => void; results: DashboardSection[]; layout?: string; } const { section: sectionLabel, items: itemsLabel } = selectors.components.Search; export const SearchResults: FC = memo( ({ editable, loading, onTagSelected, onToggleChecked, onToggleSection, results, layout }) => { const theme = useTheme(); const styles = getSectionStyles(theme); const itemProps = { editable, onToggleChecked, onTagSelected }; const renderFolders = () => { return (
{results.map((section) => { return (
{section.title && ( )} {section.expanded && (
{section.items.map((item) => ( ))}
)}
); })}
); }; const renderDashboards = () => { const items = results[0]?.items; return (
{({ height }) => ( {({ index, style }) => { const item = items[index]; // The wrapper div is needed as the inner SearchItem has margin-bottom spacing // And without this wrapper there is no room for that margin return (
  • ); }}
    )}
    ); }; if (loading) { return ; } else if (!results || !results.length) { return
    No dashboards matching your query were found.
    ; } return (
    {layout === SearchLayout.Folders ? renderFolders() : renderDashboards()}
    ); } ); SearchResults.displayName = 'SearchResults'; const getSectionStyles = stylesFactory((theme: GrafanaTheme) => { const { md } = theme.spacing; return { wrapper: css` display: flex; flex-direction: column; `, section: css` display: flex; flex-direction: column; background: ${theme.colors.panelBg}; border-bottom: solid 1px ${theme.colors.border2}; `, sectionItems: css` margin: 0 24px 0 32px; `, spinner: css` display: flex; justify-content: center; align-items: center; min-height: 100px; `, resultsContainer: css` position: relative; flex-grow: 10; margin-bottom: ${md}; background: ${theme.colors.bg1}; border: 1px solid ${theme.colors.border1}; border-radius: 3px; height: 100%; `, noResults: css` padding: ${md}; background: ${theme.colors.bg2}; font-style: italic; margin-top: ${theme.spacing.md}; `, listModeWrapper: css` position: relative; height: 100%; padding: ${md}; `, }; });