diff --git a/packages/main/src/plugin/extension/catalog/extensions-catalog-settings.ts b/packages/main/src/plugin/extension/catalog/extensions-catalog-settings.ts index fcdd767b869..c9bdb537d32 100644 --- a/packages/main/src/plugin/extension/catalog/extensions-catalog-settings.ts +++ b/packages/main/src/plugin/extension/catalog/extensions-catalog-settings.ts @@ -19,4 +19,5 @@ export enum ExtensionsCatalogSettings { SectionName = 'extensions', registryUrl = 'registryUrl', + catalogEnabled = 'catalog.enabled', } diff --git a/packages/main/src/plugin/extension/catalog/extensions-catalog.spec.ts b/packages/main/src/plugin/extension/catalog/extensions-catalog.spec.ts index d1e987ebad6..7fa9593cd44 100644 --- a/packages/main/src/plugin/extension/catalog/extensions-catalog.spec.ts +++ b/packages/main/src/plugin/extension/catalog/extensions-catalog.spec.ts @@ -400,7 +400,7 @@ test('Should use proxy object if proxySettings is undefined', () => { expect(options.agent?.https?.proxy.href).toBe('https://localhost/'); }); -test('should register local extensions enabled configuration property', () => { +test('should register local extensions and catalog enabled configuration properties', () => { extensionsCatalog.init(); expect(configurationRegistry.registerConfigurations).toHaveBeenCalledWith([ @@ -415,6 +415,12 @@ test('should register local extensions enabled configuration property', () => { default: true, hidden: true, }, + 'extensions.catalog.enabled': { + description: 'Show the extension catalog in the UI. When disabled, hides the catalog suggestions.', + type: 'boolean', + default: true, + hidden: true, + }, }), }), ]); diff --git a/packages/main/src/plugin/extension/catalog/extensions-catalog.ts b/packages/main/src/plugin/extension/catalog/extensions-catalog.ts index 627490c6574..a9e17bab962 100644 --- a/packages/main/src/plugin/extension/catalog/extensions-catalog.ts +++ b/packages/main/src/plugin/extension/catalog/extensions-catalog.ts @@ -75,6 +75,12 @@ export class ExtensionsCatalog { default: true, hidden: true, }, + [ExtensionsCatalogSettings.SectionName + '.' + ExtensionsCatalogSettings.catalogEnabled]: { + description: 'Show the extension catalog in the UI. When disabled, hides the catalog suggestions.', + type: 'boolean', + default: true, + hidden: true, + }, }, }; diff --git a/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.spec.ts b/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.spec.ts index 1e37cbc6a4a..8dd84d624e0 100644 --- a/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.spec.ts +++ b/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.spec.ts @@ -34,6 +34,8 @@ beforeAll(() => { beforeEach(() => { vi.resetAllMocks(); + // default to catalog enabled + vi.mocked(window.getConfigurationValue).mockResolvedValue(true); }); const aFakeExtension: CatalogExtension = { @@ -218,3 +220,29 @@ test('empty catalog, hide if empty', async () => { const emptyMsg = screen.queryByText('No extensions in the catalog'); expect(emptyMsg).not.toBeInTheDocument(); }); + +test('render nothing when catalog is disabled', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(false); + catalogExtensionInfos.set([aFakeExtension, bFakeExtension]); + extensionInfos.set(combined); + + render(EmbeddableCatalogExtensionList, {}); + + await vi.waitFor(() => { + expect(screen.queryByText('Available extensions')).not.toBeInTheDocument(); + expect(screen.queryByRole('group', { name: 'A Extension' })).not.toBeInTheDocument(); + expect(screen.queryByRole('group', { name: 'B Extension' })).not.toBeInTheDocument(); + }); +}); + +test('render extensions when catalog is enabled', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(true); + catalogExtensionInfos.set([aFakeExtension, bFakeExtension]); + extensionInfos.set(combined); + + render(EmbeddableCatalogExtensionList, {}); + + await vi.waitFor(() => { + expect(screen.queryByText('Available extensions')).toBeInTheDocument(); + }); +}); diff --git a/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.svelte b/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.svelte index 199f0b63572..3c882ea2d55 100644 --- a/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.svelte +++ b/packages/renderer/src/lib/extensions/EmbeddableCatalogExtensionList.svelte @@ -1,4 +1,5 @@ +{#if enableCatalog}
= derived( showEmptyScreen={showEmptyScreen} catalogExtensions={$catalogExtensions} />
+{/if} diff --git a/packages/renderer/src/lib/extensions/ExtensionList.spec.ts b/packages/renderer/src/lib/extensions/ExtensionList.spec.ts index f16b110cd61..aa3174e0be1 100644 --- a/packages/renderer/src/lib/extensions/ExtensionList.spec.ts +++ b/packages/renderer/src/lib/extensions/ExtensionList.spec.ts @@ -239,8 +239,8 @@ test('Search catalog page searches also description', async () => { test('Expect to see local extensions tab content', async () => { vi.mocked(window.getConfigurationValue).mockImplementation(async (key: string) => { - // Return true for local extensions enabled, false for development mode to show empty screen - return key === 'extensions.localExtensions.enabled'; + // Return true for local extensions and catalog enabled + return key === 'extensions.localExtensions.enabled' || key === 'extensions.catalog.enabled'; }); catalogExtensionInfos.set([]); extensionInfos.set([]); @@ -330,3 +330,28 @@ test('Expect local extensions tab to not be visible if extensions.localExtension const localExtensionsTab = screen.queryByRole('button', { name: 'Local Extensions' }); expect(localExtensionsTab).not.toBeInTheDocument(); }); + +test('Expect catalog tab is visible', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(undefined); + catalogExtensionInfos.set([]); + extensionInfos.set([]); + + render(ExtensionList); + + await vi.waitFor(() => { + const catalogTab = screen.getByRole('button', { name: 'Catalog' }); + expect(catalogTab).toBeInTheDocument(); + }); +}); + +test('Expect catalog tab to not be visible if extensions.catalog.enabled is false', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(false); + catalogExtensionInfos.set([]); + extensionInfos.set([]); + + render(ExtensionList); + + await vi.waitFor(() => { + expect(screen.queryByRole('button', { name: 'Catalog' })).not.toBeInTheDocument(); + }); +}); diff --git a/packages/renderer/src/lib/extensions/ExtensionList.svelte b/packages/renderer/src/lib/extensions/ExtensionList.svelte index 5adcd6b838c..33a67b3cff9 100644 --- a/packages/renderer/src/lib/extensions/ExtensionList.svelte +++ b/packages/renderer/src/lib/extensions/ExtensionList.svelte @@ -32,6 +32,8 @@ let enableLocalExtensions = $derived( (await window.getConfigurationValue('extensions.localExtensions.enabled')) ?? true, ); +let enableCatalog = $derived((await window.getConfigurationValue('extensions.catalog.enabled')) ?? true); + const filteredInstalledExtensions: CombinedExtensionInfoUI[] = $derived( extensionsUtils.filterInstalledExtensions($combinedInstalledExtensions, searchTerm), ); @@ -102,12 +104,14 @@ function changeScreen(newScreen: 'installed' | 'catalog' | 'development'): void changeScreen('installed'); }} selected={screen === 'installed'}>Installed - + {#if enableCatalog} + + {/if} {#if enableLocalExtensions}