mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-18 17:58:23 +00:00
## Summary Shields personal-workspace billing code paths behind the new `consolidated_billing_enabled` feature flag so they fall back to the **legacy** billing flow while the flag is `false`. Team workspaces are unaffected and continue to use the workspace-scoped billing flow. ## Changes - Add `consolidatedBillingEnabled` to `useFeatureFlags` (reads the `consolidated_billing_enabled` server flag / remote config, defaults to `false`) and to the `RemoteConfig` type. - New `useBillingRouting` composable — a single source of truth for whether the active workspace uses the workspace vs. legacy billing flow: - team workspaces disabled → legacy - personal workspace + consolidated billing off/missing → legacy - personal workspace + consolidated billing on → workspace - team workspace → workspace - workspace not loaded yet → legacy - Route `useBillingContext` and the affected UI sites (`SubscriptionPanel`, `useSubscriptionDialog`, `UsageLogsTable`, `TopUpCreditsDialogContentLegacy`) through `useBillingRouting` instead of keying on `teamWorkspacesEnabled` directly. - Update the storybook `useFeatureFlags` mock to stay in sync. ## Testing - `pnpm test:unit` for `useBillingRouting`, `useBillingContext`, `useSubscriptionDialog`, and `UsageLogsTable` (new + updated coverage for the routing matrix). Remaining quality gates (`typecheck`, `lint`) are being verified in CI. ## Related Requires the backend PR that adds the `consolidated_billing_enabled` flag to `/api/features`. --------- Co-authored-by: Amp <amp@ampcode.com>
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
import { useStorage } from '@vueuse/core'
|
|
|
|
import type { ServerFeatureFlag } from '@/composables/useFeatureFlags'
|
|
|
|
/**
|
|
* Remote configuration service
|
|
*
|
|
* Fetches configuration from the server at runtime, enabling:
|
|
* - Feature flags without rebuilding
|
|
* - Server-side feature discovery
|
|
* - Version compatibility management
|
|
* - Avoiding vendor lock-in for native apps
|
|
*
|
|
* This module is tree-shaken in OSS builds.
|
|
*/
|
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
import type { RemoteConfig } from './types'
|
|
|
|
/**
|
|
* Load state for remote configuration.
|
|
* - 'unloaded': No config loaded yet
|
|
* - 'anonymous': Config loaded without auth (bootstrap)
|
|
* - 'authenticated': Config loaded with auth (user-specific flags available)
|
|
* - 'error': Failed to load config
|
|
*/
|
|
type RemoteConfigState = 'unloaded' | 'anonymous' | 'authenticated' | 'error'
|
|
|
|
/**
|
|
* Current load state of remote configuration
|
|
*/
|
|
export const remoteConfigState = ref<RemoteConfigState>('unloaded')
|
|
|
|
/**
|
|
* Whether the authenticated config has been loaded.
|
|
* Use this to gate access to user-specific feature flags like teamWorkspacesEnabled.
|
|
*/
|
|
export const isAuthenticatedConfigLoaded = computed(
|
|
() => remoteConfigState.value === 'authenticated'
|
|
)
|
|
|
|
/**
|
|
* Reactive remote configuration
|
|
* Updated whenever config is loaded from the server
|
|
*/
|
|
export const remoteConfig = ref<RemoteConfig>({})
|
|
|
|
export function configValueOrDefault<K extends keyof RemoteConfig>(
|
|
remoteConfig: RemoteConfig,
|
|
key: K,
|
|
defaultValue: NonNullable<RemoteConfig[K]>
|
|
): NonNullable<RemoteConfig[K]> {
|
|
const configValue = remoteConfig[key]
|
|
return configValue || defaultValue
|
|
}
|
|
|
|
export const cachedTeamWorkspacesEnabled = useStorage<boolean | undefined>(
|
|
'team_workspaces_enabled' satisfies `${ServerFeatureFlag.TEAM_WORKSPACES_ENABLED}`,
|
|
undefined
|
|
)
|
|
|
|
export const cachedConsolidatedBillingEnabled = useStorage<boolean | undefined>(
|
|
'consolidated_billing_enabled' satisfies `${ServerFeatureFlag.CONSOLIDATED_BILLING_ENABLED}`,
|
|
undefined
|
|
)
|