mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: Include panel_type in query (#63229)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, FormEvent } from 'react';
|
||||
import React, { FormEvent } from 'react';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
@@ -36,6 +36,7 @@ interface Props {
|
||||
getSortOptions: () => Promise<SelectableValue[]>;
|
||||
sortPlaceholder?: string;
|
||||
onDatasourceChange: (ds?: string) => void;
|
||||
onPanelTypeChange: (pt?: string) => void;
|
||||
includePanels: boolean;
|
||||
onSetIncludePanels: (v: boolean) => void;
|
||||
state: SearchState;
|
||||
@@ -59,7 +60,7 @@ export function getValidQueryLayout(q: SearchState): SearchLayout {
|
||||
return layout;
|
||||
}
|
||||
|
||||
export const ActionRow: FC<Props> = ({
|
||||
export const ActionRow = ({
|
||||
onLayoutChange,
|
||||
onSortChange,
|
||||
onStarredFilterChange = () => {},
|
||||
@@ -68,16 +69,17 @@ export const ActionRow: FC<Props> = ({
|
||||
getSortOptions,
|
||||
sortPlaceholder,
|
||||
onDatasourceChange,
|
||||
onPanelTypeChange,
|
||||
onSetIncludePanels,
|
||||
state,
|
||||
showStarredFilter,
|
||||
hideLayout,
|
||||
}) => {
|
||||
}: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const layout = getValidQueryLayout(state);
|
||||
|
||||
// Disabled folder layout option when query is present
|
||||
const disabledOptions = state.query ? [SearchLayout.Folders] : [];
|
||||
const disabledOptions = state.query || state.datasource || state.panel_type ? [SearchLayout.Folders] : [];
|
||||
|
||||
return (
|
||||
<div className={styles.actionRow}>
|
||||
@@ -109,6 +111,11 @@ export const ActionRow: FC<Props> = ({
|
||||
</Trans>
|
||||
</Button>
|
||||
)}
|
||||
{state.panel_type && (
|
||||
<Button icon="times" variant="secondary" onClick={() => onPanelTypeChange(undefined)}>
|
||||
Panel: {state.panel_type}
|
||||
</Button>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
|
||||
<div className={styles.rowContainer}>
|
||||
|
||||
@@ -78,20 +78,7 @@ export const SearchView = ({ showManage, folderDTO, hidePseudoFolders, keyboardE
|
||||
<div className={styles.noResults}>
|
||||
<div>No results found for your query.</div>
|
||||
<br />
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
if (state.query) {
|
||||
stateManager.onQueryChange('');
|
||||
}
|
||||
if (state.tag?.length) {
|
||||
stateManager.onTagFilterChange([]);
|
||||
}
|
||||
if (state.datasource) {
|
||||
stateManager.onDatasourceChange(undefined);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button variant="secondary" onClick={stateManager.onClearSearchAndFilters}>
|
||||
Clear search and filters
|
||||
</Button>
|
||||
</div>
|
||||
@@ -189,6 +176,7 @@ export const SearchView = ({ showManage, folderDTO, hidePseudoFolders, keyboardE
|
||||
getSortOptions={getGrafanaSearcher().getSortOptions}
|
||||
sortPlaceholder={getGrafanaSearcher().sortPlaceholder}
|
||||
onDatasourceChange={stateManager.onDatasourceChange}
|
||||
onPanelTypeChange={stateManager.onPanelTypeChange}
|
||||
state={state}
|
||||
includePanels={state.includePanels!}
|
||||
onSetIncludePanels={stateManager.onSetIncludePanels}
|
||||
|
||||
@@ -170,7 +170,10 @@ export const generateColumns = (
|
||||
return (
|
||||
<div {...p.cellProps} className={cx(styles.locationCellStyle)}>
|
||||
{parts.map((p) => {
|
||||
const info = meta.locationInfo[p];
|
||||
let info = meta.locationInfo[p];
|
||||
if (!info && p === 'general') {
|
||||
info = { kind: 'folder', url: '/dashboards', name: 'General' };
|
||||
}
|
||||
return info ? (
|
||||
<a key={p} href={info.url} className={styles.locationItem}>
|
||||
<Icon name={getIconForKind(info.kind)} /> {info.name}
|
||||
|
||||
@@ -43,6 +43,11 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
initStateFromUrl(folderUid?: string) {
|
||||
const stateFromUrl = parseRouteParams(locationService.getSearchObject());
|
||||
|
||||
// Force list view when conditions are specified from the URL
|
||||
if (stateFromUrl.query || stateFromUrl.datasource || stateFromUrl.panel_type) {
|
||||
stateFromUrl.layout = SearchLayout.List;
|
||||
}
|
||||
|
||||
stateManager.setState({
|
||||
...stateFromUrl,
|
||||
folderUid: folderUid,
|
||||
@@ -63,6 +68,7 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
query: this.state.query.length === 0 ? null : this.state.query,
|
||||
tag: this.state.tag,
|
||||
datasource: this.state.datasource,
|
||||
panel_type: this.state.panel_type,
|
||||
starred: this.state.starred ? this.state.starred : null,
|
||||
sort: this.state.sort,
|
||||
});
|
||||
@@ -79,6 +85,16 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
});
|
||||
};
|
||||
|
||||
onClearSearchAndFilters = () => {
|
||||
this.setStateAndDoSearch({
|
||||
query: '',
|
||||
datasource: undefined,
|
||||
tag: [],
|
||||
panel_type: undefined,
|
||||
starred: undefined,
|
||||
});
|
||||
};
|
||||
|
||||
onQueryChange = (query: string) => {
|
||||
this.setStateAndDoSearch({ query });
|
||||
};
|
||||
@@ -103,6 +119,10 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
this.setStateAndDoSearch({ datasource });
|
||||
};
|
||||
|
||||
onPanelTypeChange = (panel_type?: string) => {
|
||||
this.setStateAndDoSearch({ panel_type });
|
||||
};
|
||||
|
||||
onStarredFilterChange = (e: FormEvent<HTMLInputElement>) => {
|
||||
const starred = e.currentTarget.checked;
|
||||
this.setStateAndDoSearch({ starred });
|
||||
@@ -142,14 +162,15 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
};
|
||||
|
||||
hasSearchFilters() {
|
||||
return this.state.query || this.state.tag.length || this.state.starred;
|
||||
return this.state.query || this.state.tag.length || this.state.starred || this.state.panel_type;
|
||||
}
|
||||
|
||||
getSearchQuery() {
|
||||
const q: SearchQuery = {
|
||||
query: this.state.query,
|
||||
tags: this.state.tag as string[],
|
||||
ds_uid: this.state.datasource as string,
|
||||
tags: this.state.tag,
|
||||
ds_uid: this.state.datasource,
|
||||
panel_type: this.state.panel_type,
|
||||
location: this.state.folderUid, // This will scope all results to the prefix
|
||||
sort: this.state.sort,
|
||||
explain: this.state.explain,
|
||||
@@ -173,6 +194,10 @@ export class SearchStateManager extends StateManagerBase<SearchState> {
|
||||
q.kind = ['dashboard', 'folder']; // skip panels
|
||||
}
|
||||
|
||||
if (q.panel_type?.length) {
|
||||
q.kind = ['panel'];
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ export interface SearchState {
|
||||
starred: boolean;
|
||||
explain?: boolean; // adds debug info
|
||||
datasource?: string;
|
||||
panel_type?: string;
|
||||
sort?: string;
|
||||
prevSort?: string; // Save sorting data between layouts
|
||||
layout: SearchLayout;
|
||||
|
||||
Reference in New Issue
Block a user