|
|
|
@ -1,51 +1,22 @@ |
|
|
|
|
import { css } from '@emotion/css'; |
|
|
|
|
import { cloneDeep } from 'lodash'; |
|
|
|
|
import React, { useState } from 'react'; |
|
|
|
|
import { useLocation } from 'react-router-dom'; |
|
|
|
|
import React from 'react'; |
|
|
|
|
|
|
|
|
|
import { GrafanaTheme2, NavSection } from '@grafana/data'; |
|
|
|
|
import { locationService } from '@grafana/runtime'; |
|
|
|
|
import { Dropdown, FilterInput, Icon, Tooltip, useStyles2 } from '@grafana/ui'; |
|
|
|
|
import { GrafanaTheme2 } from '@grafana/data'; |
|
|
|
|
import { Dropdown, Icon, Tooltip, useStyles2 } from '@grafana/ui'; |
|
|
|
|
import { contextSrv } from 'app/core/core'; |
|
|
|
|
import { useSearchQuery } from 'app/features/search/hooks/useSearchQuery'; |
|
|
|
|
import { useSelector } from 'app/types'; |
|
|
|
|
|
|
|
|
|
import { enrichConfigItems, enrichWithInteractionTracking } from '../NavBar/utils'; |
|
|
|
|
import { OrgSwitcher } from '../OrgSwitcher'; |
|
|
|
|
|
|
|
|
|
import { TopNavBarMenu } from './TopBar/TopNavBarMenu'; |
|
|
|
|
import { TopSearchBarInput } from './TopSearchBarInput'; |
|
|
|
|
import { TOP_BAR_LEVEL_HEIGHT } from './types'; |
|
|
|
|
|
|
|
|
|
export function TopSearchBar() { |
|
|
|
|
const styles = useStyles2(getStyles); |
|
|
|
|
const location = useLocation(); |
|
|
|
|
const { query, onQueryChange } = useSearchQuery({}); |
|
|
|
|
const navBarTree = useSelector((state) => state.navBarTree); |
|
|
|
|
const navTree = cloneDeep(navBarTree); |
|
|
|
|
const [showSwitcherModal, setShowSwitcherModal] = useState(false); |
|
|
|
|
const toggleSwitcherModal = () => { |
|
|
|
|
setShowSwitcherModal(!showSwitcherModal); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const onOpenSearch = () => { |
|
|
|
|
locationService.partial({ search: 'open' }); |
|
|
|
|
}; |
|
|
|
|
const onSearchChange = (value: string) => { |
|
|
|
|
onQueryChange(value); |
|
|
|
|
if (value) { |
|
|
|
|
onOpenSearch(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const configItems = enrichConfigItems( |
|
|
|
|
navTree.filter((item) => item.section === NavSection.Config), |
|
|
|
|
location, |
|
|
|
|
toggleSwitcherModal |
|
|
|
|
).map((item) => enrichWithInteractionTracking(item, false)); |
|
|
|
|
const navIndex = useSelector((state) => state.navIndex); |
|
|
|
|
|
|
|
|
|
const helpNode = configItems.find((item) => item.id === 'help'); |
|
|
|
|
const profileNode = configItems.find((item) => item.id === 'profile'); |
|
|
|
|
const signInNode = configItems.find((item) => item.id === 'signin'); |
|
|
|
|
const helpNode = navIndex['help']; |
|
|
|
|
const profileNode = navIndex['profile']; |
|
|
|
|
const signInNode = navIndex['signin']; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div className={styles.container}> |
|
|
|
@ -55,17 +26,11 @@ export function TopSearchBar() { |
|
|
|
|
</a> |
|
|
|
|
</div> |
|
|
|
|
<div className={styles.searchWrapper}> |
|
|
|
|
<FilterInput |
|
|
|
|
onClick={onOpenSearch} |
|
|
|
|
placeholder="Search Grafana" |
|
|
|
|
value={query.query ?? ''} |
|
|
|
|
onChange={onSearchChange} |
|
|
|
|
className={styles.searchInput} |
|
|
|
|
/> |
|
|
|
|
<TopSearchBarInput /> |
|
|
|
|
</div> |
|
|
|
|
<div className={styles.actions}> |
|
|
|
|
{helpNode && ( |
|
|
|
|
<Dropdown overlay={<TopNavBarMenu node={helpNode} />}> |
|
|
|
|
<Dropdown overlay={() => <TopNavBarMenu node={helpNode} />}> |
|
|
|
|
<button className={styles.actionItem}> |
|
|
|
|
<Icon name="question-circle" size="lg" /> |
|
|
|
|
</button> |
|
|
|
@ -91,7 +56,6 @@ export function TopSearchBar() { |
|
|
|
|
</Dropdown> |
|
|
|
|
)} |
|
|
|
|
</div> |
|
|
|
|
{showSwitcherModal && <OrgSwitcher onDismiss={toggleSwitcherModal} />} |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|