Files
grafana-zabbix/src/datasource-zabbix/components/ConfigEditor.tsx
2020-08-28 18:03:23 +03:00

304 lines
10 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { getDataSourceSrv } from '@grafana/runtime';
import { DataSourcePluginOptionsEditorProps, DataSourceSettings, SelectableValue } from '@grafana/data';
import { DataSourceHttpSettings, LegacyForms, Field, Input, Button, InlineFormLabel, Select } from '@grafana/ui';
const { FormField, Switch } = LegacyForms;
import { ZabbixDSOptions, ZabbixSecureJSONData } from '../types';
const SUPPORTED_SQL_DS = ['mysql', 'postgres', 'influxdb'];
export type Props = DataSourcePluginOptionsEditorProps<ZabbixDSOptions, ZabbixSecureJSONData>;
export const ConfigEditor = (props: Props) => {
const { options, onOptionsChange } = props;
const [selectedDBDatasource, setSelectedDBDatasource] = useState(null);
const [currentDSType, setCurrentDSType] = useState('');
// Apply some defaults on initial render
useEffect(() => {
const { jsonData, secureJsonFields } = options;
// Set secureJsonFields.password to password and then remove it from config
const { password, ...restJsonData } = jsonData;
if (!secureJsonFields?.password) {
if (!options.secureJsonData) {
options.secureJsonData = {};
}
options.secureJsonData.password = password;
}
onOptionsChange({
...options,
jsonData: {
trends: true,
trendsFrom: '',
trendsRange: '',
cacheTTL: '',
...restJsonData,
},
});
if (options.jsonData.dbConnectionEnable) {
if (!options.jsonData.dbConnectionDatasourceId) {
const dsName = options.jsonData.dbConnectionDatasourceName;
getDataSourceSrv().get(dsName)
.then(ds => {
if (ds) {
const selectedDs = getDirectDBDatasources().find(dsOption => dsOption.id === ds.id);
setSelectedDBDatasource({ label: selectedDs.name, value: selectedDs.id });
setCurrentDSType(selectedDs.type);
onOptionsChange({
...options,
jsonData: {
...options.jsonData,
dbConnectionDatasourceId: ds.id,
},
});
}
});
} else {
const selectedDs = getDirectDBDatasources().find(dsOption => dsOption.id === options.jsonData.dbConnectionDatasourceId);
setSelectedDBDatasource({ label: selectedDs.name, value: selectedDs.id });
setCurrentDSType(selectedDs.type);
}
}
}, []);
return (
<>
<DataSourceHttpSettings
defaultUrl={'http://localhost/zabbix/api_jsonrpc.php'}
dataSourceConfig={options}
showAccessOptions={true}
onChange={onOptionsChange}
/>
<div className="gf-form-group">
<h3 className="page-heading">Zabbix API details</h3>
<div className="gf-form max-width-25">
<FormField
labelWidth={7}
inputWidth={15}
label="Username"
value={options.jsonData.username || ''}
onChange={jsonDataChangeHandler('username', options, onOptionsChange)}
required
/>
</div>
<div className="gf-form max-width-25">
{options.secureJsonFields?.password ?
<>
<FormField
labelWidth={7}
inputWidth={15}
label="Password"
disabled={true}
value=""
placeholder="Configured"
/>
<Button onClick={resetSecureJsonField('password', options, onOptionsChange)}>Reset</Button>
</>:
<FormField
labelWidth={7}
inputWidth={15}
label="Password"
type="password"
value={options.secureJsonData?.password || options.jsonData.password || ''}
onChange={secureJsonDataChangeHandler('password', options, onOptionsChange)}
required
/>
}
</div>
<Switch
label="Trends"
labelClass="width-7"
checked={options.jsonData.trends}
onChange={jsonDataSwitchHandler('trends', options, onOptionsChange)}
/>
{options.jsonData.trends &&
<>
<div className="gf-form">
<FormField
labelWidth={7}
inputWidth={4}
label="After"
value={options.jsonData.trendsFrom || ''}
placeholder="7d"
onChange={jsonDataChangeHandler('trendsFrom', options, onOptionsChange)}
tooltip="Time after which trends will be used.
Best practice is to set this value to your history storage period (7d, 30d, etc)."
/>
</div>
<div className="gf-form">
<FormField
labelWidth={7}
inputWidth={4}
label="Range"
value={options.jsonData.trendsRange || ''}
placeholder="4d"
onChange={jsonDataChangeHandler('trendsRange', options, onOptionsChange)}
tooltip="Time range width after which trends will be used instead of history.
It's better to set this value in range of 4 to 7 days to prevent loading large amount of history data."
/>
</div>
</>
}
<div className="gf-form">
<FormField
labelWidth={7}
inputWidth={4}
label="Cache TTL"
value={options.jsonData.cacheTTL || ''}
placeholder="1h"
onChange={jsonDataChangeHandler('cacheTTL', options, onOptionsChange)}
tooltip="Zabbix data source caches metric names in memory. Specify how often data will be updated."
/>
</div>
</div>
<div className="gf-form-group">
<h3 className="page-heading">Direct DB Connection</h3>
<Switch
label="Enable"
labelClass="width-9"
checked={options.jsonData.dbConnectionEnable}
onChange={jsonDataSwitchHandler('dbConnectionEnable', options, onOptionsChange)}
/>
{options.jsonData.dbConnectionEnable &&
<>
<div className="gf-form">
<InlineFormLabel width={9}>Data Source</InlineFormLabel>
<Select
width={32}
options={getDirectDBDSOptions()}
value={selectedDBDatasource}
onChange={directDBDatasourceChanegeHandler(options, onOptionsChange, setSelectedDBDatasource, setCurrentDSType)}
/>
</div>
{currentDSType === 'influxdb' &&
<div className="gf-form">
<FormField
labelWidth={9}
inputWidth={16}
label="Retention Policy"
value={options.jsonData.dbConnectionRetentionPolicy || ''}
placeholder="Retention policy name"
onChange={jsonDataChangeHandler('dbConnectionRetentionPolicy', options, onOptionsChange)}
tooltip="Specify retention policy name for fetching long-term stored data (optional).
Leave it blank if only default retention policy used."
/>
</div>
}
</>
}
</div>
<div className="gf-form-group">
<h3 className="page-heading">Other</h3>
<Switch
label="Disable acknowledges for read-only users"
labelClass="width-20"
checked={options.jsonData.disableReadOnlyUsersAck}
onChange={jsonDataSwitchHandler('disableReadOnlyUsersAck', options, onOptionsChange)}
/>
</div>
</>
);
};
const jsonDataChangeHandler = (
key: keyof ZabbixDSOptions,
value: DataSourceSettings<ZabbixDSOptions, ZabbixSecureJSONData>,
onChange: Props['onOptionsChange']
) => (
event: React.SyntheticEvent<HTMLInputElement | HTMLSelectElement>
) => {
onChange({
...value,
jsonData: {
...value.jsonData,
[key]: event.currentTarget.value,
},
});
};
const jsonDataSwitchHandler = (
key: keyof ZabbixDSOptions,
value: DataSourceSettings<ZabbixDSOptions, ZabbixSecureJSONData>,
onChange: Props['onOptionsChange']
) => (
event: React.SyntheticEvent<HTMLInputElement>
) => {
onChange({
...value,
jsonData: {
...value.jsonData,
[key]: (event.target as HTMLInputElement).checked,
},
});
};
const secureJsonDataChangeHandler = (
key: keyof ZabbixDSOptions,
value: DataSourceSettings<ZabbixDSOptions, ZabbixSecureJSONData>,
onChange: Props['onOptionsChange']
) => (
event: React.SyntheticEvent<HTMLInputElement | HTMLSelectElement>
) => {
onChange({
...value,
secureJsonData: {
...value.secureJsonData,
[key]: event.currentTarget.value,
},
});
};
const resetSecureJsonField = (
key: keyof ZabbixDSOptions,
value: DataSourceSettings<ZabbixDSOptions, ZabbixSecureJSONData>,
onChange: Props['onOptionsChange']
) => (
event: React.SyntheticEvent<HTMLButtonElement>
) => {
onChange({
...value,
secureJsonFields: {
...value.secureJsonFields,
[key]: false,
},
});
};
const directDBDatasourceChanegeHandler = (
options: DataSourceSettings<ZabbixDSOptions, ZabbixSecureJSONData>,
onChange: Props['onOptionsChange'],
setSelectedDS: React.Dispatch<any>,
setSelectedDSType: React.Dispatch<any>,
) => (
value: SelectableValue<number>
) => {
const selectedDs = getDirectDBDatasources().find(dsOption => dsOption.id === value.value);
setSelectedDS({ label: selectedDs.name, value: selectedDs.id });
setSelectedDSType(selectedDs.type);
onChange({
...options,
jsonData: {
...options.jsonData,
dbConnectionDatasourceId: value.value
},
});
};
const getDirectDBDatasources = () => {
let dsList = (getDataSourceSrv() as any).getAll();
dsList = dsList.filter(ds => SUPPORTED_SQL_DS.includes(ds.type));
return dsList;
};
const getDirectDBDSOptions = () => {
const dsList = getDirectDBDatasources();
const dsOpts: Array<SelectableValue<number>> = dsList.map(ds => ({ label: ds.name, value: ds.id, description: ds.type }));
return dsOpts;
};