Skip to content

Commit 882542e

Browse files
authored
feat(discover2): Add per cell action to count_unique() (#19382)
1 parent c0300aa commit 882542e

File tree

2 files changed

+39
-76
lines changed

2 files changed

+39
-76
lines changed

src/sentry/static/sentry/app/views/eventsV2/table/cellAction.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export enum Actions {
1919
SHOW_LESS_THAN = 'show_less_than',
2020
TRANSACTION = 'transaction',
2121
RELEASE = 'release',
22+
DRILLDOWN = 'drilldown',
2223
}
2324

2425
type Props = {
@@ -193,6 +194,22 @@ class CellAction extends React.Component<Props, State> {
193194
);
194195
}
195196

197+
if (
198+
column.column.kind === 'function' &&
199+
column.column.function[0] === 'count_unique'
200+
) {
201+
addMenuItem(
202+
Actions.DRILLDOWN,
203+
<ActionItem
204+
key="drilldown"
205+
data-test-id="per-cell-drilldown"
206+
onClick={() => handleCellAction(Actions.DRILLDOWN, value)}
207+
>
208+
{t('View Stacks')}
209+
</ActionItem>
210+
);
211+
}
212+
196213
if (actions.length === 0) {
197214
return null;
198215
}
@@ -279,11 +296,7 @@ class CellAction extends React.Component<Props, State> {
279296
const fieldAlias = getAggregateAlias(column.name);
280297
const value = dataRow[fieldAlias];
281298

282-
// do not display per cell actions for count() and count_unique()
283-
const shouldIgnoreColumn =
284-
column.column.kind === 'function' && column.column.function[0] === 'count_unique';
285-
286-
if (!defined(value) || shouldIgnoreColumn) {
299+
if (!defined(value)) {
287300
// per cell actions do not apply to values that are null
288301
return <React.Fragment>{children}</React.Fragment>;
289302
}

src/sentry/static/sentry/app/views/eventsV2/table/tableView.tsx

Lines changed: 21 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
33
import {browserHistory} from 'react-router';
44
import {Location, LocationDescriptorObject} from 'history';
55

6-
import {Organization, OrganizationSummary, Project} from 'app/types';
6+
import {Organization, Project} from 'app/types';
77
import {trackAnalyticsEvent} from 'app/utils/analytics';
88
import GridEditable, {
99
COL_WIDTH_UNDEFINED,
@@ -195,38 +195,13 @@ class TableView extends React.Component<TableViewProps> {
195195
column: TableColumn<keyof TableDataRow>,
196196
dataRow: TableDataRow
197197
): React.ReactNode => {
198-
const {location, organization, tableData, eventView} = this.props;
198+
const {location, organization, tableData} = this.props;
199199

200200
if (!tableData || !tableData.meta) {
201201
return dataRow[column.key];
202202
}
203203
const fieldRenderer = getFieldRenderer(String(column.key), tableData.meta);
204-
const aggregation =
205-
column.column.kind === 'function' ? column.column.function[0] : undefined;
206204

207-
// Aggregation columns offer drilldown behavior
208-
if (aggregation) {
209-
return (
210-
<ExpandAggregateRow
211-
organization={organization}
212-
eventView={eventView}
213-
column={column}
214-
dataRow={dataRow}
215-
location={location}
216-
tableMeta={tableData.meta}
217-
>
218-
<CellAction
219-
column={column}
220-
dataRow={dataRow}
221-
handleCellAction={this.handleCellAction(dataRow, column, tableData.meta)}
222-
>
223-
{fieldRenderer(dataRow, {organization, location})}
224-
</CellAction>
225-
</ExpandAggregateRow>
226-
);
227-
}
228-
229-
// Scalar fields offer cell actions to build queries.
230205
return (
231206
<CellAction
232207
column={column}
@@ -345,6 +320,25 @@ class TableView extends React.Component<TableViewProps> {
345320

346321
return;
347322
}
323+
case Actions.DRILLDOWN: {
324+
// count_unique(column) drilldown
325+
326+
trackAnalyticsEvent({
327+
eventKey: 'discover_v2.results.drilldown',
328+
eventName: 'Discoverv2: Click aggregate drilldown',
329+
organization_id: parseInt(organization.id, 10),
330+
});
331+
332+
// Drilldown into each distinct value and get a count() for each value.
333+
nextView = getExpandedResults(nextView, {}, dataRow).withNewColumn({
334+
kind: 'function',
335+
function: ['count', '', undefined],
336+
});
337+
338+
browserHistory.push(nextView.getResultsViewUrlTarget(organization.slug));
339+
340+
return;
341+
}
348342
default:
349343
throw new Error(`Unknown action type. ${action}`);
350344
}
@@ -428,50 +422,6 @@ class TableView extends React.Component<TableViewProps> {
428422
}
429423
}
430424

431-
function ExpandAggregateRow(props: {
432-
organization: OrganizationSummary;
433-
children: React.ReactNode;
434-
eventView: EventView;
435-
column: TableColumn<keyof TableDataRow>;
436-
dataRow: TableDataRow;
437-
location: Location;
438-
tableMeta: MetaType;
439-
}) {
440-
const {children, column, dataRow, eventView, location, organization} = props;
441-
const aggregation =
442-
column.column.kind === 'function' ? column.column.function[0] : undefined;
443-
444-
function handleClick() {
445-
trackAnalyticsEvent({
446-
eventKey: 'discover_v2.results.drilldown',
447-
eventName: 'Discoverv2: Click aggregate drilldown',
448-
organization_id: parseInt(organization.id, 10),
449-
});
450-
}
451-
452-
// count_unique(column) drilldown
453-
if (aggregation === 'count_unique') {
454-
// Drilldown into each distinct value and get a count() for each value.
455-
const nextView = getExpandedResults(eventView, {}, dataRow).withNewColumn({
456-
kind: 'function',
457-
function: ['count', '', undefined],
458-
});
459-
460-
const target = {
461-
pathname: location.pathname,
462-
query: nextView.generateQueryStringObject(),
463-
};
464-
465-
return (
466-
<Link data-test-id="expand-count-unique" to={target} onClick={handleClick}>
467-
{children}
468-
</Link>
469-
);
470-
}
471-
472-
return <React.Fragment>{children}</React.Fragment>;
473-
}
474-
475425
const PrependHeader = styled('span')`
476426
color: ${p => p.theme.gray600};
477427
`;

0 commit comments

Comments
 (0)