Skip to content

Commit 5eb3169

Browse files
nsdeschenescodex
andcommitted
fix(explore): restore trace item attribute typing
Restore type-specific trace item attribute requests for the key fetch hook and preserve secondary aliases for number and boolean attributes. Update the related frontend specs to match the current combined-request behavior used by the shared attribute context. Co-Authored-By: Codex <noreply@openai.com>
1 parent d834ce1 commit 5eb3169

File tree

4 files changed

+52
-53
lines changed

4 files changed

+52
-53
lines changed

static/app/views/explore/contexts/traceItemAttributeContext.spec.tsx

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,16 @@ describe('shouldRemoveNumberKey', () => {
5050
});
5151

5252
function addAttributeMock(
53-
attributeType: string,
54-
body: Array<{key: string; name: string; secondaryAliases?: string[]}>
53+
body: Array<{
54+
attributeType: 'string' | 'number' | 'boolean';
55+
key: string;
56+
name: string;
57+
secondaryAliases?: string[];
58+
}>
5559
) {
5660
MockApiClient.addMockResponse({
5761
url: '/organizations/org-slug/trace-items/attributes/',
5862
body,
59-
match: [
60-
(_url, options) => {
61-
const query = options?.query || {};
62-
return query.attributeType === attributeType;
63-
},
64-
],
6563
});
6664
}
6765

@@ -87,12 +85,11 @@ describe('useTraceItemAttributes number filtering', () => {
8785
it('filters out number attributes that overlap with boolean attributes', async () => {
8886
const organization = OrganizationFixture();
8987

90-
addAttributeMock('number', [
91-
{key: 'is_transaction', name: 'is_transaction'},
92-
{key: 'custom_metric', name: 'custom_metric'},
88+
addAttributeMock([
89+
{attributeType: 'number', key: 'is_transaction', name: 'is_transaction'},
90+
{attributeType: 'number', key: 'custom_metric', name: 'custom_metric'},
91+
{attributeType: 'boolean', key: 'is_transaction', name: 'is_transaction'},
9392
]);
94-
addAttributeMock('string', []);
95-
addAttributeMock('boolean', [{key: 'is_transaction', name: 'is_transaction'}]);
9693

9794
const {result} = renderHookWithProviders(
9895
() =>
@@ -117,12 +114,10 @@ describe('useTraceItemAttributes number filtering', () => {
117114
it('filters number attributes that overlap with default boolean attributes', async () => {
118115
const organization = OrganizationFixture();
119116

120-
addAttributeMock('number', [
121-
{key: 'is_transaction', name: 'is_transaction'},
122-
{key: 'custom_metric', name: 'custom_metric'},
117+
addAttributeMock([
118+
{attributeType: 'number', key: 'is_transaction', name: 'is_transaction'},
119+
{attributeType: 'number', key: 'custom_metric', name: 'custom_metric'},
123120
]);
124-
addAttributeMock('string', []);
125-
addAttributeMock('boolean', []);
126121

127122
const {result} = renderHookWithProviders(
128123
() =>
@@ -147,13 +142,18 @@ describe('useTraceItemAttributes number filtering', () => {
147142
it('filters tags[key,number] format when boolean version exists', async () => {
148143
const organization = OrganizationFixture();
149144

150-
addAttributeMock('number', [
151-
{key: 'tags[is_transaction,number]', name: 'tags[is_transaction,number]'},
152-
{key: 'custom_metric', name: 'custom_metric'},
153-
]);
154-
addAttributeMock('string', []);
155-
addAttributeMock('boolean', [
156-
{key: 'tags[is_transaction,boolean]', name: 'tags[is_transaction,boolean]'},
145+
addAttributeMock([
146+
{
147+
attributeType: 'number',
148+
key: 'tags[is_transaction,number]',
149+
name: 'tags[is_transaction,number]',
150+
},
151+
{attributeType: 'number', key: 'custom_metric', name: 'custom_metric'},
152+
{
153+
attributeType: 'boolean',
154+
key: 'tags[is_transaction,boolean]',
155+
name: 'tags[is_transaction,boolean]',
156+
},
157157
]);
158158

159159
const {result} = renderHookWithProviders(
@@ -179,16 +179,18 @@ describe('useTraceItemAttributes number filtering', () => {
179179
it('filters overlapping number secondary aliases when boolean version exists', async () => {
180180
const organization = OrganizationFixture();
181181

182-
addAttributeMock('number', [
182+
addAttributeMock([
183183
{
184+
attributeType: 'number',
184185
key: 'custom_metric',
185186
name: 'custom_metric',
186187
secondaryAliases: ['tags[is_transaction,number]', 'tags[custom_metric,number]'],
187188
},
188-
]);
189-
addAttributeMock('string', []);
190-
addAttributeMock('boolean', [
191-
{key: 'tags[is_transaction,boolean]', name: 'tags[is_transaction,boolean]'},
189+
{
190+
attributeType: 'boolean',
191+
key: 'tags[is_transaction,boolean]',
192+
name: 'tags[is_transaction,boolean]',
193+
},
192194
]);
193195

194196
const {result} = renderHookWithProviders(
@@ -214,12 +216,11 @@ describe('useTraceItemAttributes number filtering', () => {
214216
it('preserves non-overlapping number attributes', async () => {
215217
const organization = OrganizationFixture();
216218

217-
addAttributeMock('number', [
218-
{key: 'custom_metric', name: 'custom_metric'},
219-
{key: 'another_metric', name: 'another_metric'},
219+
addAttributeMock([
220+
{attributeType: 'number', key: 'custom_metric', name: 'custom_metric'},
221+
{attributeType: 'number', key: 'another_metric', name: 'another_metric'},
222+
{attributeType: 'boolean', key: 'is_transaction', name: 'is_transaction'},
220223
]);
221-
addAttributeMock('string', []);
222-
addAttributeMock('boolean', [{key: 'is_transaction', name: 'is_transaction'}]);
223224

224225
const {result} = renderHookWithProviders(
225226
() =>

static/app/views/explore/hooks/useGetTraceItemAttributeKeys.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface UseGetTraceItemAttributeKeysProps extends UseTraceItemAttributeBasePro
1717

1818
export function useGetTraceItemAttributeKeys({
1919
traceItemType,
20+
type,
2021
projectIds,
2122
query,
2223
}: UseGetTraceItemAttributeKeysProps) {
@@ -33,6 +34,7 @@ export function useGetTraceItemAttributeKeys({
3334
organization,
3435
selection,
3536
traceItemType,
37+
type,
3638
projectIds: projectIds ?? selection.projects,
3739
search: queryString,
3840
query,
@@ -44,10 +46,7 @@ export function useGetTraceItemAttributeKeys({
4446
throw new Error(`Unable to fetch trace item attribute keys: ${e}`);
4547
}
4648

47-
const {booleanAttributes, numberAttributes, stringAttributes} =
48-
getTraceItemTagCollection(result);
49-
50-
return {...booleanAttributes, ...numberAttributes, ...stringAttributes};
49+
return getTraceItemTagCollection(result, type);
5150
},
5251
});
5352

static/app/views/explore/metrics/metricToolbar/index.spec.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,16 @@ describe('MetricToolbar', () => {
9191
expect(await screen.findByRole('button', {name: /Group by/})).toBeInTheDocument();
9292

9393
// The query is left undefined for the attributes request because
94-
// we currently don't filter the attributes for equations
95-
['string', 'number', 'boolean'].forEach(attributeType => {
96-
expect(mockAttributesRequest).toHaveBeenCalledWith(
97-
'/organizations/org-slug/trace-items/attributes/',
98-
expect.objectContaining({
99-
query: expect.objectContaining({
100-
itemType: 'tracemetrics',
101-
attributeType,
102-
query: undefined,
103-
}),
104-
})
105-
);
106-
});
94+
// we currently don't filter the attributes for equations.
95+
expect(mockAttributesRequest).toHaveBeenCalledWith(
96+
'/organizations/org-slug/trace-items/attributes/',
97+
expect.objectContaining({
98+
query: expect.objectContaining({
99+
itemType: 'tracemetrics',
100+
attributeType: ['string', 'number', 'boolean'],
101+
}),
102+
})
103+
);
107104
});
108105

109106
it('renders group by selector for function visualizations', async () => {

static/app/views/explore/utils/traceItemAttributeKeysOptions.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export function traceItemAttributeKeysOptions({
6262
const substringMatch = search || undefined;
6363
const options: TraceItemAttributeKeyOptions = {
6464
itemType: traceItemType,
65-
attributeType: Array.isArray(type) ? type : [type],
65+
attributeType: type,
6666
project: projectIds?.map(String),
6767
query,
6868
...normalizeDateTimeParams(selection.datetime),
@@ -159,12 +159,14 @@ export function getTraceItemTagCollection(
159159
key: attribute.key,
160160
name: attribute.name,
161161
kind: FieldKind.MEASUREMENT,
162+
secondaryAliases: attribute?.secondaryAliases ?? [],
162163
};
163164
} else if (type === 'boolean' || attribute.attributeType === 'boolean') {
164165
booleanAttributes[attribute.key] = {
165166
key: attribute.key,
166167
name: attribute.name,
167168
kind: FieldKind.BOOLEAN,
169+
secondaryAliases: attribute?.secondaryAliases ?? [],
168170
};
169171
}
170172
}

0 commit comments

Comments
 (0)