mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LibraryPanels: Adds folder filter to manage library panel page (#33560)
* LibraryPanels: Adds folder filter * Refactor: Adds folder filter to library search * Refactor: splits huge function into smaller functions * LibraryPanels: Adds Panels Page to Manage Folder tabs (#33618) * Chore: adds tests to LibraryPanelsSearch * Refactor: Adds reducer and tests * Chore: changes GrafanaThemeV2 * Refactor: pulls everything behind the feature toggle * Chore: removes clear icon from FolderFilter * Chore: adds filter to SortPicker * Refactor: using useAsync instead
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useReducer } from 'react';
|
||||
import { HorizontalGroup, useStyles2, VerticalGroup } from '@grafana/ui';
|
||||
import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
|
||||
import { css } from '@emotion/css';
|
||||
@@ -8,6 +8,16 @@ import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/Pan
|
||||
import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
|
||||
import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../core/constants';
|
||||
import { LibraryPanelDTO } from '../../types';
|
||||
import { FolderFilter } from '../../../../core/components/FolderFilter/FolderFilter';
|
||||
import { FolderInfo } from '../../../../types';
|
||||
import {
|
||||
folderFilterChanged,
|
||||
initialLibraryPanelsSearchState,
|
||||
libraryPanelsSearchReducer,
|
||||
panelFilterChanged,
|
||||
searchChanged,
|
||||
sortChanged,
|
||||
} from './reducer';
|
||||
|
||||
export enum LibraryPanelsSearchVariant {
|
||||
Tight = 'tight',
|
||||
@@ -18,9 +28,11 @@ export interface LibraryPanelsSearchProps {
|
||||
onClick: (panel: LibraryPanelDTO) => void;
|
||||
variant?: LibraryPanelsSearchVariant;
|
||||
showSort?: boolean;
|
||||
showFilter?: boolean;
|
||||
showPanelFilter?: boolean;
|
||||
showFolderFilter?: boolean;
|
||||
showSecondaryActions?: boolean;
|
||||
currentPanelId?: string;
|
||||
currentFolderId?: number;
|
||||
perPage?: number;
|
||||
}
|
||||
|
||||
@@ -28,26 +40,44 @@ export const LibraryPanelsSearch = ({
|
||||
onClick,
|
||||
variant = LibraryPanelsSearchVariant.Spacious,
|
||||
currentPanelId,
|
||||
currentFolderId,
|
||||
perPage = DEFAULT_PER_PAGE_PAGINATION,
|
||||
showFilter = false,
|
||||
showPanelFilter = false,
|
||||
showFolderFilter = false,
|
||||
showSort = false,
|
||||
showSecondaryActions = false,
|
||||
}: LibraryPanelsSearchProps): JSX.Element => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [sortDirection, setSortDirection] = useState<string | undefined>(undefined);
|
||||
const [panelFilter, setPanelFilter] = useState<string[]>([]);
|
||||
const styles = useStyles2(getStyles);
|
||||
const onSortChange = useCallback((sort: SelectableValue<string>) => setSortDirection(sort.value), []);
|
||||
const onFilterChange = useCallback((plugins: PanelPluginMeta[]) => setPanelFilter(plugins.map((p) => p.id)), []);
|
||||
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={setSearchQuery} placeholder={'Search by name'} width={0} />
|
||||
<HorizontalGroup spacing="sm" justify={showSort && showFilter ? 'space-between' : 'flex-end'}>
|
||||
{showSort && <SortPicker value={sortDirection} onChange={onSortChange} />}
|
||||
{showFilter && <PanelTypeFilter onChange={onFilterChange} />}
|
||||
<FilterInput
|
||||
value={searchQuery}
|
||||
onChange={onFilterChange}
|
||||
placeholder={'Search by name or description'}
|
||||
width={0}
|
||||
/>
|
||||
<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 className={styles.libraryPanelsView}>
|
||||
<LibraryPanelsView
|
||||
@@ -55,6 +85,7 @@ export const LibraryPanelsSearch = ({
|
||||
searchString={searchQuery}
|
||||
sortDirection={sortDirection}
|
||||
panelFilter={panelFilter}
|
||||
folderFilter={folderFilter}
|
||||
currentPanelId={currentPanelId}
|
||||
showSecondaryActions={showSecondaryActions}
|
||||
perPage={perPage}
|
||||
@@ -70,11 +101,12 @@ export const LibraryPanelsSearch = ({
|
||||
<VerticalGroup spacing="xs">
|
||||
<div className={styles.buttonRow}>
|
||||
<div className={styles.tightFilter}>
|
||||
<FilterInput value={searchQuery} onChange={setSearchQuery} placeholder={'Search by name'} width={0} />
|
||||
<FilterInput value={searchQuery} onChange={onFilterChange} placeholder={'Search by name'} width={0} />
|
||||
</div>
|
||||
<div className={styles.tightSortFilter}>
|
||||
{showSort && <SortPicker value={sortDirection} onChange={onSortChange} />}
|
||||
{showFilter && <PanelTypeFilter onChange={onFilterChange} />}
|
||||
{showFolderFilter && <FolderFilter onChange={onFolderFilterChange} maxMenuHeight={200} />}
|
||||
{showPanelFilter && <PanelTypeFilter onChange={onPanelFilterChange} maxMenuHeight={200} />}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.libraryPanelsView}>
|
||||
@@ -83,6 +115,7 @@ export const LibraryPanelsSearch = ({
|
||||
searchString={searchQuery}
|
||||
sortDirection={sortDirection}
|
||||
panelFilter={panelFilter}
|
||||
folderFilter={folderFilter}
|
||||
currentPanelId={currentPanelId}
|
||||
showSecondaryActions={showSecondaryActions}
|
||||
perPage={perPage}
|
||||
@@ -99,6 +132,7 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
padding: ${theme.spacing(1)};
|
||||
min-height: 400px;
|
||||
`,
|
||||
buttonRow: css`
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user