Commit ab073261 by Alex Khomenko Committed by GitHub

Search: close overlay on Esc press (#24003)

* Search: Close on Esc

* Search: Increase bottom padding for the last item in section

* Search: Move closing search to keybindingsSrv

* Search: Fix folder view

* Search: Do not move folders if already in folder
parent 11eca387
...@@ -87,6 +87,11 @@ export class KeybindingSrv { ...@@ -87,6 +87,11 @@ export class KeybindingSrv {
this.$location.search(search); this.$location.search(search);
} }
closeSearch() {
const search = _.extend(this.$location.search(), { search: null });
this.$location.search(search);
}
openAlerting() { openAlerting() {
this.$location.url('/alerting'); this.$location.url('/alerting');
} }
...@@ -148,6 +153,10 @@ export class KeybindingSrv { ...@@ -148,6 +153,10 @@ export class KeybindingSrv {
if (search.kiosk) { if (search.kiosk) {
this.$rootScope.appEvent(CoreEvents.toggleKioskMode, { exit: true }); this.$rootScope.appEvent(CoreEvents.toggleKioskMode, { exit: true });
} }
if (search.search) {
this.closeSearch();
}
} }
bind(keyArg: string | string[], fn: () => void) { bind(keyArg: string | string[], fn: () => void) {
......
...@@ -76,7 +76,9 @@ export class SearchSrv { ...@@ -76,7 +76,9 @@ export class SearchSrv {
query.folderIds = query.folderIds || []; query.folderIds = query.folderIds || [];
if (query.layout === SearchLayout.List) { if (query.layout === SearchLayout.List) {
return backendSrv.search({ ...query, type: DashboardSearchItemType.DashDB }); return backendSrv
.search({ ...query, type: DashboardSearchItemType.DashDB })
.then(results => [{ items: results }]);
} }
if (!filters) { if (!filters) {
......
...@@ -20,19 +20,13 @@ export const DashboardSearch: FC<Props> = memo(({ onCloseSearch, folder }) => { ...@@ -20,19 +20,13 @@ export const DashboardSearch: FC<Props> = memo(({ onCloseSearch, folder }) => {
const theme = useTheme(); const theme = useTheme();
const styles = getStyles(theme); const styles = getStyles(theme);
// The main search input has own keydown handler, also TagFilter uses input, so
// clicking Esc when tagFilter is active shouldn't close the whole search overlay
const onClose = () => {
onCloseSearch();
};
return ( return (
<div tabIndex={0} className={styles.overlay}> <div tabIndex={0} className={styles.overlay}>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.searchField}> <div className={styles.searchField}>
<SearchField query={query} onChange={onQueryChange} onKeyDown={onKeyDown} autoFocus clearable /> <SearchField query={query} onChange={onQueryChange} onKeyDown={onKeyDown} autoFocus clearable />
<div className={styles.closeBtn}> <div className={styles.closeBtn}>
<IconButton name="times" surface="panel" onClick={onClose} size="xxl" tooltip="Close search" /> <IconButton name="times" surface="panel" onClick={onCloseSearch} size="xxl" tooltip="Close search" />
</div> </div>
</div> </div>
<div className={styles.search}> <div className={styles.search}>
......
...@@ -67,7 +67,7 @@ export const ManageDashboards: FC<Props> = memo(({ folderId, folderUid }) => { ...@@ -67,7 +67,7 @@ export const ManageDashboards: FC<Props> = memo(({ folderId, folderUid }) => {
setIsDeleteModalOpen(true); setIsDeleteModalOpen(true);
}; };
if (canSave && folderId && !hasFilters && results.length === 0) { if (canSave && folderId && !hasFilters && results.length === 0 && !loading) {
return ( return (
<EmptyListCTA <EmptyListCTA
title="This folder doesn't have any dashboards yet" title="This folder doesn't have any dashboards yet"
......
...@@ -36,9 +36,10 @@ export const MoveToFolderModal: FC<Props> = ({ results, onMoveItems, isOpen, onD ...@@ -36,9 +36,10 @@ export const MoveToFolderModal: FC<Props> = ({ results, onMoveItems, isOpen, onD
if (result.totalCount === result.alreadyInFolderCount) { if (result.totalCount === result.alreadyInFolderCount) {
appEvents.emit(AppEvents.alertError, ['Error', `Dashboard already belongs to folder ${folderTitle}`]); appEvents.emit(AppEvents.alertError, ['Error', `Dashboard already belongs to folder ${folderTitle}`]);
} else {
onMoveItems(selectedDashboards, folder);
} }
onMoveItems(selectedDashboards, folder);
onDismiss(); onDismiss();
}); });
} }
......
...@@ -63,6 +63,10 @@ const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({ ...@@ -63,6 +63,10 @@ const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({
margin-bottom: ${SEARCH_ITEM_MARGIN}px; margin-bottom: ${SEARCH_ITEM_MARGIN}px;
padding: 0 ${theme.spacing.md}; padding: 0 ${theme.spacing.md};
&:last-child {
margin-bottom: ${SEARCH_ITEM_MARGIN * 2}px;
}
:hover { :hover {
cursor: pointer; cursor: pointer;
} }
......
...@@ -47,8 +47,8 @@ export const SearchResults: FC<Props> = ({ ...@@ -47,8 +47,8 @@ export const SearchResults: FC<Props> = ({
</div> </div>
); );
}; };
const renderDashboards = () => { const renderDashboards = () => {
const items = results[0]?.items;
return ( return (
<div className={styles.listModeWrapper}> <div className={styles.listModeWrapper}>
<AutoSizer disableWidth> <AutoSizer disableWidth>
...@@ -59,11 +59,11 @@ export const SearchResults: FC<Props> = ({ ...@@ -59,11 +59,11 @@ export const SearchResults: FC<Props> = ({
innerElementType="ul" innerElementType="ul"
itemSize={SEARCH_ITEM_HEIGHT + SEARCH_ITEM_MARGIN} itemSize={SEARCH_ITEM_HEIGHT + SEARCH_ITEM_MARGIN}
height={height} height={height}
itemCount={results.length} itemCount={items.length}
width="100%" width="100%"
> >
{({ index, style }) => { {({ index, style }) => {
const item = results[index]; const item = items[index];
// The wrapper div is needed as the inner SearchItem has margin-bottom spacing // The wrapper div is needed as the inner SearchItem has margin-bottom spacing
// And without this wrapper there is no room for that margin // And without this wrapper there is no room for that margin
return ( return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment