diff --git a/src/composables/useFeatureFlags.ts b/src/composables/useFeatureFlags.ts index de8c859124..b7d54b167d 100644 --- a/src/composables/useFeatureFlags.ts +++ b/src/composables/useFeatureFlags.ts @@ -11,7 +11,8 @@ export enum ServerFeatureFlag { MAX_UPLOAD_SIZE = 'max_upload_size', MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4', MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled', - ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled' + ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled', + PRIVATE_MODELS_ENABLED = 'private_models_enabled' } /** @@ -47,6 +48,13 @@ export function useFeatureFlags() { false ) ) + }, + get privateModelsEnabled() { + // Check remote config first (from /api/features), fall back to websocket feature flags + return ( + remoteConfig.value.private_models_enabled ?? + api.getServerFeature(ServerFeatureFlag.PRIVATE_MODELS_ENABLED, false) + ) } }) diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 515d13f9e3..cc2e62e9ba 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -2121,6 +2121,8 @@ "modelUploaded": "Model imported! 🎉", "findInLibrary": "Find it in the {type} section of the models library.", "finish": "Finish", + "upgradeToUnlockFeature": "Upgrade to unlock this feature", + "upgradeFeatureDescription": "This feature is only available with Creator or Pro plans.", "allModels": "All Models", "allCategory": "All {category}", "unknown": "Unknown", diff --git a/src/platform/assets/components/UploadModelUpgradeModal.vue b/src/platform/assets/components/UploadModelUpgradeModal.vue new file mode 100644 index 0000000000..48010a3bb0 --- /dev/null +++ b/src/platform/assets/components/UploadModelUpgradeModal.vue @@ -0,0 +1,30 @@ + + + diff --git a/src/platform/assets/components/UploadModelUpgradeModalBody.vue b/src/platform/assets/components/UploadModelUpgradeModalBody.vue new file mode 100644 index 0000000000..16d7917a4f --- /dev/null +++ b/src/platform/assets/components/UploadModelUpgradeModalBody.vue @@ -0,0 +1,9 @@ + diff --git a/src/platform/assets/components/UploadModelUpgradeModalFooter.vue b/src/platform/assets/components/UploadModelUpgradeModalFooter.vue new file mode 100644 index 0000000000..8439c16ec0 --- /dev/null +++ b/src/platform/assets/components/UploadModelUpgradeModalFooter.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/platform/assets/components/UploadModelUpgradeModalHeader.vue b/src/platform/assets/components/UploadModelUpgradeModalHeader.vue new file mode 100644 index 0000000000..e09579d824 --- /dev/null +++ b/src/platform/assets/components/UploadModelUpgradeModalHeader.vue @@ -0,0 +1,5 @@ + diff --git a/src/platform/assets/composables/useModelUpload.ts b/src/platform/assets/composables/useModelUpload.ts index e765d5c55d..86372473d4 100644 --- a/src/platform/assets/composables/useModelUpload.ts +++ b/src/platform/assets/composables/useModelUpload.ts @@ -1,6 +1,8 @@ import { useFeatureFlags } from '@/composables/useFeatureFlags' import UploadModelDialog from '@/platform/assets/components/UploadModelDialog.vue' import UploadModelDialogHeader from '@/platform/assets/components/UploadModelDialogHeader.vue' +import UploadModelUpgradeModal from '@/platform/assets/components/UploadModelUpgradeModal.vue' +import UploadModelUpgradeModalHeader from '@/platform/assets/components/UploadModelUpgradeModalHeader.vue' import type { AssetItem } from '@/platform/assets/schemas/assetSchema' import { useDialogStore } from '@/stores/dialogStore' import type { UseAsyncStateReturn } from '@vueuse/core' @@ -14,22 +16,38 @@ export function useModelUpload( const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled) function showUploadDialog() { - dialogStore.showDialog({ - key: 'upload-model', - headerComponent: UploadModelDialogHeader, - component: UploadModelDialog, - props: { - onUploadSuccess: async () => { - await execute?.() + if (!flags.privateModelsEnabled) { + // Show upgrade modal if private models are disabled + dialogStore.showDialog({ + key: 'upload-model-upgrade', + headerComponent: UploadModelUpgradeModalHeader, + component: UploadModelUpgradeModal, + dialogComponentProps: { + pt: { + header: 'py-0! pl-0!', + content: 'p-0!' + } } - }, - dialogComponentProps: { - pt: { - header: 'py-0! pl-0!', - content: 'p-0!' + }) + } else { + // Show regular upload modal + dialogStore.showDialog({ + key: 'upload-model', + headerComponent: UploadModelDialogHeader, + component: UploadModelDialog, + props: { + onUploadSuccess: async () => { + await execute?.() + } + }, + dialogComponentProps: { + pt: { + header: 'py-0! pl-0!', + content: 'p-0!' + } } - } - }) + }) + } } return { isUploadButtonEnabled, showUploadDialog } } diff --git a/src/platform/remoteConfig/types.ts b/src/platform/remoteConfig/types.ts index 8d2c400f37..e5ad9fd335 100644 --- a/src/platform/remoteConfig/types.ts +++ b/src/platform/remoteConfig/types.ts @@ -36,4 +36,5 @@ export type RemoteConfig = { telemetry_disabled_events?: TelemetryEventName[] model_upload_button_enabled?: boolean asset_update_options_enabled?: boolean + private_models_enabled?: boolean }