You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.5 KiB
125 lines
3.5 KiB
import styles from './ConfigurationForm.module.css'; |
|
|
|
import Block from '../../../GBlock/Block'; |
|
import Text from '../../../Text/Text'; |
|
import PluginState from '../../../../plugin_state'; |
|
|
|
import { Button, Field, Form, Input } from '@grafana/ui'; |
|
|
|
import cn from 'classnames/bind'; |
|
|
|
import { SubmitHandler } from 'react-hook-form'; |
|
import React, { FC, useCallback, useState } from 'react'; |
|
|
|
import { isEmpty } from 'lodash-es'; |
|
|
|
const cx = cn.bind(styles); |
|
|
|
type Props = { |
|
onSuccessfulSetup: () => void; |
|
defaultDataExporterApiUrl: string; |
|
}; |
|
|
|
type FormProps = { |
|
dataExporterApiUrl: string; |
|
}; |
|
|
|
/** |
|
* https://stackoverflow.com/a/43467144 |
|
*/ |
|
const isValidUrl = (url: string): boolean => { |
|
try { |
|
new URL(url); |
|
return true; |
|
} catch (_) { |
|
return false; |
|
} |
|
}; |
|
|
|
const FormErrorMessage: FC<{ errorMsg: string }> = ({ errorMsg }) => ( |
|
<> |
|
<pre> |
|
<Text type="link">{errorMsg}</Text> |
|
</pre> |
|
<Block withBackground className={cx('info-block')}> |
|
<Text type="secondary"> |
|
Need help? |
|
<br />- file bugs on our GitHub Issues page{' '} |
|
<a |
|
href="https://code.corpglory.net/corpglory/grafana-data-exporter-app/issues" |
|
target="_blank" |
|
rel="noreferrer" |
|
> |
|
<Text type="link">here</Text> |
|
</a> |
|
</Text> |
|
</Block> |
|
</> |
|
); |
|
|
|
const ConfigurationForm: FC<Props> = ({ onSuccessfulSetup, defaultDataExporterApiUrl }) => { |
|
const [setupErrorMsg, setSetupErrorMsg] = useState<string | null>(null); |
|
const [formLoading, setFormLoading] = useState<boolean>(false); |
|
|
|
const setupPlugin: SubmitHandler<FormProps> = useCallback( |
|
async ({ dataExporterApiUrl }) => { |
|
setFormLoading(true); |
|
|
|
const errorMsg = await PluginState.installPlugin(dataExporterApiUrl); |
|
|
|
if (!errorMsg) { |
|
onSuccessfulSetup(); |
|
} else { |
|
setSetupErrorMsg(errorMsg); |
|
setFormLoading(false); |
|
} |
|
}, |
|
[onSuccessfulSetup] |
|
); |
|
|
|
return ( |
|
<Form<FormProps> defaultValues={{ dataExporterApiUrl: defaultDataExporterApiUrl }} onSubmit={setupPlugin}> |
|
{({ register, errors }) => ( |
|
<> |
|
<div className={cx('info-block')}> |
|
<p>1. Launch the DataExporter backend</p> |
|
<Text type="secondary"> |
|
Run hobby, dev or production backend. See{' '} |
|
<a href="https://code.corpglory.net/corpglory/grafana-data-exporter" target="_blank" rel="noreferrer"> |
|
<Text type="link">here</Text> |
|
</a>{' '} |
|
on how to get started. |
|
</Text> |
|
</div> |
|
|
|
<div className={cx('info-block')}> |
|
<p>2. Let us know the base URL of your DataExporter API</p> |
|
<Text type="secondary"> |
|
The DataExporter backend must be reachable from your Grafana installation. Some examples are: |
|
<br /> |
|
- http://host.docker.internal:8080 |
|
<br />- http://localhost:8080 |
|
</Text> |
|
</div> |
|
|
|
<Field label="DataExporter backend URL" invalid={!!errors.dataExporterApiUrl} error="Must be a valid URL"> |
|
<Input |
|
{...register('dataExporterApiUrl', { |
|
required: true, |
|
validate: isValidUrl, |
|
})} |
|
/> |
|
</Field> |
|
|
|
{setupErrorMsg && <FormErrorMessage errorMsg={setupErrorMsg} />} |
|
|
|
<Button type="submit" size="md" disabled={formLoading || !isEmpty(errors)}> |
|
Connect |
|
</Button> |
|
</> |
|
)} |
|
</Form> |
|
); |
|
}; |
|
|
|
export default ConfigurationForm;
|
|
|