diff --git a/public/app/core/components/Select/FolderPicker.test.tsx b/public/app/core/components/Select/FolderPicker.test.tsx
index 63cd75a3217..c932176630c 100644
--- a/public/app/core/components/Select/FolderPicker.test.tsx
+++ b/public/app/core/components/Select/FolderPicker.test.tsx
@@ -1,4 +1,5 @@
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import selectEvent from 'react-select-event';
@@ -42,6 +43,37 @@ describe('FolderPicker', () => {
expect(pickerOptions[0]).toHaveTextContent('Dash 1');
expect(pickerOptions[1]).toHaveTextContent('Dash 3');
});
+
+ it('should allow creating a new option', async () => {
+ const newFolder = { title: 'New Folder', id: 3 } as DashboardSearchHit;
+
+ jest
+ .spyOn(api, 'searchFolders')
+ .mockResolvedValue([
+ { title: 'Dash 1', id: 1 } as DashboardSearchHit,
+ { title: 'Dash 2', id: 2 } as DashboardSearchHit,
+ ]);
+
+ const onChangeFn = jest.fn();
+
+ const create = jest.spyOn(api, 'createFolder').mockResolvedValue(newFolder);
+
+ render();
+ expect(await screen.findByTestId(selectors.components.FolderPicker.containerV2)).toBeInTheDocument();
+
+ await userEvent.type(screen.getByLabelText('Select a folder'), newFolder.title);
+ const enter = await screen.findByText('Hit enter to add');
+
+ await userEvent.click(enter);
+ await waitFor(() => {
+ expect(create).toHaveBeenCalledWith({ title: newFolder.title });
+ });
+
+ expect(onChangeFn).toHaveBeenCalledWith({ title: newFolder.title, id: newFolder.id });
+ await waitFor(() => {
+ expect(screen.getByText(newFolder.title)).toBeInTheDocument();
+ });
+ });
});
describe('getInitialValues', () => {
diff --git a/public/app/core/components/Select/FolderPicker.tsx b/public/app/core/components/Select/FolderPicker.tsx
index b8d5c006372..99380c613af 100644
--- a/public/app/core/components/Select/FolderPicker.tsx
+++ b/public/app/core/components/Select/FolderPicker.tsx
@@ -143,15 +143,19 @@ export class FolderPicker extends PureComponent {
createNewFolder = async (folderName: string) => {
const newFolder = await createFolder({ title: folderName });
- let folder = { value: -1, label: 'Not created' };
+ let folder: SelectableValue = { value: -1, label: 'Not created' };
+
if (newFolder.id > -1) {
appEvents.emit(AppEvents.alertSuccess, ['Folder Created', 'OK']);
folder = { value: newFolder.id, label: newFolder.title };
+
this.setState(
{
folder: newFolder,
},
- () => this.props.onChange({ id: newFolder.value!, title: newFolder.label! })
+ () => {
+ this.onFolderChange(folder, { action: 'create-option', option: folder });
+ }
);
} else {
appEvents.emit(AppEvents.alertError, ['Folder could not be created']);
diff --git a/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx b/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx
index 705684bdf01..991b0a5fcb0 100644
--- a/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx
+++ b/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx
@@ -1,7 +1,7 @@
import React, { FC } from 'react';
import { FolderPicker, Props as FolderPickerProps } from 'app/core/components/Select/FolderPicker';
-import { AccessControlAction, PermissionLevelString } from 'app/types';
+import { PermissionLevelString } from 'app/types';
export interface Folder {
title: string;
@@ -10,11 +10,9 @@ export interface Folder {
export interface RuleFolderPickerProps extends Omit {
value?: Folder;
- /** An empty array of permissions means no filtering at all */
- folderPermissions?: AccessControlAction[];
}
-export const RuleFolderPicker: FC = ({ value, folderPermissions = [], ...props }) => {
+export const RuleFolderPicker: FC = ({ value, ...props }) => {
return (