Skip to content

Commit

Permalink
refactor(TagExplorer): Extract ExploreHeader component (#3038)
Browse files Browse the repository at this point in the history
  • Loading branch information
grafakus authored Feb 27, 2024
1 parent 685506f commit f13bbf9
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 82 deletions.
84 changes: 2 additions & 82 deletions public/app/pages/TagExplorerView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo } from 'react';
import { NavLink, useLocation } from 'react-router-dom';
import type { Maybe } from 'true-myth';
import type { ClickEvent } from '@pyroscope/ui/Menu';
import Color from 'color';
import TotalSamplesChart from '@pyroscope/pages/tagExplorer/components/TotalSamplesChart';
import type { Profile } from '@pyroscope/legacy/models';
Expand All @@ -10,7 +9,6 @@ import Toolbar from '@pyroscope/components/Toolbar';
import TimelineChartWrapper, {
TimelineGroupData,
} from '@pyroscope/components/TimelineChart/TimelineChartWrapper';
import Dropdown, { MenuItem } from '@pyroscope/ui/Dropdown';
import TagsSelector from '@pyroscope/pages/tagExplorer/components/TagsSelector';
import TableUI, { useTableSort, BodyRow } from '@pyroscope/ui/Table';
import useTimeZone from '@pyroscope/hooks/timeZone.hook';
Expand All @@ -23,7 +21,6 @@ import {
selectQueries,
selectContinuousState,
selectAppTags,
TagsState,
fetchTagExplorerView,
fetchTagExplorerViewProfile,
ALL_TAGS,
Expand All @@ -48,6 +45,7 @@ import styles from './TagExplorerView.module.scss';
import { formatTitle } from './formatTitle';
import { FlameGraphWrapper } from '@pyroscope/components/FlameGraphWrapper';
import profileMetrics from '../constants/profile-metrics.json';
import { ExploreHeader } from '@pyroscope/pages/tagExplorer/components/ExploreHeader';

const TIMELINE_SERIES_COLORS = [
Color.rgb(242, 204, 12),
Expand Down Expand Up @@ -160,7 +158,7 @@ const TIMELINE_WRAPPER_ID = 'explore_timeline_wrapper';
const getTimelineColor = (index: number, palette: Color[]): Color =>
Color(palette[index % (palette.length - 1)]);

const getProfileMetricTitle = (appName: Maybe<string>) => {
export const getProfileMetricTitle = (appName: Maybe<string>) => {
const name = appName.unwrapOr('');
const profileMetric = (profileMetrics as Record<string, any>)[name];

Expand Down Expand Up @@ -650,82 +648,4 @@ function Table({
);
}

function ExploreHeader({
appName,
whereDropdownItems,
tags,
selectedTag,
selectedTagValue,
handleGroupByTagChange,
handleGroupByTagValueChange,
}: {
appName: Maybe<string>;
whereDropdownItems: string[];
tags: TagsState;
selectedTag: string;
selectedTagValue: string;
handleGroupByTagChange: (value: string) => void;
handleGroupByTagValueChange: (value: string) => void;
}) {
const tagKeys = Object.keys(tags.tags);
const groupByDropdownItems =
tagKeys.length > 0 ? tagKeys : ['No tags available'];

const handleGroupByClick = (e: ClickEvent) => {
handleGroupByTagChange(e.value);
};

const handleGroupByValueClick = (e: ClickEvent) => {
handleGroupByTagValueChange(e.value);
};

useEffect(() => {
if (tagKeys.length && !selectedTag) {
const firstGoodTag = tagKeys.find((tag) => !tag.startsWith('__'));
handleGroupByTagChange(firstGoodTag || tagKeys[0]);
}
}, [tagKeys, selectedTag, handleGroupByTagChange]);

return (
<div className={styles.header} data-testid="explore-header">
<span className={styles.title}>{getProfileMetricTitle(appName)}</span>
<div className={styles.queryGrouppedBy}>
<span className={styles.selectName}>grouped by</span>
<Dropdown
label="select tag"
value={selectedTag ? `tag: ${selectedTag}` : 'select tag'}
onItemClick={tagKeys.length > 0 ? handleGroupByClick : undefined}
menuButtonClassName={
selectedTag === '' ? styles.notSelectedTagDropdown : undefined
}
>
{groupByDropdownItems.map((tagName) => (
<MenuItem key={tagName} value={tagName}>
{tagName}
</MenuItem>
))}
</Dropdown>
</div>
<div className={styles.query}>
<span className={styles.selectName}>where</span>
<Dropdown
label="select where"
value={`${selectedTag ? `${selectedTag} = ` : selectedTag} ${
selectedTagValue || ALL_TAGS
}`}
onItemClick={handleGroupByValueClick}
menuButtonClassName={styles.whereSelectButton}
>
{/* always show "All" option */}
{[ALL_TAGS, ...whereDropdownItems].map((tagGroupName) => (
<MenuItem key={tagGroupName} value={tagGroupName}>
{tagGroupName}
</MenuItem>
))}
</Dropdown>
</div>
</div>
);
}

export default TagExplorerView;
86 changes: 86 additions & 0 deletions public/app/pages/tagExplorer/components/ExploreHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { useEffect } from 'react';
import type { Maybe } from 'true-myth';
import type { ClickEvent } from '@pyroscope/ui/Menu';
import Dropdown, { MenuItem } from '@pyroscope/ui/Dropdown';
import { TagsState, ALL_TAGS } from '@pyroscope/redux/reducers/continuous';
import styles from '@pyroscope/pages/TagExplorerView.module.scss';
import { getProfileMetricTitle } from '@pyroscope/pages/TagExplorerView';

export function ExploreHeader({
appName,
whereDropdownItems,
tags,
selectedTag,
selectedTagValue,
handleGroupByTagChange,
handleGroupByTagValueChange,
}: {
appName: Maybe<string>;
whereDropdownItems: string[];
tags: TagsState;
selectedTag: string;
selectedTagValue: string;
handleGroupByTagChange: (value: string) => void;
handleGroupByTagValueChange: (value: string) => void;
}) {
const tagKeys = Object.keys(tags.tags);

const groupByDropdownItems =
tagKeys.length > 0 ? tagKeys : ['No tags available'];

const handleGroupByClick = (e: ClickEvent) => {
handleGroupByTagChange(e.value);
};

const handleGroupByValueClick = (e: ClickEvent) => {
handleGroupByTagValueChange(e.value);
};

useEffect(() => {
if (tagKeys.length && !selectedTag) {
const firstGoodTag = tagKeys.find((tag) => !tag.startsWith('__'));
handleGroupByTagChange(firstGoodTag || tagKeys[0]);
}
}, [tagKeys, selectedTag, handleGroupByTagChange]);

return (
<div className={styles.header} data-testid="explore-header">
<span className={styles.title}>{getProfileMetricTitle(appName)}</span>
<div className={styles.queryGrouppedBy}>
<span className={styles.selectName}>grouped by</span>
<Dropdown
label="select tag"
value={selectedTag ? `tag: ${selectedTag}` : 'select tag'}
onItemClick={tagKeys.length > 0 ? handleGroupByClick : undefined}
menuButtonClassName={
selectedTag === '' ? styles.notSelectedTagDropdown : undefined
}
>
{groupByDropdownItems.map((tagName) => (
<MenuItem key={tagName} value={tagName}>
{tagName}
</MenuItem>
))}
</Dropdown>
</div>
<div className={styles.query}>
<span className={styles.selectName}>where</span>
<Dropdown
label="select where"
value={`${selectedTag ? `${selectedTag} = ` : selectedTag} ${
selectedTagValue || ALL_TAGS
}`}
onItemClick={handleGroupByValueClick}
menuButtonClassName={styles.whereSelectButton}
>
{/* always show "All" option */}
{[ALL_TAGS, ...whereDropdownItems].map((tagGroupName) => (
<MenuItem key={tagGroupName} value={tagGroupName}>
{tagGroupName}
</MenuItem>
))}
</Dropdown>
</div>
</div>
);
}

0 comments on commit f13bbf9

Please sign in to comment.