SearchV2: Add minor UX improvements to Search pages (#52833)

* Search: display dash for panel and folder when sort type is view or error

* Search: Disabled panel checkbox in folrder view
pull/52860/merge
Leo 3 years ago committed by GitHub
parent 9332fb65a9
commit 8d6d5f2fdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      public/app/features/search/page/components/ActionRow.tsx
  2. 54
      public/app/features/search/page/components/SearchView.test.tsx
  3. 35
      public/app/features/search/page/components/columns.tsx

@ -101,8 +101,14 @@ export const ActionRow: FC<Props> = ({
Datasource: {query.datasource}
</Button>
)}
{layout !== SearchLayout.Folders && config.featureToggles.panelTitleSearch && (
<Checkbox value={includePanels} onChange={() => setIncludePanels(!includePanels)} label="Include panels" />
{config.featureToggles.panelTitleSearch && (
<Checkbox
data-testid="include-panels"
disabled={layout === SearchLayout.Folders}
value={includePanels}
onChange={() => setIncludePanels(!includePanels)}
label="Include panels"
/>
)}
<TagFilter isClearable tags={query.tag} tagOptions={getTagOptions} onChange={onTagFilterChange} />

@ -6,16 +6,37 @@ import configureMockStore from 'redux-mock-store';
import { Observable } from 'rxjs';
import { ArrayVector, DataFrame, DataFrameView, FieldType } from '@grafana/data';
import { config } from '@grafana/runtime';
import { defaultQuery } from '../../reducers/searchQueryReducer';
import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from '../../service';
import { DashboardSearchItemType } from '../../types';
import { DashboardSearchItemType, SearchLayout } from '../../types';
import { SearchView, SearchViewProps } from './SearchView';
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
reportInteraction: jest.fn(),
}));
jest.mock('@grafana/runtime', () => {
const originalModule = jest.requireActual('@grafana/runtime');
return {
...originalModule,
reportInteraction: jest.fn(),
config: {
...originalModule.config,
featureToggles: {
panelTitleSearch: false,
},
},
};
});
jest.mock('../../reducers/searchQueryReducer', () => {
const originalModule = jest.requireActual('../../reducers/searchQueryReducer');
return {
...originalModule,
defaultQuery: {
...originalModule.defaultQuery,
},
};
});
describe('SearchView', () => {
const folderData: DataFrame = {
@ -52,6 +73,11 @@ describe('SearchView', () => {
jest.spyOn(getGrafanaSearcher(), 'search').mockResolvedValue(mockSearchResult);
});
beforeEach(() => {
config.featureToggles.panelTitleSearch = false;
defaultQuery.layout = SearchLayout.Folders;
});
it('does not show checkboxes or manage actions if showManage is false', async () => {
render(<SearchView {...baseProps} />);
await waitFor(() => expect(screen.queryAllByRole('checkbox')).toHaveLength(0));
@ -88,4 +114,22 @@ describe('SearchView', () => {
await waitFor(() => expect(screen.queryByText('No results found for your query.')).toBeInTheDocument());
expect(screen.getByRole('button', { name: 'Remove search constraints' })).toBeInTheDocument();
});
describe('include panels', () => {
it('should be enabled when layout is list', async () => {
config.featureToggles.panelTitleSearch = true;
defaultQuery.layout = SearchLayout.List;
render(<SearchView {...baseProps} />);
await waitFor(() => expect(screen.getByLabelText(/include panels/i)).toBeInTheDocument());
expect(screen.getByTestId('include-panels')).toBeEnabled();
});
it('should be disabled when layout is folder', async () => {
config.featureToggles.panelTitleSearch = true;
render(<SearchView {...baseProps} />);
await waitFor(() => expect(screen.getByLabelText(/include panels/i)).toBeInTheDocument());
expect(screen.getByTestId('include-panels')).toBeDisabled();
});
});
});

@ -2,7 +2,14 @@ import { cx } from '@emotion/css';
import React from 'react';
import SVG from 'react-inlinesvg';
import { Field, FieldType, formattedValueToString, getDisplayProcessor, getFieldDisplayName } from '@grafana/data';
import {
DisplayProcessor,
Field,
FieldType,
formattedValueToString,
getDisplayProcessor,
getFieldDisplayName,
} from '@grafana/data';
import { config, getDataSourceSrv } from '@grafana/runtime';
import { Checkbox, Icon, IconButton, IconName, TagList } from '@grafana/ui';
import appEvents from 'app/core/app_events';
@ -189,12 +196,18 @@ export const generateColumns = (
if (sortField && sortFieldWith) {
const disp = sortField.display ?? getDisplayProcessor({ field: sortField, theme: config.theme2 });
columns.push({
Header: () => <div className={styles.sortedHeader}>{getFieldDisplayName(sortField)}</div>,
Cell: (p) => {
return (
<div {...p.cellProps} className={styles.sortedItems}>
{formattedValueToString(disp(sortField.values.get(p.row.index)))}
{getDisplayValue({
sortField,
getDisplay: disp,
index: p.row.index,
kind: access.kind,
})}
</div>
);
},
@ -392,3 +405,21 @@ function makeTagsColumn(
width,
};
}
function getDisplayValue({
kind,
sortField,
index,
getDisplay,
}: {
kind: Field;
sortField: Field;
index: number;
getDisplay: DisplayProcessor;
}) {
const value = sortField.values.get(index);
if (['folder', 'panel'].includes(kind.values.get(index)) && value === 0) {
return '-';
}
return formattedValueToString(getDisplay(value));
}

Loading…
Cancel
Save