@@ -126,7 +126,7 @@ interface AntigravityQuotaGroupDefinition {
}
const ANTIGRAVITY_QUOTA_URLS = [
'https://cloudcode-pa-pa.sandbox .googleapis.com/v1internal:fetchAvailableModels' ,
'https://daily- cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels' ,
'https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:fetchAvailableModels' ,
'https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels'
] ;
@@ -171,6 +171,8 @@ const ANTIGRAVITY_QUOTA_GROUPS: AntigravityQuotaGroupDefinition[] = [
labelFromModel : true
}
] ;
// 标准化 auth_index 值(与 usage.ts 中的 normalizeAuthIndex 保持一致)
function normalizeAuthIndexValue ( value : unknown ) : string | null {
@@ -393,6 +395,7 @@ export function AuthFilesPage() {
const [ page , setPage ] = useState ( 1 ) ;
const [ pageSize , setPageSize ] = useState ( 9 ) ;
const [ antigravityPage , setAntigravityPage ] = useState ( 1 ) ;
const [ antigravityPageSize , setAntigravityPageSize ] = useState ( 6 ) ;
const [ uploading , setUploading ] = useState ( false ) ;
const [ deleting , setDeleting ] = useState < string | null > ( null ) ;
const [ deletingAll , setDeletingAll ] = useState ( false ) ;
@@ -402,6 +405,9 @@ export function AuthFilesPage() {
{ }
) ;
const [ antigravityLoading , setAntigravityLoading ] = useState ( false ) ;
const [ antigravityLoadingScope , setAntigravityLoadingScope ] = useState <
'page' | 'all' | null
> ( null ) ;
// 详情弹窗相关
const [ detailModalOpen , setDetailModalOpen ] = useState ( false ) ;
@@ -508,7 +514,6 @@ export function AuthFilesPage() {
[ files ]
) ;
const antigravityPageSize = 6 ;
const antigravityTotalPages = Math . max (
1 ,
Math . ceil ( antigravityFiles . length / antigravityPageSize )
@@ -569,71 +574,77 @@ export function AuthFilesPage() {
[ t ]
) ;
const loadAntigravityQuota = useCallback ( async ( ) = > {
if ( antigravityLoadingRef . current ) return ;
antigravityLoadingRef . current = true ;
const requestId = ++ antigravityRequestId Ref . current ;
setAntigravityLoading ( true ) ;
const loadAntigravityQuota = useCallback (
async ( targets : AuthFileItem [ ] , scope : 'page' | 'all' ) = > {
if ( antigravityLoadingRef . current ) return ;
antigravityLoading Ref . current = true ;
const requestId = ++ antigravityRequestIdRef . current ;
setAntigravityLoading ( true ) ;
setAntigravityLoadingScope ( scope ) ;
try {
if ( antigravityFile s. length === 0 ) {
setAntigravityQuota ( { } ) ;
return ;
}
try {
if ( target s. length === 0 ) return ;
const loadingState : Record < string , AntigravityQuotaState > = { } ;
antigravityFiles . forEach ( ( file ) = > {
loadingState [ file . name ] = { status : 'loading' , groups : [ ] } ;
}) ;
setAntigravityQuota ( loadingState ) ;
set AntigravityQuota ( ( prev ) = > {
const nextState = { . . . prev } ;
targets . forEach ( ( file ) = > {
nextState [ file . name ] = { status : 'loading' , groups : [ ] } ;
} ) ;
return nextState ;
} ) ;
const results = await Promise . all (
antigravityFile s. map ( async ( file ) = > {
const rawAuthIndex = file [ 'auth_index' ] ? ? file . authIndex ;
const authIndex = normalizeAuthIndexValue ( rawAuthIndex ) ;
if ( ! authIndex ) {
return {
name : file.name ,
status : 'error' as const ,
error : t ( 'antigravity_quota.missing_auth_index' )
} ;
}
const results = await Promise . all (
target s . map ( async ( file ) = > {
const rawAuthIndex = file [ 'auth_index' ] ? ? file . authIndex ;
const authIndex = normalizeAuthIndexValue ( rawAuthIndex ) ;
if ( ! authIndex ) {
return {
name : file.name ,
status : 'error' as const ,
error : t ( 'antigravity_quota.missing_auth_index' )
} ;
}
try {
const groups = await fetchAntigravityQuota ( authIndex ) ;
return { name : file.name , status : 'success' as const , groups } ;
} catch ( err : unknown ) {
const message = err instanceof Error ? err.message : t ( 'common.unknown_error' ) ;
return { name : file.name , status : 'error' as const , error : message } ;
}
} )
) ;
try {
const groups = await fetchAntigravityQuota ( authIndex ) ;
return { name : file.name , status : 'success' as const , groups } ;
} catch ( err : unknown ) {
const message = err instanceof Error ? err.message : t ( 'common.unknown_error' ) ;
return { name : file.name , status : 'error' as const , error : message } ;
}
} )
) ;
if ( requestId !== antigravityRequestIdRef . current ) return ;
if ( requestId !== antigravityRequestIdRef . current ) return ;
const nextState : Record < string , AntigravityQuotaState > = { } ;
results . forEach ( ( result ) = > {
if ( result . status === 'success' ) {
nextState [ result . name ] = {
status : 'success' ,
groups : result.groups
} ;
} else {
nextState [ result . name ] = {
status : 'error' ,
groups : [ ] ,
error : result.error
} ;
set AntigravityQuota ( ( prev ) = > {
const nextState = { . . . p rev } ;
results . forEach ( ( result ) = > {
if ( result . status === 'success' ) {
nextState [ result . name ] = {
status : 'success' ,
groups : result.groups
} ;
} else {
nextState [ result . name ] = {
status : 'error' ,
groups : [ ] ,
error : result.error
} ;
}
} ) ;
return nextState ;
} ) ;
} finally {
if ( requestId === antigravityRequestIdRef . current ) {
setAntigravityLoading ( false ) ;
setAntigravityLoadingScope ( null ) ;
antigravityLoadingRef . current = false ;
}
} ) ;
setAntigravityQuota ( nextState ) ;
} finally {
if ( requestId === antigravityRequestIdRef . current ) {
setAntigravityLoading ( false ) ;
antigravityLoadingRef . current = false ;
}
}
} , [ antigravityFiles , fetchAntigravityQuota , t ] ) ;
} ,
[ fetchAntigravityQuota , t ]
) ;
useEffect ( ( ) = > {
loadFiles ( ) ;
@@ -646,15 +657,20 @@ export function AuthFilesPage() {
setAntigravityQuota ( { } ) ;
return ;
}
load AntigravityQuota( ) ;
} , [ antigravityFiles , loadAntigravityQuota ] ) ;
set AntigravityQuota( ( prev ) = > {
const nextState : Record < string , AntigravityQuotaState > = { } ;
antigravityFiles . forEach ( ( file ) = > {
const cached = prev [ file . name ] ;
if ( cached ) {
nextState [ file . name ] = cached ;
}
} ) ;
return nextState ;
} ) ;
} , [ antigravityFiles ] ) ;
// 定时刷新状态数据( 每240秒)
useInterval ( loadKeyStats , 240 _000 ) ;
useInterval ( ( ) = > {
if ( antigravityFiles . length === 0 ) return ;
loadAntigravityQuota ( ) ;
} , 240 _000 ) ;
// 提取所有存在的类型
const existingTypes = useMemo ( ( ) = > {
@@ -1211,8 +1227,10 @@ export function AuthFilesPage() {
< / div >
< div className = { styles . quotaSection } >
{ quotaStatus === 'loading' || quotaStatus === 'idle' ? (
{ quotaStatus === 'loading' ? (
< div className = { styles . quotaMessage } > { t ( 'antigravity_quota.loading' ) } < / div >
) : quotaStatus === 'idle' ? (
< div className = { styles . quotaMessage } > { t ( 'antigravity_quota.idle' ) } < / div >
) : quotaStatus === 'error' ? (
< div className = { styles . quotaError } >
{ t ( 'antigravity_quota.load_failed' , {
@@ -1383,15 +1401,26 @@ export function AuthFilesPage() {
< Card
title = { t ( 'antigravity_quota.title' ) }
extra = {
< Button
variant = "secondary"
size = "sm "
onClick = { loadAntigravityQuota }
disabled = { disableControls || antigravityLoading || antigravityFiles . length === 0 }
loading = { antigravityLoading }
>
{ t ( 'common.refresh' ) }
< / B utton>
< div className = { styles . headerActions } >
< Button
variant = "secondary "
size = "sm"
onClick = { ( ) = > loadAntigravityQuota ( antigravityPageItems , 'page' ) }
disabled = { disableControls || antigravityLoading || antigravityPageItems . length === 0 }
loading = { antigravityLoading && antigravityLoadingScope === 'page' }
>
{ t ( 'antigravity_quota.refresh_b utton' ) }
< / Button >
< Button
variant = "secondary"
size = "sm"
onClick = { ( ) = > loadAntigravityQuota ( antigravityFiles , 'all' ) }
disabled = { disableControls || antigravityLoading || antigravityFiles . length === 0 }
loading = { antigravityLoading && antigravityLoadingScope === 'all' }
>
{ t ( 'antigravity_quota.fetch_all' ) }
< / Button >
< / div >
}
>
{ antigravityFiles . length === 0 ? (
@@ -1401,6 +1430,31 @@ export function AuthFilesPage() {
/ >
) : (
< >
< div className = { styles . antigravityControls } >
< div className = { styles . antigravityControl } >
< label > { t ( 'auth_files.page_size_label' ) } < / label >
< select
className = { styles . pageSizeSelect }
value = { antigravityPageSize }
onChange = { ( e ) = > {
setAntigravityPageSize ( Number ( e . target . value ) || 6 ) ;
setAntigravityPage ( 1 ) ;
} }
>
< option value = { 6 } > 6 < / option >
< option value = { 9 } > 9 < / option >
< option value = { 12 } > 12 < / option >
< option value = { 18 } > 18 < / option >
< option value = { 24 } > 24 < / option >
< / select >
< / div >
< div className = { styles . antigravityControl } >
< label > { t ( 'common.info' ) } < / label >
< div className = { styles . statsInfo } >
{ antigravityFiles . length } { t ( 'auth_files.files_count' ) }
< / div >
< / div >
< / div >
< div className = { styles . antigravityGrid } >
{ antigravityPageItems . map ( renderAntigravityCard ) }
< / div >