grafana/public/app/features/search/components/DashboardSearch.tsx
Chi-Hsuan Huang 546f569e0c
Chore: Enable eslint-plugin-react partial rules (#29428)
* Chore: Enable eslint react/display-name

Enable react/display-name and fixed the corresponding linting issue

part of: #29201

* Chore: Enable eslint react/no-deprecated

Enable react/no-deprecated and add the UNSAFE_ prefix for deprected methods

part of: #29201

* Chore: Enable eslint react/no-find-dom-node

Enable react/no-find-dom-node rule and use ref instead

part of: #29201

* Test: Update TeamGroupSync test snapshot

Since we added the displayName for ToolTip compontent and tag name is changed.

* Fix: Fixed ClickOutsideWrapper render

The props.children might contains numbers of nodes which make cloneElement failed. Change to simply use a div to wrapper
the children and assign the ref to div for this feature

* Style: Use shorthand method definition style for inline component

* Fix: Rebase master and fix linting

Rebase from master branch and fix new displayName linting warning
2020-12-01 16:19:52 +01:00

107 lines
3.0 KiB
TypeScript

import React, { FC, memo } from 'react';
import { css } from 'emotion';
import { useTheme, CustomScrollbar, stylesFactory, IconButton } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { useSearchQuery } from '../hooks/useSearchQuery';
import { useDashboardSearch } from '../hooks/useDashboardSearch';
import { SearchField } from './SearchField';
import { SearchResults } from './SearchResults';
import { ActionRow } from './ActionRow';
import { connectWithRouteParams, ConnectProps, DispatchProps } from '../connect';
export interface OwnProps {
onCloseSearch: () => void;
}
export type Props = OwnProps & ConnectProps & DispatchProps;
export const DashboardSearch: FC<Props> = memo(({ onCloseSearch, params, updateLocation }) => {
const { query, onQueryChange, onTagFilterChange, onTagAdd, onSortChange, onLayoutChange } = useSearchQuery(
params,
updateLocation
);
const { results, loading, onToggleSection, onKeyDown } = useDashboardSearch(query, onCloseSearch);
const theme = useTheme();
const styles = getStyles(theme);
return (
<div tabIndex={0} className={styles.overlay}>
<div className={styles.container}>
<div className={styles.searchField}>
<SearchField query={query} onChange={onQueryChange} onKeyDown={onKeyDown} autoFocus clearable />
<div className={styles.closeBtn}>
<IconButton name="times" surface="panel" onClick={onCloseSearch} size="xxl" tooltip="Close search" />
</div>
</div>
<div className={styles.search}>
<ActionRow
{...{
onLayoutChange,
onSortChange,
onTagFilterChange,
query,
}}
/>
<CustomScrollbar>
<SearchResults
results={results}
loading={loading}
onTagSelected={onTagAdd}
editable={false}
onToggleSection={onToggleSection}
layout={query.layout}
/>
</CustomScrollbar>
</div>
</div>
</div>
);
});
DashboardSearch.displayName = 'DashboardSearch';
export default connectWithRouteParams(DashboardSearch);
const getStyles = stylesFactory((theme: GrafanaTheme) => {
return {
overlay: css`
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: ${theme.zIndex.sidemenu};
position: fixed;
background: ${theme.colors.dashboardBg};
@media only screen and (min-width: ${theme.breakpoints.md}) {
left: 60px;
z-index: ${theme.zIndex.navbarFixed + 1};
}
`,
container: css`
max-width: 1400px;
margin: 0 auto;
padding: ${theme.spacing.md};
height: 100%;
@media only screen and (min-width: ${theme.breakpoints.md}) {
padding: 32px;
}
`,
closeBtn: css`
right: -5px;
top: 2px;
z-index: 1;
position: absolute;
`,
searchField: css`
position: relative;
`,
search: css`
display: flex;
flex-direction: column;
height: 100%;
`,
};
});