mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
BrowseDashboards: Only remember the most recent expanded folder (#74617)
* BrowseDashboards: Only remember the most recent expanded folder * set to null * cleanup * only clear removed folder if it was the most recently opened * comments + variable
This commit is contained in:
@@ -82,6 +82,7 @@ import { preloadPlugins } from './features/plugins/pluginPreloader';
|
||||
import { QueryRunner } from './features/query/state/QueryRunner';
|
||||
import { runRequest } from './features/query/state/runRequest';
|
||||
import { initWindowRuntime } from './features/runtime/init';
|
||||
import { cleanupOldExpandedFolders } from './features/search/utils';
|
||||
import { variableAdapters } from './features/variables/adapters';
|
||||
import { createAdHocVariableAdapter } from './features/variables/adhoc/adapter';
|
||||
import { createConstantVariableAdapter } from './features/variables/constant/adapter';
|
||||
@@ -215,6 +216,13 @@ export class GrafanaApp {
|
||||
// Read initial kiosk mode from url at app startup
|
||||
chromeService.setKioskModeFromUrl(queryParams.kiosk);
|
||||
|
||||
// Clean up old search local storage values
|
||||
try {
|
||||
cleanupOldExpandedFolders();
|
||||
} catch (err) {
|
||||
console.warn('Failed to clean up old expanded folders', err);
|
||||
}
|
||||
|
||||
this.context = {
|
||||
backend: backendSrv,
|
||||
location: locationService,
|
||||
|
||||
@@ -6,6 +6,7 @@ export const SEARCH_ITEM_HEIGHT = 58;
|
||||
export const SEARCH_ITEM_MARGIN = 8;
|
||||
export const DEFAULT_SORT = { label: 'A\u2013Z', value: 'alpha-asc' };
|
||||
export const SECTION_STORAGE_KEY = 'search.sections';
|
||||
export const SEARCH_EXPANDED_FOLDER_STORAGE_KEY = 'grafana.search.expanded-folder';
|
||||
export const GENERAL_FOLDER_ID = 0;
|
||||
export const GENERAL_FOLDER_UID = 'general';
|
||||
export const GENERAL_FOLDER_TITLE = 'General';
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useCallback, useId } from 'react';
|
||||
import { useAsync, useLocalStorage } from 'react-use';
|
||||
import React, { useCallback, useId, useState } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, toIconName } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Card, Checkbox, CollapsableSection, Icon, Spinner, useStyles2 } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { getSectionStorageKey } from 'app/features/search/utils';
|
||||
|
||||
import { SearchItem } from '../..';
|
||||
import { GENERAL_FOLDER_UID } from '../../constants';
|
||||
import { GENERAL_FOLDER_UID, SEARCH_EXPANDED_FOLDER_STORAGE_KEY } from '../../constants';
|
||||
import { getGrafanaSearcher } from '../../service';
|
||||
import { getFolderChildren } from '../../service/folders';
|
||||
import { queryResultToViewItem } from '../../service/utils';
|
||||
@@ -57,9 +56,14 @@ export const FolderSection = ({
|
||||
renderStandaloneBody,
|
||||
tags,
|
||||
}: SectionHeaderProps) => {
|
||||
const uid = section.uid;
|
||||
const editable = selectionToggle != null;
|
||||
|
||||
const styles = useStyles2(useCallback((theme: GrafanaTheme2) => getSectionHeaderStyles(theme, editable), [editable]));
|
||||
const [sectionExpanded, setSectionExpanded] = useLocalStorage(getSectionStorageKey(section.title), false);
|
||||
const [sectionExpanded, setSectionExpanded] = useState(() => {
|
||||
const lastExpandedFolder = window.localStorage.getItem(SEARCH_EXPANDED_FOLDER_STORAGE_KEY);
|
||||
return lastExpandedFolder === uid;
|
||||
});
|
||||
|
||||
const results = useAsync(async () => {
|
||||
if (!sectionExpanded && !renderStandaloneBody) {
|
||||
@@ -72,7 +76,20 @@ export const FolderSection = ({
|
||||
}, [sectionExpanded, tags]);
|
||||
|
||||
const onSectionExpand = () => {
|
||||
setSectionExpanded(!sectionExpanded);
|
||||
const newExpandedValue = !sectionExpanded;
|
||||
|
||||
if (newExpandedValue) {
|
||||
// If we've just expanded the section, remember it to local storage
|
||||
window.localStorage.setItem(SEARCH_EXPANDED_FOLDER_STORAGE_KEY, uid);
|
||||
} else {
|
||||
// Else, when closing a section, remove it from local storage only if this folder was the most recently opened
|
||||
const lastExpandedFolder = window.localStorage.getItem(SEARCH_EXPANDED_FOLDER_STORAGE_KEY);
|
||||
if (lastExpandedFolder === uid) {
|
||||
window.localStorage.removeItem(SEARCH_EXPANDED_FOLDER_STORAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
setSectionExpanded(newExpandedValue);
|
||||
};
|
||||
|
||||
const onToggleFolder = (evt: React.FormEvent) => {
|
||||
|
||||
@@ -14,6 +14,18 @@ export const hasFilters = (query: SearchState) => {
|
||||
return Boolean(query.query || query.tag?.length > 0 || query.starred || query.sort);
|
||||
};
|
||||
|
||||
/** Cleans up old local storage values that remembered many open folders */
|
||||
export const cleanupOldExpandedFolders = () => {
|
||||
const keyPrefix = SECTION_STORAGE_KEY + '.';
|
||||
|
||||
for (let index = 0; index < window.localStorage.length; index++) {
|
||||
const lsKey = window.localStorage.key(index);
|
||||
if (lsKey?.startsWith(keyPrefix)) {
|
||||
window.localStorage.removeItem(lsKey);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get storage key for a dashboard folder by its title
|
||||
* @param title
|
||||
|
||||
Reference in New Issue
Block a user