123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import { css } from '@emotion/css';
- import React, { useReducer } from 'react';
- import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
- import { HorizontalGroup, useStyles2, VerticalGroup, FilterInput } from '@grafana/ui';
- import { FolderFilter } from '../../../../core/components/FolderFilter/FolderFilter';
- import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter';
- import { SortPicker } from '../../../../core/components/Select/SortPicker';
- import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../core/constants';
- import { FolderInfo } from '../../../../types';
- import { LibraryElementDTO } from '../../types';
- import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
- import {
- folderFilterChanged,
- initialLibraryPanelsSearchState,
- libraryPanelsSearchReducer,
- panelFilterChanged,
- searchChanged,
- sortChanged,
- } from './reducer';
- export enum LibraryPanelsSearchVariant {
- Tight = 'tight',
- Spacious = 'spacious',
- }
- export interface LibraryPanelsSearchProps {
- onClick: (panel: LibraryElementDTO) => void;
- variant?: LibraryPanelsSearchVariant;
- showSort?: boolean;
- showPanelFilter?: boolean;
- showFolderFilter?: boolean;
- showSecondaryActions?: boolean;
- currentPanelId?: string;
- currentFolderId?: number;
- perPage?: number;
- }
- export const LibraryPanelsSearch = ({
- onClick,
- variant = LibraryPanelsSearchVariant.Spacious,
- currentPanelId,
- currentFolderId,
- perPage = DEFAULT_PER_PAGE_PAGINATION,
- showPanelFilter = false,
- showFolderFilter = false,
- showSort = false,
- showSecondaryActions = false,
- }: LibraryPanelsSearchProps): JSX.Element => {
- const styles = useStyles2(getStyles);
- const [{ sortDirection, panelFilter, folderFilter, searchQuery }, dispatch] = useReducer(libraryPanelsSearchReducer, {
- ...initialLibraryPanelsSearchState,
- folderFilter: currentFolderId ? [currentFolderId.toString(10)] : [],
- });
- const onFilterChange = (searchString: string) => dispatch(searchChanged(searchString));
- const onSortChange = (sorting: SelectableValue<string>) => dispatch(sortChanged(sorting));
- const onFolderFilterChange = (folders: FolderInfo[]) => dispatch(folderFilterChanged(folders));
- const onPanelFilterChange = (plugins: PanelPluginMeta[]) => dispatch(panelFilterChanged(plugins));
- if (variant === LibraryPanelsSearchVariant.Spacious) {
- return (
- <div className={styles.container}>
- <VerticalGroup spacing="lg">
- <FilterInput
- value={searchQuery}
- onChange={onFilterChange}
- placeholder={'Search by name or description'}
- width={0}
- />
- <div className={styles.buttonRow}>
- <HorizontalGroup
- spacing="sm"
- justify={(showSort && showPanelFilter) || showFolderFilter ? 'space-between' : 'flex-end'}
- >
- {showSort && (
- <SortPicker value={sortDirection} onChange={onSortChange} filter={['alpha-asc', 'alpha-desc']} />
- )}
- <HorizontalGroup
- spacing="sm"
- justify={showFolderFilter && showPanelFilter ? 'space-between' : 'flex-end'}
- >
- {showFolderFilter && <FolderFilter onChange={onFolderFilterChange} />}
- {showPanelFilter && <PanelTypeFilter onChange={onPanelFilterChange} />}
- </HorizontalGroup>
- </HorizontalGroup>
- </div>
- <div className={styles.libraryPanelsView}>
- <LibraryPanelsView
- onClickCard={onClick}
- searchString={searchQuery}
- sortDirection={sortDirection}
- panelFilter={panelFilter}
- folderFilter={folderFilter}
- currentPanelId={currentPanelId}
- showSecondaryActions={showSecondaryActions}
- perPage={perPage}
- />
- </div>
- </VerticalGroup>
- </div>
- );
- }
- return (
- <div className={styles.container}>
- <VerticalGroup spacing="xs">
- <div className={styles.tightButtonRow}>
- <div className={styles.tightFilter}>
- <FilterInput value={searchQuery} onChange={onFilterChange} placeholder={'Search by name'} width={0} />
- </div>
- <div className={styles.tightSortFilter}>
- {showSort && <SortPicker value={sortDirection} onChange={onSortChange} />}
- {showFolderFilter && <FolderFilter onChange={onFolderFilterChange} maxMenuHeight={200} />}
- {showPanelFilter && <PanelTypeFilter onChange={onPanelFilterChange} maxMenuHeight={200} />}
- </div>
- </div>
- <div className={styles.libraryPanelsView}>
- <LibraryPanelsView
- onClickCard={onClick}
- searchString={searchQuery}
- sortDirection={sortDirection}
- panelFilter={panelFilter}
- folderFilter={folderFilter}
- currentPanelId={currentPanelId}
- showSecondaryActions={showSecondaryActions}
- perPage={perPage}
- />
- </div>
- </VerticalGroup>
- </div>
- );
- };
- function getStyles(theme: GrafanaTheme2) {
- return {
- container: css`
- width: 100%;
- overflow-y: auto;
- padding: ${theme.spacing(1)};
- `,
- buttonRow: css`
- display: flex;
- justify-content: space-between;
- width: 100%;
- margin-top: ${theme.spacing(2)}; // Clear types link
- `,
- tightButtonRow: css`
- display: flex;
- justify-content: space-between;
- width: 100%;
- margin-top: ${theme.spacing(4)}; // Clear types link
- `,
- tightFilter: css`
- flex-grow: 1;
- `,
- tightSortFilter: css`
- flex-grow: 1;
- padding: ${theme.spacing(0, 0, 0, 0.5)};
- `,
- libraryPanelsView: css`
- width: 100%;
- `,
- };
- }
|