Improve click handling in split view
This commit is contained in:
@@ -40,6 +40,9 @@ export const Basic: StoryObj<typeof meta> = {
|
||||
onSandwich={(item) => {
|
||||
console.log('Sandwich:', item);
|
||||
}}
|
||||
onSearch={(symbol) => {
|
||||
console.log('Search:', symbol);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -25,10 +25,11 @@ type Props = {
|
||||
colorScheme: ColorScheme | ColorSchemeDiff;
|
||||
search: string;
|
||||
compact?: boolean;
|
||||
onSearch?: (symbol: string) => void;
|
||||
};
|
||||
|
||||
const FlameGraphCallTreeContainer = memo(
|
||||
({ data, onSymbolClick, sandwichItem, onSandwich, onTableSort, colorScheme: initialColorScheme, search, compact = false }: Props) => {
|
||||
({ data, onSymbolClick, sandwichItem, onSandwich, onTableSort, colorScheme: initialColorScheme, search, compact = false, onSearch }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
|
||||
@@ -354,13 +355,15 @@ const FlameGraphCallTreeContainer = memo(
|
||||
row={row}
|
||||
onFocus={handleSetFocusMode}
|
||||
onShowCallers={handleSetCallersMode}
|
||||
onSearch={onSearch}
|
||||
focusedNodeId={focusedNodeId}
|
||||
callersNodeLabel={callersNodeLabel}
|
||||
styles={styles}
|
||||
searchNodes={searchNodes}
|
||||
/>
|
||||
),
|
||||
width: 50,
|
||||
minWidth: 50,
|
||||
width: onSearch ? 75 : 50,
|
||||
minWidth: onSearch ? 75 : 50,
|
||||
disableSortBy: true,
|
||||
},
|
||||
{
|
||||
@@ -435,13 +438,15 @@ const FlameGraphCallTreeContainer = memo(
|
||||
row={row}
|
||||
onFocus={handleSetFocusMode}
|
||||
onShowCallers={handleSetCallersMode}
|
||||
onSearch={onSearch}
|
||||
focusedNodeId={focusedNodeId}
|
||||
callersNodeLabel={callersNodeLabel}
|
||||
styles={styles}
|
||||
searchNodes={searchNodes}
|
||||
/>
|
||||
),
|
||||
width: 50,
|
||||
minWidth: 50,
|
||||
width: onSearch ? 75 : 50,
|
||||
minWidth: onSearch ? 75 : 50,
|
||||
disableSortBy: true,
|
||||
},
|
||||
{
|
||||
@@ -755,16 +760,20 @@ function ActionsCell({
|
||||
row,
|
||||
onFocus,
|
||||
onShowCallers,
|
||||
onSearch,
|
||||
focusedNodeId,
|
||||
callersNodeLabel,
|
||||
styles,
|
||||
searchNodes,
|
||||
}: {
|
||||
row: Row<CallTreeNode> & UseExpandedRowProps<CallTreeNode>;
|
||||
onFocus: (nodeIdOrLabel: string, isLabel?: boolean) => void;
|
||||
onShowCallers: (label: string) => void;
|
||||
onSearch?: (symbol: string) => void;
|
||||
focusedNodeId: string | undefined;
|
||||
callersNodeLabel: string | undefined;
|
||||
styles: any;
|
||||
searchNodes?: string[];
|
||||
}) {
|
||||
const hasChildren = row.original.hasChildren;
|
||||
const isTheFocusedNode = row.original.id === focusedNodeId ||
|
||||
@@ -773,6 +782,7 @@ function ActionsCell({
|
||||
const inCallersMode = callersNodeLabel !== undefined;
|
||||
const inFocusMode = focusedNodeId !== undefined;
|
||||
const isRootNode = row.original.depth === 0 && !row.original.parentId;
|
||||
const isSearchMatch = searchNodes?.includes(row.original.id) ?? false;
|
||||
|
||||
// Show focus button if:
|
||||
// - Node has children AND
|
||||
@@ -830,6 +840,22 @@ function ActionsCell({
|
||||
<div className={styles.actionButtonPlaceholder} />
|
||||
)}
|
||||
</div>
|
||||
{onSearch && !isSearchMatch && (
|
||||
<div className={styles.actionButtonSlot}>
|
||||
<Button
|
||||
icon="search"
|
||||
fill="text"
|
||||
size="sm"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onSearch(row.original.label);
|
||||
}}
|
||||
tooltip="Search for this function"
|
||||
aria-label="Search"
|
||||
className={styles.actionButton}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1239,7 +1265,7 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
justifyContent: 'flex-end',
|
||||
gap: theme.spacing(0.5),
|
||||
height: '20px',
|
||||
minWidth: '60px', // Fixed width to ensure consistent alignment
|
||||
minWidth: '60px', // Fixed width to ensure consistent alignment (72px when search button is present)
|
||||
}),
|
||||
actionButtonSlot: css({
|
||||
display: 'flex',
|
||||
|
||||
@@ -207,6 +207,30 @@ const FlameGraphContainer = ({
|
||||
[setSearch, resetFocus, onTableSymbolClick, search]
|
||||
);
|
||||
|
||||
// Separate callback for CallTree that doesn't trigger search
|
||||
const onCallTreeSymbolClick = useCallback(
|
||||
(symbol: string) => {
|
||||
onTableSymbolClick?.(symbol);
|
||||
},
|
||||
[onTableSymbolClick]
|
||||
);
|
||||
|
||||
// Search callback for CallTree search button
|
||||
const onCallTreeSearch = useCallback(
|
||||
(symbol: string) => {
|
||||
const anchored = `^${escapeStringForRegex(symbol)}$`;
|
||||
|
||||
if (search === anchored) {
|
||||
setSearch('');
|
||||
} else {
|
||||
onTableSymbolClick?.(symbol);
|
||||
setSearch(anchored);
|
||||
resetFocus();
|
||||
}
|
||||
},
|
||||
[setSearch, resetFocus, onTableSymbolClick, search]
|
||||
);
|
||||
|
||||
if (!dataContainer) {
|
||||
return null;
|
||||
}
|
||||
@@ -275,13 +299,14 @@ const FlameGraphContainer = ({
|
||||
const callTree = (
|
||||
<FlameGraphCallTreeContainer
|
||||
data={dataContainer}
|
||||
onSymbolClick={onSymbolClick}
|
||||
onSymbolClick={onCallTreeSymbolClick}
|
||||
sandwichItem={sandwichItem}
|
||||
onSandwich={setSandwichItem}
|
||||
onTableSort={onTableSort}
|
||||
colorScheme={colorScheme}
|
||||
search={search}
|
||||
compact={isCallTreeInSplitView}
|
||||
onSearch={onCallTreeSearch}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user