mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
Folder: Provide adhoc ui for nested folder creation (#59126)
chore: provide adhoc ui for nested folder creation
This commit is contained in:
parent
4e6b8f658e
commit
7d82a27835
@ -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<typeof connector>;
|
||||
|
||||
export class NewDashboardsFolder extends PureComponent<Props> {
|
||||
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<Props> {
|
||||
});
|
||||
};
|
||||
|
||||
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 (
|
||||
<Page navId="dashboards/browse" pageNav={this.pageNav}>
|
||||
<Page.Contents>
|
||||
{!config.featureToggles.topnav && <h3>New dashboard folder</h3>}
|
||||
<Form defaultValues={initialFormModel} onSubmit={this.onSubmit}>
|
||||
{({ register, errors }) => (
|
||||
<>
|
||||
<Field
|
||||
label="Folder name"
|
||||
invalid={!!errors.folderName}
|
||||
error={errors.folderName && errors.folderName.message}
|
||||
>
|
||||
<Input
|
||||
id="folder-name-input"
|
||||
{...register('folderName', {
|
||||
required: 'Folder name is required.',
|
||||
validate: async (v) => await this.validateFolderName(v),
|
||||
})}
|
||||
/>
|
||||
</Field>
|
||||
<Button type="submit">Create</Button>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Page navId="dashboards/browse" pageNav={pageNav}>
|
||||
<Page.Contents>
|
||||
{!config.featureToggles.topnav && <h3>New dashboard folder</h3>}
|
||||
<Form defaultValues={initialFormModel} onSubmit={onSubmit}>
|
||||
{({ register, errors }) => (
|
||||
<>
|
||||
<Field
|
||||
label="Folder name"
|
||||
invalid={!!errors.folderName}
|
||||
error={errors.folderName && errors.folderName.message}
|
||||
>
|
||||
<Input
|
||||
id="folder-name-input"
|
||||
{...register('folderName', {
|
||||
required: 'Folder name is required.',
|
||||
validate: async (v) => await validateFolderName(v),
|
||||
})}
|
||||
/>
|
||||
</Field>
|
||||
<Button type="submit">Create</Button>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default connector(NewDashboardsFolder);
|
||||
|
@ -143,9 +143,9 @@ export function addFolderPermission(newItem: NewDashboardAclItem): ThunkResult<v
|
||||
};
|
||||
}
|
||||
|
||||
export function createNewFolder(folderName: string): ThunkResult<void> {
|
||||
export function createNewFolder(folderName: string, uid?: string): ThunkResult<void> {
|
||||
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));
|
||||
|
@ -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<Props> = ({ 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<Props> = ({ folderUid, canCreateFolders = fals
|
||||
return (
|
||||
<Menu>
|
||||
{canCreateDashboards && <Menu.Item url={actionUrl('new')} label="New Dashboard" />}
|
||||
{!folderUid && canCreateFolders && <Menu.Item url="dashboards/folder/new" label="New Folder" />}
|
||||
{canCreateFolders && (config.featureToggles.nestedFolders || !folderUid) && (
|
||||
<Menu.Item url={actionUrl('new_folder')} label="New Folder" />
|
||||
)}
|
||||
{canCreateDashboards && <Menu.Item url={actionUrl('import')} label="Import" />}
|
||||
</Menu>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user