Chore: Remove deprecated components from dashboard import pages (#83747)

* Add Form component to core

* Chore: Replace deprecated components in DashboardImportPage.tsx

* Chore: Replace deprecated components in ImportDashboardForm.tsx

* Chore: Replace deprecated components in ImportDashboardOverview.tsx
This commit is contained in:
Alex Khomenko
2024-03-04 17:22:13 +02:00
committed by GitHub
parent c644826f50
commit 9bd84b30e9
5 changed files with 83 additions and 29 deletions
+1
View File
@@ -383,6 +383,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/core/components/GraphNG/ @grafana/dataviz-squad
/public/app/core/components/TimeSeries/ @grafana/dataviz-squad
/public/app/core/components/TimelineChart/ @grafana/dataviz-squad
/public/app/core/components/Form/ @grafana/grafana-frontend-platform
/public/app/features/all.ts @grafana/grafana-frontend-platform
/public/app/features/admin/ @grafana/identity-access-team
+62
View File
@@ -0,0 +1,62 @@
import { css } from '@emotion/css';
import React, { HTMLProps, useEffect } from 'react';
import {
useForm,
Mode,
DefaultValues,
SubmitHandler,
FieldValues,
UseFormReturn,
FieldErrors,
FieldPath,
} from 'react-hook-form';
export type FormAPI<T extends FieldValues> = Omit<UseFormReturn<T>, 'handleSubmit'> & {
errors: FieldErrors<T>;
};
interface FormProps<T extends FieldValues> extends Omit<HTMLProps<HTMLFormElement>, 'onSubmit' | 'children'> {
validateOn?: Mode;
validateOnMount?: boolean;
validateFieldsOnMount?: FieldPath<T> | Array<FieldPath<T>>;
defaultValues?: DefaultValues<T>;
onSubmit: SubmitHandler<T>;
children: (api: FormAPI<T>) => React.ReactNode;
/** Sets max-width for container. Use it instead of setting individual widths on inputs.*/
maxWidth?: number | 'none';
}
export function Form<T extends FieldValues>({
defaultValues,
onSubmit,
validateOnMount = false,
validateFieldsOnMount,
children,
validateOn = 'onSubmit',
maxWidth = 600,
...htmlProps
}: FormProps<T>) {
const { handleSubmit, trigger, formState, ...rest } = useForm<T>({
mode: validateOn,
defaultValues,
});
useEffect(() => {
if (validateOnMount) {
trigger(validateFieldsOnMount);
}
}, [trigger, validateFieldsOnMount, validateOnMount]);
return (
<form
className={css({
maxWidth: maxWidth !== 'none' ? maxWidth + 'px' : maxWidth,
width: '100%',
})}
onSubmit={handleSubmit(onSubmit)}
{...htmlProps}
>
{children({ errors: formState.errors, formState, trigger, ...rest })}
</form>
);
}
@@ -8,14 +8,11 @@ import { config, reportInteraction } from '@grafana/runtime';
import {
Button,
Field,
Form,
HorizontalGroup,
Input,
Spinner,
stylesFactory,
TextArea,
Themeable2,
VerticalGroup,
FileDropzone,
withTheme2,
DropzoneFile,
@@ -23,8 +20,10 @@ import {
LinkButton,
TextLink,
Label,
Stack,
} from '@grafana/ui';
import appEvents from 'app/core/app_events';
import { Form } from 'app/core/components/Form/Form';
import { Page } from 'app/core/components/Page/Page';
import { t, Trans } from 'app/core/internationalization';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
@@ -208,14 +207,14 @@ class UnthemedDashboardImport extends PureComponent<Props> {
placeholder={JSON_PLACEHOLDER}
/>
</Field>
<HorizontalGroup>
<Stack>
<Button type="submit" data-testid={selectors.components.DashboardImportPage.submit}>
<Trans i18nKey="dashboard-import.form-actions.load">Load</Trans>
</Button>
<LinkButton variant="secondary" href={`${config.appSubUrl}/dashboards`}>
<Trans i18nKey="dashboard-import.form-actions.cancel">Cancel</Trans>
</LinkButton>
</HorizontalGroup>
</Stack>
</>
)}
</Form>
@@ -236,11 +235,11 @@ class UnthemedDashboardImport extends PureComponent<Props> {
<Page navId="dashboards/browse" pageNav={this.pageNav}>
<Page.Contents>
{loadingState === LoadingState.Loading && (
<VerticalGroup justify="center">
<HorizontalGroup justify="center">
<Stack direction={'column'} justifyContent="center">
<Stack justifyContent="center">
<Spinner size="xxl" />
</HorizontalGroup>
</VerticalGroup>
</Stack>
</Stack>
)}
{[LoadingState.Error, LoadingState.NotStarted].includes(loadingState) && this.renderImportForm()}
{loadingState === LoadingState.Done && <ImportDashboardOverview />}
@@ -1,18 +1,9 @@
import React, { useEffect, useState } from 'react';
import { Controller, FieldErrors, UseFormReturn } from 'react-hook-form';
import { selectors } from '@grafana/e2e-selectors';
import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';
import {
Button,
Field,
FormAPI,
FormFieldErrors,
FormsOnSubmit,
HorizontalGroup,
Input,
InputControl,
Legend,
} from '@grafana/ui';
import { Button, Field, FormFieldErrors, FormsOnSubmit, Stack, Input, Legend } from '@grafana/ui';
import { OldFolderPicker } from 'app/core/components/Select/OldFolderPicker';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
@@ -27,11 +18,11 @@ import { validateTitle, validateUid } from '../utils/validation';
import { ImportDashboardLibraryPanelsList } from './ImportDashboardLibraryPanelsList';
interface Props extends Pick<FormAPI<ImportDashboardDTO>, 'register' | 'errors' | 'control' | 'getValues' | 'watch'> {
interface Props extends Pick<UseFormReturn<ImportDashboardDTO>, 'register' | 'control' | 'getValues' | 'watch'> {
uidReset: boolean;
inputs: DashboardInputs;
initialFolderUid: string;
errors: FieldErrors<ImportDashboardDTO>;
onCancel: () => void;
onUidReset: () => void;
onSubmit: FormsOnSubmit<ImportDashboardDTO>;
@@ -80,7 +71,7 @@ export const ImportDashboardForm = ({
/>
</Field>
<Field label="Folder">
<InputControl
<Controller
render={({ field: { ref, ...field } }) => (
<OldFolderPicker {...field} enableCreateNew initialFolderUid={initialFolderUid} />
)}
@@ -123,7 +114,7 @@ export const ImportDashboardForm = ({
invalid={errors.dataSources && !!errors.dataSources[index]}
error={errors.dataSources && errors.dataSources[index] && 'A data source is required'}
>
<InputControl
<Controller
name={dataSourceOption}
render={({ field: { ref, ...field } }) => (
<DataSourcePicker
@@ -166,7 +157,7 @@ export const ImportDashboardForm = ({
description="List of existing library panels. These panels are not affected by the import."
folderName={watchFolder.title}
/>
<HorizontalGroup>
<Stack>
<Button
type="submit"
data-testid={selectors.components.ImportDashboardForm.submit}
@@ -180,7 +171,7 @@ export const ImportDashboardForm = ({
<Button type="reset" variant="secondary" onClick={onCancel}>
Cancel
</Button>
</HorizontalGroup>
</Stack>
</>
);
};
@@ -3,7 +3,8 @@ import { connect, ConnectedProps } from 'react-redux';
import { dateTimeFormat } from '@grafana/data';
import { locationService, reportInteraction } from '@grafana/runtime';
import { Form, Legend } from '@grafana/ui';
import { Box, Legend } from '@grafana/ui';
import { Form } from 'app/core/components/Form/Form';
import { StoreState } from 'app/types';
import { clearLoadedDashboard, importDashboard } from '../state/actions';
@@ -64,7 +65,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
return (
<>
{source === DashboardSource.Gcom && (
<div style={{ marginBottom: '24px' }}>
<Box marginBottom={3}>
<div>
<Legend>
Importing dashboard from{' '}
@@ -90,7 +91,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
</tr>
</tbody>
</table>
</div>
</Box>
)}
<Form
onSubmit={this.onSubmit}