From ab9f2dc9efe0d92e29726e2cf685ff614fdbb1df Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Tue, 23 Sep 2025 08:24:04 -0600 Subject: [PATCH] Provisioning: Prevent dashboard imports on provisioned folders (#111476) --- .../components/CreateNewButton.test.tsx | 49 +++++++++++++++++++ .../components/CreateNewButton.tsx | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx b/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx index 370ddcf6f5a..11d83f9e35f 100644 --- a/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx +++ b/public/app/features/browse-dashboards/components/CreateNewButton.test.tsx @@ -2,12 +2,20 @@ import { render as rtlRender, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { TestProvider } from 'test/helpers/TestProvider'; +import { ManagerKind } from 'app/features/apiserver/types'; +import { useIsProvisionedInstance } from 'app/features/provisioning/hooks/useIsProvisionedInstance'; import { FolderDTO } from 'app/types/folders'; import { mockFolderDTO } from '../fixtures/folder.fixture'; import CreateNewButton from './CreateNewButton'; +jest.mock('app/features/provisioning/hooks/useIsProvisionedInstance', () => ({ + useIsProvisionedInstance: jest.fn(), +})); + +const mockUseIsProvisionedInstance = useIsProvisionedInstance as jest.MockedFunction; + const mockParentFolder = mockFolderDTO(); function render(...[ui, options]: Parameters) { @@ -21,6 +29,9 @@ async function renderAndOpen(folder?: FolderDTO) { } describe('NewActionsButton', () => { + beforeEach(() => { + mockUseIsProvisionedInstance.mockReturnValue(false); + }); it('should display the correct urls with a given parent folder', async () => { await renderAndOpen(mockParentFolder); @@ -75,4 +86,42 @@ describe('NewActionsButton', () => { expect(screen.queryByText('Import')).not.toBeInTheDocument(); expect(screen.getByText('New folder')).toBeInTheDocument(); }); + + it('should hide Import button when folder is provisioned', async () => { + const provisionedFolder = mockFolderDTO(1, { managedBy: ManagerKind.Repo }); + await renderAndOpen(provisionedFolder); + + expect(screen.getByRole('link', { name: 'New dashboard' })).toBeInTheDocument(); + expect(screen.getByText('New folder')).toBeInTheDocument(); + expect(screen.queryByText('Import')).not.toBeInTheDocument(); + }); + + it('should show Import button when folder is not provisioned', async () => { + const regularFolder = mockFolderDTO(1, { managedBy: undefined }); + await renderAndOpen(regularFolder); + + expect(screen.getByRole('link', { name: 'New dashboard' })).toBeInTheDocument(); + expect(screen.getByText('New folder')).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Import' })).toBeInTheDocument(); + }); + + it('should hide Import button when entire instance is provisioned', async () => { + mockUseIsProvisionedInstance.mockReturnValue(true); + const regularFolder = mockFolderDTO(1, { managedBy: undefined }); + await renderAndOpen(regularFolder); + + expect(screen.getByRole('link', { name: 'New dashboard' })).toBeInTheDocument(); + expect(screen.getByText('New folder')).toBeInTheDocument(); + expect(screen.queryByText('Import')).not.toBeInTheDocument(); + }); + + it('should hide Import button when both instance and folder are provisioned', async () => { + mockUseIsProvisionedInstance.mockReturnValue(true); + const provisionedFolder = mockFolderDTO(1, { managedBy: ManagerKind.Repo }); + await renderAndOpen(provisionedFolder); + + expect(screen.getByRole('link', { name: 'New dashboard' })).toBeInTheDocument(); + expect(screen.getByText('New folder')).toBeInTheDocument(); + expect(screen.queryByText('Import')).not.toBeInTheDocument(); + }); }); diff --git a/public/app/features/browse-dashboards/components/CreateNewButton.tsx b/public/app/features/browse-dashboards/components/CreateNewButton.tsx index 017ec917e75..c71b67a911f 100644 --- a/public/app/features/browse-dashboards/components/CreateNewButton.tsx +++ b/public/app/features/browse-dashboards/components/CreateNewButton.tsx @@ -86,7 +86,7 @@ export default function CreateNewButton({ /> )} {canCreateFolder && setShowNewFolderDrawer(true)} label={getNewFolderPhrase()} />} - {canCreateDashboard && ( + {canCreateDashboard && !isProvisionedInstance && parentFolder?.managedBy !== ManagerKind.Repo && (