Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/sentry/static/sentry/app/views/eventsV2/table/cellAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum Actions {
SHOW_LESS_THAN = 'show_less_than',
TRANSACTION = 'transaction',
RELEASE = 'release',
DRILLDOWN = 'drilldown',
}

type Props = {
Expand Down Expand Up @@ -193,6 +194,22 @@ class CellAction extends React.Component<Props, State> {
);
}

if (
column.column.kind === 'function' &&
column.column.function[0] === 'count_unique'
) {
addMenuItem(
Actions.DRILLDOWN,
<ActionItem
key="drilldown"
data-test-id="per-cell-drilldown"
onClick={() => handleCellAction(Actions.DRILLDOWN, value)}
>
{t('View Stacks')}
</ActionItem>
);
}

if (actions.length === 0) {
return null;
}
Expand Down Expand Up @@ -279,11 +296,7 @@ class CellAction extends React.Component<Props, State> {
const fieldAlias = getAggregateAlias(column.name);
const value = dataRow[fieldAlias];

// do not display per cell actions for count() and count_unique()
const shouldIgnoreColumn =
column.column.kind === 'function' && column.column.function[0] === 'count_unique';

if (!defined(value) || shouldIgnoreColumn) {
if (!defined(value)) {
// per cell actions do not apply to values that are null
return <React.Fragment>{children}</React.Fragment>;
}
Expand Down
92 changes: 21 additions & 71 deletions src/sentry/static/sentry/app/views/eventsV2/table/tableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import {browserHistory} from 'react-router';
import {Location, LocationDescriptorObject} from 'history';

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

if (!tableData || !tableData.meta) {
return dataRow[column.key];
}
const fieldRenderer = getFieldRenderer(String(column.key), tableData.meta);
const aggregation =
column.column.kind === 'function' ? column.column.function[0] : undefined;

// Aggregation columns offer drilldown behavior
if (aggregation) {
return (
<ExpandAggregateRow
organization={organization}
eventView={eventView}
column={column}
dataRow={dataRow}
location={location}
tableMeta={tableData.meta}
>
<CellAction
column={column}
dataRow={dataRow}
handleCellAction={this.handleCellAction(dataRow, column, tableData.meta)}
>
{fieldRenderer(dataRow, {organization, location})}
</CellAction>
</ExpandAggregateRow>
);
}

// Scalar fields offer cell actions to build queries.
return (
<CellAction
column={column}
Expand Down Expand Up @@ -345,6 +320,25 @@ class TableView extends React.Component<TableViewProps> {

return;
}
case Actions.DRILLDOWN: {
// count_unique(column) drilldown

trackAnalyticsEvent({
eventKey: 'discover_v2.results.drilldown',
eventName: 'Discoverv2: Click aggregate drilldown',
organization_id: parseInt(organization.id, 10),
});

// Drilldown into each distinct value and get a count() for each value.
nextView = getExpandedResults(nextView, {}, dataRow).withNewColumn({
kind: 'function',
function: ['count', '', undefined],
});

browserHistory.push(nextView.getResultsViewUrlTarget(organization.slug));

return;
}
default:
throw new Error(`Unknown action type. ${action}`);
}
Expand Down Expand Up @@ -428,50 +422,6 @@ class TableView extends React.Component<TableViewProps> {
}
}

function ExpandAggregateRow(props: {
organization: OrganizationSummary;
children: React.ReactNode;
eventView: EventView;
column: TableColumn<keyof TableDataRow>;
dataRow: TableDataRow;
location: Location;
tableMeta: MetaType;
}) {
const {children, column, dataRow, eventView, location, organization} = props;
const aggregation =
column.column.kind === 'function' ? column.column.function[0] : undefined;

function handleClick() {
trackAnalyticsEvent({
eventKey: 'discover_v2.results.drilldown',
eventName: 'Discoverv2: Click aggregate drilldown',
organization_id: parseInt(organization.id, 10),
});
}

// count_unique(column) drilldown
if (aggregation === 'count_unique') {
// Drilldown into each distinct value and get a count() for each value.
const nextView = getExpandedResults(eventView, {}, dataRow).withNewColumn({
kind: 'function',
function: ['count', '', undefined],
});

const target = {
pathname: location.pathname,
query: nextView.generateQueryStringObject(),
};

return (
<Link data-test-id="expand-count-unique" to={target} onClick={handleClick}>
{children}
</Link>
);
}

return <React.Fragment>{children}</React.Fragment>;
}

const PrependHeader = styled('span')`
color: ${p => p.theme.gray600};
`;
Expand Down