RecentlyViewedDashboards: Clear history button (#115519)

* RecentlyViewedDashboards: Clear history button
This commit is contained in:
Yunwen Zheng
2025-12-18 10:22:40 -05:00
committed by GitHub
parent 7e5eb46bea
commit 58a026b6a5
3 changed files with 37 additions and 11 deletions
@@ -1,10 +1,12 @@
import { css } from '@emotion/css';
import { useAsync } from 'react-use';
import { useState } from 'react';
import { useAsyncRetry } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { GrafanaTheme2, store } from '@grafana/data';
import { t, Trans } from '@grafana/i18n';
import { evaluateBooleanFlag } from '@grafana/runtime/internal';
import { CollapsableSection, Grid, Spinner, Text, useStyles2 } from '@grafana/ui';
import { Button, CollapsableSection, Spinner, Stack, Text, useStyles2, Grid } from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv';
import { useDashboardLocationInfo } from 'app/features/search/hooks/useDashboardLocationInfo';
import { DashListItem } from 'app/plugins/panel/dashlist/DashListItem';
@@ -12,10 +14,18 @@ import { getRecentlyViewedDashboards } from './utils';
const MAX_RECENT = 5;
const recentDashboardsKey = `dashboard_impressions-${contextSrv.user.orgId}`;
export function RecentlyViewedDashboards() {
const [isOpen, setIsOpen] = useState(true);
const styles = useStyles2(getStyles);
const { value: recentDashboards = [], loading } = useAsync(async () => {
const {
value: recentDashboards = [],
loading,
retry,
} = useAsyncRetry(async () => {
if (!evaluateBooleanFlag('recentlyViewedDashboards', false)) {
return [];
}
@@ -23,6 +33,11 @@ export function RecentlyViewedDashboards() {
}, []);
const { foldersByUid } = useDashboardLocationInfo(recentDashboards.length > 0);
const handleClearHistory = () => {
store.set(recentDashboardsKey, JSON.stringify([]));
retry();
};
if (!evaluateBooleanFlag('recentlyViewedDashboards', false)) {
return null;
}
@@ -31,11 +46,19 @@ export function RecentlyViewedDashboards() {
<CollapsableSection
headerDataTestId="browseDashboardsRecentlyViewedTitle"
label={
<Text variant="h5" element="h3">
<Trans i18nKey="browse-dashboards.recently-viewed.title">Recently viewed</Trans>
</Text>
<Stack direction="row" justifyContent="space-between" alignItems="baseline" width="100%">
<Text variant="h5" element="h3" onClick={() => setIsOpen(!isOpen)}>
<Trans i18nKey="browse-dashboards.recently-viewed.title">Recently viewed</Trans>
</Text>
<Button icon="times" size="xs" variant="secondary" fill="text" onClick={handleClearHistory}>
{t('browse-dashboards.recently-viewed.clear', 'Clear history')}
</Button>
</Stack>
}
isOpen={true}
isOpen={isOpen}
// passing empty function to disable controlled mode, we only want to control isOpen when click on title
// this avoid entire header section being clickable which can be confusing with the Clear history button
onToggle={() => {}}
className={styles.title}
contentClassName={styles.content}
>
@@ -71,14 +94,16 @@ export function RecentlyViewedDashboards() {
const getStyles = (theme: GrafanaTheme2) => {
return {
title: css({
'& button svg': {
cursor: 'default',
'& [id^="collapse-button-"] svg': {
color: theme.colors.primary.text,
},
h3: {
background: `linear-gradient(90deg, ${theme.colors.primary.text} 0%, ${theme.colors.secondary.text} 100%)`,
background: `linear-gradient(90deg, ${theme.colors.primary.shade} 0%, ${theme.colors.primary.text} 100%)`,
WebkitTextFillColor: 'transparent',
backgroundClip: 'text',
color: 'transparent',
cursor: 'pointer',
},
}),
content: css({
+1 -1
View File
@@ -6,7 +6,7 @@ export const getStyles = (theme: GrafanaTheme2) => {
const gradient = `linear-gradient(
90deg,
${colorManipulator.alpha(theme.colors.primary.text, 0.1)} 0%,
${colorManipulator.alpha(theme.colors.secondary.text, 0.1)} 100%
${colorManipulator.alpha(theme.colors.secondary.main, 0.1)} 100%
)`;
return {
dashlistLink: css({
+1
View File
@@ -3717,6 +3717,7 @@
"text": "No results found for your query"
},
"recently-viewed": {
"clear": "Clear history",
"empty": "Nothing viewed yet",
"title": "Recently viewed"
},