Chore: Remove pinNavItems feature toggle (#113855)
This commit is contained in:
@@ -53,7 +53,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes |
|
||||
| `pluginProxyPreserveTrailingSlash` | Preserve plugin proxy trailing slash. | |
|
||||
| `azureMonitorPrometheusExemplars` | Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars | Yes |
|
||||
| `pinNavItems` | Enables pinning of nav items | Yes |
|
||||
| `ssoSettingsLDAP` | Use the new SSO Settings API to configure LDAP | Yes |
|
||||
| `cloudWatchRoundUpEndTime` | Round up end time for metric queries to the next minute to avoid missing data | Yes |
|
||||
| `newFiltersUI` | Enables new combobox style UI for the Ad hoc filters variable in scenes architecture | Yes |
|
||||
|
||||
@@ -566,11 +566,6 @@ export interface FeatureToggles {
|
||||
*/
|
||||
azureMonitorPrometheusExemplars?: boolean;
|
||||
/**
|
||||
* Enables pinning of nav items
|
||||
* @default true
|
||||
*/
|
||||
pinNavItems?: boolean;
|
||||
/**
|
||||
* Enables the gRPC server for authorization
|
||||
*/
|
||||
authZGRPCServer?: boolean;
|
||||
|
||||
@@ -975,13 +975,6 @@ var (
|
||||
Owner: grafanaPartnerPluginsSquad,
|
||||
Expression: "true", // enabled by default
|
||||
},
|
||||
{
|
||||
Name: "pinNavItems",
|
||||
Description: "Enables pinning of nav items",
|
||||
Stage: FeatureStageGeneralAvailability,
|
||||
Owner: grafanaFrontendSearchNavOrganise,
|
||||
Expression: "true", // enabled by default
|
||||
},
|
||||
{
|
||||
Name: "authZGRPCServer",
|
||||
Description: "Enables the gRPC server for authorization",
|
||||
|
||||
Generated
-1
@@ -127,7 +127,6 @@ preserveDashboardStateWhenNavigating,experimental,@grafana/dashboards-squad,fals
|
||||
alertingCentralAlertHistory,experimental,@grafana/alerting-squad,false,false,true
|
||||
pluginProxyPreserveTrailingSlash,GA,@grafana/plugins-platform-backend,false,false,false
|
||||
azureMonitorPrometheusExemplars,GA,@grafana/partner-datasources,false,false,false
|
||||
pinNavItems,GA,@grafana/grafana-search-navigate-organise,false,false,false
|
||||
authZGRPCServer,experimental,@grafana/identity-access-team,false,false,false
|
||||
ssoSettingsLDAP,GA,@grafana/identity-access-team,false,true,false
|
||||
zanzana,experimental,@grafana/identity-access-team,false,false,false
|
||||
|
||||
|
Generated
-4
@@ -519,10 +519,6 @@ const (
|
||||
// Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars
|
||||
FlagAzureMonitorPrometheusExemplars = "azureMonitorPrometheusExemplars"
|
||||
|
||||
// FlagPinNavItems
|
||||
// Enables pinning of nav items
|
||||
FlagPinNavItems = "pinNavItems"
|
||||
|
||||
// FlagAuthZGRPCServer
|
||||
// Enables the gRPC server for authorization
|
||||
FlagAuthZGRPCServer = "authZGRPCServer"
|
||||
|
||||
+1
@@ -3084,6 +3084,7 @@
|
||||
"name": "pinNavItems",
|
||||
"resourceVersion": "1762958248290",
|
||||
"creationTimestamp": "2024-06-10T11:40:03Z",
|
||||
"deletionTimestamp": "2025-11-13T14:52:10Z",
|
||||
"annotations": {
|
||||
"grafana.app/updatedTimestamp": "2025-11-12 14:37:28.29086 +0000 UTC"
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/star"
|
||||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlesimpl"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"github.com/open-feature/go-sdk/openfeature"
|
||||
)
|
||||
|
||||
type ServiceImpl struct {
|
||||
@@ -86,7 +84,6 @@ func ProvideService(cfg *setting.Cfg, accessControl ac.AccessControl, pluginStor
|
||||
func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Preference) (*navtree.NavTreeRoot, error) {
|
||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||
treeRoot := &navtree.NavTreeRoot{}
|
||||
ctx := c.Req.Context()
|
||||
|
||||
treeRoot.AddSection(s.getHomeNode(c, prefs))
|
||||
|
||||
@@ -188,9 +185,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Prefere
|
||||
treeRoot.RemoveSectionByID(navtree.NavIDCfg)
|
||||
}
|
||||
|
||||
flagDetails, err := openfeature.NewDefaultClient().BooleanValueDetails(ctx, featuremgmt.FlagPinNavItems, true, openfeature.TransactionContext(ctx))
|
||||
s.log.Debug("flag evaluation: ", "flagDetails", flagDetails, "err", err)
|
||||
if flagDetails.Value && c.IsSignedIn {
|
||||
if c.IsSignedIn {
|
||||
treeRoot.AddSection(&navtree.NavLink{
|
||||
Text: "Bookmarks",
|
||||
Id: navtree.NavIDBookmarks,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { usePatchUserPreferencesMutation } from '@grafana/api-clients/rtkq/legac
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { ScrollContainer, useStyles2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { setBookmark } from 'app/core/reducers/navBarTree';
|
||||
@@ -40,25 +40,23 @@ export const MegaMenu = memo(
|
||||
.filter((item) => item.id !== 'profile' && item.id !== 'help')
|
||||
.map((item) => enrichWithInteractionTracking(item, state.megaMenuDocked));
|
||||
|
||||
if (config.featureToggles.pinNavItems) {
|
||||
const bookmarksItem = navItems.find((item) => item.id === 'bookmarks');
|
||||
if (bookmarksItem) {
|
||||
// Add children to the bookmarks section
|
||||
bookmarksItem.children = pinnedItems.reduce((acc: NavModelItem[], url) => {
|
||||
const item = findByUrl(navItems, url);
|
||||
if (!item) {
|
||||
return acc;
|
||||
}
|
||||
const newItem = {
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
url: item.url,
|
||||
parentItem: { id: 'bookmarks', text: 'Bookmarks' },
|
||||
};
|
||||
acc.push(enrichWithInteractionTracking(newItem, state.megaMenuDocked));
|
||||
const bookmarksItem = navItems.find((item) => item.id === 'bookmarks');
|
||||
if (bookmarksItem) {
|
||||
// Add children to the bookmarks section
|
||||
bookmarksItem.children = pinnedItems.reduce((acc: NavModelItem[], url) => {
|
||||
const item = findByUrl(navItems, url);
|
||||
if (!item) {
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
const newItem = {
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
url: item.url,
|
||||
parentItem: { id: 'bookmarks', text: 'Bookmarks' },
|
||||
};
|
||||
acc.push(enrichWithInteractionTracking(newItem, state.megaMenuDocked));
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
const activeItem = getActiveItem(navItems, state.sectionNav.node, location.pathname);
|
||||
@@ -85,8 +83,8 @@ export const MegaMenu = memo(
|
||||
);
|
||||
|
||||
const onPinItem = (item: NavModelItem) => {
|
||||
const url = item.url;
|
||||
if (url && config.featureToggles.pinNavItems) {
|
||||
const { url } = item;
|
||||
if (url) {
|
||||
const isSaved = isPinned(url);
|
||||
const newItems = isSaved ? pinnedItems.filter((i) => url !== i) : [...pinnedItems, url];
|
||||
const interactionName = isSaved ? 'grafana_nav_item_unpinned' : 'grafana_nav_item_pinned';
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as React from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Icon, IconButton, Link, useTheme2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
@@ -39,7 +38,6 @@ export function MegaMenuItemText({ children, isActive, onClick, target, url, onP
|
||||
<div
|
||||
className={cx(styles.wrapper, {
|
||||
[styles.wrapperActive]: isActive,
|
||||
[styles.wrapperBookmark]: config.featureToggles.pinNavItems,
|
||||
})}
|
||||
>
|
||||
<LinkComponent
|
||||
@@ -52,7 +50,7 @@ export function MegaMenuItemText({ children, isActive, onClick, target, url, onP
|
||||
>
|
||||
{linkContent}
|
||||
</LinkComponent>
|
||||
{config.featureToggles.pinNavItems && contextSrv.isSignedIn && url && url !== '/bookmarks' && (
|
||||
{contextSrv.isSignedIn && url && url !== '/bookmarks' && (
|
||||
<IconButton
|
||||
name="bookmark"
|
||||
className={'pin-icon'}
|
||||
@@ -77,8 +75,6 @@ const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive']) => ({
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}),
|
||||
wrapperBookmark: css({
|
||||
'.pin-icon': {
|
||||
visibility: 'hidden',
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useGetUserPreferencesQuery } from '@grafana/api-clients/rtkq/legacy/preferences';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { contextSrv } from '../../../services/context_srv';
|
||||
|
||||
@@ -9,8 +8,5 @@ export const usePinnedItems = () => {
|
||||
const preferences = useGetUserPreferencesQuery(undefined, { skip: !contextSrv.user.isSignedIn });
|
||||
const pinnedItems = useMemo(() => preferences.data?.navbar?.bookmarkUrls || [], [preferences]);
|
||||
|
||||
if (config.featureToggles.pinNavItems) {
|
||||
return pinnedItems;
|
||||
}
|
||||
return [];
|
||||
return pinnedItems;
|
||||
};
|
||||
|
||||
@@ -61,8 +61,7 @@ export const enrichWithInteractionTracking = (
|
||||
reportInteraction('grafana_navigation_item_clicked', {
|
||||
path: newItem.url ?? newItem.id,
|
||||
menuIsDocked: megaMenuDockedState,
|
||||
itemIsBookmarked: Boolean(config.featureToggles.pinNavItems && newItem?.parentItem?.id === 'bookmarks'),
|
||||
bookmarkToggleOn: Boolean(config.featureToggles.pinNavItems),
|
||||
itemIsBookmarked: newItem?.parentItem?.id === 'bookmarks',
|
||||
isNew,
|
||||
});
|
||||
onClick?.();
|
||||
|
||||
@@ -52,9 +52,6 @@ const navTreeSlice = createSlice({
|
||||
}
|
||||
},
|
||||
setBookmark: (state, action: PayloadAction<{ item: NavModelItem; isSaved: boolean }>) => {
|
||||
if (!config.featureToggles.pinNavItems) {
|
||||
return;
|
||||
}
|
||||
const bookmarks = state.find((navItem) => navItem.id === 'bookmarks');
|
||||
const { item, isSaved } = action.payload;
|
||||
if (bookmarks) {
|
||||
|
||||
Reference in New Issue
Block a user