Skip to content

Commit

Permalink
feat(insights): add geo region selector in web vitals landing (#76062)
Browse files Browse the repository at this point in the history
Work towards #75230 

Adds geo region selector, for now marked as "experimental" and internal
only because we need to allow data to come in so its not always working.
<img width="938" alt="image"
src="https://github.com/user-attachments/assets/e60c71fc-b005-435c-a605-465f5acda2b1">

This will go in many other modules and areas of our app, but for now
just web vitals landing for testing purposes.

---------

Co-authored-by: Ash <0Calories@users.noreply.github.com>
  • Loading branch information
DominikB2014 and 0Calories authored Aug 13, 2024
1 parent 33e02db commit 8505e05
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState} from 'react';
import React, {Fragment, useState} from 'react';
import styled from '@emotion/styled';
import omit from 'lodash/omit';

Expand Down Expand Up @@ -34,6 +34,7 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding';
import {useModuleBreadcrumbs} from 'sentry/views/insights/common/utils/useModuleBreadcrumbs';
import SubregionSelector from 'sentry/views/insights/common/views/spans/selectors/subregionSelector';
import {ModuleName, SpanIndexedField} from 'sentry/views/insights/types';

export function WebVitalsLandingPage() {
Expand Down Expand Up @@ -84,7 +85,12 @@ export function WebVitalsLandingPage() {
<TopMenuContainer>
<ModulePageFilterBar
moduleName={ModuleName.VITAL}
extraFilters={<BrowserTypeSelector />}
extraFilters={
<Fragment>
<BrowserTypeSelector />
<SubregionSelector />
</Fragment>
}
/>
</TopMenuContainer>
<MainContentContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {Fragment} from 'react';
import styled from '@emotion/styled';

import FeatureBadge from 'sentry/components/badge/featureBadge';
import {
CompactSelect,
type SelectOption,
type SelectProps,
} from 'sentry/components/compactSelect';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {trackAnalytics} from 'sentry/utils/analytics';
import {decodeList} from 'sentry/utils/queryString';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import useOrganization from 'sentry/utils/useOrganization';
import {useSpanMetrics} from 'sentry/views/insights/common/queries/useDiscover';
import {SpanMetricsField, subregionCodeToName} from 'sentry/views/insights/types';

export default function SubregionSelector() {
const organization = useOrganization();
const location = useLocation();
const navigate = useNavigate();
const hasGeoSelectorFeature = organization.features.includes('insights-region-filter');

const value = decodeList(location.query[SpanMetricsField.USER_GEO_SUBREGION]);
const {data, isLoading} = useSpanMetrics(
{fields: [SpanMetricsField.USER_GEO_SUBREGION], enabled: hasGeoSelectorFeature},
'api.insights.user-geo-subregion-selector'
);

type Options = SelectProps<string>['options'];

const options: Options =
data?.map(row => {
const subregionCode = row[SpanMetricsField.USER_GEO_SUBREGION];
const text = subregionCodeToName[subregionCode] || '';
return {
value: subregionCode,
label: text,
textValue: text,
};
}) ?? [];

if (!hasGeoSelectorFeature) {
return <Fragment />;
}

return (
<CompactSelect
triggerProps={{
prefix: (
<Fragment>
<StyledFeatureBadge type="experimental" />
{t('Geo region')}
</Fragment>
),
}}
multiple
loading={isLoading}
clearable
value={value}
triggerLabel={value.length === 0 ? t('All') : undefined}
menuTitle={t('Filter region')}
options={options}
onChange={(selectedOptions: SelectOption<string>[]) => {
trackAnalytics('insight.vital.select_browser_value', {
organization,
browsers: selectedOptions.map(v => v.value),
});

navigate({
...location,
query: {
...location.query,
[SpanMetricsField.USER_GEO_SUBREGION]: selectedOptions.map(
option => option.value
),
},
});
}}
/>
);
}

const StyledFeatureBadge = styled(FeatureBadge)`
margin-right: ${space(1)};
`;
33 changes: 32 additions & 1 deletion static/app/views/insights/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export enum SpanMetricsField {
URL_FULL = 'url.full',
USER_AGENT_ORIGINAL = 'user_agent.original',
CLIENT_ADDRESS = 'client.address',
USER_GEO_SUBREGION = 'user.geo.subregion',
}

export type SpanNumberFields =
Expand Down Expand Up @@ -83,7 +84,8 @@ export type SpanStringFields =
| 'span.status_code'
| 'span.ai.pipeline.group'
| 'project'
| 'messaging.destination.name';
| 'messaging.destination.name'
| SpanMetricsField.USER_GEO_SUBREGION;

export type SpanMetricsQueryFilters = {
[Field in SpanStringFields]?: string;
Expand Down Expand Up @@ -220,6 +222,7 @@ export enum SpanIndexedField {
MESSAGING_MESSAGE_RECEIVE_LATENCY = 'measurements.messaging.message.receive.latency',
MESSAGING_MESSAGE_RETRY_COUNT = 'measurements.messaging.message.retry.count',
MESSAGING_MESSAGE_DESTINATION_NAME = 'messaging.destination.name',
USER_GEO_SUBREGION = 'user.geo.subregion',
}

export type SpanIndexedResponse = {
Expand Down Expand Up @@ -287,6 +290,7 @@ export type SpanIndexedResponse = {
[SpanIndexedField.MESSAGING_MESSAGE_RECEIVE_LATENCY]: number;
[SpanIndexedField.MESSAGING_MESSAGE_RETRY_COUNT]: number;
[SpanIndexedField.MESSAGING_MESSAGE_DESTINATION_NAME]: string;
[SpanIndexedField.USER_GEO_SUBREGION]: string;
};

export type SpanIndexedPropery = keyof SpanIndexedResponse;
Expand Down Expand Up @@ -336,3 +340,30 @@ export type MetricsQueryFilters = {
} & {
[SpanIndexedField.PROJECT_ID]?: string;
};

// Maps the subregion code to the subregion name according to UN m49 standard
// We also define this in relay in `country_subregion.rs`
export const subregionCodeToName = {
'21': 'North America',
'13': 'Central America',
'29': 'Caribbean',
'5': 'South America',
'154': 'Northern Europe',
'155': 'Western Europe',
'39': 'Southern Europe',
'151': 'Eastern Europe',
'30': 'Eastern Asia',
'34': 'Southern Asia',
'35': 'South Eastern Asia',
'145': 'Western Asia',
'143': 'Central Asia',
'15': 'Northern Africa',
'11': 'Western Africa',
'17': 'Middle Africa',
'14': 'Eastern Africa',
'18': 'Southern Africa',
'54': 'Melanesia',
'57': 'Micronesia',
'61': 'Polynesia',
'53': 'Australia and New Zealand',
};

0 comments on commit 8505e05

Please sign in to comment.