mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Interaction tracking for logs pinning and filtering in content outline (#90213)
* Add interaction tracking * Move reportInteraction out of scrollIntoView to improve readability * move activateFilter logic inside handleItemClicked
This commit is contained in:
parent
434f386982
commit
8a6e92c0c9
@ -7,6 +7,7 @@ import { reportInteraction } from '@grafana/runtime';
|
||||
import { useStyles2, PanelContainer, CustomScrollbar } from '@grafana/ui';
|
||||
|
||||
import { ContentOutlineItemContextProps, useContentOutlineContext } from './ContentOutlineContext';
|
||||
import { ITEM_TYPES } from './ContentOutlineItem';
|
||||
import { ContentOutlineItemButton } from './ContentOutlineItemButton';
|
||||
|
||||
function scrollableChildren(item: ContentOutlineItemContextProps) {
|
||||
@ -56,7 +57,12 @@ export function ContentOutline({ scroller, panelId }: { scroller: HTMLElement |
|
||||
}, {});
|
||||
});
|
||||
|
||||
const scrollIntoView = (ref: HTMLElement | null, itemPanelId: string, customOffsetTop = 0) => {
|
||||
const scrollIntoView = (
|
||||
ref: HTMLElement | null,
|
||||
itemPanelId: string,
|
||||
itemType: ITEM_TYPES | undefined,
|
||||
customOffsetTop = 0
|
||||
) => {
|
||||
let scrollValue = 0;
|
||||
let el: HTMLElement | null | undefined = ref;
|
||||
|
||||
@ -73,11 +79,24 @@ export function ContentOutline({ scroller, panelId }: { scroller: HTMLElement |
|
||||
top: scrollValue + customOffsetTop,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
};
|
||||
|
||||
const handleItemClicked = (item: ContentOutlineItemContextProps) => {
|
||||
if (item.level === 'child' && item.type === 'filter') {
|
||||
const activeParent = outlineItems.find((parent) => {
|
||||
return parent.children?.find((child) => child.id === item.id);
|
||||
});
|
||||
|
||||
if (activeParent) {
|
||||
scrollIntoView(activeParent.ref, activeParent.panelId, activeParent.type, activeParent.customTopOffset);
|
||||
}
|
||||
} else {
|
||||
scrollIntoView(item.ref, item.panelId, item.type, item.customTopOffset);
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'select_section',
|
||||
type: itemPanelId,
|
||||
type: item.panelId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const toggle = () => {
|
||||
@ -131,16 +150,6 @@ export function ContentOutline({ scroller, panelId }: { scroller: HTMLElement |
|
||||
}
|
||||
}, [outlineItems, verticalScroll]);
|
||||
|
||||
const activateFilter = (filterId: string) => {
|
||||
const activeParent = outlineItems.find((item) => {
|
||||
return item.children?.find((child) => child.id === filterId);
|
||||
});
|
||||
|
||||
if (activeParent) {
|
||||
scrollIntoView(activeParent.ref, activeParent.panelId, activeParent.customTopOffset);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PanelContainer className={styles.wrapper} id={panelId}>
|
||||
<CustomScrollbar>
|
||||
@ -173,7 +182,7 @@ export function ContentOutline({ scroller, panelId }: { scroller: HTMLElement |
|
||||
isChildActive(item, activeSectionChildId) && !contentOutlineExpanded && sectionsExpanded[item.id],
|
||||
})}
|
||||
icon={item.icon}
|
||||
onClick={() => scrollIntoView(item.ref, item.panelId)}
|
||||
onClick={() => handleItemClicked(item)}
|
||||
tooltip={item.title}
|
||||
collapsible={isCollapsible(item)}
|
||||
collapsed={!sectionsExpanded[item.id]}
|
||||
@ -208,9 +217,7 @@ export function ContentOutline({ scroller, panelId }: { scroller: HTMLElement |
|
||||
})}
|
||||
indentStyle={styles.indentChild}
|
||||
onClick={(e) => {
|
||||
child.type === 'filter'
|
||||
? activateFilter(child.id)
|
||||
: scrollIntoView(child.ref, child.panelId, child.customTopOffset);
|
||||
handleItemClicked(child);
|
||||
child.onClick?.(e);
|
||||
}}
|
||||
tooltip={child.title}
|
||||
|
@ -262,6 +262,10 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
highlight: currentLevelSelected && !allLevelsSelected,
|
||||
onClick: (e: React.MouseEvent) => {
|
||||
toggleLegendRef.current?.(level.levelStr, mapMouseEventToMode(e));
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'section',
|
||||
type: `Logs:filter:${level.levelStr}`,
|
||||
});
|
||||
},
|
||||
ref: null,
|
||||
color: LogLevelColor[level.logLevel],
|
||||
@ -658,6 +662,11 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
</Trans>
|
||||
</span>
|
||||
);
|
||||
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'section',
|
||||
type: 'Logs:pinned:pinned-log-limit-reached',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -677,16 +686,31 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
ref: null,
|
||||
color: LogLevelColor[row.logLevel],
|
||||
childOnTop: true,
|
||||
onClick: () => onOpenContext(row, () => {}),
|
||||
onClick: () => {
|
||||
onOpenContext(row, () => {});
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'section',
|
||||
type: 'Logs:pinned:pinned-log-clicked',
|
||||
});
|
||||
},
|
||||
onRemove: (id: string) => {
|
||||
unregister?.(id);
|
||||
if (getPinnedLogsCount() < PINNED_LOGS_LIMIT) {
|
||||
setPinLineButtonTooltipTitle('Pin to content outline');
|
||||
}
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'section',
|
||||
type: 'Logs:pinned:pinned-log-deleted',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
props.onPinLineCallback?.();
|
||||
|
||||
reportInteraction('explore_toolbar_contentoutline_clicked', {
|
||||
item: 'section',
|
||||
type: 'Logs:pinned:pinned-log-added',
|
||||
});
|
||||
};
|
||||
|
||||
const getPinnedLogsCount = () => {
|
||||
|
Loading…
Reference in New Issue
Block a user