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
32 changes: 9 additions & 23 deletions static/app/components/dashboards/widgetQueryFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import space from 'app/styles/space';
import {Organization} from 'app/types';
import {
aggregateFunctionOutputType,
generateFieldAsString,
isAggregateEquation,
isAggregateField,
isLegalYAxisType,
QueryFieldValue,
} from 'app/utils/discover/fields';
Expand Down Expand Up @@ -87,24 +84,14 @@ function WidgetQueryFields({
onChange(newFields);
}

function getAggregateFields(): QueryFieldValue[] {
return fields.filter(field => {
const fieldStr = generateFieldAsString(field);
return isAggregateField(fieldStr) || isAggregateEquation(fieldStr);
});
}

function handleTopNChangeField(value: QueryFieldValue, fieldIndex: number) {
const aggregateFields = getAggregateFields();
const otherFields = fields.filter(field => !!!aggregateFields.includes(field));
aggregateFields[fieldIndex] = value;
const newFields = [...otherFields, ...aggregateFields];
function handleTopNChangeField(value: QueryFieldValue) {
const newFields = [...fields];
newFields[fields.length - 1] = value;
onChange(newFields);
}

function handleTopNColumnChange(columns: QueryFieldValue[]) {
const aggregateFields = getAggregateFields();
const newFields = [...columns, ...aggregateFields];
const newFields = [...columns, fields[fields.length - 1]];
onChange(newFields);
}

Expand Down Expand Up @@ -186,9 +173,8 @@ function WidgetQueryFields({
};

if (displayType === 'top_n') {
const aggregateFields = getAggregateFields();
const otherFields = fields.filter(field => !!!aggregateFields.includes(field));
const fieldValue = aggregateFields[0];
const fieldValue = fields[fields.length - 1];
const columns = fields.slice(0, fields.length - 1);

return (
<React.Fragment>
Expand All @@ -203,7 +189,7 @@ function WidgetQueryFields({
required
>
<StyledColumnEditCollection
columns={otherFields}
columns={columns}
onChange={handleTopNColumnChange}
fieldOptions={fieldOptions}
organization={organization}
Expand All @@ -219,11 +205,11 @@ function WidgetQueryFields({
required
stacked
>
<QueryFieldWrapper key={`${aggregateFields[0]}:0`}>
<QueryFieldWrapper key={`${fieldValue}:0`}>
<QueryField
fieldValue={fieldValue}
fieldOptions={generateFieldOptions({organization})}
onChange={value => handleTopNChangeField(value, 0)}
onChange={value => handleTopNChangeField(value)}
filterPrimaryOptions={filterPrimaryOptions}
filterAggregateParameters={filterAggregateParameters(fieldValue)}
/>
Expand Down
24 changes: 3 additions & 21 deletions static/app/components/modals/addDashboardWidgetModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
TagCollection,
} from 'app/types';
import trackAdvancedAnalyticsEvent from 'app/utils/analytics/trackAdvancedAnalyticsEvent';
import {Aggregation, parseFunction} from 'app/utils/discover/fields';
import Measurements from 'app/utils/measurements/measurements';
import withApi from 'app/utils/withApi';
import withGlobalSelection from 'app/utils/withGlobalSelection';
Expand Down Expand Up @@ -260,13 +259,9 @@ class AddDashboardWidgetModal extends React.Component<Props, State> {
query.fields = [...defaultTableColumns];
});
} else if (displayType === DisplayType.TOP_N) {
// Function columns not valid group bys for TOP_N display
const topNFields = [
...defaultTableColumns.filter(column => !parseFunction(column)),
...defaultWidgetQuery.fields,
];
normalized.forEach(query => {
query.fields = [...topNFields];
// Append Y-Axis to query.fields since TOP_N view assumes the last field is the Y-Axis
query.fields = [...defaultTableColumns, defaultWidgetQuery.fields[0]];
query.orderby = defaultWidgetQuery.orderby;
});
} else {
Expand Down Expand Up @@ -460,14 +455,6 @@ class AddDashboardWidgetModal extends React.Component<Props, State> {
measurementKeys,
});

const topNFieldOptions = (measurementKeys: string[]) =>
generateFieldOptions({
organization,
tagKeys: Object.values(tags).map(({key}) => key),
measurementKeys,
aggregations: {} as Record<string, Aggregation>,
});

const isUpdatingWidget = typeof onUpdateWidget === 'function' && !!previousWidget;

return (
Expand Down Expand Up @@ -526,12 +513,7 @@ class AddDashboardWidgetModal extends React.Component<Props, State> {
<Measurements organization={organization}>
{({measurements}) => {
const measurementKeys = Object.values(measurements).map(({key}) => key);
let amendedFieldOptions;
if (state.displayType === 'top_n') {
amendedFieldOptions = topNFieldOptions(measurementKeys);
} else {
amendedFieldOptions = fieldOptions(measurementKeys);
}
const amendedFieldOptions = fieldOptions(measurementKeys);
return (
<WidgetQueriesForm
organization={organization}
Expand Down
23 changes: 1 addition & 22 deletions static/app/views/dashboardsV2/widget/eventWidget/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import isEqual from 'lodash/isEqual';

import {
aggregateOutputType,
getAggregateFields,
isAggregateFieldOrEquation,
isLegalYAxisType,
} from 'app/utils/discover/fields';
Expand Down Expand Up @@ -61,27 +60,7 @@ export function normalizeQueries(
queries = queries.slice(0, 3);
}

if (displayType === DisplayType.TABLE) {
return queries;
}

if (displayType === DisplayType.TOP_N) {
queries = queries.slice(0, 1);
const aggregateFields = getAggregateFields(queries[0].fields);

let otherFields = queries[0].fields.filter(
field => !!!aggregateFields.includes(field)
);

otherFields = otherFields.length ? otherFields : ['title'];

const fields: string[] = [
...otherFields,
aggregateFields.length ? aggregateFields[0] : 'count()',
];

queries = queries.map(query => ({...query, fields}));

if ([DisplayType.TABLE, DisplayType.TOP_N].includes(displayType)) {
return queries;
}

Expand Down
89 changes: 89 additions & 0 deletions tests/js/spec/components/dashboards/widgetQueryFields.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {mountWithTheme} from 'sentry-test/enzyme';
import {initializeOrg} from 'sentry-test/initializeOrg';

import WidgetQueryFields from 'app/components/dashboards/widgetQueryFields';
import {DisplayType} from 'app/views/dashboardsV2/types';
import {FieldValueKind} from 'app/views/eventsV2/table/types';

describe('BaseChart', function () {
const {routerContext} = initializeOrg();
// @ts-expect-error
const organization = TestStubs.Organization();
let wrapper;

beforeEach(() => {
wrapper = mountWithTheme(
<WidgetQueryFields
displayType={DisplayType.TOP_N}
fieldOptions={{
'function:count': {
label: 'count()',
value: {
kind: FieldValueKind.FUNCTION,
meta: {
name: 'count',
parameters: [],
},
},
},
'field:title': {
label: 'title',
value: {
kind: FieldValueKind.FIELD,
meta: {
name: 'title',
dataType: 'string',
},
},
},
'function:p95': {
label: 'p95(…)',
value: {
kind: FieldValueKind.FUNCTION,
meta: {
name: 'p95',
parameters: [],
},
},
},
}}
fields={[
{
kind: 'field',
field: 'title',
},
{
kind: 'function',
function: ['count', '', undefined, undefined],
},
{
kind: 'function',
function: ['p95', 'transaction.duration', undefined, undefined],
},
]}
organization={organization}
onChange={() => undefined}
/>,
routerContext
);
});

it('renders with grey dotted previous period when using only a single series', function () {
const columns = wrapper.find('StyledColumnEditCollection').find('QueryField');
expect(columns.length).toEqual(2);
expect(columns.at(0).props().fieldValue).toEqual({
kind: 'field',
field: 'title',
});
expect(columns.at(1).props().fieldValue).toEqual({
kind: 'function',
function: ['count', '', undefined, undefined],
});
expect(
wrapper.find('QueryFieldWrapper').find('QueryField').props().fieldValue
).toEqual({
function: ['p95', 'transaction.duration', undefined, undefined],
kind: 'function',
});
});
});
12 changes: 11 additions & 1 deletion tests/js/spec/components/modals/addDashboardWidgetModal.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function mountModal({
fromDiscover,
defaultWidgetQuery,
displayType,
defaultTableColumns,
}) {
return mountWithTheme(
<AddDashboardWidgetModal
Expand All @@ -33,6 +34,7 @@ function mountModal({
fromDiscover={fromDiscover}
defaultWidgetQuery={defaultWidgetQuery}
displayType={displayType}
defaultTableColumns={defaultTableColumns}
/>,
initialData.routerContext
);
Expand Down Expand Up @@ -873,6 +875,13 @@ describe('Modals -> AddDashboardWidgetModal', function () {
const wrapper = mountModal({
initialData,
onAddWidget: data => (widget = data),
defaultTableColumns: ['title', 'count()', 'count_unique(user)', 'epm()'],
defaultWidgetQuery: {
name: '',
fields: ['count()'],
conditions: 'tag:value',
orderby: '',
},
});
// Select Top n display
selectByLabel(wrapper, 'Top Events', {name: 'displayType', at: 0, control: true});
Expand Down Expand Up @@ -952,12 +961,13 @@ describe('Modals -> AddDashboardWidgetModal', function () {
fromDiscover: true,
displayType: types.DisplayType.TOP_N,
defaultWidgetQuery: {fields: ['count_unique(user)'], orderby: '-count_unique_user'},
defaultTableColumns: ['title', 'count()', 'count_unique(user)'],
defaultTableColumns: ['title', 'count()'],
});

expect(wrapper.find('SelectPicker').at(1).props().value.value).toEqual('top_n');
expect(wrapper.find('WidgetQueriesForm').props().queries[0].fields).toEqual([
'title',
'count()',
'count_unique(user)',
]);
expect(wrapper.find('WidgetQueriesForm').props().queries[0].orderby).toEqual(
Expand Down