Bookmarks: Store URLs instead of ids (#91121)

This commit is contained in:
Joao Silva 2024-07-31 13:56:39 +01:00 committed by GitHub
parent 562380079f
commit 85d0e17dc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 37 additions and 40 deletions

View File

@ -53,7 +53,7 @@ Content-Type: application/json
"timezone": "utc",
"weekStart": "",
"navbar": {
"bookmarkIds": null
"bookmarkUrls": null
},
"queryHistory": {
"homeTab": ""
@ -142,7 +142,7 @@ Content-Type: application/json
"timezone": "",
"weekStart": "",
"navbar": {
"bookmarkIds": null
"bookmarkUrls": null
},
"queryHistory": {
"homeTab": ""

View File

@ -49,7 +49,7 @@ lineage: schemas: [{
} @cuetsy(kind="interface")
#NavbarPreference: {
bookmarkIds: [...string]
bookmarkUrls: [...string]
} @cuetsy(kind="interface")
}
}]

View File

@ -22,11 +22,11 @@ export interface CookiePreferences {
}
export interface NavbarPreference {
bookmarkIds: Array<string>;
bookmarkUrls: Array<string>;
}
export const defaultNavbarPreference: Partial<NavbarPreference> = {
bookmarkIds: [],
bookmarkUrls: [],
};
/**

View File

@ -18,7 +18,7 @@ type CookiePreferences struct {
// NavbarPreference defines model for NavbarPreference.
type NavbarPreference struct {
BookmarkIds []string `json:"bookmarkIds"`
BookmarkUrls []string `json:"bookmarkUrls"`
}
// QueryHistoryPreference defines model for QueryHistoryPreference.

View File

@ -338,11 +338,11 @@ func (s *ServiceImpl) buildStarredItemsNavLinks(c *contextmodel.ReqContext) ([]*
func (s *ServiceImpl) buildBookmarksNavLinks(prefs *pref.Preference, treeRoot *navtree.NavTreeRoot) []*navtree.NavLink {
bookmarksChildNavs := []*navtree.NavLink{}
bookmarkIds := prefs.JSONData.Navbar.BookmarkIds
bookmarkUrls := prefs.JSONData.Navbar.BookmarkUrls
if len(bookmarkIds) > 0 {
for _, id := range bookmarkIds {
item := treeRoot.FindById(id)
if len(bookmarkUrls) > 0 {
for _, url := range bookmarkUrls {
item := treeRoot.FindByURL(url)
if item != nil {
bookmarksChildNavs = append(bookmarksChildNavs, &navtree.NavLink{
Id: item.Id,

View File

@ -98,7 +98,7 @@ type QueryHistoryPreference struct {
}
type NavbarPreference struct {
BookmarkIds []string `json:"bookmarkIds"`
BookmarkUrls []string `json:"bookmarkUrls"`
}
func (j *PreferenceJSONData) FromDB(data []byte) error {

View File

@ -97,11 +97,11 @@ func GetPreferencesFor(ctx context.Context,
dto.Language = &preference.JSONData.Language
}
if preference.JSONData.Navbar.BookmarkIds != nil {
if preference.JSONData.Navbar.BookmarkUrls != nil {
dto.Navbar = &preferences.NavbarPreference{
BookmarkIds: []string{},
BookmarkUrls: []string{},
}
dto.Navbar.BookmarkIds = preference.JSONData.Navbar.BookmarkIds
dto.Navbar.BookmarkUrls = preference.JSONData.Navbar.BookmarkUrls
}
if preference.JSONData.QueryHistory.HomeTab != "" {

View File

@ -71,8 +71,8 @@ func (s *Service) GetWithDefaults(ctx context.Context, query *pref.GetPreference
res.JSONData.QueryHistory.HomeTab = p.JSONData.QueryHistory.HomeTab
}
if p.JSONData.Navbar.BookmarkIds != nil {
res.JSONData.Navbar.BookmarkIds = p.JSONData.Navbar.BookmarkIds
if p.JSONData.Navbar.BookmarkUrls != nil {
res.JSONData.Navbar.BookmarkUrls = p.JSONData.Navbar.BookmarkUrls
}
if p.JSONData.CookiePreferences != nil {
@ -174,11 +174,11 @@ func (s *Service) Patch(ctx context.Context, cmd *pref.PatchPreferenceCommand) e
preference.JSONData.Language = *cmd.Language
}
if cmd.Navbar != nil && cmd.Navbar.BookmarkIds != nil {
if cmd.Navbar != nil && cmd.Navbar.BookmarkUrls != nil {
if preference.JSONData == nil {
preference.JSONData = &pref.PreferenceJSONData{}
}
preference.JSONData.Navbar.BookmarkIds = cmd.Navbar.BookmarkIds
preference.JSONData.Navbar.BookmarkUrls = cmd.Navbar.BookmarkUrls
}
if cmd.QueryHistory != nil {

View File

@ -17112,7 +17112,7 @@
"type": "object",
"title": "NavbarPreference defines model for NavbarPreference.",
"properties": {
"bookmarkIds": {
"bookmarkUrls": {
"type": "array",
"items": {
"type": "string"

View File

@ -54,29 +54,28 @@ export const MegaMenu = memo(
};
const isPinned = useCallback(
(id?: string) => {
if (!id || !pinnedItems?.length) {
(url?: string) => {
if (!url || !pinnedItems?.length) {
return false;
}
return pinnedItems?.includes(id);
return pinnedItems?.includes(url);
},
[pinnedItems]
);
const onPinItem = (item: NavModelItem) => {
const id = item.id;
if (id && config.featureToggles.pinNavItems) {
const navItem = navTree.find((item) => item.id === id);
const isSaved = isPinned(id);
const newItems = isSaved ? pinnedItems.filter((i) => id !== i) : [...pinnedItems, id];
const url = item.url;
if (url && config.featureToggles.pinNavItems) {
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';
reportInteraction(interactionName, {
path: navItem?.url ?? id,
path: url,
});
patchPreferences({
patchPrefsCmd: {
navbar: {
bookmarkIds: newItems,
bookmarkUrls: newItems,
},
},
}).then((data) => {

View File

@ -104,9 +104,8 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
}}
target={link.target}
url={link.url}
id={link.id}
onPin={() => onPin(link)}
isPinned={isPinned(link.id)}
isPinned={isPinned(link.url)}
>
<div
className={cx(styles.labelWrapper, {

View File

@ -13,12 +13,11 @@ export interface Props {
onClick?: () => void;
target?: HTMLAnchorElement['target'];
url: string;
id?: string;
onPin: (id?: string) => void;
isPinned?: boolean;
}
export function MegaMenuItemText({ children, isActive, onClick, target, url, id, onPin, isPinned }: Props) {
export function MegaMenuItemText({ children, isActive, onClick, target, url, onPin, isPinned }: Props) {
const theme = useTheme2();
const styles = getStyles(theme, isActive);
const LinkComponent = !target && url.startsWith('/') ? Link : 'a';
@ -51,12 +50,12 @@ export function MegaMenuItemText({ children, isActive, onClick, target, url, id,
>
{linkContent}
</LinkComponent>
{config.featureToggles.pinNavItems && id && id !== 'bookmarks' && (
{config.featureToggles.pinNavItems && url && url !== '/bookmarks' && (
<IconButton
name="bookmark"
className={'pin-icon'}
iconType={isPinned ? 'solid' : 'default'}
onClick={() => onPin(id)}
onClick={() => onPin(url)}
aria-label={
isPinned
? t('navigation.item.remove-bookmark', 'Remove from Bookmarks')

View File

@ -5,7 +5,7 @@ import { useGetUserPreferencesQuery } from 'app/features/preferences/api';
export const usePinnedItems = () => {
const preferences = useGetUserPreferencesQuery();
const pinnedItems = useMemo(() => preferences.data?.navbar?.bookmarkIds || [], [preferences]);
const pinnedItems = useMemo(() => preferences.data?.navbar?.bookmarkUrls || [], [preferences]);
if (config.featureToggles.pinNavItems) {
return pinnedItems;

View File

@ -73,7 +73,7 @@ export class SharedPreferences extends PureComponent<Props, State> {
weekStart: '',
language: '',
queryHistory: { homeTab: '' },
navbar: { bookmarkIds: [] },
navbar: { bookmarkUrls: [] },
};
this.themeOptions = getBuiltInThemes(config.featureToggles.extraThemes).map((theme) => ({

View File

@ -71,7 +71,7 @@ const navTreeSlice = createSlice({
};
bookmarks.children.push(newBookmark);
} else {
bookmarks.children = bookmarks.children?.filter((i) => i.id !== item.id) ?? [];
bookmarks.children = bookmarks.children?.filter((i) => i.url !== item.url) ?? [];
}
}
},

View File

@ -38,7 +38,7 @@ export type CookiePreferencesDefinesModelForCookiePreferences = {
};
};
export type NavbarPreferenceDefinesModelForNavbarPreference = {
bookmarkIds?: string[];
bookmarkUrls?: string[];
};
export type QueryHistoryPreferenceDefinesModelForQueryHistoryPreference = {
/** HomeTab one of: '' | 'query' | 'starred'; */

View File

@ -7188,7 +7188,7 @@
},
"NavbarPreference": {
"properties": {
"bookmarkIds": {
"bookmarkUrls": {
"items": {
"type": "string"
},