From 60d1856e05515d92cb8ea67fe27ba612d42c2be2 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 23 Jul 2026 19:42:14 +0200 Subject: [PATCH] remove integrations feature preview and old layout --- .../FeaturePreview/FeaturePreviewContext.tsx | 6 - .../FeaturePreview/FeaturePreviewModal.tsx | 1 - .../App/FeaturePreview/useFeaturePreviews.ts | 12 - .../ConstrainedIntegrationTabScaffold.tsx | 5 +- .../Integrations/CronJobs/OverviewTab.tsx | 5 - .../Integrations/DataApi/OverviewTab.tsx | 5 - .../Integrations/GraphQL/OverviewTab.tsx | 7 +- .../MarketplaceIntegrationOverviewTab.tsx | 8 +- .../Integration/RequiredExtensionsSection.tsx | 7 +- .../Landing/useAvailableIntegrations.tsx | 10 +- .../Landing/useIntegrationDetail.ts | 8 +- .../Landing/useIntegrationDetail.utils.ts | 8 +- .../Integrations/Queues/OverviewTab.tsx | 49 +-- .../Integrations/Vault/OverviewTab.tsx | 7 +- .../Integrations/Webhooks/OverviewTab.tsx | 10 +- .../Wrappers/CreateWrapperSheet.tsx | 24 +- .../Integrations/Wrappers/OverviewTab.tsx | 5 - .../StripeSyncEngine/OverviewTab.tsx | 22 +- .../layouts/ProjectIntegrationsLayout.tsx | 8 +- .../ProjectIntegrationsLayoutDispatch.tsx | 8 +- .../integrations/[id]/[pageId]/index.tsx | 6 +- .../project/[ref]/integrations/index.tsx | 312 +----------------- packages/common/constants/local-storage.ts | 2 - 23 files changed, 35 insertions(+), 500 deletions(-) diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index ce32634141e..fcce4010dde 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -134,12 +134,6 @@ export const useIsSqlEditorManualSaveEnabled = () => { return sqlEditorManualSaveEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE] } -export const useIsMarketplaceEnabled = () => { - const { flags } = useFeaturePreviewContext() - const isMarketplaceEnabled = useFlag('marketplaceIntegrations') - return isMarketplaceEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE] -} - export const useFeaturePreviewModal = () => { const featurePreviews = useFeaturePreviews() const [featurePreviewModal, setFeaturePreviewModal] = useQueryState('featurePreviewModal') diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index 5453e536903..ff6056d3a2c 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -50,7 +50,6 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: { [LOCAL_STORAGE_KEYS.UI_PREVIEW_PLATFORM_WEBHOOKS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_JIT_DB_ACCESS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE]: , - [LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE]: , } export const FeaturePreviewModal = () => { diff --git a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts index 65be8e9df45..fa640215f72 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts +++ b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts @@ -22,7 +22,6 @@ export type FeaturePreview = { export const useFeaturePreviews = (): FeaturePreview[] => { const platformWebhooksEnabled = useFlag('platformWebhooks') const jitDbAccessEnabled = useFlag('jitDbAccess') - const isMarketplaceEnabled = useFlag('marketplaceIntegrations') const sqlEditorManualSaveEnabled = useFlag('sqlEditorManualSave') const unifiedLogsDefaultOptIn = useFlag('unifiedLogsDefaultOptIn') @@ -90,16 +89,6 @@ export const useFeaturePreviews = (): FeaturePreview[] => { isDefaultOptIn: false, getRoute: (ref?: string) => `/project/${ref}/database/column-privileges`, }, - { - key: LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE, - name: 'One-Click Integrations', - discussionsUrl: undefined, - enabled: isMarketplaceEnabled, - isNew: true, - isPlatformOnly: false, - isDefaultOptIn: true, - getRoute: (ref?: string) => `/project/${ref}/integrations`, - }, { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE, name: 'Disable snippet auto-saving', @@ -114,7 +103,6 @@ export const useFeaturePreviews = (): FeaturePreview[] => { unifiedLogsDefaultOptIn, platformWebhooksEnabled, jitDbAccessEnabled, - isMarketplaceEnabled, sqlEditorManualSaveEnabled, ] ) diff --git a/apps/studio/components/interfaces/Integrations/ConstrainedIntegrationTabScaffold.tsx b/apps/studio/components/interfaces/Integrations/ConstrainedIntegrationTabScaffold.tsx index bcdacecb969..8be669986b2 100644 --- a/apps/studio/components/interfaces/Integrations/ConstrainedIntegrationTabScaffold.tsx +++ b/apps/studio/components/interfaces/Integrations/ConstrainedIntegrationTabScaffold.tsx @@ -1,8 +1,6 @@ import { PropsWithChildren } from 'react' import { cn } from 'ui' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' - interface ConstrainedIntegrationTabScaffoldProps extends PropsWithChildren { className?: string } @@ -11,9 +9,8 @@ export const ConstrainedIntegrationTabScaffold = ({ children, className, }: ConstrainedIntegrationTabScaffoldProps) => { - const isMarketplace = useIsMarketplaceEnabled() return ( -
+
{children}
) diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/CronJobs/OverviewTab.tsx index 491455185b1..0081d009e93 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/CronJobs/OverviewTab.tsx @@ -1,10 +1,5 @@ import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' -import { RequiredExtensionsSection } from '../Integration/RequiredExtensionsSection' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' export const CronOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return return } diff --git a/apps/studio/components/interfaces/Integrations/DataApi/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/DataApi/OverviewTab.tsx index 54e702b3748..4e928d729eb 100644 --- a/apps/studio/components/interfaces/Integrations/DataApi/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/DataApi/OverviewTab.tsx @@ -1,12 +1,7 @@ import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' import { DataApiURLSettings } from './DataApiURLSettings' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' export const DataApiOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return - return (
diff --git a/apps/studio/components/interfaces/Integrations/GraphQL/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/GraphQL/OverviewTab.tsx index 573b2b59e21..1375aa3d40f 100644 --- a/apps/studio/components/interfaces/Integrations/GraphQL/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/GraphQL/OverviewTab.tsx @@ -1,10 +1,5 @@ -import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' import { RequiredExtensionsSection } from '../Integration/RequiredExtensionsSection' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' export const GraphQLOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return - return + return } diff --git a/apps/studio/components/interfaces/Integrations/Integration/MarketplaceIntegrationOverviewTab.tsx b/apps/studio/components/interfaces/Integrations/Integration/MarketplaceIntegrationOverviewTab.tsx index b6cc6f0aed3..bc14c3b77b3 100644 --- a/apps/studio/components/interfaces/Integrations/Integration/MarketplaceIntegrationOverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Integration/MarketplaceIntegrationOverviewTab.tsx @@ -1,11 +1,5 @@ import type { PropsWithChildren } from 'react' -import { IntegrationOverviewTab } from './IntegrationOverviewTab' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' - export const MarketplaceIntegrationOverviewTab = (props: PropsWithChildren) => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return null - return {props.children} + return null } diff --git a/apps/studio/components/interfaces/Integrations/Integration/RequiredExtensionsSection.tsx b/apps/studio/components/interfaces/Integrations/Integration/RequiredExtensionsSection.tsx index 070985b792c..16a352e8312 100644 --- a/apps/studio/components/interfaces/Integrations/Integration/RequiredExtensionsSection.tsx +++ b/apps/studio/components/interfaces/Integrations/Integration/RequiredExtensionsSection.tsx @@ -1,7 +1,5 @@ import { Badge, Card, CardContent, cn, Separator } from 'ui' -import { useIsMarketplaceEnabled } from '../../App/FeaturePreview/FeaturePreviewContext' -import { MissingExtensionAlert } from './MissingExtensionAlert' import { useIntegrationDetail } from '@/components/interfaces/Integrations/Landing/useIntegrationDetail' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' @@ -21,7 +19,6 @@ export const RequiredExtensionsSection = ({ projectRef: project?.ref, connectionString: project?.connectionString, }) - const isMarketplaceEnabled = useIsMarketplaceEnabled() const requiredExtensions = integration?.requiredExtensions ?? [] @@ -59,10 +56,8 @@ export const RequiredExtensionsSection = ({ {extension ? ( isInstalled ? ( Installed - ) : isMarketplaceEnabled ? ( - Required ) : ( - + Required ) ) : ( Unavailable diff --git a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx index c0817a4b86c..8ea3c654a7c 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx @@ -13,7 +13,6 @@ import { useContext, useMemo } from 'react' import { cn } from 'ui' import { INTEGRATIONS, Loading, type IntegrationDefinition } from './Integrations.constants' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useMarketplaceIntegrationsQuery, type MarketplaceIntegration, @@ -55,16 +54,15 @@ const isPreviewEnabled = (featureFlags: FeatureFlagContextType, listingSlug: str const useMarketplaceListings = () => { const { hasLoaded } = useContext(FeatureFlagContext) - const isMarketplaceEnabled = useIsMarketplaceEnabled() const { data: marketplaceData, error } = useMarketplaceIntegrationsQuery({ - enabled: isMarketplaceEnabled, + enabled: true, }) const isPending = - IS_PLATFORM && (!hasLoaded || (isMarketplaceEnabled && !marketplaceData && !error)) + IS_PLATFORM && (!hasLoaded || (!marketplaceData && !error)) const isSuccess = - !IS_PLATFORM || (hasLoaded && (!isMarketplaceEnabled || (!!marketplaceData && !error))) - const isError = IS_PLATFORM && isMarketplaceEnabled && !!error + !IS_PLATFORM || (hasLoaded && (!!marketplaceData && !error)) + const isError = IS_PLATFORM && !!error // This flag can globally enable preview listings for all partners for a given user (i.e. for Supabase users) const previewAllListingsEnabled = useFlag('previewMarketplaceListingsEnabled') diff --git a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts index 2e5b3da8f54..dafd7a15d0b 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts +++ b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts @@ -11,7 +11,6 @@ import { getInstallActionType, type InstallActionType, } from './useIntegrationDetail.utils' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' @@ -27,7 +26,6 @@ export const useIntegrationDetail = () => { const { ref, id, pageId, childId } = useParams() const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers']) - const isMarketplaceEnabled = useIsMarketplaceEnabled() const { data: project } = useSelectedProjectQuery() const { data: extensions } = useDatabaseExtensionsQuery({ @@ -65,10 +63,9 @@ export const useIntegrationDetail = () => { getFilteredNavItems({ integration, isInstalled, - isMarketplaceEnabled, areRequiredExtensionsInstalled, }), - [integration, isInstalled, isMarketplaceEnabled, areRequiredExtensionsInstalled] + [integration, isInstalled, areRequiredExtensionsInstalled] ) const activeRoute = pageId ?? 'overview' @@ -105,11 +102,10 @@ export const useIntegrationDetail = () => { () => getInstallActionType({ integration, - isMarketplaceEnabled, areRequiredExtensionsInstalled, isInstalled, }), - [integration, isMarketplaceEnabled, areRequiredExtensionsInstalled, isInstalled] + [integration, areRequiredExtensionsInstalled, isInstalled] ) const isReady = !!router?.isReady diff --git a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts index a21552f9ad6..0836cdc6d9b 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts +++ b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts @@ -27,17 +27,15 @@ export function areRequiredExtensionsInstalledFor( export function getFilteredNavItems({ integration, isInstalled, - isMarketplaceEnabled, areRequiredExtensionsInstalled, }: { integration: IntegrationDefinition | undefined isInstalled: boolean - isMarketplaceEnabled: boolean areRequiredExtensionsInstalled: boolean }): Navigation[] { if (!integration?.navigation) return [] if (isInstalled || integration.type !== 'wrapper') return integration.navigation - if (isMarketplaceEnabled || areRequiredExtensionsInstalled) return integration.navigation + if (areRequiredExtensionsInstalled) return integration.navigation return integration.navigation.filter((nav) => nav.route !== 'wrappers') } @@ -46,18 +44,16 @@ export function getFilteredNavItems({ */ export function getInstallActionType({ integration, - isMarketplaceEnabled, areRequiredExtensionsInstalled, isInstalled, }: { integration: IntegrationDefinition | undefined - isMarketplaceEnabled: boolean areRequiredExtensionsInstalled: boolean isInstalled: boolean }): InstallActionType { if (!integration) return null if (integration.type === 'oauth') return 'oauth' - if (integration.type === 'wrapper' && (isMarketplaceEnabled || areRequiredExtensionsInstalled)) { + if (integration.type === 'wrapper' && areRequiredExtensionsInstalled) { return 'add-wrapper' } if (isInstalled) return 'installed' diff --git a/apps/studio/components/interfaces/Integrations/Queues/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/Queues/OverviewTab.tsx index 26fc8374fc8..7fac91eb44f 100644 --- a/apps/studio/components/interfaces/Integrations/Queues/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Queues/OverviewTab.tsx @@ -1,52 +1,5 @@ -import { useParams } from 'common' -import Link from 'next/link' -import { Button } from 'ui' -import { Admonition } from 'ui-patterns/admonition' - -import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' import { RequiredExtensionsSection } from '../Integration/RequiredExtensionsSection' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' -import { useQueuesExposePostgrestStatusQuery } from '@/data/database-queues/database-queues-expose-postgrest-status-query' -import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' - -const QueuesContent = () => { - const { ref } = useParams() - const { data: project } = useSelectedProjectQuery() - const { data: isExposed } = useQueuesExposePostgrestStatusQuery({ - projectRef: project?.ref, - connectionString: project?.connectionString, - }) - - const { data: extensions = [] } = useDatabaseExtensionsQuery({ - projectRef: project?.ref, - connectionString: project?.connectionString, - }) - const isQueuesInstalled = !!extensions.find((x) => x.name === 'pgmq')?.installed_version - - if (isExposed) return null - - return ( - -

- You may choose to toggle the exposure of Queues through Data APIs via the queues settings -

- - {isQueuesInstalled && ( - - )} -
- ) -} export const QueuesOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return - return } /> + return } diff --git a/apps/studio/components/interfaces/Integrations/Vault/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/Vault/OverviewTab.tsx index 120e6f7c16b..cdc711167da 100644 --- a/apps/studio/components/interfaces/Integrations/Vault/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Vault/OverviewTab.tsx @@ -1,10 +1,5 @@ -import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' import { RequiredExtensionsSection } from '../Integration/RequiredExtensionsSection' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' export const VaultOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return - return + return } diff --git a/apps/studio/components/interfaces/Integrations/Webhooks/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/Webhooks/OverviewTab.tsx index 454acf34276..00c66682b05 100644 --- a/apps/studio/components/interfaces/Integrations/Webhooks/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Webhooks/OverviewTab.tsx @@ -4,9 +4,7 @@ import { toast } from 'sonner' import { Admonition } from 'ui-patterns/admonition' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' -import { IntegrationOverviewTab } from '../Integration/IntegrationOverviewTab' import { RequiredExtensionsSection } from '../Integration/RequiredExtensionsSection' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { NoPermission } from '@/components/ui/NoPermission' import { useHooksEnableMutation } from '@/data/database/hooks-enable-mutation' @@ -89,11 +87,5 @@ const WebhooksContent = () => { } export const WebhooksOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) { - return - } - - return } /> + return } diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx index d231545c009..87c2a39f88d 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx @@ -32,7 +32,6 @@ import { NewTable, } from './Wrappers.utils' import WrapperTableEditor from './WrapperTableEditor' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { getExtensionDefaultSchema } from '@/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/IntegrationOverviewTabV2.utils' import { RequiredExtensionsSection } from '@/components/interfaces/Integrations/Integration/RequiredExtensionsSection' import { useIntegrationDetail } from '@/components/interfaces/Integrations/Landing/useIntegrationDetail' @@ -66,7 +65,6 @@ export const CreateWrapperSheet = ({ onCloseWithConfirmation, }: CreateWrapperSheetProps) => { const queryClient = useQueryClient() - const isMarketplaceEnabled = useIsMarketplaceEnabled() const { integration } = useIntegrationDetail() const { data: project } = useSelectedProjectQuery() @@ -261,18 +259,16 @@ export const CreateWrapperSheet = ({ Create a {wrapperMeta.label} wrapper
- {isMarketplaceEnabled && ( -
- {needsExtensions && ( - - )} - -
- )} +
+ {needsExtensions && ( + + )} + +
Wrapper Configuration}> { } export const WrapperOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) return - return ( }>
diff --git a/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/OverviewTab.tsx b/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/OverviewTab.tsx index e05b84a39ea..dab27d1ac6b 100644 --- a/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/OverviewTab.tsx +++ b/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/OverviewTab.tsx @@ -23,7 +23,6 @@ import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import * as z from 'zod' -import { IntegrationOverviewTab } from '../../Integration/IntegrationOverviewTab' import { RequiredExtensionsSection } from '../../Integration/RequiredExtensionsSection' import { InstallationError } from './InstallationError' import { IntegrationInstalledActions, IntegrationNotInstalledActions } from './IntegrationActions' @@ -38,7 +37,6 @@ import { isUninstalling, } from './stripe-sync-status' import { StripeSyncChangesCard } from './StripeSyncChangesCard' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useStripeSyncStatus } from '@/components/interfaces/Integrations/templates/StripeSyncEngine/useStripeSyncStatus' import { useStripeSyncInstallMutation } from '@/data/database-integrations/stripe/stripe-sync-install-mutation' import { useStripeSyncUninstallMutation } from '@/data/database-integrations/stripe/stripe-sync-uninstall-mutation' @@ -392,22 +390,10 @@ const StripeSyncContent = ({ hideInstallCTA = false }: { hideInstallCTA?: boolea } export const StripeSyncEngineOverviewTab = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - - if (isMarketplaceEnabled) { - return ( - <> - - - - ) - } - return ( - -
- -
-
+ <> + + + ) } diff --git a/apps/studio/components/layouts/ProjectIntegrationsLayout.tsx b/apps/studio/components/layouts/ProjectIntegrationsLayout.tsx index 51ca726cb0b..00222d51dde 100644 --- a/apps/studio/components/layouts/ProjectIntegrationsLayout.tsx +++ b/apps/studio/components/layouts/ProjectIntegrationsLayout.tsx @@ -4,7 +4,6 @@ import { PropsWithChildren } from 'react' import { Menu, Separator } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useInstalledIntegrations } from '@/components/interfaces/Integrations/Landing/useInstalledIntegrations' import { ProjectLayout } from '@/components/layouts/ProjectLayout' import { AlertError } from '@/components/ui/AlertError' @@ -46,7 +45,6 @@ const IntegrationCategoriesMenu = ({ page }: { page: string }) => { const router = useRouter() const { ref } = useParams() const { hasLoaded: flagsLoaded } = useFeatureFlags() - const isMarketplaceEnabled = useIsMarketplaceEnabled() const urlParams = new URLSearchParams(router.asPath.split('?')[1] || '') const categoryParam = urlParams.get('category') @@ -54,10 +52,10 @@ const IntegrationCategoriesMenu = ({ page }: { page: string }) => { const { integrationsWrappers: showWrappers } = useIsFeatureEnabled(['integrations:wrappers']) const { data: categories = [], isPending: isPendingCategories } = useMarketplaceCategoriesQuery({ - enabled: isMarketplaceEnabled, + enabled: true, }) const { data: listings = [], isPending: isPendingListings } = useMarketplaceIntegrationsQuery({ - enabled: isMarketplaceEnabled, + enabled: true, }) const populatedCategoryIds = new Set( @@ -68,7 +66,7 @@ const IntegrationCategoriesMenu = ({ page }: { page: string }) => { ) const isLoading = IS_PLATFORM - ? !flagsLoaded || (isMarketplaceEnabled && (isPendingCategories || isPendingListings)) + ? !flagsLoaded || (isPendingCategories || isPendingListings) : false const allCategories = [ diff --git a/apps/studio/components/layouts/ProjectIntegrationsLayoutDispatch.tsx b/apps/studio/components/layouts/ProjectIntegrationsLayoutDispatch.tsx index 31cd36043a5..ce3cb3103f1 100644 --- a/apps/studio/components/layouts/ProjectIntegrationsLayoutDispatch.tsx +++ b/apps/studio/components/layouts/ProjectIntegrationsLayoutDispatch.tsx @@ -1,13 +1,7 @@ import type { PropsWithChildren } from 'react' -import { ProjectIntegrationsLayout } from './ProjectIntegrationsLayout' import { ProjectMarketplaceLayout } from './ProjectMarketplaceLayout' -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' export const ProjectIntegrationsLayoutDispatch = ({ children }: PropsWithChildren) => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - if (isMarketplaceEnabled) { - return {children} - } - return {children} + return {children} } diff --git a/apps/studio/pages/project/[ref]/integrations/[id]/[pageId]/index.tsx b/apps/studio/pages/project/[ref]/integrations/[id]/[pageId]/index.tsx index 6f2e09f5412..14c1662d9db 100644 --- a/apps/studio/pages/project/[ref]/integrations/[id]/[pageId]/index.tsx +++ b/apps/studio/pages/project/[ref]/integrations/[id]/[pageId]/index.tsx @@ -1,14 +1,10 @@ -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import LegacyIntegrationPage from '@/components/interfaces/Integrations/Integration/LegacyIntegrationPage' import { MarketplaceDetail } from '@/components/interfaces/Integrations/Marketplace/MarketplaceDetail' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { ProjectIntegrationsLayoutDispatch } from '@/components/layouts/ProjectIntegrationsLayoutDispatch' import type { NextPageWithLayout } from '@/types' const IntegrationPage: NextPageWithLayout = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - if (isMarketplaceEnabled) return - return + return } IntegrationPage.getLayout = (page) => ( diff --git a/apps/studio/pages/project/[ref]/integrations/index.tsx b/apps/studio/pages/project/[ref]/integrations/index.tsx index b8c4ddbb007..b6dff89ba87 100644 --- a/apps/studio/pages/project/[ref]/integrations/index.tsx +++ b/apps/studio/pages/project/[ref]/integrations/index.tsx @@ -1,320 +1,10 @@ -import { IS_PLATFORM, useFeatureFlags } from 'common' -import { Database } from 'common/marketplace.types' -import { Search } from 'lucide-react' -import { useRouter } from 'next/router' -import { parseAsString, useQueryState } from 'nuqs' -import { useMemo, type ReactNode } from 'react' -import { Input } from 'ui-patterns/DataInputs/Input' -import { PageContainer } from 'ui-patterns/PageContainer' -import { - PageHeader, - PageHeaderAside, - PageHeaderDescription, - PageHeaderMeta, - PageHeaderSummary, - PageHeaderTitle, -} from 'ui-patterns/PageHeader' -import { PageSection, PageSectionContent, PageSectionMeta } from 'ui-patterns/PageSection' -import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' - -import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import { - IntegrationCard, - IntegrationLoadingCard, -} from '@/components/interfaces/Integrations/Landing/IntegrationCard' -import { IntegrationDefinition } from '@/components/interfaces/Integrations/Landing/Integrations.constants' -import { useAvailableIntegrations } from '@/components/interfaces/Integrations/Landing/useAvailableIntegrations' -import { useInstalledIntegrations } from '@/components/interfaces/Integrations/Landing/useInstalledIntegrations' -import { useIntegrationFilteringAndSort } from '@/components/interfaces/Integrations/Landing/useIntegrationFilteringAndSort' import { MarketplaceIndex } from '@/components/interfaces/Integrations/Marketplace/MarketplaceIndex' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { ProjectIntegrationsLayoutDispatch } from '@/components/layouts/ProjectIntegrationsLayoutDispatch' -import { AlertError } from '@/components/ui/AlertError' -import { DocsButton } from '@/components/ui/DocsButton' -import { NoSearchResults } from '@/components/ui/NoSearchResults' -import { useMarketplaceCategoriesQuery } from '@/data/marketplace/integration-categories-query' -import { BASE_PATH, DOCS_URL } from '@/lib/constants' import type { NextPageWithLayout } from '@/types' -const FEATURED_INTEGRATIONS = ['cron', 'queues', 'stripe_sync_engine'] - -// Featured integration images -const FEATURED_INTEGRATION_IMAGES: Record = { - cron: `${BASE_PATH}/img/integrations/covers/cron-cover.webp`, - queues: `${BASE_PATH}/img/integrations/covers/queues-cover.png`, - stripe_wrapper: `${BASE_PATH}/img/integrations/covers/stripe-cover.png`, - stripe_sync_engine: `${BASE_PATH}/img/integrations/covers/stripe-cover.png`, -} - -function getIntegrationImage(integration: IntegrationDefinition) { - let featured_image = FEATURED_INTEGRATION_IMAGES[integration.id] - if (featured_image) { - return featured_image - } - - if (integration.files?.length) { - const heroImage = integration?.files?.[0] - return heroImage?.src ?? undefined - } -} - -type PageContent = { - title: string - subtitle: string - secondaryActions?: ReactNode -} - -const DEFAULT_PAGE_CONTENT: PageContent = { - title: 'Extend your database', - subtitle: - 'Extensions and wrappers that add functionality to your database and connect to external services.', -} - -const CATEGORY_PAGE_CONTENT = { - wrapper: { - title: 'Wrappers', - subtitle: - 'Connect to external data sources and services by querying APIs, databases, and files as if they were Postgres tables.', - secondaryActions: ( - - ), - }, - postgres_extension: { - title: 'Postgres Modules', - subtitle: 'Extend your database with powerful Postgres extensions.', - }, -} satisfies Record - -// Converts a category string to title -// Example: some_catory -> Some Category -function formatCategoryTitle(category: string) { - return category - .split(/[-_]/) - .filter(Boolean) - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(' ') -} - -const PageHeaderContentSkeleton = () => ( -
- - -
-) - -// Returns selected category to filter by -function useFilterCategory() { - const router = useRouter() - const [selectedCategory] = useQueryState( - 'category', - parseAsString.withDefault('all').withOptions({ clearOnDefault: true }) - ) - const categoryFromUrl = useMemo(() => { - const queryString = router.asPath.split('?')[1] - if (!queryString) return null - - return new URLSearchParams(queryString).get('category') - }, [router.asPath]) - const resolvedSelectedCategory = router.isReady - ? (categoryFromUrl ?? selectedCategory) - : undefined - const filterCategory = resolvedSelectedCategory ?? 'all' - return filterCategory -} - -// Dynamic page content based on selected category -function usePageContent( - integrationFilterCategory: string, - categories: Database['public']['Views']['categories']['Row'][] -) { - const pageContent = useMemo(() => { - if (integrationFilterCategory === 'all') { - return DEFAULT_PAGE_CONTENT - } - - if (integrationFilterCategory in CATEGORY_PAGE_CONTENT) { - return CATEGORY_PAGE_CONTENT[integrationFilterCategory as keyof typeof CATEGORY_PAGE_CONTENT] - } - - const selectedMarketplaceCategory = categories.find( - (category) => category.slug === integrationFilterCategory - ) - - return { - title: selectedMarketplaceCategory?.name ?? formatCategoryTitle(integrationFilterCategory), - subtitle: selectedMarketplaceCategory?.description ?? DEFAULT_PAGE_CONTENT.subtitle, - } - }, [categories, integrationFilterCategory]) - return pageContent -} - const IntegrationsPage: NextPageWithLayout = () => { - const isMarketplaceEnabled = useIsMarketplaceEnabled() - if (isMarketplaceEnabled) return - return -} - -const LegacyIntegrationsPage = () => { - const { hasLoaded: flagsLoaded } = useFeatureFlags() - const isMarketplaceEnabled = useIsMarketplaceEnabled() - const [search, setSearch] = useQueryState( - 'search', - parseAsString.withDefault('').withOptions({ clearOnDefault: true }) - ) - - const { - data: availableIntegrations, - error, - isPending: isLoadingAvailableIntegrations, - isError, - isSuccess: isSuccessAvailableIntegrations, - } = useAvailableIntegrations() - - const { - installedIntegrations, - isLoading: isLoadingInstalledIntegrations, - isSuccess: isSuccessInstalledIntegrations, - } = useInstalledIntegrations() - - const installedIds = installedIntegrations.map((i) => i.id) - const isLoading = isLoadingAvailableIntegrations || isLoadingInstalledIntegrations - const isSuccess = isSuccessAvailableIntegrations && isSuccessInstalledIntegrations - - const selectedCategory = useFilterCategory() - - const { data: categories = [], isPending: isPendingCategories } = useMarketplaceCategoriesQuery({ - enabled: isMarketplaceEnabled, - }) - - const isLoadingSelectedCategory = - selectedCategory !== 'all' && - !(selectedCategory in CATEGORY_PAGE_CONTENT) && - (IS_PLATFORM ? !flagsLoaded || (isMarketplaceEnabled && isPendingCategories) : false) - - const pageContent = usePageContent(selectedCategory, categories) - - const filteredIntegrations = useMemo(() => { - let filtered = availableIntegrations ?? [] - - if (selectedCategory !== 'all') { - filtered = filtered.filter( - (i) => i.type === selectedCategory || i.categories?.includes(selectedCategory) - ) - } - - if (search.length > 0) { - filtered = filtered.filter((i) => i.name.toLowerCase().includes(search.toLowerCase())) - } - - return filtered - }, [availableIntegrations, selectedCategory, search]) - - const hasActiveFilter = selectedCategory !== 'all' || search.length > 0 - - const { sorted: filteredAndSortedIntegrations, featured: featuredIntegrations } = - useIntegrationFilteringAndSort(filteredIntegrations, availableIntegrations, installedIds, { - featuredIds: FEATURED_INTEGRATIONS, - hasActiveFilter, - includeFeaturedFlag: true, - }) - - return ( - <> - - - - {isLoadingSelectedCategory ? ( - - ) : ( - <> - {pageContent.title} - {pageContent.subtitle} - - )} - - {pageContent.secondaryActions && ( - {pageContent.secondaryActions} - )} - - - - - - - setSearch(e.target.value)} - placeholder="Search integrations..." - icon={} - className="w-52" - /> - - - - {isLoading && ( -
- {Array.from({ length: 8 }).map((_, idx) => ( - - ))} -
- )} - - {/* Error State */} - {isError && ( - - )} - - {/* Success State */} - {isSuccess && ( - <> - {/* No Search Results */} - {search.length > 0 && filteredAndSortedIntegrations.length === 0 && ( - setSearch('')} /> - )} - - {/* Featured Integrations */} - {featuredIntegrations && featuredIntegrations.length > 0 && ( -
- {featuredIntegrations.map((integration) => ( - - ))} -
- )} - - {/* All Filtered and Sorted Integrations */} - {filteredAndSortedIntegrations.length > 0 && ( -
- {filteredAndSortedIntegrations.map((integration) => ( - - ))} -
- )} - - )} -
-
-
- - ) + return } IntegrationsPage.getLayout = (page) => ( diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts index 6b74bf66803..9a96b713c27 100644 --- a/packages/common/constants/local-storage.ts +++ b/packages/common/constants/local-storage.ts @@ -26,7 +26,6 @@ export const LOCAL_STORAGE_KEYS = { UI_PREVIEW_PLATFORM_WEBHOOKS: 'supabase-ui-platform-webhooks', UI_PREVIEW_JIT_DB_ACCESS: 'supabase-ui-jit-db-access', UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE: 'supabase-ui-sql-editor-manual-save', - UI_PREVIEW_MARKETPLACE: 'supabase-ui-marketplace', AI_ASSISTANT_MCP_OPT_IN: 'ai-assistant-mcp-opt-in', SIGN_IN_CHATGPT_ENABLED: 'siwc-enabled', @@ -155,7 +154,6 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [ LOCAL_STORAGE_KEYS.UI_PREVIEW_PLATFORM_WEBHOOKS, LOCAL_STORAGE_KEYS.UI_PREVIEW_JIT_DB_ACCESS, LOCAL_STORAGE_KEYS.UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE, - LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE, LOCAL_STORAGE_KEYS.LAST_SIGN_IN_METHOD, LOCAL_STORAGE_KEYS.HIDE_PROMO_TOAST, LOCAL_STORAGE_KEYS.BLOG_VIEW,