diff --git a/static/app/components/events/autofix/v1/drawer.tsx b/static/app/components/events/autofix/v1/drawer.tsx index 1043cb940d4b93..3055201642636c 100644 --- a/static/app/components/events/autofix/v1/drawer.tsx +++ b/static/app/components/events/autofix/v1/drawer.tsx @@ -1,4 +1,5 @@ import {useMemo} from 'react'; +import {useQuery} from '@tanstack/react-query'; import {Flex} from '@sentry/scraps/layout'; @@ -13,8 +14,8 @@ import {Placeholder} from 'sentry/components/placeholder'; import type {Event} from 'sentry/types/event'; import type {Group} from 'sentry/types/group'; import type {Project} from 'sentry/types/project'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {useOrganization} from 'sentry/utils/useOrganization'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; import {useAiConfig} from 'sentry/views/issueDetails/streamline/hooks/useAiConfig'; interface SeerDrawerProps { @@ -70,7 +71,7 @@ function InnerSeerDrawer({ aiConfig, }: InnerSeerDrawerProps) { const organization = useOrganization(); - const {isPending, data} = useSeerOnboardingCheck(); + const {isPending, data} = useQuery(getSeerOnboardingCheckQueryOptions({organization})); const seatBasedSeer = organization.features.includes('seat-based-seer-enabled'); diff --git a/static/app/components/events/autofix/v2/autofixConfigureSeer.tsx b/static/app/components/events/autofix/v2/autofixConfigureSeer.tsx index d62de12af241d4..e7fd5d6216fd35 100644 --- a/static/app/components/events/autofix/v2/autofixConfigureSeer.tsx +++ b/static/app/components/events/autofix/v2/autofixConfigureSeer.tsx @@ -1,5 +1,6 @@ import {Fragment, type CSSProperties} from 'react'; import styled from '@emotion/styled'; +import {useQuery} from '@tanstack/react-query'; import seerConfigSeerImg from 'sentry-images/spot/seer-config-seer.svg'; import seerConfigShipImg from 'sentry-images/spot/seer-config-ship.svg'; @@ -19,9 +20,9 @@ import {t} from 'sentry/locale'; import type {Event} from 'sentry/types/event'; import type {Group} from 'sentry/types/group'; import type {Project} from 'sentry/types/project'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {MarkedText} from 'sentry/utils/marked/markedText'; import {useOrganization} from 'sentry/utils/useOrganization'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; export const AiSetupConfiguration = HookOrDefault({ hookName: 'component:ai-setup-configuration', @@ -44,7 +45,7 @@ interface AutofixConfigureSeerProps { export function AutofixConfigureSeer({event, group, project}: AutofixConfigureSeerProps) { const organization = useOrganization(); - const {data: setupCheck} = useSeerOnboardingCheck(); + const {data: setupCheck} = useQuery(getSeerOnboardingCheckQueryOptions({organization})); const {data, isPending, isError} = useGroupSummary(group, event, project); const orgNeedsToConfigureSeer = diff --git a/static/app/utils/analytics/seerAnalyticsEvents.tsx b/static/app/utils/analytics/seerAnalyticsEvents.tsx index 12743b8b8bcdee..207a88dde81f2f 100644 --- a/static/app/utils/analytics/seerAnalyticsEvents.tsx +++ b/static/app/utils/analytics/seerAnalyticsEvents.tsx @@ -109,10 +109,10 @@ export type SeerAnalyticsEventsParameters = { user_id: string; }; 'seer.config_reminder.rendered': { + can_write_settings: boolean; has_code_review_beta: boolean; has_legacy_seer: boolean; has_seat_based_seer: boolean; - initial_step: string; }; 'seer.explorer.feedback_submitted': { block_index: number; diff --git a/static/app/utils/getSeerOnboardingCheckQueryOptions.tsx b/static/app/utils/getSeerOnboardingCheckQueryOptions.tsx new file mode 100644 index 00000000000000..032286c9c4d34f --- /dev/null +++ b/static/app/utils/getSeerOnboardingCheckQueryOptions.tsx @@ -0,0 +1,27 @@ +import type {Organization} from 'sentry/types/organization'; +import {apiOptions} from 'sentry/utils/api/apiOptions'; + +interface SeerOnboardingCheckResponse { + hasSupportedScmIntegration: boolean; + isAutofixEnabled: boolean; + isCodeReviewEnabled: boolean; + isSeerConfigured: boolean; + needsConfigReminder: boolean; +} + +interface Props { + organization: Organization; + staleTime?: number; +} + +export function getSeerOnboardingCheckQueryOptions({organization, staleTime = 0}: Props) { + return apiOptions.as()( + '/organizations/$organizationIdOrSlug/seer/onboarding-check/', + { + path: { + organizationIdOrSlug: organization.slug, + }, + staleTime, + } + ); +} diff --git a/static/app/utils/useSeerOnboardingCheck.tsx b/static/app/utils/useSeerOnboardingCheck.tsx deleted file mode 100644 index 933605d5ab3fb6..00000000000000 --- a/static/app/utils/useSeerOnboardingCheck.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import {apiOptions} from 'sentry/utils/api/apiOptions'; -import {useQuery} from 'sentry/utils/queryClient'; -import {useOrganization} from 'sentry/utils/useOrganization'; - -interface SeerOnboardingCheckResponse { - hasSupportedScmIntegration: boolean; - isAutofixEnabled: boolean; - isCodeReviewEnabled: boolean; - isSeerConfigured: boolean; - needsConfigReminder: boolean; -} - -export function useSeerOnboardingCheck({ - enabled = true, - staleTime = 0, -}: { - enabled?: boolean; - staleTime?: number; -} = {}) { - const organization = useOrganization(); - return useQuery({ - ...apiOptions.as()( - '/organizations/$organizationIdOrSlug/seer/onboarding-check/', - { - path: { - organizationIdOrSlug: organization.slug, - }, - staleTime, - } - ), - enabled, - }); -} diff --git a/static/app/views/issueDetails/streamline/sidebar/autofixSection.tsx b/static/app/views/issueDetails/streamline/sidebar/autofixSection.tsx index 2b53486b83a272..09ad92f6046376 100644 --- a/static/app/views/issueDetails/streamline/sidebar/autofixSection.tsx +++ b/static/app/views/issueDetails/streamline/sidebar/autofixSection.tsx @@ -1,5 +1,6 @@ import {useCallback, useMemo, type CSSProperties} from 'react'; import styled from '@emotion/styled'; +import {useQuery} from '@tanstack/react-query'; import seerConfigConnectImg from 'sentry-images/spot/seer-config-connect-2.svg'; @@ -39,11 +40,11 @@ import {t} from 'sentry/locale'; import type {Event} from 'sentry/types/event'; import type {Group} from 'sentry/types/group'; import type {Project} from 'sentry/types/project'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig'; import {useRouteAnalyticsParams} from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams'; import {useLocation} from 'sentry/utils/useLocation'; import {useOrganization} from 'sentry/utils/useOrganization'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; import {SectionKey} from 'sentry/views/issueDetails/streamline/context'; import {SidebarFoldSection} from 'sentry/views/issueDetails/streamline/foldSection'; import {useAiConfig} from 'sentry/views/issueDetails/streamline/hooks/useAiConfig'; @@ -125,7 +126,9 @@ export interface AutofixContentProps { export function AutofixContent({aiConfig, group, project, event}: AutofixContentProps) { const organization = useOrganization(); const autofix = useExplorerAutofix(group.id); - const {data: setupCheck, isPending} = useSeerOnboardingCheck(); + const {data: setupCheck, isPending} = useQuery( + getSeerOnboardingCheckQueryOptions({organization}) + ); useAutoTriggerAutofix({autofix, group}); diff --git a/static/app/views/settings/seer/overview/codeReviewOverviewSection.tsx b/static/app/views/settings/seer/overview/codeReviewOverviewSection.tsx index bb218427bf5def..c91198c974bc4a 100644 --- a/static/app/views/settings/seer/overview/codeReviewOverviewSection.tsx +++ b/static/app/views/settings/seer/overview/codeReviewOverviewSection.tsx @@ -20,6 +20,7 @@ import {t, tct, tn} from 'sentry/locale'; import {DEFAULT_CODE_REVIEW_TRIGGERS} from 'sentry/types/integrations'; import type {Organization} from 'sentry/types/organization'; import {useFetchAllPages} from 'sentry/utils/api/apiFetch'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {useInfiniteQuery, useQueryClient} from 'sentry/utils/queryClient'; import {fetchMutation} from 'sentry/utils/queryClient'; import {useOrganization} from 'sentry/utils/useOrganization'; @@ -94,6 +95,10 @@ export function CodeReviewOverviewSection({ if (queryKey) { queryClient.invalidateQueries({queryKey}); } + // Invalidate the onboarding check query to get the updated settings + queryClient.invalidateQueries({ + queryKey: getSeerOnboardingCheckQueryOptions({organization}).queryKey, + }); (mutations ?? []).forEach(mutation => { // Invalidate related queries queryClient.invalidateQueries({ diff --git a/static/gsApp/components/primaryNavSeerConfigReminder.tsx b/static/gsApp/components/primaryNavSeerConfigReminder.tsx index 186f96826f3530..436ea75ae6e4bb 100644 --- a/static/gsApp/components/primaryNavSeerConfigReminder.tsx +++ b/static/gsApp/components/primaryNavSeerConfigReminder.tsx @@ -6,12 +6,9 @@ import {Heading, Text} from '@sentry/scraps/text'; import {IconSeer} from 'sentry/icons'; import {t} from 'sentry/locale'; -import type {Integration} from 'sentry/types/integrations'; -import type {Organization} from 'sentry/types/organization'; import {trackAnalytics} from 'sentry/utils/analytics'; -import {getApiUrl} from 'sentry/utils/api/getApiUrl'; -import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser'; -import {useApiQuery} from 'sentry/utils/queryClient'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; +import {useQuery} from 'sentry/utils/queryClient'; import {useOrganization} from 'sentry/utils/useOrganization'; import { PrimaryNavigation, @@ -19,145 +16,79 @@ import { } from 'sentry/views/navigation/primary/components'; import {useCanWriteSettings} from 'getsentry/views/seerAutomation/components/useCanWriteSettings'; -import {useSeerOnboardingStep} from 'getsentry/views/seerAutomation/onboarding/hooks/useSeerOnboardingStep'; -import {Steps} from 'getsentry/views/seerAutomation/onboarding/types'; - -// See also: `IntegrationProviderSlug` in sentry/integrations/types.py -// `vsts` is ignored for now, not on the early roadmap in January 2026. -const SCM_PROVIDER_KEYS = [ - 'github', - 'github_enterprise', - 'gitlab', - 'bitbucket', - 'bitbucket_server', -]; - -/** - * Fetches all SCM integrations for an organization, filtering for Seer related SCM providers. - */ -function useScmIntegrations() { - const organization = useOrganization(); - const {data, isPending} = useApiQuery( - [ - getApiUrl('/organizations/$organizationIdOrSlug/integrations/', { - path: {organizationIdOrSlug: organization.slug}, - }), - {query: {includeConfig: 0}}, - ], - { - staleTime: 120000, // Cache for 2 minutes - } - ); - - // Filter to only SCM integrations - const scmIntegrations = - data?.filter(integration => SCM_PROVIDER_KEYS.includes(integration.provider.key)) ?? - []; - - const hasGithub = scmIntegrations.some(integration => - ['github', 'github_enterprise'].includes(integration.provider.key) - ); - const hasOnlyNonGithubScm = - scmIntegrations.length > 0 && - !hasGithub && - scmIntegrations.every(integration => - ['gitlab', 'bitbucket', 'bitbucket_server'].includes(integration.provider.key) - ); - - return { - scmIntegrations, - hasGithub, - hasOnlyNonGithubScm, - isPending, - }; -} - -function useCanSeeReminder(organization: Organization) { +function useReminderData() { + const organization = useOrganization(); const canWrite = useCanWriteSettings(); - const {isPending, initialStep} = useSeerOnboardingStep(); - const {hasOnlyNonGithubScm, isPending: isScmPending} = useScmIntegrations(); const hasSeatBasedSeer = organization.features.includes('seat-based-seer-enabled'); const hasLegacySeer = organization.features.includes('seer-added'); const hasCodeReviewBeta = organization.features.includes('code-review-beta'); - const hasSeer = hasSeatBasedSeer || hasLegacySeer || hasCodeReviewBeta; - const analyticsParams = useMemo( - () => ({ - has_seat_based_seer: hasSeatBasedSeer, - has_legacy_seer: hasLegacySeer, + const analyticsParams = useMemo(() => { + return { + can_write_settings: canWrite, has_code_review_beta: hasCodeReviewBeta, - initial_step: Steps[initialStep]?.toString() ?? 'unknown', - }), - [hasSeatBasedSeer, hasLegacySeer, hasCodeReviewBeta, initialStep] - ); - - if (!organization.features.includes('seer-config-reminder')) { - return {canSeeReminder: false, analyticsParams}; - } - - if (!hasSeer) { - return {canSeeReminder: false, analyticsParams}; - } - - if (!canWrite && !isActiveSuperuser()) { - return {canSeeReminder: false, analyticsParams}; - } + has_legacy_seer: hasLegacySeer, + has_seat_based_seer: hasSeatBasedSeer, + }; + }, [canWrite, hasSeatBasedSeer, hasLegacySeer, hasCodeReviewBeta]); - if (isPending || isScmPending || initialStep === Steps.WRAP_UP) { - return {canSeeReminder: false, analyticsParams}; - } + const { + isPending, + isError, + data: data, + } = useQuery(getSeerOnboardingCheckQueryOptions({organization, staleTime: 60_000})); - // If org has zero SCM integrations => show icon - // If org has 1 or more GitHub SCM connections => show icon - // If org has only BitBucket and/or GitLab SCM's => no icon - if (hasOnlyNonGithubScm) { - return {canSeeReminder: false, analyticsParams}; + if (!canWrite || !hasSeatBasedSeer || isPending || isError) { + return {canSeeReminder: false, analyticsParams, title: null, description: null}; } + const {hasSupportedScmIntegration, isAutofixEnabled, isCodeReviewEnabled} = data; - return { - canSeeReminder: true, - analyticsParams, - }; -} - -function useReminderCopywriting() { - const organization = useOrganization(); - const {initialStep} = useSeerOnboardingStep(); - const hasSeatBasedSeer = organization.features.includes('seat-based-seer-enabled'); - const hasLegacySeer = organization.features.includes('seer-added'); - - const descriptionByStep: Record = { - [Steps.CONNECT_GITHUB]: { + if (!hasSupportedScmIntegration) { + return { + canSeeReminder: true, + analyticsParams, title: t('Connect GitHub'), description: t( - 'Seer is enabled, but Github is not connected. Connect your GitHub account to enable Root Cause Analysis and Code Review.' + 'Seer is enabled, but Github is not connected. Connect your GitHub account to enable Autofix and Code Review.' + ), + }; + } + + if (!isAutofixEnabled) { + return { + canSeeReminder: true, + analyticsParams, + title: ( + + + {t('Start using Autofix')} + ), - }, - [Steps.SETUP_ROOT_CAUSE_ANALYSIS]: { - title: t('Start using Seer\u2019s Issue Autofix'), description: t( - 'Seer is enabled but Root Cause Analysis is not configured. Configure Seer to automatically look at issues and generate code fixes.' + 'Seer is enabled but projects are not connected to repos. Connect your source code and run Root Cause Analysis, Solution generation, and PR creation.' + ), + }; + } + + if (!isCodeReviewEnabled) { + return { + canSeeReminder: true, + analyticsParams, + title: ( + + + {t('Start using Code Review')} + ), - }, - [Steps.SETUP_CODE_REVIEW]: { - title: t('Start using Seer\u2019s AI Code Review'), description: t( 'Seer is enabled but Code Review is not configured. Configure Seer to automatically review PRs and flag potential issues.' ), - }, - [Steps.SETUP_DEFAULTS]: null, - [Steps.WRAP_UP]: null, - }; - - if (hasSeatBasedSeer) { - return descriptionByStep[initialStep]; + }; } - if (hasLegacySeer) { - return descriptionByStep[Steps.SETUP_CODE_REVIEW]; - } - return descriptionByStep[Steps.SETUP_ROOT_CAUSE_ANALYSIS]; + + return {canSeeReminder: false, analyticsParams, title: null, description: null}; } export function PrimaryNavSeerConfigReminder() { @@ -169,10 +100,8 @@ export function PrimaryNavSeerConfigReminder() { state, } = usePrimaryNavigationButtonOverlay(); - const {canSeeReminder, analyticsParams} = useCanSeeReminder(organization); - const copy = useReminderCopywriting(); + const {canSeeReminder, title, description, analyticsParams} = useReminderData(); - // Track impression on mount useEffect(() => { if (canSeeReminder) { trackAnalytics('seer.config_reminder.rendered', { @@ -182,7 +111,7 @@ export function PrimaryNavSeerConfigReminder() { } }, [canSeeReminder, analyticsParams, organization]); - if (!canSeeReminder || !copy) { + if (!canSeeReminder) { return null; } @@ -200,11 +129,12 @@ export function PrimaryNavSeerConfigReminder() { /> {isOpen && ( - - {copy.title} - {copy.description} + + {title} + {description} state.close()} diff --git a/static/gsApp/views/seerAutomation/components/repoTable/seerRepoTable.tsx b/static/gsApp/views/seerAutomation/components/repoTable/seerRepoTable.tsx index f5faa68c1237c0..f8a233d7d7f1e5 100644 --- a/static/gsApp/views/seerAutomation/components/repoTable/seerRepoTable.tsx +++ b/static/gsApp/views/seerAutomation/components/repoTable/seerRepoTable.tsx @@ -26,6 +26,7 @@ import {IconSearch} from 'sentry/icons/iconSearch'; import {t, tct} from 'sentry/locale'; import type {RepositoryWithSettings} from 'sentry/types/integrations'; import {useFetchAllPages} from 'sentry/utils/api/apiFetch'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import { ListItemCheckboxProvider, useListItemCheckboxContext, @@ -121,6 +122,9 @@ export function SeerRepoTable() { }); }, onSettled: mutations => { + queryClient.invalidateQueries({ + queryKey: getSeerOnboardingCheckQueryOptions({organization}).queryKey, + }); (mutations ?? []).forEach(mutation => { queryClient.invalidateQueries({ queryKey: getRepositoryWithSettingsQueryKey(organization, mutation.id), diff --git a/static/gsApp/views/seerAutomation/components/seerConnectGitHubBanner.tsx b/static/gsApp/views/seerAutomation/components/seerConnectGitHubBanner.tsx index 9055fe684e1779..530a02698daa37 100644 --- a/static/gsApp/views/seerAutomation/components/seerConnectGitHubBanner.tsx +++ b/static/gsApp/views/seerAutomation/components/seerConnectGitHubBanner.tsx @@ -1,6 +1,7 @@ import {useCallback} from 'react'; import {ThemeProvider} from '@emotion/react'; import styled from '@emotion/styled'; +import {useQuery} from '@tanstack/react-query'; import seerConfigMainBg from 'sentry-images/spot/seer-config-main-bg.svg'; @@ -8,16 +9,20 @@ import {Container, Flex, Grid, Stack} from '@sentry/scraps/layout'; import {Heading, Text} from '@sentry/scraps/text'; import {t} from 'sentry/locale'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {useInvertedTheme} from 'sentry/utils/theme/useInvertedTheme'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; +import {useOrganization} from 'sentry/utils/useOrganization'; import {GithubButton} from 'getsentry/views/seerAutomation/onboarding/githubButton'; import {SeerOnboardingProvider} from 'getsentry/views/seerAutomation/onboarding/hooks/seerOnboardingContext'; export function SeerConnectGitHubBanner() { + const organization = useOrganization(); const theme = useInvertedTheme(); - const {data, isFetched, isError} = useSeerOnboardingCheck(); + const {data, isFetched, isError} = useQuery( + getSeerOnboardingCheckQueryOptions({organization}) + ); const handleAddIntegration = useCallback(() => { window.location.reload(); diff --git a/static/gsApp/views/seerAutomation/components/seerWizardSetupBanner.tsx b/static/gsApp/views/seerAutomation/components/seerWizardSetupBanner.tsx index a8bde832dd19f7..165996f19fefcc 100644 --- a/static/gsApp/views/seerAutomation/components/seerWizardSetupBanner.tsx +++ b/static/gsApp/views/seerAutomation/components/seerWizardSetupBanner.tsx @@ -1,5 +1,6 @@ import {ThemeProvider} from '@emotion/react'; import styled from '@emotion/styled'; +import {useQuery} from '@tanstack/react-query'; import seerConfigMainBg from 'sentry-images/spot/seer-config-main-bg.svg'; @@ -9,15 +10,17 @@ import {Heading, Text} from '@sentry/scraps/text'; import {IconSeer} from 'sentry/icons'; import {t} from 'sentry/locale'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {useInvertedTheme} from 'sentry/utils/theme/useInvertedTheme'; import {useOrganization} from 'sentry/utils/useOrganization'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; export function SeerWizardSetupBanner() { const organization = useOrganization(); const theme = useInvertedTheme(); - const {data, isFetched, isError} = useSeerOnboardingCheck(); + const {data, isFetched, isError} = useQuery( + getSeerOnboardingCheckQueryOptions({organization}) + ); if (!isFetched || isError) { return null; diff --git a/static/gsApp/views/seerAutomation/onboarding/hooks/useSeerOnboardingStep.tsx b/static/gsApp/views/seerAutomation/onboarding/hooks/useSeerOnboardingStep.tsx index 6f85cfb3f312ae..681526a937c365 100644 --- a/static/gsApp/views/seerAutomation/onboarding/hooks/useSeerOnboardingStep.tsx +++ b/static/gsApp/views/seerAutomation/onboarding/hooks/useSeerOnboardingStep.tsx @@ -1,9 +1,15 @@ -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; +import {useQuery} from '@tanstack/react-query'; + +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; +import {useOrganization} from 'sentry/utils/useOrganization'; import {Steps} from 'getsentry/views/seerAutomation/onboarding/types'; export function useSeerOnboardingStep(): {initialStep: Steps; isPending: boolean} { - const {isPending, data} = useSeerOnboardingCheck({staleTime: 60_000}); + const organization = useOrganization(); + const {isPending, data} = useQuery( + getSeerOnboardingCheckQueryOptions({organization, staleTime: 60_000}) + ); let initialStep = Steps.CONNECT_GITHUB; diff --git a/static/gsApp/views/subscriptionPage/usageOverview/components/panel.tsx b/static/gsApp/views/subscriptionPage/usageOverview/components/panel.tsx index 6fdc9aa9c258f1..cf4b0195ccd7d5 100644 --- a/static/gsApp/views/subscriptionPage/usageOverview/components/panel.tsx +++ b/static/gsApp/views/subscriptionPage/usageOverview/components/panel.tsx @@ -1,4 +1,5 @@ import {Fragment} from 'react'; +import {useQuery} from '@tanstack/react-query'; import {Tag} from '@sentry/scraps/badge'; import {LinkButton} from '@sentry/scraps/button'; @@ -10,7 +11,7 @@ import {IconClock, IconSettings, IconWarning} from 'sentry/icons'; import {t, tct, tn} from 'sentry/locale'; import {DataCategory} from 'sentry/types/core'; import {getDaysSinceDate} from 'sentry/utils/getDaysSinceDate'; -import {useSeerOnboardingCheck} from 'sentry/utils/useSeerOnboardingCheck'; +import {getSeerOnboardingCheckQueryOptions} from 'sentry/utils/getSeerOnboardingCheckQueryOptions'; import {useProductBillingMetadata} from 'getsentry/hooks/useProductBillingMetadata'; import {AddOnCategory, OnDemandBudgetMode} from 'getsentry/types'; @@ -146,9 +147,9 @@ export function ProductBreakdownPanel({ // TODO(billing): if we ever show the setup state for other products, this will need refactoring // maybe a billing hook for setup checks const shouldCheckSetup = selectedProduct === AddOnCategory.SEER && isEnabled; - const {data: setupCheck, isLoading: setupCheckLoading} = useSeerOnboardingCheck({ + const {data: setupCheck, isLoading: setupCheckLoading} = useQuery({ + ...getSeerOnboardingCheckQueryOptions({organization, staleTime: 60_000}), enabled: shouldCheckSetup, - staleTime: 60_000, }); const setupRequired = shouldCheckSetup &&