mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Starting moving more stuff into data source picker * WIP progress * Progress on datasource picker rethink * Things are working now some details to figure out * Removed commented part * Complex work on getting data source lists * Fixed variable support showing correct data sources * Tried fixing dashboard import but failed * Fixes * Fixed import dashboard * Fixed unit test * Fixed explore test * Fixed test * Fix * fixed more tests * fixed more tests * fixed showing which option is default in picker * Changed query variable to use data source picker, updated tests and e2e * Fixed more tests * Updated snapshots, had wrong typescript version
161 lines
5.1 KiB
TypeScript
161 lines
5.1 KiB
TypeScript
import React, { FC, useEffect, useState } from 'react';
|
||
import {
|
||
Button,
|
||
FormAPI,
|
||
FormsOnSubmit,
|
||
HorizontalGroup,
|
||
FormFieldErrors,
|
||
Input,
|
||
Field,
|
||
InputControl,
|
||
Legend,
|
||
} from '@grafana/ui';
|
||
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
|
||
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
||
import { DashboardInput, DashboardInputs, DataSourceInput, ImportDashboardDTO } from '../state/reducers';
|
||
import { validateTitle, validateUid } from '../utils/validation';
|
||
|
||
interface Props extends Omit<FormAPI<ImportDashboardDTO>, 'formState'> {
|
||
uidReset: boolean;
|
||
inputs: DashboardInputs;
|
||
initialFolderId: number;
|
||
|
||
onCancel: () => void;
|
||
onUidReset: () => void;
|
||
onSubmit: FormsOnSubmit<ImportDashboardDTO>;
|
||
}
|
||
|
||
export const ImportDashboardForm: FC<Props> = ({
|
||
register,
|
||
errors,
|
||
control,
|
||
getValues,
|
||
uidReset,
|
||
inputs,
|
||
initialFolderId,
|
||
onUidReset,
|
||
onCancel,
|
||
onSubmit,
|
||
watch,
|
||
}) => {
|
||
const [isSubmitted, setSubmitted] = useState(false);
|
||
const watchDataSources = watch('dataSources');
|
||
|
||
/*
|
||
This useEffect is needed for overwriting a dashboard. It
|
||
submits the form even if there's validation errors on title or uid.
|
||
*/
|
||
useEffect(() => {
|
||
if (isSubmitted && (errors.title || errors.uid)) {
|
||
onSubmit(getValues({ nest: true }), {} as any);
|
||
}
|
||
}, [errors]);
|
||
|
||
return (
|
||
<>
|
||
<Legend>Options</Legend>
|
||
<Field label="Name" invalid={!!errors.title} error={errors.title && errors.title.message}>
|
||
<Input
|
||
name="title"
|
||
type="text"
|
||
ref={register({
|
||
required: 'Name is required',
|
||
validate: async (v: string) => await validateTitle(v, getValues().folder.id),
|
||
})}
|
||
/>
|
||
</Field>
|
||
<Field label="Folder">
|
||
<InputControl
|
||
as={FolderPicker}
|
||
name="folder"
|
||
useNewForms
|
||
enableCreateNew
|
||
initialFolderId={initialFolderId}
|
||
control={control}
|
||
/>
|
||
</Field>
|
||
<Field
|
||
label="Unique identifier (uid)"
|
||
description="The unique identifier (uid) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs.
|
||
The uid allows having consistent URL’s for accessing dashboards so changing the title of a dashboard will not break any
|
||
bookmarked links to that dashboard."
|
||
invalid={!!errors.uid}
|
||
error={errors.uid && errors.uid.message}
|
||
>
|
||
<>
|
||
{!uidReset ? (
|
||
<Input
|
||
name="uid"
|
||
disabled
|
||
ref={register({ validate: async (v: string) => await validateUid(v) })}
|
||
addonAfter={!uidReset && <Button onClick={onUidReset}>Change uid</Button>}
|
||
/>
|
||
) : (
|
||
<Input name="uid" ref={register({ required: true, validate: async (v: string) => await validateUid(v) })} />
|
||
)}
|
||
</>
|
||
</Field>
|
||
{inputs.dataSources &&
|
||
inputs.dataSources.map((input: DataSourceInput, index: number) => {
|
||
const dataSourceOption = `dataSources[${index}]`;
|
||
const current = watchDataSources ?? [];
|
||
return (
|
||
<Field
|
||
label={input.label}
|
||
key={dataSourceOption}
|
||
invalid={errors.dataSources && !!errors.dataSources[index]}
|
||
error={errors.dataSources && errors.dataSources[index] && 'A data source is required'}
|
||
>
|
||
<InputControl
|
||
as={DataSourcePicker}
|
||
noDefault={true}
|
||
pluginId={input.pluginId}
|
||
name={`${dataSourceOption}`}
|
||
current={current[index]?.name}
|
||
control={control}
|
||
placeholder={input.info}
|
||
rules={{ required: true }}
|
||
/>
|
||
</Field>
|
||
);
|
||
})}
|
||
{inputs.constants &&
|
||
inputs.constants.map((input: DashboardInput, index) => {
|
||
const constantIndex = `constants[${index}]`;
|
||
return (
|
||
<Field
|
||
label={input.label}
|
||
error={errors.constants && errors.constants[index] && `${input.label} needs a value`}
|
||
invalid={errors.constants && !!errors.constants[index]}
|
||
key={constantIndex}
|
||
>
|
||
<Input ref={register({ required: true })} name={`${constantIndex}`} defaultValue={input.value} />
|
||
</Field>
|
||
);
|
||
})}
|
||
<HorizontalGroup>
|
||
<Button
|
||
type="submit"
|
||
variant={getButtonVariant(errors)}
|
||
onClick={() => {
|
||
setSubmitted(true);
|
||
}}
|
||
>
|
||
{getButtonText(errors)}
|
||
</Button>
|
||
<Button type="reset" variant="secondary" onClick={onCancel}>
|
||
Cancel
|
||
</Button>
|
||
</HorizontalGroup>
|
||
</>
|
||
);
|
||
};
|
||
|
||
function getButtonVariant(errors: FormFieldErrors<ImportDashboardDTO>) {
|
||
return errors && (errors.title || errors.uid) ? 'destructive' : 'primary';
|
||
}
|
||
|
||
function getButtonText(errors: FormFieldErrors<ImportDashboardDTO>) {
|
||
return errors && (errors.title || errors.uid) ? 'Import (Overwrite)' : 'Import';
|
||
}
|