import React, { useEffect, useState } from 'react'; import { getDataSourceSrv, config } from '@grafana/runtime'; import { DataSourcePluginOptionsEditorProps, DataSourceSettings, GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Field, Icon, Input, Label, SecretInput, SecureSocksProxySettings, Select, Switch, Tooltip, useStyles2, } from '@grafana/ui'; import { ZabbixAuthType, ZabbixDSOptions, ZabbixSecureJSONData } from '../types/config'; import { gte } from 'semver'; import { Auth, ConfigSection, ConfigSubSection, EditorStack, convertLegacyAuthProps, ConnectionSettings, DataSourceDescription, AdvancedHttpSettings, } from '@grafana/plugin-ui'; import { Divider } from './Divider'; import { css } from '@emotion/css'; // the postgres-plugin changed it's id, so we list both the old name and the new name const SUPPORTED_SQL_DS = ['mysql', 'grafana-postgresql-datasource', 'postgres', 'influxdb']; const authOptions: Array> = [ { label: 'User and password', value: ZabbixAuthType.UserLogin }, { label: 'API token', value: ZabbixAuthType.Token }, ]; export type Props = DataSourcePluginOptionsEditorProps; export const ConfigEditor = (props: Props) => { const styles = useStyles2(getStyles); 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: { authType: ZabbixAuthType.UserLogin, trends: true, trendsFrom: '', trendsRange: '', cacheTTL: '', timeout: undefined, disableDataAlignment: false, ...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 ( <> )} {options.jsonData?.authType === ZabbixAuthType.Token && ( <> )}
Cache TTL Zabbix data source caches metric names in memory. Specify how often data will be updated. } > } > Timeout Zabbix API connection timeout in seconds. Default is 30.}> } > { onOptionsChange({ ...options, jsonData: { ...options.jsonData, timeout: parseInt(event.currentTarget.value, 10) }, }); }} /> {options.jsonData.trends && ( <> After Time after which trends will be used. Best practice is to set this value to your history storage period (7d, 30d, etc). } > } > Range Time range width after which trends will be used instead of history. It&aposs better to set this value in range of 4 to 7 days to prevent loading large amount of history data. } > } > )} {options.jsonData.dbConnectionEnable && ( <> )} )} Disable data alignment Data alignment feature aligns points based on item update interval. For instance, if value collected once per minute, then timestamp of the each point will be set to the start of corresponding minute. This alignment required for proper work of the stacked graphs. If you don't need stacked graphs and want to get exactly the same timestamps as in Zabbix, then you can disable this feature. } > } > {config.secureSocksDSProxyEnabled && gte(config.buildInfo.version, '10.0.0-0') && ( )} ); }; const getStyles = (theme: GrafanaTheme2) => { return { space: css({ width: '100%', height: theme.spacing(2), }), }; }; const jsonDataChangeHandler = ( key: keyof ZabbixDSOptions, value: DataSourceSettings, onChange: Props['onOptionsChange'] ) => (event: React.SyntheticEvent) => { onChange({ ...value, jsonData: { ...value.jsonData, [key]: event.currentTarget.value, }, }); }; const jsonDataSelectHandler = ( key: keyof ZabbixDSOptions, value: DataSourceSettings, onChange: Props['onOptionsChange'] ) => (option: SelectableValue) => { onChange({ ...value, jsonData: { ...value.jsonData, [key]: option.value, }, }); }; const jsonDataSwitchHandler = ( key: keyof ZabbixDSOptions, value: DataSourceSettings, onChange: Props['onOptionsChange'] ) => (event: React.SyntheticEvent) => { onChange({ ...value, jsonData: { ...value.jsonData, [key]: (event.target as HTMLInputElement).checked, }, }); }; const secureJsonDataChangeHandler = ( key: keyof ZabbixSecureJSONData, value: DataSourceSettings, onChange: Props['onOptionsChange'] ) => (event: React.SyntheticEvent) => { onChange({ ...value, secureJsonData: { ...value.secureJsonData, [key]: event.currentTarget.value, }, }); }; const resetSecureJsonField = ( key: keyof ZabbixSecureJSONData, value: DataSourceSettings, onChange: Props['onOptionsChange'] ) => () => { onChange({ ...value, secureJsonFields: { ...value.secureJsonFields, [key]: false, }, }); }; const directDBDatasourceChanegeHandler = ( options: DataSourceSettings, onChange: Props['onOptionsChange'], setSelectedDS: React.Dispatch, setSelectedDSType: React.Dispatch ) => (value: SelectableValue) => { 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> = dsList.map((ds) => ({ label: ds.name, value: ds.id, description: ds.type, })); return dsOpts; };