From 7d82a27835d6604bc9a1ce110fa3ecaf6b55988f Mon Sep 17 00:00:00 2001 From: Leo <108552997+lpskdl@users.noreply.github.com> Date: Wed, 23 Nov 2022 13:08:36 +0100 Subject: [PATCH] Folder: Provide adhoc ui for nested folder creation (#59126) chore: provide adhoc ui for nested folder creation --- .../components/NewDashboardsFolder.tsx | 85 +++++++++---------- public/app/features/folders/state/actions.ts | 4 +- .../search/components/DashboardActions.tsx | 12 ++- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/public/app/features/folders/components/NewDashboardsFolder.tsx b/public/app/features/folders/components/NewDashboardsFolder.tsx index f7743e4e80d..6bcc584ab3b 100644 --- a/public/app/features/folders/components/NewDashboardsFolder.tsx +++ b/public/app/features/folders/components/NewDashboardsFolder.tsx @@ -1,10 +1,11 @@ -import React, { PureComponent } from 'react'; +import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { NavModelItem } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Button, Input, Form, Field } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { validationSrv } from '../../manage-dashboards/services/ValidationSrv'; import { createNewFolder } from '../state/actions'; @@ -21,16 +22,22 @@ interface FormModel { folderName: string; } -const initialFormModel: FormModel = { folderName: '' }; - type Props = OwnProps & ConnectedProps; -export class NewDashboardsFolder extends PureComponent { - onSubmit = (formData: FormModel) => { - this.props.createNewFolder(formData.folderName); - }; +const initialFormModel: FormModel = { folderName: '' }; - validateFolderName = (folderName: string) => { +const pageNav: NavModelItem = { + text: 'Create a new folder', + subTitle: 'Folders provide a way to group dashboards and alert rules.', + breadcrumbs: [{ title: 'Dashboards', url: 'dashboards' }], +}; + +function NewDashboardsFolder({ createNewFolder }: Props) { + const [queryParams] = useQueryParams(); + const onSubmit = (formData: FormModel) => { + createNewFolder(formData.folderName, String(queryParams['folderUid'])); + }; + const validateFolderName = (folderName: string) => { return validationSrv .validateNewFolderName(folderName) .then(() => { @@ -41,41 +48,33 @@ export class NewDashboardsFolder extends PureComponent { }); }; - pageNav: NavModelItem = { - text: 'Create a new folder', - subTitle: 'Folders provide a way to group dashboards and alert rules.', - breadcrumbs: [{ title: 'Dashboards', url: 'dashboards' }], - }; - - render() { - return ( - - - {!config.featureToggles.topnav &&

New dashboard folder

} -
- {({ register, errors }) => ( - <> - - await this.validateFolderName(v), - })} - /> - - - - )} -
-
-
- ); - } + return ( + + + {!config.featureToggles.topnav &&

New dashboard folder

} +
+ {({ register, errors }) => ( + <> + + await validateFolderName(v), + })} + /> + + + + )} +
+
+
+ ); } export default connector(NewDashboardsFolder); diff --git a/public/app/features/folders/state/actions.ts b/public/app/features/folders/state/actions.ts index 68743eef477..e98f48a7475 100644 --- a/public/app/features/folders/state/actions.ts +++ b/public/app/features/folders/state/actions.ts @@ -143,9 +143,9 @@ export function addFolderPermission(newItem: NewDashboardAclItem): ThunkResult { +export function createNewFolder(folderName: string, uid?: string): ThunkResult { return async (dispatch) => { - const newFolder = await getBackendSrv().post('/api/folders', { title: folderName }); + const newFolder = await getBackendSrv().post('/api/folders', { title: folderName, parentUid: uid }); await contextSrv.fetchUserPermissions(); dispatch(notifyApp(createSuccessNotification('Folder Created', 'OK'))); locationService.push(locationUtil.stripBaseFromUrl(newFolder.url)); diff --git a/public/app/features/search/components/DashboardActions.tsx b/public/app/features/search/components/DashboardActions.tsx index 07dfdbe4408..ffea5252147 100644 --- a/public/app/features/search/components/DashboardActions.tsx +++ b/public/app/features/search/components/DashboardActions.tsx @@ -1,5 +1,6 @@ import React, { FC } from 'react'; +import { config } from '@grafana/runtime'; import { Menu, Dropdown, Button, Icon } from '@grafana/ui'; export interface Props { @@ -11,8 +12,13 @@ export interface Props { export const DashboardActions: FC = ({ folderUid, canCreateFolders = false, canCreateDashboards = false }) => { const actionUrl = (type: string) => { let url = `dashboard/${type}`; + const isTypeNewFolder = type === 'new_folder'; - if (folderUid) { + if (isTypeNewFolder) { + url = `dashboards/folder/new/`; + } + + if ((isTypeNewFolder && config.featureToggles.nestedFolders) || folderUid) { url += `?folderUid=${folderUid}`; } @@ -23,7 +29,9 @@ export const DashboardActions: FC = ({ folderUid, canCreateFolders = fals return ( {canCreateDashboards && } - {!folderUid && canCreateFolders && } + {canCreateFolders && (config.featureToggles.nestedFolders || !folderUid) && ( + + )} {canCreateDashboards && } );