Recent dashboards: Add experimental toggle (#116121)
* Add experimentRecentlyViewedDashboards toggle * Emit dashboards_browse_list_viewed event * Move feature toggle to parent * merge
This commit is contained in:
@@ -984,6 +984,11 @@ export interface FeatureToggles {
|
||||
*/
|
||||
recentlyViewedDashboards?: boolean;
|
||||
/**
|
||||
* A/A test for recently viewed dashboards feature
|
||||
* @default false
|
||||
*/
|
||||
experimentRecentlyViewedDashboards?: boolean;
|
||||
/**
|
||||
* Enable configuration of alert enrichments in Grafana Cloud.
|
||||
* @default false
|
||||
*/
|
||||
|
||||
@@ -1625,6 +1625,15 @@ var (
|
||||
FrontendOnly: true,
|
||||
Expression: "false",
|
||||
},
|
||||
{
|
||||
Name: "experimentRecentlyViewedDashboards",
|
||||
Description: "A/A test for recently viewed dashboards feature",
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaFrontendSearchNavOrganise,
|
||||
FrontendOnly: true,
|
||||
HideFromDocs: true,
|
||||
Expression: "false",
|
||||
},
|
||||
{
|
||||
Name: "alertEnrichment",
|
||||
Description: "Enable configuration of alert enrichments in Grafana Cloud.",
|
||||
|
||||
Generated
+1
@@ -223,6 +223,7 @@ kubernetesAuthnMutation,experimental,@grafana/identity-access-team,false,false,f
|
||||
kubernetesExternalGroupMapping,experimental,@grafana/identity-access-team,false,false,false
|
||||
restoreDashboards,experimental,@grafana/grafana-search-navigate-organise,false,false,false
|
||||
recentlyViewedDashboards,experimental,@grafana/grafana-search-navigate-organise,false,false,true
|
||||
experimentRecentlyViewedDashboards,experimental,@grafana/grafana-search-navigate-organise,false,false,true
|
||||
alertEnrichment,experimental,@grafana/alerting-squad,false,false,false
|
||||
alertEnrichmentMultiStep,experimental,@grafana/alerting-squad,false,false,false
|
||||
alertEnrichmentConditional,experimental,@grafana/alerting-squad,false,false,false
|
||||
|
||||
|
+15
@@ -1365,6 +1365,21 @@
|
||||
"hideFromDocs": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "experimentRecentlyViewedDashboards",
|
||||
"resourceVersion": "1768214542023",
|
||||
"creationTimestamp": "2026-01-12T10:42:22Z"
|
||||
},
|
||||
"spec": {
|
||||
"description": "A/A test for recently viewed dashboards feature",
|
||||
"stage": "experimental",
|
||||
"codeowner": "@grafana/grafana-search-navigate-organise",
|
||||
"frontend": true,
|
||||
"hideFromDocs": true,
|
||||
"expression": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "exploreLogsAggregatedMetrics",
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { memo, useEffect, useMemo } from 'react';
|
||||
import { memo, useEffect, useMemo, useRef } from 'react';
|
||||
import { useLocation, useParams } from 'react-router-dom-v5-compat';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { evaluateBooleanFlag } from '@grafana/runtime/internal';
|
||||
import { LinkButton, FilterInput, useStyles2, Text, Stack } from '@grafana/ui';
|
||||
import { useGetFolderQueryFacade, useUpdateFolder } from 'app/api/clients/folder/v1beta1/hooks';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
@@ -44,6 +45,7 @@ const BrowseDashboardsPage = memo(({ queryParams }: { queryParams: Record<string
|
||||
const location = useLocation();
|
||||
const search = useMemo(() => new URLSearchParams(location.search), [location.search]);
|
||||
const { isReadOnlyRepo, repoType } = useGetResourceRepositoryView({ folderName: folderUID });
|
||||
const isRecentlyViewedEnabled = !folderUID && evaluateBooleanFlag('recentlyViewedDashboards', false);
|
||||
|
||||
useEffect(() => {
|
||||
stateManager.initStateFromUrl(folderUID);
|
||||
@@ -73,6 +75,23 @@ const BrowseDashboardsPage = memo(({ queryParams }: { queryParams: Record<string
|
||||
}
|
||||
}, [isSearching, searchState.result, stateManager]);
|
||||
|
||||
// Emit exposure event for A/A test once when page loads
|
||||
const hasEmittedExposureEvent = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isRecentlyViewedEnabled || hasEmittedExposureEvent.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasEmittedExposureEvent.current = true;
|
||||
const isExperimentTreatment = evaluateBooleanFlag('experimentRecentlyViewedDashboards', false);
|
||||
|
||||
reportInteraction('dashboards_browse_list_viewed', {
|
||||
experiment_dashboard_list_recently_viewed: isExperimentTreatment ? 'treatment' : 'control',
|
||||
has_recently_viewed_component: isExperimentTreatment,
|
||||
});
|
||||
}, [isRecentlyViewedEnabled]);
|
||||
|
||||
const { data: folderDTO } = useGetFolderQueryFacade(folderUID);
|
||||
const [saveFolder] = useUpdateFolder();
|
||||
const navModel = useMemo(() => {
|
||||
@@ -179,8 +198,8 @@ const BrowseDashboardsPage = memo(({ queryParams }: { queryParams: Record<string
|
||||
>
|
||||
<Page.Contents className={styles.pageContents}>
|
||||
<ProvisionedFolderPreviewBanner queryParams={queryParams} />
|
||||
{/* only show recently viewed dashboards when in root */}
|
||||
{!folderUID && <RecentlyViewedDashboards />}
|
||||
{/* only show recently viewed dashboards when in root and flag is enabled */}
|
||||
{isRecentlyViewedEnabled && <RecentlyViewedDashboards />}
|
||||
<div>
|
||||
<FilterInput
|
||||
placeholder={getSearchPlaceholder(searchState.includePanels)}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useAsyncRetry } from 'react-use';
|
||||
import { GrafanaTheme2, store } from '@grafana/data';
|
||||
import { t, Trans } from '@grafana/i18n';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { evaluateBooleanFlag } from '@grafana/runtime/internal';
|
||||
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';
|
||||
@@ -28,9 +27,6 @@ export function RecentlyViewedDashboards() {
|
||||
retry,
|
||||
error,
|
||||
} = useAsyncRetry(async () => {
|
||||
if (!evaluateBooleanFlag('recentlyViewedDashboards', false)) {
|
||||
return [];
|
||||
}
|
||||
return getRecentlyViewedDashboards(MAX_RECENT);
|
||||
}, []);
|
||||
const { foldersByUid } = useDashboardLocationInfo(recentDashboards.length > 0);
|
||||
@@ -48,7 +44,7 @@ export function RecentlyViewedDashboards() {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
if (!evaluateBooleanFlag('recentlyViewedDashboards', false) || recentDashboards.length === 0) {
|
||||
if (recentDashboards.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user