Files
grafana/public/app/features/search/components/SearchItem.tsx
Alex Khomenko c21e45e428 Search: display sort metadata (#31167)
* Search: display metadata

* Search: update SortPicker icon

* Search: display folder meta data

* Search: reset sort picker on layout change

* Search: align tags in Card component

* Search: replace hyphen with dash

* Search: preserve sort state on layout change

* Search: update tests

* Search: fix tests

* Update pkg/services/search/hits.go

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update public/app/features/search/components/SearchItem.tsx

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update public/app/features/search/components/SearchItem.tsx

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Update public/app/features/search/types.ts

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Search: fix type error

* Search: add General folder name and adjust icon margin

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
2021-02-17 14:06:19 +02:00

92 lines
2.6 KiB
TypeScript

import React, { FC, useCallback } from 'react';
import { css } from 'emotion';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
import { TagList, Card, useStyles, Icon, IconName } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { DashboardSectionItem, OnToggleChecked } from '../types';
import { SearchCheckbox } from './SearchCheckbox';
import { SEARCH_ITEM_HEIGHT } from '../constants';
export interface Props {
item: DashboardSectionItem;
editable?: boolean;
onTagSelected: (name: string) => any;
onToggleChecked?: OnToggleChecked;
}
const selectors = e2eSelectors.pages.Dashboards;
const getIconFromMeta = (meta = ''): IconName => {
const metaIconMap = new Map<string, IconName>([
['errors', 'info-circle'],
['views', 'eye'],
]);
return metaIconMap.has(meta) ? metaIconMap.get(meta)! : 'sort-amount-down';
};
export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSelected }) => {
const styles = useStyles(getStyles);
const tagSelected = useCallback((tag: string, event: React.MouseEvent<HTMLElement>) => {
onTagSelected(tag);
}, []);
const toggleItem = useCallback(
(event: React.MouseEvent) => {
event.preventDefault();
if (onToggleChecked) {
onToggleChecked(item);
}
},
[item]
);
const folderTitle = item.folderTitle || 'General';
return (
<Card
aria-label={selectors.dashboards(item.title)}
heading={item.title}
href={item.url}
style={{ minHeight: SEARCH_ITEM_HEIGHT }}
className={styles.container}
>
<Card.Figure align={'center'}>
<SearchCheckbox editable={editable} checked={item.checked} onClick={toggleItem} />
</Card.Figure>
<Card.Meta separator={''}>
<span className={styles.metaContainer}>
<Icon name={'folder'} />
{folderTitle}
</span>
{item.sortMetaName && (
<span className={styles.metaContainer}>
<Icon name={getIconFromMeta(item.sortMetaName)} />
{item.sortMeta} {item.sortMetaName}
</span>
)}
</Card.Meta>
<Card.Tags>
<TagList tags={item.tags} onClick={tagSelected} />
</Card.Tags>
</Card>
);
};
const getStyles = (theme: GrafanaTheme) => {
return {
container: css`
padding: ${theme.spacing.sm} ${theme.spacing.md};
`,
metaContainer: css`
display: flex;
align-items: center;
margin-right: ${theme.spacing.sm};
svg {
margin-right: ${theme.spacing.xs};
margin-bottom: 0;
}
`,
};
};