mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: simulate folder mange pages within the playground page (#49041)
This commit is contained in:
parent
e574870104
commit
acd31ae9f0
@ -5,7 +5,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
|
|||||||
|
|
||||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { Input, useStyles2, Spinner, InlineSwitch, InlineFieldRow, InlineField, Button } from '@grafana/ui';
|
import { Input, useStyles2, Spinner, InlineSwitch, InlineFieldRow, InlineField, Button, Select } from '@grafana/ui';
|
||||||
import Page from 'app/core/components/Page/Page';
|
import Page from 'app/core/components/Page/Page';
|
||||||
import { TermCount } from 'app/core/components/TagFilter/TagFilter';
|
import { TermCount } from 'app/core/components/TagFilter/TagFilter';
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ import { getGrafanaSearcher, SearchQuery } from '../service';
|
|||||||
import { SearchLayout } from '../types';
|
import { SearchLayout } from '../types';
|
||||||
|
|
||||||
import { ActionRow, getValidQueryLayout } from './components/ActionRow';
|
import { ActionRow, getValidQueryLayout } from './components/ActionRow';
|
||||||
|
import { FolderSection } from './components/FolderSection';
|
||||||
import { FolderView } from './components/FolderView';
|
import { FolderView } from './components/FolderView';
|
||||||
import { ManageActions } from './components/ManageActions';
|
import { ManageActions } from './components/ManageActions';
|
||||||
import { SearchResultsGrid } from './components/SearchResultsGrid';
|
import { SearchResultsGrid } from './components/SearchResultsGrid';
|
||||||
@ -33,7 +34,16 @@ export default function SearchPage() {
|
|||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
const { query, onQueryChange, onTagFilterChange, onTagAdd, onDatasourceChange, onSortChange, onLayoutChange } =
|
const { query, onQueryChange, onTagFilterChange, onTagAdd, onDatasourceChange, onSortChange, onLayoutChange } =
|
||||||
useSearchQuery({});
|
useSearchQuery({});
|
||||||
|
|
||||||
const [showManage, setShowManage] = useState(false); // grid vs list view
|
const [showManage, setShowManage] = useState(false); // grid vs list view
|
||||||
|
const [folder, setFolder] = useState<string>(); // grid vs list view
|
||||||
|
const folders = useAsync(async () => {
|
||||||
|
const rsp = await getGrafanaSearcher().search({
|
||||||
|
query: '*',
|
||||||
|
kind: ['folder'],
|
||||||
|
});
|
||||||
|
return rsp.view.map((v) => ({ value: v.uid, label: v.name }));
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [searchSelection, setSearchSelection] = useState(newSearchSelection());
|
const [searchSelection, setSearchSelection] = useState(newSearchSelection());
|
||||||
const layout = getValidQueryLayout(query);
|
const layout = getValidQueryLayout(query);
|
||||||
@ -48,10 +58,10 @@ export default function SearchPage() {
|
|||||||
query: qstr,
|
query: qstr,
|
||||||
tags: query.tag as string[],
|
tags: query.tag as string[],
|
||||||
ds_uid: query.datasource as string,
|
ds_uid: query.datasource as string,
|
||||||
|
location: folder, // This will scope all results to the prefix
|
||||||
};
|
};
|
||||||
console.log('DO QUERY', q);
|
|
||||||
return getGrafanaSearcher().search(q);
|
return getGrafanaSearcher().search(q);
|
||||||
}, [query, layout]);
|
}, [query, layout, folder]);
|
||||||
|
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const onSearchQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const onSearchQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
@ -128,6 +138,17 @@ export default function SearchPage() {
|
|||||||
|
|
||||||
const selection = showManage ? searchSelection.isSelected : undefined;
|
const selection = showManage ? searchSelection.isSelected : undefined;
|
||||||
if (layout === SearchLayout.Folders) {
|
if (layout === SearchLayout.Folders) {
|
||||||
|
if (folder) {
|
||||||
|
return (
|
||||||
|
<FolderSection
|
||||||
|
section={{ uid: folder, kind: 'folder', title: folder }}
|
||||||
|
selection={selection}
|
||||||
|
selectionToggle={toggleSelection}
|
||||||
|
onTagSelected={onTagAdd}
|
||||||
|
renderStandaloneBody={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
return <FolderView selection={selection} selectionToggle={toggleSelection} onTagSelected={onTagAdd} />;
|
return <FolderView selection={selection} selectionToggle={toggleSelection} onTagSelected={onTagAdd} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +199,14 @@ export default function SearchPage() {
|
|||||||
<InlineField label="Show manage options">
|
<InlineField label="Show manage options">
|
||||||
<InlineSwitch value={showManage} onChange={() => setShowManage(!showManage)} />
|
<InlineSwitch value={showManage} onChange={() => setShowManage(!showManage)} />
|
||||||
</InlineField>
|
</InlineField>
|
||||||
|
<InlineField label="Folder">
|
||||||
|
<Select
|
||||||
|
options={folders.value ?? []}
|
||||||
|
isLoading={folders.loading}
|
||||||
|
onChange={(v) => setFolder(v?.value)}
|
||||||
|
isClearable
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
|
|
||||||
{Boolean(searchSelection.items.size > 0) ? (
|
{Boolean(searchSelection.items.size > 0) ? (
|
||||||
|
@ -28,16 +28,23 @@ interface SectionHeaderProps {
|
|||||||
selectionToggle?: SelectionToggle;
|
selectionToggle?: SelectionToggle;
|
||||||
onTagSelected: (tag: string) => void;
|
onTagSelected: (tag: string) => void;
|
||||||
section: DashboardSection;
|
section: DashboardSection;
|
||||||
|
renderStandaloneBody?: boolean; // render the body on its own
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FolderSection: FC<SectionHeaderProps> = ({ section, selectionToggle, onTagSelected, selection }) => {
|
export const FolderSection: FC<SectionHeaderProps> = ({
|
||||||
|
section,
|
||||||
|
selectionToggle,
|
||||||
|
onTagSelected,
|
||||||
|
selection,
|
||||||
|
renderStandaloneBody,
|
||||||
|
}) => {
|
||||||
const editable = selectionToggle != null;
|
const editable = selectionToggle != null;
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const styles = getSectionHeaderStyles(theme, section.selected, editable);
|
const styles = getSectionHeaderStyles(theme, section.selected, editable);
|
||||||
const [sectionExpanded, setSectionExpanded] = useLocalStorage(getSectionStorageKey(section.title), false);
|
const [sectionExpanded, setSectionExpanded] = useLocalStorage(getSectionStorageKey(section.title), false);
|
||||||
|
|
||||||
const results = useAsync(async () => {
|
const results = useAsync(async () => {
|
||||||
if (!sectionExpanded) {
|
if (!sectionExpanded && !renderStandaloneBody) {
|
||||||
return Promise.resolve([] as DashboardSectionItem[]);
|
return Promise.resolve([] as DashboardSectionItem[]);
|
||||||
}
|
}
|
||||||
let folderUid: string | undefined = section.uid;
|
let folderUid: string | undefined = section.uid;
|
||||||
@ -144,6 +151,11 @@ export const FolderSection: FC<SectionHeaderProps> = ({ section, selectionToggle
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Skip the folder wrapper
|
||||||
|
if (renderStandaloneBody) {
|
||||||
|
return <div>{renderResults()}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CollapsableSection
|
<CollapsableSection
|
||||||
isOpen={sectionExpanded ?? false}
|
isOpen={sectionExpanded ?? false}
|
||||||
|
Loading…
Reference in New Issue
Block a user