@@ -10,12 +10,12 @@ import {
1010} from "#/api/queries/groups" ;
1111import { ErrorAlert } from "#/components/Alert/ErrorAlert" ;
1212import { Spinner } from "#/components/Spinner/Spinner" ;
13+ import { useDashboard } from "#/modules/dashboard/useDashboard" ;
1314import { useFeatureVisibility } from "#/modules/dashboard/useFeatureVisibility" ;
1415import { dollarsToMicros , microsToDollars } from "#/utils/currency" ;
1516import type { GroupPageOutletContext } from "./GroupPage" ;
1617import GroupSettingsPageView from "./GroupSettingsPageView" ;
1718
18- // Empty is uncapped (no budget row); otherwise the budget in micros.
1919const budgetFromInput = ( dollars : string ) : number | null =>
2020 dollars . trim ( ) === "" ? null : dollarsToMicros ( dollars ) ;
2121
@@ -29,8 +29,12 @@ const GroupSettingsPage: FC = () => {
2929 const patchGroupMutation = useMutation ( patchGroup ( queryClient , organization ) ) ;
3030 const navigate = useNavigate ( ) ;
3131
32- // Budget routes are gated on aibridge; useFeatureVisibility is {} unlicensed.
33- const aibridgeVisible = Boolean ( useFeatureVisibility ( ) . aibridge ) ;
32+ const { experiments } = useDashboard ( ) ;
33+ // TODO(AIGOV-443): remove the ai-gateway-cost-control experiment gate once
34+ // the cost-control feature is stable.
35+ const aibridgeVisible =
36+ Boolean ( useFeatureVisibility ( ) . aibridge ) &&
37+ experiments . includes ( "ai-gateway-cost-control" ) ;
3438 const budgetQuery = useQuery ( {
3539 ...groupAIBudget ( groupData . id ) ,
3640 enabled : aibridgeVisible ,
@@ -39,7 +43,6 @@ const GroupSettingsPage: FC = () => {
3943 saveGroupAIBudget ( queryClient , groupData . id ) ,
4044 ) ;
4145
42- // Load the budget before rendering so the form initializes with it.
4346 if ( aibridgeVisible && budgetQuery . isLoading ) {
4447 return (
4548 < div className = "flex items-center justify-center p-10" >
@@ -69,20 +72,28 @@ const GroupSettingsPage: FC = () => {
6972 add_users : [ ] ,
7073 remove_users : [ ] ,
7174 } ) ;
72-
73- // Save only when the budget changed (0 disables, empty uncaps).
74- const next = budgetFromInput ( monthly_budget_per_member ) ;
75- if ( aibridgeVisible && next !== currentBudgetMicros ) {
76- await saveBudgetMutation . mutateAsync ( next ) ;
77- }
78-
79- navigate ( `/organizations/${ organization } /groups/${ data . name } ` ) ;
8075 } catch ( error ) {
8176 toast . error (
8277 getErrorMessage ( error , `Failed to update group "${ groupName } ".` ) ,
8378 { description : getErrorDetail ( error ) } ,
8479 ) ;
80+ return ;
8581 }
82+
83+ const next = budgetFromInput ( monthly_budget_per_member ) ;
84+ if ( aibridgeVisible && next !== currentBudgetMicros ) {
85+ try {
86+ await saveBudgetMutation . mutateAsync ( next ) ;
87+ } catch ( error ) {
88+ toast . error (
89+ getErrorMessage ( error , "Failed to update the AI budget." ) ,
90+ { description : getErrorDetail ( error ) } ,
91+ ) ;
92+ return ;
93+ }
94+ }
95+
96+ navigate ( `/organizations/${ organization } /groups/${ data . name } ` ) ;
8697 } }
8798 group = { groupData }
8899 showAISettings = { aibridgeVisible }
0 commit comments