Show AI provider sections regardless of billing status (#18845)

## Summary

- Removes the `isBillingEnabled` guard that was hiding the Providers and
Custom Providers sections in the Admin AI settings
- The `GET_AI_PROVIDERS` query was being skipped when billing was
enabled, and the provider UI sections were conditionally hidden —
there's no reason to gate provider configuration behind billing status
- Cleans up the now-unused `billingState` and `useAtomStateValue`
imports

## Test plan

- [ ] Verify Providers and Custom Providers sections are visible in
Admin > AI settings on cloud (billing enabled)
- [ ] Verify they remain visible on self-hosted (billing disabled)


Made with [Cursor](https://cursor.com)
This commit is contained in:
Félix Malfait
2026-03-23 10:29:32 +01:00
committed by GitHub
parent 77d4bd9158
commit bb9e3c44a1
@@ -2,28 +2,26 @@ import { useMemo } from 'react';
import { useMutation, useQuery } from '@apollo/client/react';
import { t } from '@lingui/core/macro';
import { Tag } from 'twenty-ui/components';
import { H2Title, IconBolt, IconLock, IconRobot } from 'twenty-ui/display';
import { Card, Section } from 'twenty-ui/layout';
import { Tag } from 'twenty-ui/components';
import { useClientConfig } from '@/client-config/hooks/useClientConfig';
import { billingState } from '@/client-config/states/billingState';
import { AI_PROVIDER_SOURCE } from '@/settings/admin-panel/ai/constants/AiProviderSource';
import { SettingsAdminTabSkeletonLoader } from '@/settings/admin-panel/components/SettingsAdminTabSkeletonLoader';
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
import { Select } from '@/ui/input/components/Select';
import { SettingsAdminAiModelsTable } from '@/settings/admin-panel/ai/components/SettingsAdminAiModelsTable';
import { SettingsAdminAiProviderListCard } from '@/settings/admin-panel/ai/components/SettingsAdminAiProviderListCard';
import { AI_PROVIDER_SOURCE } from '@/settings/admin-panel/ai/constants/AiProviderSource';
import { SET_ADMIN_AI_MODEL_RECOMMENDED } from '@/settings/admin-panel/ai/graphql/mutations/setAdminAiModelRecommended';
import { SET_ADMIN_DEFAULT_AI_MODEL } from '@/settings/admin-panel/ai/graphql/mutations/setAdminDefaultAiModel';
import { GET_ADMIN_AI_MODELS } from '@/settings/admin-panel/ai/graphql/queries/getAdminAiModels';
import { GET_AI_PROVIDERS } from '@/settings/admin-panel/ai/graphql/queries/getAiProviders';
import { type GetAiProvidersResult } from '@/settings/admin-panel/ai/types/GetAiProvidersResult';
import { parseProviderItems } from '@/settings/admin-panel/ai/utils/parseProviderItems';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { SET_ADMIN_AI_MODEL_RECOMMENDED } from '@/settings/admin-panel/ai/graphql/mutations/setAdminAiModelRecommended';
import { SET_ADMIN_DEFAULT_AI_MODEL } from '@/settings/admin-panel/ai/graphql/mutations/setAdminDefaultAiModel';
import { getModelIcon } from '@/settings/admin-panel/ai/utils/getModelIcon';
import { parseProviderItems } from '@/settings/admin-panel/ai/utils/parseProviderItems';
import { SettingsAdminTabSkeletonLoader } from '@/settings/admin-panel/components/SettingsAdminTabSkeletonLoader';
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import {
AiModelRole,
type AdminAiModelConfig,
@@ -31,8 +29,6 @@ import {
export const SettingsAdminAI = () => {
const { enqueueErrorSnackBar } = useSnackBar();
const billing = useAtomStateValue(billingState);
const isBillingEnabled = billing?.isBillingEnabled ?? false;
const { refetch: refetchClientConfig } = useClientConfig();
const { data, loading: isLoadingModels } = useQuery<{
@@ -47,9 +43,7 @@ export const SettingsAdminAI = () => {
const [setDefaultModel] = useMutation(SET_ADMIN_DEFAULT_AI_MODEL);
const { data: providersData, loading: isLoadingProviders } =
useQuery<GetAiProvidersResult>(GET_AI_PROVIDERS, {
skip: isBillingEnabled,
});
useQuery<GetAiProvidersResult>(GET_AI_PROVIDERS);
const models = data?.getAdminAiModels?.models ?? [];
@@ -123,41 +117,37 @@ export const SettingsAdminAI = () => {
return (
<>
{!isBillingEnabled && (
<>
<Section>
<H2Title
title={t`Providers`}
description={t`Built-in providers activated by API key. Click to manage models.`}
/>
<Section>
<H2Title
title={t`Providers`}
description={t`Built-in providers activated by API key. Click to manage models.`}
/>
<SettingsAdminAiProviderListCard
providers={catalogProviders}
showAddButton={false}
/>
</Section>
<SettingsAdminAiProviderListCard
providers={catalogProviders}
showAddButton={false}
/>
</Section>
<Section>
<H2Title
title={t`Custom Providers`}
description={t`Add custom endpoints, private gateways, or additional regions.`}
adornment={
<Tag
text={t`Enterprise`}
color="transparent"
Icon={IconLock}
variant="border"
/>
}
<Section>
<H2Title
title={t`Custom Providers`}
description={t`Add custom endpoints, private gateways, or additional regions.`}
adornment={
<Tag
text={t`Enterprise`}
color="transparent"
Icon={IconLock}
variant="border"
/>
}
/>
<SettingsAdminAiProviderListCard
providers={customProviders}
showAddButton
/>
</Section>
</>
)}
<SettingsAdminAiProviderListCard
providers={customProviders}
showAddButton
/>
</Section>
{availableModelOptions.length > 0 && (
<Section>