diff --git a/static/app/components/events/metrics/metricsSection.tsx b/static/app/components/events/metrics/metricsSection.tsx index e4f6ca57d8d7b3..6f0224b93854d6 100644 --- a/static/app/components/events/metrics/metricsSection.tsx +++ b/static/app/components/events/metrics/metricsSection.tsx @@ -15,11 +15,9 @@ import {trackAnalytics} from 'sentry/utils/analytics'; import {useLocation} from 'sentry/utils/useLocation'; import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {METRICS_DRAWER_QUERY_PARAM} from 'sentry/views/explore/metrics/constants'; import {MetricsSamplesTable} from 'sentry/views/explore/metrics/metricInfoTabs/metricsSamplesTable'; import {canUseMetricsUI} from 'sentry/views/explore/metrics/metricsFlags'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {SectionKey} from 'sentry/views/issueDetails/streamline/context'; import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection'; import {TraceViewMetricsProviderWrapper} from 'sentry/views/performance/newTraceDetails/traceMetrics'; @@ -107,12 +105,7 @@ function MetricsSectionContent({ openDrawer( () => ( - - - + ), { diff --git a/static/app/components/events/ourlogs/ourlogsDrawer.tsx b/static/app/components/events/ourlogs/ourlogsDrawer.tsx index 8cbafe343914e7..383ea8a53ebedb 100644 --- a/static/app/components/events/ourlogs/ourlogsDrawer.tsx +++ b/static/app/components/events/ourlogs/ourlogsDrawer.tsx @@ -61,12 +61,14 @@ export function OurlogsDrawer({ const setLogsQuery = useSetQueryParamsQuery(); const logsSearch = useQueryParamsSearch(); + const logsAttributeConfig = {traceItemType: TraceItemDataset.LOGS, enabled: true}; + const {attributes: stringAttributes, secondaryAliases: stringSecondaryAliases} = - useTraceItemAttributes('string'); + useTraceItemAttributes(logsAttributeConfig, 'string'); const {attributes: numberAttributes, secondaryAliases: numberSecondaryAliases} = - useTraceItemAttributes('number'); + useTraceItemAttributes(logsAttributeConfig, 'number'); const {attributes: booleanAttributes, secondaryAliases: booleanSecondaryAliases} = - useTraceItemAttributes('boolean'); + useTraceItemAttributes(logsAttributeConfig, 'boolean'); const tracesItemSearchQueryBuilderProps = { initialQuery: logsSearch.formatString(), diff --git a/static/app/components/events/ourlogs/ourlogsSection.tsx b/static/app/components/events/ourlogs/ourlogsSection.tsx index 3a9a890816cd36..f2dfec562beb8a 100644 --- a/static/app/components/events/ourlogs/ourlogsSection.tsx +++ b/static/app/components/events/ourlogs/ourlogsSection.tsx @@ -21,12 +21,10 @@ import { LogsPageDataProvider, useLogsPageDataQueryResult, } from 'sentry/views/explore/contexts/logs/logsPageData'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {LOGS_DRAWER_QUERY_PARAM} from 'sentry/views/explore/logs/constants'; import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider'; import {LogRowContent} from 'sentry/views/explore/logs/tables/logsTableRow'; import {useQueryParamsSearch} from 'sentry/views/explore/queryParams/context'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {SectionKey} from 'sentry/views/issueDetails/streamline/context'; import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection'; @@ -116,20 +114,18 @@ function OurlogsSectionContent({ freeze={traceId ? {traceId} : undefined} > - - - + ), diff --git a/static/app/components/performance/spanSearchQueryBuilder.tsx b/static/app/components/performance/spanSearchQueryBuilder.tsx index 10bedfcd73e5c5..a6abb159ddea31 100644 --- a/static/app/components/performance/spanSearchQueryBuilder.tsx +++ b/static/app/components/performance/spanSearchQueryBuilder.tsx @@ -67,12 +67,13 @@ export function useSpanSearchQueryBuilderProps(props: UseSpanSearchQueryBuilderP spanSearchQueryBuilderProps: TraceItemSearchQueryBuilderProps; spanSearchQueryBuilderProviderProps: UseTraceItemSearchQueryBuilderPropsReturnType; } { + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; const {tags: numberAttributes, secondaryAliases: numberSecondaryAliases} = - useTraceItemTags('number'); + useTraceItemTags(spansConfig, 'number'); const {tags: stringAttributes, secondaryAliases: stringSecondaryAliases} = - useTraceItemTags('string'); + useTraceItemTags(spansConfig, 'string'); const {tags: booleanAttributes, secondaryAliases: booleanSecondaryAliases} = - useTraceItemTags('boolean'); + useTraceItemTags(spansConfig, 'boolean'); const stringAttributesWithSemver = useMemo(() => { if (SpanFields.RELEASE in stringAttributes) { diff --git a/static/app/components/preprod/preprodSearchBar.tsx b/static/app/components/preprod/preprodSearchBar.tsx index 386def1f835c8f..537eeff4996ecb 100644 --- a/static/app/components/preprod/preprodSearchBar.tsx +++ b/static/app/components/preprod/preprodSearchBar.tsx @@ -4,7 +4,7 @@ import type {TagCollection} from 'sentry/types/group'; import useOrganization from 'sentry/utils/useOrganization'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; import {HIDDEN_PREPROD_ATTRIBUTES} from 'sentry/views/explore/constants'; -import {useTraceItemAttributesWithConfig} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {TraceItemDataset} from 'sentry/views/explore/types'; interface PreprodSearchBarProps { @@ -80,11 +80,11 @@ export function PreprodSearchBar({ const hiddenKeys = allowedKeys ? undefined : HIDDEN_PREPROD_ATTRIBUTES; const {attributes: rawStringAttributes, secondaryAliases: rawStringSecondaryAliases} = - useTraceItemAttributesWithConfig(traceItemAttributeConfig, 'string', hiddenKeys); + useTraceItemAttributes(traceItemAttributeConfig, 'string', hiddenKeys); const {attributes: rawNumberAttributes, secondaryAliases: rawNumberSecondaryAliases} = - useTraceItemAttributesWithConfig(traceItemAttributeConfig, 'number', hiddenKeys); + useTraceItemAttributes(traceItemAttributeConfig, 'number', hiddenKeys); const {attributes: rawBooleanAttributes, secondaryAliases: rawBooleanSecondaryAliases} = - useTraceItemAttributesWithConfig(traceItemAttributeConfig, 'boolean', hiddenKeys); + useTraceItemAttributes(traceItemAttributeConfig, 'boolean', hiddenKeys); const stringAttributes = useMemo( () => diff --git a/static/app/views/alerts/rules/metric/eapField.spec.tsx b/static/app/views/alerts/rules/metric/eapField.spec.tsx index e3ab8ebb6bf540..30f7ba9cf320b7 100644 --- a/static/app/views/alerts/rules/metric/eapField.spec.tsx +++ b/static/app/views/alerts/rules/metric/eapField.spec.tsx @@ -5,8 +5,6 @@ import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrar import EAPField from 'sentry/views/alerts/rules/metric/eapField'; import {EventTypes} from 'sentry/views/alerts/rules/metric/types'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; describe('EAPField', () => { const organization = OrganizationFixture(); @@ -21,13 +19,11 @@ describe('EAPField', () => { it('renders', () => { render( - - {}} - eventTypes={[EventTypes.TRACE_ITEM_SPAN]} - /> - + {}} + eventTypes={[EventTypes.TRACE_ITEM_SPAN]} + /> ); expect(fieldsMock).toHaveBeenCalledWith( `/organizations/${organization.slug}/trace-items/attributes/`, @@ -54,13 +50,11 @@ describe('EAPField', () => { it('renders epm with argument disabled', () => { render( - - {}} - eventTypes={[EventTypes.TRACE_ITEM_SPAN]} - /> - + {}} + eventTypes={[EventTypes.TRACE_ITEM_SPAN]} + /> ); expect(fieldsMock).toHaveBeenCalledWith( `/organizations/${organization.slug}/trace-items/attributes/`, @@ -81,13 +75,11 @@ describe('EAPField', () => { it('renders failure_rate with argument disabled', () => { render( - - {}} - eventTypes={[EventTypes.TRACE_ITEM_SPAN]} - /> - + {}} + eventTypes={[EventTypes.TRACE_ITEM_SPAN]} + /> ); expect(fieldsMock).toHaveBeenCalledWith( `/organizations/${organization.slug}/trace-items/attributes/`, @@ -115,13 +107,11 @@ describe('EAPField', () => { it('should call onChange with the new aggregate string when switching aggregates', async () => { const onChange = jest.fn(); render( - - - + ); expect(fieldsMock).toHaveBeenCalledWith( `/organizations/${organization.slug}/trace-items/attributes/`, @@ -144,13 +134,11 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('count(span.duration)'); return ( - - - + ); } @@ -177,13 +165,11 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('count(span.duration)'); return ( - - - + ); } @@ -212,13 +198,11 @@ describe('EAPField', () => { it('renders count with argument disabled for logs', () => { render( - - {}} - eventTypes={[EventTypes.TRACE_ITEM_LOG]} - /> - + {}} + eventTypes={[EventTypes.TRACE_ITEM_LOG]} + /> ); expect(fieldsMock).toHaveBeenCalledWith( `/organizations/${organization.slug}/trace-items/attributes/`, @@ -246,13 +230,11 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('count(message)'); return ( - - - + ); } @@ -281,13 +263,11 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('count(message)'); return ( - - - + ); } @@ -316,13 +296,11 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('count(span.duration)'); return ( - - - + ); } @@ -345,13 +323,11 @@ describe('EAPField', () => { it('should call onChange with correct apdex aggregate when switching to apdex', async () => { const onChange = jest.fn(); render( - - - + ); await userEvent.click(screen.getByText('count')); @@ -368,16 +344,14 @@ describe('EAPField', () => { function Component() { const [aggregate, setAggregate] = useState('apdex(span.duration,300)'); return ( - - { - setAggregate(newAggregate); - onChange(newAggregate, {}); - }} - eventTypes={[EventTypes.TRACE_ITEM_SPAN]} - /> - + { + setAggregate(newAggregate); + onChange(newAggregate, {}); + }} + eventTypes={[EventTypes.TRACE_ITEM_SPAN]} + /> ); } diff --git a/static/app/views/alerts/rules/metric/eapField.tsx b/static/app/views/alerts/rules/metric/eapField.tsx index 7d5af166c25fe3..f0383436d0f621 100644 --- a/static/app/views/alerts/rules/metric/eapField.tsx +++ b/static/app/views/alerts/rules/metric/eapField.tsx @@ -6,6 +6,7 @@ import {Flex} from '@sentry/scraps/layout'; import {Select} from '@sentry/scraps/select'; import {t} from 'sentry/locale'; +import type {Project} from 'sentry/types/project'; import {defined} from 'sentry/utils'; import {parseFunction} from 'sentry/utils/discover/fields'; import { @@ -38,6 +39,7 @@ interface Props { aggregate: string; eventTypes: EventTypes[]; onChange: (value: string, meta: Record) => void; + project?: Project; } const SUPPORTED_MULTI_PARAM_AGGREGATES = [ @@ -69,11 +71,7 @@ const LOG_OPERATIONS = [ value: aggregate as OurLogsAggregate, })) satisfies Array<{label: string; value: OurLogsAggregate}>; -function EAPFieldWrapper({aggregate, onChange, eventTypes}: Props) { - return ; -} - -function EAPField({aggregate, onChange, eventTypes}: Props) { +export default function EAPField({aggregate, onChange, eventTypes, project}: Props) { const traceItemType = getTraceItemTypeForDatasetAndEventType( Dataset.EVENTS_ANALYTICS_PLATFORM, @@ -84,9 +82,24 @@ function EAPField({aggregate, onChange, eventTypes}: Props) { arguments: undefined, }; - const {attributes: storedNumberTags} = useTraceItemAttributes('number'); - const {attributes: storedStringTags} = useTraceItemAttributes('string'); - const {attributes: storedBooleanTags} = useTraceItemAttributes('boolean'); + const traceItemAttributeConfig = { + traceItemType, + enabled: true, + projects: project ? [project] : undefined, + }; + + const {attributes: storedNumberTags} = useTraceItemAttributes( + traceItemAttributeConfig, + 'number' + ); + const {attributes: storedStringTags} = useTraceItemAttributes( + traceItemAttributeConfig, + 'string' + ); + const {attributes: storedBooleanTags} = useTraceItemAttributes( + traceItemAttributeConfig, + 'boolean' + ); const storedTags = useMemo(() => { return aggregation === AggregationKey.COUNT_UNIQUE @@ -308,8 +321,6 @@ function EAPField({aggregate, onChange, eventTypes}: Props) { ); } -export default EAPFieldWrapper; - const FlexWrapper = styled('div')` flex: 1; `; diff --git a/static/app/views/alerts/rules/metric/ruleConditionsForm.tsx b/static/app/views/alerts/rules/metric/ruleConditionsForm.tsx index 29e8f1cae901b8..9cd2d9c5249023 100644 --- a/static/app/views/alerts/rules/metric/ruleConditionsForm.tsx +++ b/static/app/views/alerts/rules/metric/ruleConditionsForm.tsx @@ -71,10 +71,7 @@ import { import {getTraceItemTypeForDatasetAndEventType} from 'sentry/views/alerts/wizard/utils'; import {SESSIONS_FILTER_TAGS} from 'sentry/views/dashboards/widgetBuilder/releaseWidget/fields'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import { - TraceItemAttributeProvider, - useTraceItemAttributes, -} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {TraceItemDataset} from 'sentry/views/explore/types'; import { deprecateTransactionAlerts, @@ -651,203 +648,192 @@ class RuleConditionsForm extends PureComponent { ) : ( - - {isExtrapolatedChartData && ( - + )} + {confidenceEnabled && isLowConfidenceChartData && ( + + + {t( + 'Your low sample count may impact the accuracy of this alert. Edit your query or increase your sampling rate.' )} - /> - )} - {confidenceEnabled && isLowConfidenceChartData && ( - - - {t( - 'Your low sample count may impact the accuracy of this alert. Edit your query or increase your sampling rate.' - )} - - - )} - {!isErrorMigration && this.renderInterval()} - {t('Filter events')} - - - {this.renderProjectSelector()} - ({ - ...base, - }), - option: (base: any) => ({ - ...base, - }), - }} - options={environmentOptions} - isDisabled={ - disabled || - this.state.environments === null || - isErrorMigration || - this.disableTransactionAlertType - } - isClearable - inline={false} - flexibleControlStateSize - /> - {allowChangeEventTypes && this.renderEventTypeFilter()} - - - - + + )} + {!isErrorMigration && this.renderInterval()} + {t('Filter events')} + + + {this.renderProjectSelector()} + ({ + ...base, + }), + option: (base: any) => ({ + ...base, + }), }} + options={environmentOptions} + isDisabled={ + disabled || + this.state.environments === null || + isErrorMigration || + this.disableTransactionAlertType + } + isClearable + inline={false} flexibleControlStateSize - > - {({onChange, onBlur, initialData, value}: any) => { - return isEapAlertType(alertType) ? ( - { - onFilterSearch(query, parsedQuery); + /> + {allowChangeEventTypes && this.renderEventTypeFilter()} + + + + + {({onChange, onBlur, initialData, value}: any) => { + return isEapAlertType(alertType) ? ( + { + onFilterSearch(query, parsedQuery); + onChange(query, {}); + }} + project={project} + traceItemType={traceItemType ?? TraceItemDataset.SPANS} + /> + ) : ( + + { + onFilterSearch(query, true); onChange(query, {}); }} - project={project} - traceItemType={traceItemType ?? TraceItemDataset.SPANS} + onBlur={(query, {parsedQuery}) => { + onFilterSearch(query, parsedQuery); + onBlur(query); + }} + // We only need strict validation for Transaction queries, everything else is fine + disallowUnsupportedFilters={ + organization.features.includes('alert-allow-indexed') || + (hasOnDemandMetricAlertFeature(organization) && + isOnDemandQueryString(value)) + ? false + : dataset === Dataset.GENERIC_METRICS + } + /> + {isExtrapolatedChartData && + isOnDemandQueryString(value) && + (isOnDemandLimitReached ? ( + + {getOnDemandKeys(value) + .map(key => `"${key}"`) + .join(', ')} + + ), + docLink: ( + + ), + } + )} + isHoverable + /> + ) : ( + + {getOnDemandKeys(value) + .map(key => `"${key}"`) + .join(', ')} + + ), + strong: , + } + )} + /> + ))} + + ); + }} + + + + + {(args: any) => { + if ( + args.value?.includes('is:unresolved') && + comparisonType === AlertRuleComparisonType.DYNAMIC + ) { + return ( + - ) : ( - - { - onFilterSearch(query, true); - onChange(query, {}); - }} - onBlur={(query, {parsedQuery}) => { - onFilterSearch(query, parsedQuery); - onBlur(query); - }} - // We only need strict validation for Transaction queries, everything else is fine - disallowUnsupportedFilters={ - organization.features.includes('alert-allow-indexed') || - (hasOnDemandMetricAlertFeature(organization) && - isOnDemandQueryString(value)) - ? false - : dataset === Dataset.GENERIC_METRICS - } - /> - {isExtrapolatedChartData && - isOnDemandQueryString(value) && - (isOnDemandLimitReached ? ( - - {getOnDemandKeys(value) - .map(key => `"${key}"`) - .join(', ')} - - ), - docLink: ( - - ), - } - )} - isHoverable - /> - ) : ( - - {getOnDemandKeys(value) - .map(key => `"${key}"`) - .join(', ')} - - ), - strong: , - } - )} - /> - ))} - ); - }} - - - - - {(args: any) => { - if ( - args.value?.includes('is:unresolved') && - comparisonType === AlertRuleComparisonType.DYNAMIC - ) { - return ( - - ); - } - return null; - }} - - - + } + return null; + }} + + )} @@ -868,12 +854,14 @@ function EAPSearchQueryBuilderWithContext({ project, traceItemType, }: EAPSearchQueryBuilderWithContextProps) { + const traceItemAttributeConfig = {traceItemType, enabled: true, projects: [project]}; + const {attributes: numberAttributes, secondaryAliases: numberSecondaryAliases} = - useTraceItemAttributes('number'); + useTraceItemAttributes(traceItemAttributeConfig, 'number'); const {attributes: stringAttributes, secondaryAliases: stringSecondaryAliases} = - useTraceItemAttributes('string'); + useTraceItemAttributes(traceItemAttributeConfig, 'string'); const {attributes: booleanAttributes, secondaryAliases: booleanSecondaryAliases} = - useTraceItemAttributes('boolean'); + useTraceItemAttributes(traceItemAttributeConfig, 'boolean'); const tracesItemSearchQueryBuilderProps = { initialQuery, diff --git a/static/app/views/alerts/rules/metric/wizardField.tsx b/static/app/views/alerts/rules/metric/wizardField.tsx index 97f2b7bdfaaea1..4c729b7e8b22ed 100644 --- a/static/app/views/alerts/rules/metric/wizardField.tsx +++ b/static/app/views/alerts/rules/metric/wizardField.tsx @@ -280,6 +280,7 @@ export default function WizardField({ { return onChange(newAggregate, {}); }} diff --git a/static/app/views/dashboards/datasetConfig/logs.tsx b/static/app/views/dashboards/datasetConfig/logs.tsx index 62642221f9fff8..4554c68bde47e5 100644 --- a/static/app/views/dashboards/datasetConfig/logs.tsx +++ b/static/app/views/dashboards/datasetConfig/logs.tsx @@ -39,10 +39,7 @@ import { TraceItemSearchQueryBuilder, useTraceItemSearchQueryBuilderProps, } from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import { - useTraceItemAttributes, - useTraceItemAttributesWithConfig, -} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {isLogsEnabled} from 'sentry/views/explore/logs/isLogsEnabled'; import {LOG_AGGREGATES} from 'sentry/views/explore/logs/logsToolbar'; import {TraceItemDataset} from 'sentry/views/explore/types'; @@ -120,15 +117,20 @@ function LogsSearchBar({ WidgetBuilderSearchBarProps, 'widgetQuery' | 'onSearch' | 'portalTarget' | 'onClose' >) { + const organization = useOrganization(); const { selection: {projects}, } = usePageFilters(); + const logsAttributeConfig = { + traceItemType: TraceItemDataset.LOGS, + enabled: isLogsEnabled(organization), + }; const {attributes: stringAttributes, secondaryAliases: stringSecondaryAliases} = - useTraceItemAttributes('string'); + useTraceItemAttributes(logsAttributeConfig, 'string'); const {attributes: numberAttributes, secondaryAliases: numberSecondaryAliases} = - useTraceItemAttributes('number'); + useTraceItemAttributes(logsAttributeConfig, 'number'); const {attributes: booleanAttributes, secondaryAliases: booleanSecondaryAliases} = - useTraceItemAttributes('boolean'); + useTraceItemAttributes(logsAttributeConfig, 'boolean'); return ( ) { return render( - - - , + , {organization: {features: ['search-query-builder-input-flow-changes']}} ); } diff --git a/static/app/views/dashboards/widgetBuilder/components/exploreArithmeticBuilder.tsx b/static/app/views/dashboards/widgetBuilder/components/exploreArithmeticBuilder.tsx index bbf03f1eace215..d95ac526bbef5d 100644 --- a/static/app/views/dashboards/widgetBuilder/components/exploreArithmeticBuilder.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/exploreArithmeticBuilder.tsx @@ -9,6 +9,7 @@ import { FieldKind, getFieldDefinition, } from 'sentry/utils/fields'; +import {useWidgetBuilderTraceItemConfig} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; import {useExploreSuggestedAttribute} from 'sentry/views/explore/hooks/useExploreSuggestedAttribute'; @@ -19,9 +20,10 @@ type Props = { export function ExploreArithmeticBuilder({equation, onUpdate}: Props) { const expression = stripEquationPrefix(equation); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const traceItemConfig = useWidgetBuilderTraceItemConfig(); + const {tags: numberTags} = useTraceItemTags(traceItemConfig, 'number'); + const {tags: stringTags} = useTraceItemTags(traceItemConfig, 'string'); + const {tags: booleanTags} = useTraceItemTags(traceItemConfig, 'boolean'); const functionArguments: FunctionArgument[] = useMemo(() => { return [ diff --git a/static/app/views/dashboards/widgetBuilder/components/groupBySelector.spec.tsx b/static/app/views/dashboards/widgetBuilder/components/groupBySelector.spec.tsx index 23398992a73979..d8824e24d2ca50 100644 --- a/static/app/views/dashboards/widgetBuilder/components/groupBySelector.spec.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/groupBySelector.spec.tsx @@ -5,8 +5,6 @@ import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrar import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; import WidgetBuilderGroupBySelector from 'sentry/views/dashboards/widgetBuilder/components/groupBySelector'; import {WidgetBuilderProvider} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; const organization = OrganizationFixture({ features: [], @@ -23,9 +21,7 @@ describe('WidgetBuilderGroupBySelector', () => { it('renders', async () => { render( - - - + , { organization, @@ -40,9 +36,7 @@ describe('WidgetBuilderGroupBySelector', () => { it('renders the group by field and works for spans', async () => { render( - - - + , { organization, @@ -73,9 +67,7 @@ describe('WidgetBuilderGroupBySelector', () => { it('renders the group by field and works for logs', async () => { render( - - - + , { organization, @@ -110,9 +102,7 @@ describe('WidgetBuilderGroupBySelector', () => { render( - - - + , { initialRouterConfig: { @@ -144,9 +134,7 @@ describe('WidgetBuilderGroupBySelector', () => { render( - - - + , { initialRouterConfig: { @@ -177,9 +165,7 @@ describe('WidgetBuilderGroupBySelector', () => { render( - - - + , { initialRouterConfig: { @@ -216,9 +202,7 @@ describe('WidgetBuilderGroupBySelector', () => { render( - - - + , { organization, diff --git a/static/app/views/dashboards/widgetBuilder/components/groupBySelector.tsx b/static/app/views/dashboards/widgetBuilder/components/groupBySelector.tsx index 9b919ba9a386e1..1ffd7a0383700a 100644 --- a/static/app/views/dashboards/widgetBuilder/components/groupBySelector.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/groupBySelector.tsx @@ -14,6 +14,7 @@ import {SectionHeader} from 'sentry/views/dashboards/widgetBuilder/components/co import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext'; import {useDisableTransactionWidget} from 'sentry/views/dashboards/widgetBuilder/hooks/useDisableTransactionWidget'; import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState'; +import {useWidgetBuilderTraceItemConfig} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig'; import {HIDDEN_PREPROD_ATTRIBUTES} from 'sentry/views/explore/constants'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; import {HiddenTraceMetricGroupByFields} from 'sentry/views/explore/metrics/constants'; @@ -38,9 +39,14 @@ function WidgetBuilderGroupBySelector({ } else if (state.dataset === WidgetType.PREPROD_APP_SIZE) { hiddenKeys = HIDDEN_PREPROD_ATTRIBUTES; } - const {tags: numericSpanTags} = useTraceItemTags('number', hiddenKeys); - const {tags: stringSpanTags} = useTraceItemTags('string', hiddenKeys); - const {tags: booleanSpanTags} = useTraceItemTags('boolean', hiddenKeys); + const traceItemConfig = useWidgetBuilderTraceItemConfig(); + const {tags: numericSpanTags} = useTraceItemTags(traceItemConfig, 'number', hiddenKeys); + const {tags: stringSpanTags} = useTraceItemTags(traceItemConfig, 'string', hiddenKeys); + const {tags: booleanSpanTags} = useTraceItemTags( + traceItemConfig, + 'boolean', + hiddenKeys + ); const groupByOptions = useMemo(() => { const datasetConfig = getDatasetConfig(state.dataset); diff --git a/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx b/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx index 9f4f8dac6fda69..5c008d2b22b8d6 100644 --- a/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx @@ -20,10 +20,8 @@ import {useDimensions} from 'sentry/utils/useDimensions'; import {useLocation} from 'sentry/utils/useLocation'; import useMedia from 'sentry/utils/useMedia'; import useOrganization from 'sentry/utils/useOrganization'; -import {useHasTraceMetricsDashboards} from 'sentry/views/dashboards/hooks/useHasTraceMetricsDashboards'; import { DisplayType, - WidgetType, type DashboardDetails, type DashboardFilters, type Widget, @@ -47,10 +45,6 @@ import { WidgetBuilderProvider, } from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext'; import {DashboardsMEPProvider} from 'sentry/views/dashboards/widgetCard/dashboardsMEPContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {isLogsEnabled} from 'sentry/views/explore/logs/isLogsEnabled'; -import {createTraceMetricFilter} from 'sentry/views/explore/metrics/utils'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {useNavContext} from 'sentry/views/nav/context'; import {MetricsDataSwitcher} from 'sentry/views/performance/landing/metricsDataSwitcher'; @@ -69,47 +63,6 @@ type WidgetBuilderV2Props = { setOpenWidgetTemplates: (openWidgetTemplates: boolean) => void; }; -function TraceItemAttributeProviderFromDataset({children}: {children: React.ReactNode}) { - const {state} = useWidgetBuilderContext(); - const organization = useOrganization(); - const hasTraceMetricsDashboards = useHasTraceMetricsDashboards(); - - let enabled = false; - let traceItemType = TraceItemDataset.SPANS; - let query = undefined; - - if (state.dataset === WidgetType.SPANS) { - enabled = organization.features.includes('visibility-explore-view'); - traceItemType = TraceItemDataset.SPANS; - } - - if (state.dataset === WidgetType.LOGS) { - enabled = isLogsEnabled(organization); - traceItemType = TraceItemDataset.LOGS; - } - - if (state.dataset === WidgetType.TRACEMETRICS && state.traceMetric) { - enabled = hasTraceMetricsDashboards; - traceItemType = TraceItemDataset.TRACEMETRICS; - query = createTraceMetricFilter(state.traceMetric); - } - - if (state.dataset === WidgetType.PREPROD_APP_SIZE) { - enabled = organization.features.includes('preprod-app-size-dashboard'); - traceItemType = TraceItemDataset.PREPROD; - } - - return ( - - {children} - - ); -} - function WidgetBuilderV2({ isOpen, onClose, @@ -192,65 +145,63 @@ function WidgetBuilderV2({ - - - - - { - onClose(); - setTranslate(DEFAULT_WIDGET_DRAG_POSITIONING); - }} - onSave={onSave} - onQueryConditionChange={setQueryConditionsValid} - dashboard={dashboard} - dashboardFilters={dashboardFilters} - setIsPreviewDraggable={setIsPreviewDraggable} - isWidgetInvalid={!queryConditionsValid} - openWidgetTemplates={openWidgetTemplates} - setOpenWidgetTemplates={setOpenWidgetTemplates} - onDataFetched={handleWidgetDataFetched} - thresholdMetaState={thresholdMetaState} - /> - - {(!isSmallScreen || isPreviewDraggable) && ( - - - - - - )} - - - + + + + { + onClose(); + setTranslate(DEFAULT_WIDGET_DRAG_POSITIONING); + }} + onSave={onSave} + onQueryConditionChange={setQueryConditionsValid} + dashboard={dashboard} + dashboardFilters={dashboardFilters} + setIsPreviewDraggable={setIsPreviewDraggable} + isWidgetInvalid={!queryConditionsValid} + openWidgetTemplates={openWidgetTemplates} + setOpenWidgetTemplates={setOpenWidgetTemplates} + onDataFetched={handleWidgetDataFetched} + thresholdMetaState={thresholdMetaState} + /> + + {(!isSmallScreen || isPreviewDraggable) && ( + + + + + + )} + + diff --git a/static/app/views/dashboards/widgetBuilder/components/sortBySelector.spec.tsx b/static/app/views/dashboards/widgetBuilder/components/sortBySelector.spec.tsx index 072c895788e84c..312e7ff6bbfa72 100644 --- a/static/app/views/dashboards/widgetBuilder/components/sortBySelector.spec.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/sortBySelector.spec.tsx @@ -8,8 +8,6 @@ import {ELLIPSIS} from 'sentry/utils/string/unicode'; import {useNavigate} from 'sentry/utils/useNavigate'; import WidgetBuilderSortBySelector from 'sentry/views/dashboards/widgetBuilder/components/sortBySelector'; import {WidgetBuilderProvider} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; jest.mock('sentry/utils/useNavigate', () => ({ useNavigate: jest.fn(), @@ -44,9 +42,7 @@ describe('WidgetBuilderSortBySelector', () => { it('renders for spans', async () => { render( - - - + , { organization, @@ -63,9 +59,7 @@ describe('WidgetBuilderSortBySelector', () => { it('renders for logs', async () => { render( - - - + , { organization, @@ -82,9 +76,7 @@ describe('WidgetBuilderSortBySelector', () => { it('renders correct fields for table widgets', async () => { render( - - - + , { organization, @@ -112,9 +104,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization, @@ -150,9 +140,7 @@ describe('WidgetBuilderSortBySelector', () => { it('renders the correct limit options', async () => { render( - - - + , { organization, @@ -165,9 +153,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization, @@ -194,9 +180,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization, @@ -231,9 +215,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization, @@ -280,9 +262,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization: organizationWithFlag, @@ -328,9 +308,7 @@ describe('WidgetBuilderSortBySelector', () => { it('renders a limit selector for categorical bar widgets', async () => { render( - - - + , { organization, @@ -355,9 +333,7 @@ describe('WidgetBuilderSortBySelector', () => { it('does not render a limit selector for table widgets', async () => { render( - - - + , { organization, @@ -384,9 +360,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization, @@ -431,9 +405,7 @@ describe('WidgetBuilderSortBySelector', () => { render( - - - + , { organization: organizationWithFlag, diff --git a/static/app/views/dashboards/widgetBuilder/components/sortBySelector.tsx b/static/app/views/dashboards/widgetBuilder/components/sortBySelector.tsx index cbcbeb2b6f6475..2355dc7dcbe411 100644 --- a/static/app/views/dashboards/widgetBuilder/components/sortBySelector.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/sortBySelector.tsx @@ -24,6 +24,7 @@ import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/con import useDashboardWidgetSource from 'sentry/views/dashboards/widgetBuilder/hooks/useDashboardWidgetSource'; import useIsEditingWidget from 'sentry/views/dashboards/widgetBuilder/hooks/useIsEditingWidget'; import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState'; +import {useWidgetBuilderTraceItemConfig} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig'; import { getResultsLimit, SortDirection, @@ -46,9 +47,14 @@ function WidgetBuilderSortBySelector() { if (state.dataset === WidgetType.TRACEMETRICS) { hiddenKeys = HiddenTraceMetricGroupByFields; } - const {tags: numericSpanTags} = useTraceItemTags('number', hiddenKeys); - const {tags: stringSpanTags} = useTraceItemTags('string', hiddenKeys); - const {tags: booleanSpanTags} = useTraceItemTags('boolean', hiddenKeys); + const traceItemConfig = useWidgetBuilderTraceItemConfig(); + const {tags: numericSpanTags} = useTraceItemTags(traceItemConfig, 'number', hiddenKeys); + const {tags: stringSpanTags} = useTraceItemTags(traceItemConfig, 'string', hiddenKeys); + const {tags: booleanSpanTags} = useTraceItemTags( + traceItemConfig, + 'boolean', + hiddenKeys + ); if ( state.dataset === WidgetType.SPANS || diff --git a/static/app/views/dashboards/widgetBuilder/components/visualize/index.spec.tsx b/static/app/views/dashboards/widgetBuilder/components/visualize/index.spec.tsx index 59ba084ecdf9df..60d2c0e9e0aece 100644 --- a/static/app/views/dashboards/widgetBuilder/components/visualize/index.spec.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/visualize/index.spec.tsx @@ -36,57 +36,55 @@ describe('Visualize', () => { jest.mocked(useCustomMeasurements).mockReturnValue({customMeasurements: {}}); - jest - .mocked(useTraceItemTags) - .mockImplementation((type?: 'number' | 'string' | 'boolean') => { - if (type === 'number') { - const tags: TagCollection = { - 'span.duration': { - key: 'span.duration', - name: 'span.duration', - kind: FieldKind.MEASUREMENT, - secondaryAliases: [], - }, - 'span.self_time': { - key: 'span.self_time', - name: 'span.self_time', - kind: FieldKind.MEASUREMENT, - secondaryAliases: [], - }, - }; - return {tags, isLoading: false, secondaryAliases: {}}; - } - - if (type === 'boolean') { - const tags: TagCollection = { - 'span.status': { - key: 'span.status', - name: 'span.status', - kind: FieldKind.BOOLEAN, - }, - }; - return {tags, isLoading: false, secondaryAliases: {}}; - } - + jest.mocked(useTraceItemTags).mockImplementation((_config, type?) => { + if (type === 'number') { const tags: TagCollection = { - 'span.op': { - key: 'span.op', - name: 'span.op', - kind: FieldKind.TAG, + 'span.duration': { + key: 'span.duration', + name: 'span.duration', + kind: FieldKind.MEASUREMENT, + secondaryAliases: [], }, - 'span.description': { - key: 'span.description', - name: 'span.description', - kind: FieldKind.TAG, + 'span.self_time': { + key: 'span.self_time', + name: 'span.self_time', + kind: FieldKind.MEASUREMENT, + secondaryAliases: [], }, }; + return {tags, isLoading: false, secondaryAliases: {}}; + } - return { - tags, - secondaryAliases: {}, - isLoading: false, + if (type === 'boolean') { + const tags: TagCollection = { + 'span.status': { + key: 'span.status', + name: 'span.status', + kind: FieldKind.BOOLEAN, + }, }; - }); + return {tags, isLoading: false, secondaryAliases: {}}; + } + + const tags: TagCollection = { + 'span.op': { + key: 'span.op', + name: 'span.op', + kind: FieldKind.TAG, + }, + 'span.description': { + key: 'span.description', + name: 'span.description', + kind: FieldKind.TAG, + }, + }; + + return { + tags, + secondaryAliases: {}, + isLoading: false, + }; + }); mockNavigate = jest.fn(); jest.mocked(useNavigate).mockReturnValue(mockNavigate); @@ -1259,44 +1257,42 @@ describe('Visualize', () => { describe('spans', () => { beforeEach(() => { - jest - .mocked(useTraceItemTags) - .mockImplementation((type?: 'string' | 'number' | 'boolean') => { - if (type === 'number') { - return { - tags: { - 'span.duration': { - key: 'span.duration', - name: 'span.duration', - kind: 'measurement', - }, - 'tags[anotherNumericTag,number]': { - key: 'anotherNumericTag', - name: 'anotherNumericTag', - kind: 'measurement', - }, - } as TagCollection, - secondaryAliases: {}, - isLoading: false, - }; - } - - if (type === 'boolean') { - return {tags: {}, isLoading: false, secondaryAliases: {}}; - } - + jest.mocked(useTraceItemTags).mockImplementation((_config, type?) => { + if (type === 'number') { return { tags: { - 'span.description': { - key: 'span.description', - name: 'span.description', - kind: 'tag', + 'span.duration': { + key: 'span.duration', + name: 'span.duration', + kind: 'measurement', + }, + 'tags[anotherNumericTag,number]': { + key: 'anotherNumericTag', + name: 'anotherNumericTag', + kind: 'measurement', }, } as TagCollection, secondaryAliases: {}, isLoading: false, }; - }); + } + + if (type === 'boolean') { + return {tags: {}, isLoading: false, secondaryAliases: {}}; + } + + return { + tags: { + 'span.description': { + key: 'span.description', + name: 'span.description', + kind: 'tag', + }, + } as TagCollection, + secondaryAliases: {}, + isLoading: false, + }; + }); }); it('shows numeric tags as primary options for chart widgets', async () => { @@ -1432,29 +1428,27 @@ describe('Visualize', () => { }); it('differentiates between function and column values in selection', async () => { - jest - .mocked(useTraceItemTags) - .mockImplementation((type?: 'string' | 'number' | 'boolean') => { - if (type === 'number') { - return { - tags: { - 'tags[count,number]': {key: 'count', name: 'count', kind: 'measurement'}, - } as TagCollection, - secondaryAliases: {}, - isLoading: false, - }; - } - - if (type === 'boolean') { - return {tags: {}, secondaryAliases: {}, isLoading: false}; - } - + jest.mocked(useTraceItemTags).mockImplementation((_config, type?) => { + if (type === 'number') { return { - tags: {count: {key: 'count', name: 'count', kind: 'tag'}} as TagCollection, + tags: { + 'tags[count,number]': {key: 'count', name: 'count', kind: 'measurement'}, + } as TagCollection, secondaryAliases: {}, isLoading: false, }; - }); + } + + if (type === 'boolean') { + return {tags: {}, secondaryAliases: {}, isLoading: false}; + } + + return { + tags: {count: {key: 'count', name: 'count', kind: 'tag'}} as TagCollection, + secondaryAliases: {}, + isLoading: false, + }; + }); render( diff --git a/static/app/views/dashboards/widgetBuilder/components/visualize/index.tsx b/static/app/views/dashboards/widgetBuilder/components/visualize/index.tsx index e48de445d98da4..cfd16e16eae600 100644 --- a/static/app/views/dashboards/widgetBuilder/components/visualize/index.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/visualize/index.tsx @@ -62,6 +62,7 @@ import useDashboardWidgetSource from 'sentry/views/dashboards/widgetBuilder/hook import {useDisableTransactionWidget} from 'sentry/views/dashboards/widgetBuilder/hooks/useDisableTransactionWidget'; import useIsEditingWidget from 'sentry/views/dashboards/widgetBuilder/hooks/useIsEditingWidget'; import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState'; +import {useWidgetBuilderTraceItemConfig} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig'; import {SESSIONS_TAGS} from 'sentry/views/dashboards/widgetBuilder/releaseWidget/fields'; import ArithmeticInput from 'sentry/views/discover/table/arithmeticInput'; import {validateColumnTypes} from 'sentry/views/discover/table/queryField'; @@ -294,9 +295,14 @@ function Visualize({error, setError}: VisualizeProps) { if (state.dataset === WidgetType.TRACEMETRICS) { hiddenKeys = HiddenTraceMetricSearchFields; } - const {tags: numericSpanTags} = useTraceItemTags('number', hiddenKeys); - const {tags: stringSpanTags} = useTraceItemTags('string', hiddenKeys); - const {tags: booleanSpanTags} = useTraceItemTags('boolean', hiddenKeys); + const traceItemConfig = useWidgetBuilderTraceItemConfig(); + const {tags: numericSpanTags} = useTraceItemTags(traceItemConfig, 'number', hiddenKeys); + const {tags: stringSpanTags} = useTraceItemTags(traceItemConfig, 'string', hiddenKeys); + const {tags: booleanSpanTags} = useTraceItemTags( + traceItemConfig, + 'boolean', + hiddenKeys + ); // Span column options are explicitly defined and bypass all of the // fieldOptions filtering and logic used for showing options for diff --git a/static/app/views/dashboards/widgetBuilder/components/xAxisSelector.tsx b/static/app/views/dashboards/widgetBuilder/components/xAxisSelector.tsx index 1d6370e4c0e51e..67f8176d2509cd 100644 --- a/static/app/views/dashboards/widgetBuilder/components/xAxisSelector.tsx +++ b/static/app/views/dashboards/widgetBuilder/components/xAxisSelector.tsx @@ -17,6 +17,7 @@ import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/con import useDashboardWidgetSource from 'sentry/views/dashboards/widgetBuilder/hooks/useDashboardWidgetSource'; import useIsEditingWidget from 'sentry/views/dashboards/widgetBuilder/hooks/useIsEditingWidget'; import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState'; +import {useWidgetBuilderTraceItemConfig} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig'; import {FieldValueKind} from 'sentry/views/discover/table/types'; import {TypeBadge} from 'sentry/views/explore/components/typeBadge'; import {HIDDEN_PREPROD_ATTRIBUTES} from 'sentry/views/explore/constants'; @@ -42,7 +43,9 @@ export function WidgetBuilderXAxisSelector() { // Only use string tags for categorical X-axis (numeric values don't make good // categories). This has a major caveat that _some_ numerical tags like HTTP // response status _are_ good for grouping, so we may want to allow that. + const traceItemConfig = useWidgetBuilderTraceItemConfig(); const {tags: stringSpanTags, isLoading: isLoadingSpanTags} = useTraceItemTags( + traceItemConfig, 'string', hiddenKeys ); diff --git a/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig.ts b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig.ts new file mode 100644 index 00000000000000..41bc5163b1d0d3 --- /dev/null +++ b/static/app/views/dashboards/widgetBuilder/hooks/useWidgetBuilderTraceItemConfig.ts @@ -0,0 +1,48 @@ +import useOrganization from 'sentry/utils/useOrganization'; +import {useHasTraceMetricsDashboards} from 'sentry/views/dashboards/hooks/useHasTraceMetricsDashboards'; +import {WidgetType} from 'sentry/views/dashboards/types'; +import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext'; +import type {TraceItemAttributeConfig} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {isLogsEnabled} from 'sentry/views/explore/logs/isLogsEnabled'; +import {createTraceMetricFilter} from 'sentry/views/explore/metrics/utils'; +import {TraceItemDataset} from 'sentry/views/explore/types'; + +export function useWidgetBuilderTraceItemConfig(): TraceItemAttributeConfig { + const {state} = useWidgetBuilderContext(); + const organization = useOrganization(); + const hasTraceMetricsDashboards = useHasTraceMetricsDashboards(); + + if (state.dataset === WidgetType.SPANS) { + return { + traceItemType: TraceItemDataset.SPANS, + enabled: organization.features.includes('visibility-explore-view'), + }; + } + + if (state.dataset === WidgetType.LOGS) { + return { + traceItemType: TraceItemDataset.LOGS, + enabled: isLogsEnabled(organization), + }; + } + + if (state.dataset === WidgetType.TRACEMETRICS && state.traceMetric) { + return { + traceItemType: TraceItemDataset.TRACEMETRICS, + enabled: hasTraceMetricsDashboards, + query: createTraceMetricFilter(state.traceMetric), + }; + } + + if (state.dataset === WidgetType.PREPROD_APP_SIZE) { + return { + traceItemType: TraceItemDataset.PREPROD, + enabled: organization.features.includes('preprod-app-size-dashboard'), + }; + } + + return { + traceItemType: TraceItemDataset.SPANS, + enabled: false, + }; +} diff --git a/static/app/views/explore/components/toolbar/toolbarVisualize/visualizeEquation.tsx b/static/app/views/explore/components/toolbar/toolbarVisualize/visualizeEquation.tsx index 5b125f82adce8c..143495835b334f 100644 --- a/static/app/views/explore/components/toolbar/toolbarVisualize/visualizeEquation.tsx +++ b/static/app/views/explore/components/toolbar/toolbarVisualize/visualizeEquation.tsx @@ -18,6 +18,7 @@ import {ToolbarRow} from 'sentry/views/explore/components/toolbar/styles'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; import {useExploreSuggestedAttribute} from 'sentry/views/explore/hooks/useExploreSuggestedAttribute'; import {Visualize} from 'sentry/views/explore/queryParams/visualize'; +import {TraceItemDataset} from 'sentry/views/explore/types'; interface VisualizeEquationProps { onDelete: () => void; @@ -34,9 +35,10 @@ export function VisualizeEquation({ }: VisualizeEquationProps) { const expression = stripEquationPrefix(visualize.yAxis); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: numberTags} = useTraceItemTags(spansConfig, 'number'); + const {tags: stringTags} = useTraceItemTags(spansConfig, 'string'); + const {tags: booleanTags} = useTraceItemTags(spansConfig, 'boolean'); const functionArguments: FunctionArgument[] = useMemo(() => { return [ diff --git a/static/app/views/explore/contexts/spanTagsContext.tsx b/static/app/views/explore/contexts/spanTagsContext.tsx index 060fd55dab1f42..acc5eeb551ee39 100644 --- a/static/app/views/explore/contexts/spanTagsContext.tsx +++ b/static/app/views/explore/contexts/spanTagsContext.tsx @@ -1,10 +1,15 @@ -import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import { + useTraceItemAttributes, + type TraceItemAttributeConfig, +} from 'sentry/views/explore/contexts/traceItemAttributeContext'; export function useTraceItemTags( + config: TraceItemAttributeConfig, type?: 'number' | 'string' | 'boolean', hiddenKeys?: string[] ) { const {attributes, isLoading, secondaryAliases} = useTraceItemAttributes( + config, type, hiddenKeys ); diff --git a/static/app/views/explore/contexts/traceItemAttributeContext.tsx b/static/app/views/explore/contexts/traceItemAttributeContext.tsx index 540083bd9dcd42..9dbb3e15cfc852 100644 --- a/static/app/views/explore/contexts/traceItemAttributeContext.tsx +++ b/static/app/views/explore/contexts/traceItemAttributeContext.tsx @@ -1,5 +1,4 @@ -import type React from 'react'; -import {createContext, useContext, useMemo} from 'react'; +import {useMemo} from 'react'; import type {TagCollection} from 'sentry/types/group'; import type {Project} from 'sentry/types/project'; @@ -49,11 +48,7 @@ type TraceItemAttributeResult = { secondaryAliases: TagCollection; }; -const TraceItemAttributeContext = createContext< - TypedTraceItemAttributesResult | undefined ->(undefined); - -type TraceItemAttributeConfig = { +export type TraceItemAttributeConfig = { enabled: boolean; traceItemType: TraceItemDataset; projects?: Project[]; @@ -61,42 +56,6 @@ type TraceItemAttributeConfig = { search?: string; }; -const DISABLED_CONFIG: TraceItemAttributeConfig = { - enabled: false, - traceItemType: TraceItemDataset.SPANS, -}; - -type TraceItemAttributeProviderProps = { - children: React.ReactNode; -} & TraceItemAttributeConfig; - -/** - * @deprecated Use `useTraceItemAttributes` with a config argument instead - * of wrapping children in a provider. - */ -export function TraceItemAttributeProvider({ - children, - traceItemType, - enabled, - projects, - search, - query, -}: TraceItemAttributeProviderProps) { - const typedAttributesResult = useTraceItemAttributeConfig({ - traceItemType, - enabled, - projects, - search, - query, - }); - - return ( - - {children} - - ); -} - function useTraceItemAttributeConfig({ traceItemType, enabled, @@ -259,91 +218,11 @@ function processTraceItemAttributes( }; } -function isTraceItemAttributeConfig( - value: TraceItemAttributeConfig | TraceItemAttributeType | undefined -): value is TraceItemAttributeConfig { - return typeof value === 'object' && value !== null; -} - -function isTraceItemAttributeType( - value: TraceItemAttributeType | string[] | undefined -): value is TraceItemAttributeType { - return value === 'boolean' || value === 'number' || value === 'string'; -} - -function resolveTraceItemAttributeArgs( - configOrType: TraceItemAttributeConfig | TraceItemAttributeType | undefined, - typeOrHiddenKeys: TraceItemAttributeType | string[] | undefined, - maybeHiddenKeys: string[] | undefined -) { - if (isTraceItemAttributeConfig(configOrType)) { - return { - isConfigMode: true, - config: configOrType, - type: isTraceItemAttributeType(typeOrHiddenKeys) ? typeOrHiddenKeys : undefined, - hiddenKeys: maybeHiddenKeys, - }; - } - - return { - isConfigMode: false, - config: DISABLED_CONFIG, - type: configOrType, - hiddenKeys: Array.isArray(typeOrHiddenKeys) ? typeOrHiddenKeys : undefined, - }; -} - export function useTraceItemAttributes( config: TraceItemAttributeConfig, type?: TraceItemAttributeType, hiddenKeys?: string[] -): TraceItemAttributeResult; - -/** - * @deprecated Pass a `TraceItemAttributeConfig` as the first argument instead - * of relying on `TraceItemAttributeProvider` context. - */ -export function useTraceItemAttributes( - type?: TraceItemAttributeType, - hiddenKeys?: string[] -): TraceItemAttributeResult; - -export function useTraceItemAttributes( - configOrType?: TraceItemAttributeConfig | TraceItemAttributeType, - typeOrHiddenKeys?: TraceItemAttributeType | string[], - maybeHiddenKeys?: string[] ): TraceItemAttributeResult { - const args = resolveTraceItemAttributeArgs( - configOrType, - typeOrHiddenKeys, - maybeHiddenKeys - ); - - // Always call both to satisfy React hooks rules of unconditional calls. - // When in context mode, useTraceItemAttributeConfig runs with enabled: false (no API calls). - // When in config mode, useContext just returns undefined harmlessly. - const contextResult = useContext(TraceItemAttributeContext); - const configResult = useTraceItemAttributeConfig(args.config); - - const typedAttributesResult = args.isConfigMode ? configResult : contextResult; - - if (typedAttributesResult === undefined) { - throw new Error( - 'useTraceItemAttributes must be used within a TraceItemAttributeProvider or called with a config' - ); - } - - return processTraceItemAttributes(typedAttributesResult, args.type, args.hiddenKeys); -} - -/** - * @deprecated Use `useTraceItemAttributes` with a config argument instead. - */ -export function useTraceItemAttributesWithConfig( - config: TraceItemAttributeConfig, - type?: TraceItemAttributeType, - hiddenKeys?: string[] -) { const typedAttributesResult = useTraceItemAttributeConfig(config); return processTraceItemAttributes(typedAttributesResult, type, hiddenKeys); } diff --git a/static/app/views/explore/hooks/useSortByFields.spec.tsx b/static/app/views/explore/hooks/useSortByFields.spec.tsx index d5543347b3d706..3f5e34a7df0037 100644 --- a/static/app/views/explore/hooks/useSortByFields.spec.tsx +++ b/static/app/views/explore/hooks/useSortByFields.spec.tsx @@ -8,7 +8,7 @@ import type {Organization} from 'sentry/types/organization'; import {QueryClientProvider} from 'sentry/utils/queryClient'; import {useLocation} from 'sentry/utils/useLocation'; import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import type {TraceItemAttributeConfig} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useSortByFields} from 'sentry/views/explore/hooks/useSortByFields'; import {TraceItemDataset} from 'sentry/views/explore/types'; import {OrganizationContext} from 'sentry/views/organizationContext'; @@ -20,11 +20,7 @@ function createWrapper(organization: Organization) { return function ({children}: {children?: React.ReactNode}) { return ( - - - {children} - - + {children} ); }; @@ -32,6 +28,10 @@ function createWrapper(organization: Organization) { describe('useSortByFields', () => { const organization = OrganizationFixture(); + const spansConfig: TraceItemAttributeConfig = { + traceItemType: TraceItemDataset.SPANS, + enabled: true, + }; beforeEach(() => { MockApiClient.clearMockResponses(); @@ -48,6 +48,7 @@ describe('useSortByFields', () => { const {result} = renderHook( () => useSortByFields({ + config: spansConfig, fields: [ 'id', 'span.op', @@ -79,6 +80,7 @@ describe('useSortByFields', () => { const {result} = renderHook( () => useSortByFields({ + config: spansConfig, fields: ['span.op', 'span.description'], groupBys: ['span.op'], yAxes: ['avg(span.duration)'], diff --git a/static/app/views/explore/hooks/useSortByFields.tsx b/static/app/views/explore/hooks/useSortByFields.tsx index 07fed505a0f496..2b2f184f1cfe3d 100644 --- a/static/app/views/explore/hooks/useSortByFields.tsx +++ b/static/app/views/explore/hooks/useSortByFields.tsx @@ -7,18 +7,20 @@ import {classifyTagKey, prettifyTagKey} from 'sentry/utils/fields'; import {TypeBadge} from 'sentry/views/explore/components/typeBadge'; import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; +import type {TraceItemAttributeConfig} from 'sentry/views/explore/contexts/traceItemAttributeContext'; interface Props { + config: TraceItemAttributeConfig; fields: readonly string[]; groupBys: readonly string[]; mode: Mode; yAxes: string[]; } -export function useSortByFields({fields, yAxes, groupBys, mode}: Props) { - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); +export function useSortByFields({config, fields, yAxes, groupBys, mode}: Props) { + const {tags: numberTags} = useTraceItemTags(config, 'number'); + const {tags: stringTags} = useTraceItemTags(config, 'string'); + const {tags: booleanTags} = useTraceItemTags(config, 'boolean'); const fieldOptions: Array> = useMemo(() => { const uniqueOptions: string[] = []; diff --git a/static/app/views/explore/hooks/useVisualizeFields.spec.tsx b/static/app/views/explore/hooks/useVisualizeFields.spec.tsx index 3a18049ace4309..76e2b589ade9cd 100644 --- a/static/app/views/explore/hooks/useVisualizeFields.spec.tsx +++ b/static/app/views/explore/hooks/useVisualizeFields.spec.tsx @@ -9,7 +9,6 @@ import {parseFunction} from 'sentry/utils/discover/fields'; import {QueryClientProvider} from 'sentry/utils/queryClient'; import {useLocation} from 'sentry/utils/useLocation'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useVisualizeFields} from 'sentry/views/explore/hooks/useVisualizeFields'; import {TraceItemDataset} from 'sentry/views/explore/types'; import {OrganizationContext} from 'sentry/views/organizationContext'; @@ -17,24 +16,22 @@ import {OrganizationContext} from 'sentry/views/organizationContext'; jest.mock('sentry/utils/useLocation'); const mockedUsedLocation = jest.mocked(useLocation); +const spanConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + function createWrapper(organization: Organization) { return function ({children}: {children?: React.ReactNode}) { return ( - - - {children} - - + {children} ); }; } function useWrapper(yAxis: string) { - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const {tags: stringTags} = useTraceItemTags(spanConfig, 'string'); + const {tags: numberTags} = useTraceItemTags(spanConfig, 'number'); + const {tags: booleanTags} = useTraceItemTags(spanConfig, 'boolean'); return useVisualizeFields({ numberTags, stringTags, diff --git a/static/app/views/explore/logs/content.tsx b/static/app/views/explore/logs/content.tsx index 94b8ddd4b5a9ff..1986c4c9e1844d 100644 --- a/static/app/views/explore/logs/content.tsx +++ b/static/app/views/explore/logs/content.tsx @@ -20,7 +20,6 @@ import useOrganization from 'sentry/utils/useOrganization'; import useProjects from 'sentry/utils/useProjects'; import ExploreBreadcrumb from 'sentry/views/explore/components/breadcrumb'; import {LogsPageDataProvider} from 'sentry/views/explore/contexts/logs/logsPageData'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useGetSavedQuery} from 'sentry/views/explore/hooks/useGetSavedQueries'; import {LogsTabOnboarding} from 'sentry/views/explore/logs/logsOnboarding'; import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider'; @@ -64,19 +63,17 @@ export default function LogsContent() { > - - - {defined(onboardingProject) ? ( - - ) : ( - - )} - - + + {defined(onboardingProject) ? ( + + ) : ( + + )} + diff --git a/static/app/views/explore/logs/logsTab.spec.tsx b/static/app/views/explore/logs/logsTab.spec.tsx index edcede579d09b9..11c230a5ee92ff 100644 --- a/static/app/views/explore/logs/logsTab.spec.tsx +++ b/static/app/views/explore/logs/logsTab.spec.tsx @@ -12,12 +12,10 @@ import { LOGS_QUERY_KEY, } from 'sentry/views/explore/contexts/logs/logsPageParams'; import {LOGS_SORT_BYS_KEY} from 'sentry/views/explore/contexts/logs/sortBys'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {AlwaysPresentLogFields} from 'sentry/views/explore/logs/constants'; import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider'; import {LogsTabContent} from 'sentry/views/explore/logs/logsTab'; import {OurLogKnownFieldKey} from 'sentry/views/explore/logs/types'; -import {TraceItemDataset} from 'sentry/views/explore/types'; const datePageFilterProps: DatePageFilterProps = { defaultPeriod: '7d' as const, @@ -42,9 +40,7 @@ describe('LogsTabContent', () => { analyticsPageSource={LogsAnalyticsPageSource.EXPLORE_LOGS} source="location" > - - {children} - + {children} ); } diff --git a/static/app/views/explore/logs/logsTab.tsx b/static/app/views/explore/logs/logsTab.tsx index 9cd09d3c9e348e..8c882e3beb127a 100644 --- a/static/app/views/explore/logs/logsTab.tsx +++ b/static/app/views/explore/logs/logsTab.tsx @@ -43,7 +43,10 @@ import { } from 'sentry/views/explore/contexts/logs/logsPageData'; import {usePersistedLogsPageParams} from 'sentry/views/explore/contexts/logs/logsPageParams'; import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode'; -import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import { + useTraceItemAttributes, + type TraceItemAttributeConfig, +} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useLogAnalytics} from 'sentry/views/explore/hooks/useAnalytics'; import {useChartInterval} from 'sentry/views/explore/hooks/useChartInterval'; import { @@ -88,6 +91,7 @@ import { useSetQueryParamsMode, } from 'sentry/views/explore/queryParams/context'; import {ColumnEditorModal} from 'sentry/views/explore/tables/columnEditorModal'; +import {TraceItemDataset} from 'sentry/views/explore/types'; import {useRawCounts} from 'sentry/views/explore/useRawCounts'; // eslint-disable-next-line boundaries/element-types @@ -168,21 +172,26 @@ export function LogsTabContent({datePageFilterProps}: LogsTabProps) { limit: 50, }); + const logsAttributeConfig: TraceItemAttributeConfig = { + traceItemType: TraceItemDataset.LOGS, + enabled: true, + }; + const { attributes: stringAttributes, isLoading: stringAttributesLoading, secondaryAliases: stringSecondaryAliases, - } = useTraceItemAttributes('string', HiddenLogSearchFields); + } = useTraceItemAttributes(logsAttributeConfig, 'string', HiddenLogSearchFields); const { attributes: numberAttributes, isLoading: numberAttributesLoading, secondaryAliases: numberSecondaryAliases, - } = useTraceItemAttributes('number', HiddenLogSearchFields); + } = useTraceItemAttributes(logsAttributeConfig, 'number', HiddenLogSearchFields); const { attributes: booleanAttributes, isLoading: booleanAttributesLoading, secondaryAliases: booleanSecondaryAliases, - } = useTraceItemAttributes('boolean', HiddenLogSearchFields); + } = useTraceItemAttributes(logsAttributeConfig, 'boolean', HiddenLogSearchFields); const averageLogsPerSecond = calculateAverageLogsPerSecond(timeseriesResult); diff --git a/static/app/views/explore/logs/logsToolbar.tsx b/static/app/views/explore/logs/logsToolbar.tsx index 3b7c4db0c253fb..a4957b95025ad6 100644 --- a/static/app/views/explore/logs/logsToolbar.tsx +++ b/static/app/views/explore/logs/logsToolbar.tsx @@ -24,10 +24,7 @@ import { } from 'sentry/views/explore/components/toolbar/toolbarVisualize'; import {TypeBadge} from 'sentry/views/explore/components/typeBadge'; import {DragNDropContext} from 'sentry/views/explore/contexts/dragNDropContext'; -import { - TraceItemAttributeProvider, - useTraceItemAttributes, -} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import { OurLogKnownFieldKey, type OurLogsAggregate, @@ -99,59 +96,41 @@ export const LOG_AGGREGATES: Array> = [ export function LogsToolbar() { return ( - - + + ); } -function LogsToolbarVisualizeWrapper() { +function ToolbarVisualize() { const [search, setSearch] = useState(undefined); const debouncedSearch = useDebouncedValue(search, 200); - return ( - - setSearch(undefined)} /> - - ); -} -function LogsToolbarGroupByWrapper() { - const [search, setSearch] = useState(undefined); - const debouncedSearch = useDebouncedValue(search, 200); - return ( - - setSearch(undefined)} /> - - ); -} + const logsAttributeConfig = { + traceItemType: TraceItemDataset.LOGS, + enabled: true, + search: debouncedSearch, + }; -interface LogsToolbarProps { - onClose: () => void; - onSearch: (search: string) => void; -} - -function ToolbarVisualize({onSearch, onClose}: LogsToolbarProps) { const {attributes: stringTags, isLoading: stringTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'string', HiddenLogSearchFields ); const {attributes: numberTags, isLoading: numberTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'number', HiddenLogSearchFields ); const {attributes: booleanTags, isLoading: booleanTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'boolean', HiddenLogSearchFields ); + const onSearch = setSearch; + const onClose = useCallback(() => setSearch(undefined), []); + const sortedNumberKeys: string[] = useMemo(() => { const keys = Object.keys(numberTags); keys.sort(); @@ -404,20 +383,35 @@ function VisualizeDropdown({ ); } -function ToolbarGroupBy({onSearch, onClose}: LogsToolbarProps) { +function ToolbarGroupBy() { + const [search, setSearch] = useState(undefined); + const debouncedSearch = useDebouncedValue(search, 200); + + const logsAttributeConfig = { + traceItemType: TraceItemDataset.LOGS, + enabled: true, + search: debouncedSearch, + }; + const {attributes: numberTags, isLoading: numberTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'number', HiddenLogSearchFields ); const {attributes: stringTags, isLoading: stringTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'string', HiddenLogSearchFields ); const {attributes: booleanTags, isLoading: booleanTagsLoading} = useTraceItemAttributes( + logsAttributeConfig, 'boolean', HiddenLogSearchFields ); + const onSearch = setSearch; + const onClose = useCallback(() => setSearch(undefined), []); + const groupBys = useQueryParamsGroupBys(); const setGroupBys = useSetQueryParamsGroupBys(); diff --git a/static/app/views/explore/metrics/metricsTab.spec.tsx b/static/app/views/explore/metrics/metricsTab.spec.tsx index 7d199775a18206..db82add11e74aa 100644 --- a/static/app/views/explore/metrics/metricsTab.spec.tsx +++ b/static/app/views/explore/metrics/metricsTab.spec.tsx @@ -14,10 +14,8 @@ import { import type {DatePageFilterProps} from 'sentry/components/pageFilters/date/datePageFilter'; import {trackAnalytics} from 'sentry/utils/analytics'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {MetricsTabContent} from 'sentry/views/explore/metrics/metricsTab'; import {MultiMetricsQueryParamsProvider} from 'sentry/views/explore/metrics/multiMetricsQueryParams'; -import {TraceItemDataset} from 'sentry/views/explore/types'; jest.mock('sentry/utils/analytics'); const trackAnalyticsMock = jest.mocked(trackAnalytics); @@ -52,13 +50,7 @@ describe('MetricsTabContent', () => { }); function ProviderWrapper({children}: {children: React.ReactNode}) { - return ( - - - {children} - - - ); + return {children}; } const initialRouterConfig = { diff --git a/static/app/views/explore/multiQueryMode/content.spec.tsx b/static/app/views/explore/multiQueryMode/content.spec.tsx index 8821381a8be63d..3a9fa812f15a55 100644 --- a/static/app/views/explore/multiQueryMode/content.spec.tsx +++ b/static/app/views/explore/multiQueryMode/content.spec.tsx @@ -1,4 +1,3 @@ -import {type ReactNode} from 'react'; import {AutofixSetupFixture} from 'sentry-fixture/autofixSetupFixture'; import {TimeSeriesFixture} from 'sentry-fixture/timeSeries'; @@ -12,25 +11,13 @@ import { } from 'sentry-test/reactTestingLibrary'; import PageFiltersStore from 'sentry/components/pageFilters/store'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {MultiQueryModeContent} from 'sentry/views/explore/multiQueryMode/content'; import {useReadQueriesFromLocation} from 'sentry/views/explore/multiQueryMode/locationUtils'; -import {TraceItemDataset} from 'sentry/views/explore/types'; jest.mock('sentry/components/lazyRender', () => ({ LazyRender: ({children}: {children: React.ReactNode}) => children, })); -function Wrapper() { - return function ({children}: {children: ReactNode}) { - return ( - - {children} - - ); - }; -} - describe('MultiQueryModeContent', () => { const {organization, project} = initializeOrg(); let eventsRequest: any; @@ -114,7 +101,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); expect(within(section).getByRole('button', {name: 'spans'})).toBeDisabled(); @@ -127,7 +114,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); @@ -190,7 +177,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); await userEvent.click(within(section).getByRole('button', {name: 'count'})); @@ -205,7 +192,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); @@ -270,7 +257,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); @@ -333,7 +320,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); await userEvent.click(within(section).getByRole('button', {name: 'count'})); @@ -348,7 +335,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); const section = await screen.findByTestId('section-visualize-0'); @@ -431,7 +418,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(await screen.findByRole('button', {name: 'Bar'})).toBeInTheDocument(); @@ -479,7 +466,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); await userEvent.click(await screen.findByRole('button', {name: 'Bar'})); await userEvent.click(screen.getByRole('option', {name: 'Area'})); @@ -515,7 +502,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -557,7 +544,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -599,7 +586,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -644,7 +631,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -686,7 +673,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -740,7 +727,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -801,7 +788,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -905,7 +892,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -1056,7 +1043,7 @@ describe('MultiQueryModeContent', () => { return ; } - render(, {additionalWrapper: Wrapper()}); + render(); expect(queries).toEqual([ { @@ -1100,7 +1087,6 @@ describe('MultiQueryModeContent', () => { it('sets interval correctly', async () => { const {router} = render(, { organization, - additionalWrapper: Wrapper(), initialRouterConfig: { location: { pathname: '/traces/compare', @@ -1131,7 +1117,6 @@ describe('MultiQueryModeContent', () => { it('renders a save query button', async () => { render(, { organization, - additionalWrapper: Wrapper(), }); expect(await screen.findByLabelText('Save')).toBeInTheDocument(); await userEvent.click(screen.getByLabelText('Save')); @@ -1175,7 +1160,6 @@ describe('MultiQueryModeContent', () => { render(, { organization, - additionalWrapper: Wrapper(), initialRouterConfig: { location: { pathname: '/traces/compare', diff --git a/static/app/views/explore/multiQueryMode/content.tsx b/static/app/views/explore/multiQueryMode/content.tsx index ea7988929436f8..621447dcae1fb7 100644 --- a/static/app/views/explore/multiQueryMode/content.tsx +++ b/static/app/views/explore/multiQueryMode/content.tsx @@ -34,7 +34,6 @@ import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import useOrganization from 'sentry/utils/useOrganization'; import {WidgetSyncContextProvider} from 'sentry/views/dashboards/contexts/widgetSyncContext'; import {getIdFromLocation} from 'sentry/views/explore/contexts/pageParamsContext/id'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useGetSavedQuery} from 'sentry/views/explore/hooks/useGetSavedQueries'; import {useSaveMultiQuery} from 'sentry/views/explore/hooks/useSaveMultiQuery'; import {useVisitQuery} from 'sentry/views/explore/hooks/useVisitQuery'; @@ -221,9 +220,7 @@ export function MultiQueryModeContent() { return ( - - - + ); } diff --git a/static/app/views/explore/multiQueryMode/queryConstructors/groupBy.tsx b/static/app/views/explore/multiQueryMode/queryConstructors/groupBy.tsx index b6f29d399ca8e1..7458c66ee2b1aa 100644 --- a/static/app/views/explore/multiQueryMode/queryConstructors/groupBy.tsx +++ b/static/app/views/explore/multiQueryMode/queryConstructors/groupBy.tsx @@ -20,9 +20,10 @@ import {TraceItemDataset} from 'sentry/views/explore/types'; type Props = {index: number; query: ReadableExploreQueryParts}; export function GroupBySection({query, index}: Props) { - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: numberTags} = useTraceItemTags(spansConfig, 'number'); + const {tags: stringTags} = useTraceItemTags(spansConfig, 'string'); + const {tags: booleanTags} = useTraceItemTags(spansConfig, 'boolean'); const updateGroupBys = useUpdateQueryAtIndex(index); diff --git a/static/app/views/explore/multiQueryMode/queryConstructors/sortBy.tsx b/static/app/views/explore/multiQueryMode/queryConstructors/sortBy.tsx index 2c87bfd58a9d23..d865966cf0ed2b 100644 --- a/static/app/views/explore/multiQueryMode/queryConstructors/sortBy.tsx +++ b/static/app/views/explore/multiQueryMode/queryConstructors/sortBy.tsx @@ -18,6 +18,7 @@ import { SectionHeader, SectionLabel, } from 'sentry/views/explore/multiQueryMode/queryConstructors/styles'; +import {TraceItemDataset} from 'sentry/views/explore/types'; type Props = { index: number; @@ -30,7 +31,14 @@ export function SortBySection({query, index}: Props) { const groupBys = query.groupBys; const yAxes = query.yAxes; - const fieldOptions = useSortByFields({fields, yAxes, groupBys, mode}); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const fieldOptions = useSortByFields({ + config: spansConfig, + fields, + yAxes, + groupBys, + mode, + }); const updateSort = useUpdateQueryAtIndex(index); const kindOptions: Array> = useMemo(() => { diff --git a/static/app/views/explore/multiQueryMode/queryConstructors/visualize.tsx b/static/app/views/explore/multiQueryMode/queryConstructors/visualize.tsx index 22a34b487d44d2..f3ddac9eafecc5 100644 --- a/static/app/views/explore/multiQueryMode/queryConstructors/visualize.tsx +++ b/static/app/views/explore/multiQueryMode/queryConstructors/visualize.tsx @@ -30,9 +30,10 @@ type Props = { }; export function VisualizeSection({query, index}: Props) { - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: stringTags} = useTraceItemTags(spansConfig, 'string'); + const {tags: numberTags} = useTraceItemTags(spansConfig, 'number'); + const {tags: booleanTags} = useTraceItemTags(spansConfig, 'boolean'); const parsedFunction = findFirstFunction(query.yAxes); diff --git a/static/app/views/explore/multiQueryMode/queryVisualizations/table.tsx b/static/app/views/explore/multiQueryMode/queryVisualizations/table.tsx index 67f433c43d169c..83f32e38ef50f2 100644 --- a/static/app/views/explore/multiQueryMode/queryVisualizations/table.tsx +++ b/static/app/views/explore/multiQueryMode/queryVisualizations/table.tsx @@ -46,6 +46,7 @@ import { type ReadableExploreQueryParts, } from 'sentry/views/explore/multiQueryMode/locationUtils'; import {MultiQueryFieldRenderer} from 'sentry/views/explore/tables/fieldRenderer'; +import {TraceItemDataset} from 'sentry/views/explore/types'; const TABLE_HEIGHT = 258; @@ -96,9 +97,10 @@ function AggregatesTable({ const columns = useMemo(() => eventView.getColumns(), [eventView]); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: numberTags} = useTraceItemTags(spansConfig, 'number'); + const {tags: stringTags} = useTraceItemTags(spansConfig, 'string'); + const {tags: booleanTags} = useTraceItemTags(spansConfig, 'boolean'); const tableRef = useRef(null); const {initialTableStyles} = useTableStyles(fields, tableRef, { @@ -234,9 +236,10 @@ function SpansTable({spansTableResult, query: queryParts, index}: SampleTablePro [fields] ); - const {tags: numberTags} = useTraceItemTags('number'); - const {tags: stringTags} = useTraceItemTags('string'); - const {tags: booleanTags} = useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: numberTags} = useTraceItemTags(spansConfig, 'number'); + const {tags: stringTags} = useTraceItemTags(spansConfig, 'string'); + const {tags: booleanTags} = useTraceItemTags(spansConfig, 'boolean'); const tableRef = useRef(null); const {initialTableStyles} = useTableStyles(visibleFields, tableRef, { diff --git a/static/app/views/explore/spans/content.tsx b/static/app/views/explore/spans/content.tsx index ebdf1f31b1f222..00e7e99eeaef7c 100644 --- a/static/app/views/explore/spans/content.tsx +++ b/static/app/views/explore/spans/content.tsx @@ -25,7 +25,6 @@ import { MAX_DAYS_FOR_CROSS_EVENTS, MAX_PERIOD_FOR_CROSS_EVENTS, } from 'sentry/views/explore/constants'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {useGetSavedQuery} from 'sentry/views/explore/hooks/useGetSavedQueries'; import { useQueryParamsCrossEvents, @@ -107,7 +106,7 @@ function SpansTabWrapper({children}: SpansTabContextProps) { return ( - {children} + {children} ); } @@ -144,14 +143,6 @@ function SpansTabTourTrigger() { return null; } -function ExploreTagsProvider({children}: SpansTabContextProps) { - return ( - - {children} - - ); -} - function SpansTabHeader() { const id = useQueryParamsId(); const title = useQueryParamsTitle(); diff --git a/static/app/views/explore/spans/spansTab.spec.tsx b/static/app/views/explore/spans/spansTab.spec.tsx index dae29ef96ca299..2f08113f69b854 100644 --- a/static/app/views/explore/spans/spansTab.spec.tsx +++ b/static/app/views/explore/spans/spansTab.spec.tsx @@ -16,23 +16,15 @@ import type {TagCollection} from 'sentry/types/group'; import {trackAnalytics} from 'sentry/utils/analytics'; import {FieldKind} from 'sentry/utils/fields'; import * as spanTagsModule from 'sentry/views/explore/contexts/spanTagsContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import { useQueryParamsFields, useQueryParamsGroupBys, } from 'sentry/views/explore/queryParams/context'; import {SpansQueryParamsProvider} from 'sentry/views/explore/spans/spansQueryParamsProvider'; import {SpansTabContent} from 'sentry/views/explore/spans/spansTab'; -import {TraceItemDataset} from 'sentry/views/explore/types'; function Wrapper({children}: {children: ReactNode}) { - return ( - - - {children} - - - ); + return {children}; } jest.mock('sentry/utils/analytics'); @@ -332,7 +324,7 @@ describe('SpansTabContent', () => { beforeEach(() => { const useSpanTagsSpy = jest .spyOn(spanTagsModule, 'useTraceItemTags') - .mockImplementation(type => { + .mockImplementation((_config, type) => { switch (type) { case 'number': return {tags: mockNumberTags, isLoading: false, secondaryAliases: {}}; diff --git a/static/app/views/explore/spans/spansTabSearchSection.tsx b/static/app/views/explore/spans/spansTabSearchSection.tsx index 4ddda427d09aa6..bc21201dae6f46 100644 --- a/static/app/views/explore/spans/spansTabSearchSection.tsx +++ b/static/app/views/explore/spans/spansTabSearchSection.tsx @@ -43,7 +43,6 @@ import { import {MAX_CROSS_EVENT_QUERIES} from 'sentry/views/explore/constants'; import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import { useQueryParamsCrossEvents, useQueryParamsFields, @@ -127,17 +126,16 @@ const SpansTabCrossEventSearchBar = memo( const crossEvents = useQueryParamsCrossEvents(); const setCrossEvents = useSetQueryParamsCrossEvents(); + const traceItemType = + type === 'logs' ? TraceItemDataset.LOGS : TraceItemDataset.SPANS; + + const crossEventConfig = {traceItemType, enabled: true}; const {tags: numberAttributes, secondaryAliases: numberSecondaryAliases} = - useTraceItemTags('number'); + useTraceItemTags(crossEventConfig, 'number'); const {tags: stringAttributes, secondaryAliases: stringSecondaryAliases} = - useTraceItemTags('string'); + useTraceItemTags(crossEventConfig, 'string'); const {tags: booleanAttributes, secondaryAliases: booleanSecondaryAliases} = - useTraceItemTags('boolean'); - - let traceItemType = TraceItemDataset.SPANS; - if (type === 'logs') { - traceItemType = TraceItemDataset.LOGS; - } + useTraceItemTags(crossEventConfig, 'boolean'); const eapSpanSearchQueryBuilderProps = useMemo( () => ({ @@ -308,13 +306,11 @@ function SpansTabCrossEventSearchBars() { /> ) : ( - - - + )} - - - - - + + + + + + + ); } diff --git a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx index 3fd1de38ffbc9a..442e89b949e49f 100644 --- a/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx +++ b/static/app/views/insights/common/views/spanSummaryPage/sampleList/index.tsx @@ -30,7 +30,6 @@ import type { import DurationChart from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/durationChart'; import SampleInfo from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleInfo'; import SampleTable from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleTable/sampleTable'; -import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider'; import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import {ModuleName, SpanFields} from 'sentry/views/insights/types'; import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils'; @@ -171,63 +170,61 @@ export function SampleList({groupId, moduleName, transactionRoute, referrer}: Pr return ( - - - - - - - - - - - - - - - - - setHighlightedSpanId(undefined)} - onMouseOverSample={sample => setHighlightedSpanId(sample.span_id)} - groupId={groupId} + + + + + + + + + + + + + - - + + + setHighlightedSpanId(undefined)} + onMouseOverSample={sample => setHighlightedSpanId(sample.span_id)} + groupId={groupId} + moduleName={moduleName} + transactionName={transactionName} + subregions={subregions} + spanSearch={spanSearch} + columnOrder={columnOrder} + additionalFields={additionalFields} + referrer={referrer} + /> + ); } diff --git a/static/app/views/insights/http/components/httpSamplesPanel.tsx b/static/app/views/insights/http/components/httpSamplesPanel.tsx index df001f8ef45bc3..0b3153107295b0 100644 --- a/static/app/views/insights/http/components/httpSamplesPanel.tsx +++ b/static/app/views/insights/http/components/httpSamplesPanel.tsx @@ -53,7 +53,6 @@ import {Referrer} from 'sentry/views/insights/http/referrers'; import {BASE_FILTERS} from 'sentry/views/insights/http/settings'; import decodePanel from 'sentry/views/insights/http/utils/queryParameterDecoders/panel'; import decodeResponseCodeClass from 'sentry/views/insights/http/utils/queryParameterDecoders/responseCodeClass'; -import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider'; import { ModuleName, SpanFields, @@ -361,208 +360,203 @@ export function HTTPSamplesPanel() { return ( - - - - - - - - - - + + + + + + + + + - + - + - + - + - + + + + + + + + {t('By Duration')} + + + {t('By Response Code')} + + + + ( + + )} + /> + + + + {query.panel === 'duration' && ( + + + - - - - - - + + )} + + {query.panel === 'status' && ( + + + + + + )} + + + + + + {query.panel === 'duration' && ( + + + setHighlightedSpanId(sample.span_id)} + onSampleMouseOut={() => setHighlightedSpanId(undefined)} + error={durationSamplesDataError} + // TODO: The samples endpoint doesn't provide its own meta, so we need to create it manually + meta={{ + fields: { + 'span.response_code': 'number', + }, + units: {}, + }} + referrer={TraceViewSources.REQUESTS_MODULE} + /> + + + + + + + )} + + {query.panel === 'status' && ( + + + - - - - {query.panel === 'duration' && ( - - - - - - )} - - {query.panel === 'status' && ( - - - - - - )} - - - - - - {query.panel === 'duration' && ( - - - setHighlightedSpanId(sample.span_id)} - onSampleMouseOut={() => setHighlightedSpanId(undefined)} - error={durationSamplesDataError} - // TODO: The samples endpoint doesn't provide its own meta, so we need to create it manually - meta={{ - fields: { - 'span.response_code': 'number', - }, - units: {}, - }} - referrer={TraceViewSources.REQUESTS_MODULE} - /> - - - - - - - )} - - {query.panel === 'status' && ( - - - - - - - - - - )} - - - + + + + + + + )} + + ); } diff --git a/static/app/views/insights/mcp-prompts/views/mcpPromptsLandingPage.tsx b/static/app/views/insights/mcp-prompts/views/mcpPromptsLandingPage.tsx index be2c5935246539..a0134398f53ad3 100644 --- a/static/app/views/insights/mcp-prompts/views/mcpPromptsLandingPage.tsx +++ b/static/app/views/insights/mcp-prompts/views/mcpPromptsLandingPage.tsx @@ -11,8 +11,6 @@ import {DataCategory} from 'sentry/types/core'; import {useDatePageFilterProps} from 'sentry/utils/useDatePageFilterProps'; import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; import {ModuleFeature} from 'sentry/views/insights/common/components/moduleFeature'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; @@ -103,9 +101,7 @@ function PageWithProviders() { analyticEventName="insight.page_loads.mcp_prompts" maxPickableDays={datePageFilterProps.maxPickableDays} > - - - + ); } diff --git a/static/app/views/insights/mcp-resources/views/mcpResourcesLandingPage.tsx b/static/app/views/insights/mcp-resources/views/mcpResourcesLandingPage.tsx index 5bd52d4433b908..d587c0e69051e3 100644 --- a/static/app/views/insights/mcp-resources/views/mcpResourcesLandingPage.tsx +++ b/static/app/views/insights/mcp-resources/views/mcpResourcesLandingPage.tsx @@ -11,8 +11,6 @@ import {DataCategory} from 'sentry/types/core'; import {useDatePageFilterProps} from 'sentry/utils/useDatePageFilterProps'; import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; import {ModuleFeature} from 'sentry/views/insights/common/components/moduleFeature'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; @@ -103,9 +101,7 @@ function PageWithProviders() { analyticEventName="insight.page_loads.mcp_resources" maxPickableDays={datePageFilterProps.maxPickableDays} > - - - + ); } diff --git a/static/app/views/insights/mcp-tools/views/mcpToolsLandingPage.tsx b/static/app/views/insights/mcp-tools/views/mcpToolsLandingPage.tsx index 3b0ad812f053b6..22d49023019baf 100644 --- a/static/app/views/insights/mcp-tools/views/mcpToolsLandingPage.tsx +++ b/static/app/views/insights/mcp-tools/views/mcpToolsLandingPage.tsx @@ -11,8 +11,6 @@ import {DataCategory} from 'sentry/types/core'; import {useDatePageFilterProps} from 'sentry/utils/useDatePageFilterProps'; import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; import {ModuleFeature} from 'sentry/views/insights/common/components/moduleFeature'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; @@ -103,9 +101,7 @@ function PageWithProviders() { analyticEventName="insight.page_loads.mcp_tools" maxPickableDays={datePageFilterProps.maxPickableDays} > - - - + ); } diff --git a/static/app/views/insights/mobile/common/components/spanSamplesPanelContainer.tsx b/static/app/views/insights/mobile/common/components/spanSamplesPanelContainer.tsx index 4814f01684ec49..1370936f116f64 100644 --- a/static/app/views/insights/mobile/common/components/spanSamplesPanelContainer.tsx +++ b/static/app/views/insights/mobile/common/components/spanSamplesPanelContainer.tsx @@ -28,7 +28,6 @@ import {DataTitles} from 'sentry/views/insights/common/views/spans/types'; import DurationChart from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/durationChart'; import SampleTable from 'sentry/views/insights/common/views/spanSummaryPage/sampleList/sampleTable/sampleTable'; import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject'; -import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider'; import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters'; import { SpanFields, @@ -181,99 +180,97 @@ export function SpanSamplesContainer({ return ( - - - {release && ( - - - - {formatVersionAndCenterTruncate(release)} - - - - )} - + + {release && ( + + + + {formatVersionAndCenterTruncate(release)} + + + + )} + - - - - - - + + + - - - + - setHighlightedSpanId(undefined)} - onMouseOverSample={sample => setHighlightedSpanId(sample.span_id)} - groupId={groupId} - transactionName={transactionName} + + - + + + setHighlightedSpanId(undefined)} + onMouseOverSample={sample => setHighlightedSpanId(sample.span_id)} + groupId={groupId} + transactionName={transactionName} + moduleName={moduleName} + release={release} + columnOrder={[ + { + key: 'span_id', + name: t('Span ID'), + width: COL_WIDTH_UNDEFINED, + }, + { + key: 'profile_id', + name: t('Profile'), + width: COL_WIDTH_UNDEFINED, + }, + { + key: 'avg_comparison', + name: t('Compared to Average'), + width: COL_WIDTH_UNDEFINED, + }, + ]} + additionalFields={[SpanFields.PROFILER_ID]} + /> ); } diff --git a/static/app/views/insights/pages/agents/overview.tsx b/static/app/views/insights/pages/agents/overview.tsx index c1565d09788563..d31685ef664b15 100644 --- a/static/app/views/insights/pages/agents/overview.tsx +++ b/static/app/views/insights/pages/agents/overview.tsx @@ -22,8 +22,6 @@ import {useIsSentryEmployee} from 'sentry/utils/useIsSentryEmployee'; import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import useOrganization from 'sentry/utils/useOrganization'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {AgentSelector} from 'sentry/views/insights/common/components/agentSelector'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; @@ -213,9 +211,7 @@ function PageWithProviders() { return ( - - - + ); } diff --git a/static/app/views/insights/pages/conversations/overview.tsx b/static/app/views/insights/pages/conversations/overview.tsx index 14e322c699d195..e092e65bcaae79 100644 --- a/static/app/views/insights/pages/conversations/overview.tsx +++ b/static/app/views/insights/pages/conversations/overview.tsx @@ -22,7 +22,6 @@ import SchemaHintsList from 'sentry/views/explore/components/schemaHints/schemaH import {SchemaHintsSources} from 'sentry/views/explore/components/schemaHints/schemaHintsUtils'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; import {useTraceItemTags} from 'sentry/views/explore/contexts/spanTagsContext'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {TraceItemDataset} from 'sentry/views/explore/types'; import {AgentSelector} from 'sentry/views/insights/common/components/agentSelector'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; @@ -97,12 +96,19 @@ function ConversationsContent({datePageFilterProps}: ConversationsOverviewPagePr // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const {tags: numberTags = [], isLoading: numberTagsLoading} = - useTraceItemTags('number'); - const {tags: stringTags = [], isLoading: stringTagsLoading} = - useTraceItemTags('string'); - const {tags: booleanTags = [], isLoading: booleanTagsLoading} = - useTraceItemTags('boolean'); + const spansConfig = {traceItemType: TraceItemDataset.SPANS, enabled: true}; + const {tags: numberTags = [], isLoading: numberTagsLoading} = useTraceItemTags( + spansConfig, + 'number' + ); + const {tags: stringTags = [], isLoading: stringTagsLoading} = useTraceItemTags( + spansConfig, + 'string' + ); + const {tags: booleanTags = [], isLoading: booleanTagsLoading} = useTraceItemTags( + spansConfig, + 'boolean' + ); const hasRawSearchReplacement = organization.features.includes( 'search-query-builder-raw-search-replacement' @@ -192,9 +198,7 @@ function PageWithProviders() { return ( - - - + ); } diff --git a/static/app/views/insights/pages/frontend/frontendOverviewPage.tsx b/static/app/views/insights/pages/frontend/frontendOverviewPage.tsx index 90aaeb51959083..65a52b0f7d5661 100644 --- a/static/app/views/insights/pages/frontend/frontendOverviewPage.tsx +++ b/static/app/views/insights/pages/frontend/frontendOverviewPage.tsx @@ -59,7 +59,6 @@ import { } from 'sentry/views/insights/pages/frontend/settings'; import {useFrontendQuery} from 'sentry/views/insights/pages/frontend/useFrontendQuery'; import useHasPlatformizedFrontendOverview from 'sentry/views/insights/pages/frontend/utils/useHasPlatformizedFrontendOverview'; -import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider'; import {NextJsOverviewPage} from 'sentry/views/insights/pages/platform/nextjs'; import {useIsNextJsInsightsAvailable} from 'sentry/views/insights/pages/platform/nextjs/features'; import {PlatformizedNextJsOverviewPage} from 'sentry/views/insights/pages/platform/nextjs/platformizedNextJsOverviewPage'; @@ -167,7 +166,7 @@ function FrontendOverviewPage({datePageFilterProps}: FrontendOverviewPageProps) {!showOnboarding && ( - + - + )} diff --git a/static/app/views/insights/pages/insightsSpanTagProvider.tsx b/static/app/views/insights/pages/insightsSpanTagProvider.tsx deleted file mode 100644 index 3ebde8d8085847..00000000000000 --- a/static/app/views/insights/pages/insightsSpanTagProvider.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; - -export function InsightsSpanTagProvider({children}: {children: React.ReactNode}) { - return ( - - {children} - - ); -} diff --git a/static/app/views/insights/pages/mcp/overview.tsx b/static/app/views/insights/pages/mcp/overview.tsx index 8ce8c49b1f07a1..7b5d8d9781cf09 100644 --- a/static/app/views/insights/pages/mcp/overview.tsx +++ b/static/app/views/insights/pages/mcp/overview.tsx @@ -15,8 +15,6 @@ import {useDatePageFilterProps} from 'sentry/utils/useDatePageFilterProps'; import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays'; import useOrganization from 'sentry/utils/useOrganization'; import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder'; -import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext'; -import {TraceItemDataset} from 'sentry/views/explore/types'; import {InsightsEnvironmentSelector} from 'sentry/views/insights/common/components/enviornmentSelector'; import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout'; import {InsightsProjectSelector} from 'sentry/views/insights/common/components/projectSelector'; @@ -131,9 +129,7 @@ function PageWithProviders() { return ( - - - + ); } diff --git a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx index 5ad25f914bd37b..8e5b3df4c598e1 100644 --- a/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx +++ b/static/app/views/insights/queues/components/messageSpanSamplesPanel.tsx @@ -36,7 +36,6 @@ import {SampleDrawerBody} from 'sentry/views/insights/common/components/sampleDr import {SampleDrawerHeaderTransaction} from 'sentry/views/insights/common/components/sampleDrawerHeaderTransaction'; import {getDurationChartTitle} from 'sentry/views/insights/common/views/spans/types'; import {useSpanSamples} from 'sentry/views/insights/http/queries/useSpanSamples'; -import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider'; import {MessageSpanSamplesTable} from 'sentry/views/insights/queues/components/tables/messageSpanSamplesTable'; import {useQueuesMetricsQuery} from 'sentry/views/insights/queues/queries/useQueuesMetricsQuery'; import {Referrer} from 'sentry/views/insights/queues/referrers'; @@ -290,121 +289,117 @@ export function MessageSpanSamplesPanel() { return ( - - - - - - - - - - {messageActorType === MessageActorType.PRODUCER ? ( - - ) : ( - + + + + + + + + + {messageActorType === MessageActorType.PRODUCER ? ( + + ) : ( + + )} + + + + + + ( + )} - - - - - + /> + {messageActorType === MessageActorType.CONSUMER && ( ( - + )} /> - {messageActorType === MessageActorType.CONSUMER && ( - ( - - )} - /> - )} - - - - - - - - - - - - - setHighlightedSpanId(sample.span_id)} - onSampleMouseOut={() => setHighlightedSpanId(undefined)} - error={durationSamplesDataError} - // Samples endpoint doesn't provide meta data, so we need to provide it here - meta={{ - fields: { - [SpanFields.SPAN_DURATION]: 'duration', - [SpanFields.MESSAGING_MESSAGE_BODY_SIZE]: 'size', - [SpanFields.MESSAGING_MESSAGE_RETRY_COUNT]: 'number', - }, - units: { - [SpanFields.SPAN_DURATION]: DurationUnit.MILLISECOND, - [SpanFields.MESSAGING_MESSAGE_BODY_SIZE]: SizeUnit.BYTE, - }, - }} - type={messageActorType} - /> - - - - - - - - + )} + + + + + + + + + + + + + setHighlightedSpanId(sample.span_id)} + onSampleMouseOut={() => setHighlightedSpanId(undefined)} + error={durationSamplesDataError} + // Samples endpoint doesn't provide meta data, so we need to provide it here + meta={{ + fields: { + [SpanFields.SPAN_DURATION]: 'duration', + [SpanFields.MESSAGING_MESSAGE_BODY_SIZE]: 'size', + [SpanFields.MESSAGING_MESSAGE_RETRY_COUNT]: 'number', + }, + units: { + [SpanFields.SPAN_DURATION]: DurationUnit.MILLISECOND, + [SpanFields.MESSAGING_MESSAGE_BODY_SIZE]: SizeUnit.BYTE, + }, + }} + type={messageActorType} + /> + + + + + + + ); } diff --git a/static/app/views/replays/detail/ourlogs/index.tsx b/static/app/views/replays/detail/ourlogs/index.tsx index 7b18c658bb1c46..3079704d0f95e8 100644 --- a/static/app/views/replays/detail/ourlogs/index.tsx +++ b/static/app/views/replays/detail/ourlogs/index.tsx @@ -15,10 +15,7 @@ import { useLogsPageData, } from 'sentry/views/explore/contexts/logs/logsPageData'; import {logsTimestampAscendingSortBy} from 'sentry/views/explore/contexts/logs/sortBys'; -import { - TraceItemAttributeProvider, - useTraceItemAttributes, -} from 'sentry/views/explore/contexts/traceItemAttributeContext'; +import {useTraceItemAttributes} from 'sentry/views/explore/contexts/traceItemAttributeContext'; import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider'; import { LoadingRenderer, @@ -62,9 +59,7 @@ export default function OurLogs() { }} > - - - + ); @@ -75,10 +70,21 @@ interface OurLogsContentProps { startTimestampMs: number; } +const logsAttributeConfig = {traceItemType: TraceItemDataset.LOGS, enabled: true}; + function OurLogsContent({replayId, startTimestampMs}: OurLogsContentProps) { - const {attributes: stringAttributes} = useTraceItemAttributes('string'); - const {attributes: numberAttributes} = useTraceItemAttributes('number'); - const {attributes: booleanAttributes} = useTraceItemAttributes('boolean'); + const {attributes: stringAttributes} = useTraceItemAttributes( + logsAttributeConfig, + 'string' + ); + const {attributes: numberAttributes} = useTraceItemAttributes( + logsAttributeConfig, + 'number' + ); + const {attributes: booleanAttributes} = useTraceItemAttributes( + logsAttributeConfig, + 'boolean' + ); const scrollContainerRef = useRef(null); const {currentTime, setCurrentTime} = useReplayContext();