mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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
This commit is contained in:
parent
11eca387a0
commit
ab07326169
@ -87,6 +87,11 @@ export class KeybindingSrv {
|
||||
this.$location.search(search);
|
||||
}
|
||||
|
||||
closeSearch() {
|
||||
const search = _.extend(this.$location.search(), { search: null });
|
||||
this.$location.search(search);
|
||||
}
|
||||
|
||||
openAlerting() {
|
||||
this.$location.url('/alerting');
|
||||
}
|
||||
@ -148,6 +153,10 @@ export class KeybindingSrv {
|
||||
if (search.kiosk) {
|
||||
this.$rootScope.appEvent(CoreEvents.toggleKioskMode, { exit: true });
|
||||
}
|
||||
|
||||
if (search.search) {
|
||||
this.closeSearch();
|
||||
}
|
||||
}
|
||||
|
||||
bind(keyArg: string | string[], fn: () => void) {
|
||||
|
@ -76,7 +76,9 @@ export class SearchSrv {
|
||||
query.folderIds = query.folderIds || [];
|
||||
|
||||
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) {
|
||||
|
@ -20,19 +20,13 @@ export const DashboardSearch: FC<Props> = memo(({ onCloseSearch, folder }) => {
|
||||
const theme = useTheme();
|
||||
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 (
|
||||
<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={onClose} size="xxl" tooltip="Close search" />
|
||||
<IconButton name="times" surface="panel" onClick={onCloseSearch} size="xxl" tooltip="Close search" />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.search}>
|
||||
|
@ -67,7 +67,7 @@ export const ManageDashboards: FC<Props> = memo(({ folderId, folderUid }) => {
|
||||
setIsDeleteModalOpen(true);
|
||||
};
|
||||
|
||||
if (canSave && folderId && !hasFilters && results.length === 0) {
|
||||
if (canSave && folderId && !hasFilters && results.length === 0 && !loading) {
|
||||
return (
|
||||
<EmptyListCTA
|
||||
title="This folder doesn't have any dashboards yet"
|
||||
|
@ -36,9 +36,10 @@ export const MoveToFolderModal: FC<Props> = ({ results, onMoveItems, isOpen, onD
|
||||
|
||||
if (result.totalCount === result.alreadyInFolderCount) {
|
||||
appEvents.emit(AppEvents.alertError, ['Error', `Dashboard already belongs to folder ${folderTitle}`]);
|
||||
} else {
|
||||
onMoveItems(selectedDashboards, folder);
|
||||
}
|
||||
|
||||
onMoveItems(selectedDashboards, folder);
|
||||
onDismiss();
|
||||
});
|
||||
}
|
||||
|
@ -63,6 +63,10 @@ const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
margin-bottom: ${SEARCH_ITEM_MARGIN}px;
|
||||
padding: 0 ${theme.spacing.md};
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: ${SEARCH_ITEM_MARGIN * 2}px;
|
||||
}
|
||||
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ export const SearchResults: FC<Props> = ({
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderDashboards = () => {
|
||||
const items = results[0]?.items;
|
||||
return (
|
||||
<div className={styles.listModeWrapper}>
|
||||
<AutoSizer disableWidth>
|
||||
@ -59,11 +59,11 @@ export const SearchResults: FC<Props> = ({
|
||||
innerElementType="ul"
|
||||
itemSize={SEARCH_ITEM_HEIGHT + SEARCH_ITEM_MARGIN}
|
||||
height={height}
|
||||
itemCount={results.length}
|
||||
itemCount={items.length}
|
||||
width="100%"
|
||||
>
|
||||
{({ index, style }) => {
|
||||
const item = results[index];
|
||||
const item = items[index];
|
||||
// The wrapper div is needed as the inner SearchItem has margin-bottom spacing
|
||||
// And without this wrapper there is no room for that margin
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user