diff --git a/package.json b/package.json index f3858f07b..24efb38b3 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dependencies": { "@emotion/css": "^11.1.3", "@grafana/data": "10.1.2", + "@grafana/experimental": "^1.7.4", "@grafana/runtime": "10.1.2", "@grafana/ui": "10.1.2", "react": "17.0.2", diff --git a/src/datasource/components/ConfigEditor.tsx b/src/datasource/components/ConfigEditor.tsx index 494c33024..d8a13ee03 100644 --- a/src/datasource/components/ConfigEditor.tsx +++ b/src/datasource/components/ConfigEditor.tsx @@ -1,11 +1,32 @@ import React, { useEffect, useState } from 'react'; import { getDataSourceSrv, config } from '@grafana/runtime'; -import { DataSourcePluginOptionsEditorProps, DataSourceSettings, SelectableValue } from '@grafana/data'; -import { Button, DataSourceHttpSettings, InlineFormLabel, LegacyForms, Select } from '@grafana/ui'; +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'; import { gte } from 'semver'; - -const { FormField, Switch } = LegacyForms; +import { + Auth, + ConfigSection, + ConfigSubSection, + Stack, + convertLegacyAuthProps, + ConnectionSettings, + DataSourceDescription, + AdvancedHttpSettings, +} from '@grafana/experimental'; +import { Divider } from './Divider'; +import { css } from '@emotion/css'; const SUPPORTED_SQL_DS = ['mysql', 'postgres', 'influxdb']; @@ -16,6 +37,7 @@ const authOptions: Array> = [ export type Props = DataSourcePluginOptionsEditorProps; export const ConfigEditor = (props: Props) => { + const styles = useStyles2(getStyles); const { options, onOptionsChange } = props; const [selectedDBDatasource, setSelectedDBDatasource] = useState(null); @@ -79,233 +101,300 @@ export const ConfigEditor = (props: Props) => { return ( <> - + + + + + + + + -
-

Zabbix API details

-
- - Auth type - + + + + -
-
- {options.secureJsonFields?.password ? ( - <> - - - - ) : ( - - )} -
+ + + resetSecureJsonField('password', options, onOptionsChange)} + onBlur={secureJsonDataChangeHandler('password', options, onOptionsChange)} + /> + )} - - {options.jsonData.trends && ( + + {options.jsonData?.authType === ZabbixAuthType.Token && ( <> -
- -
-
- + resetSecureJsonField('apiToken', options, onOptionsChange)} + onBlur={secureJsonDataChangeHandler('apiToken', options, onOptionsChange)} /> -
+ )} -
- -
-
- { - onOptionsChange({ - ...options, - jsonData: { ...options.jsonData, timeout: parseInt(event.currentTarget.value, 10) }, - }); - }} - tooltip="Zabbix API connection timeout in seconds. Default is 30." - /> -
-
- -
-

Direct DB Connection

- - {options.jsonData.dbConnectionEnable && ( - <> -
- Data Source - + + + + + 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') && ( + )} -
- -
-

Other

- - -
- - {config.featureToggles['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, diff --git a/src/datasource/components/Divider.tsx b/src/datasource/components/Divider.tsx new file mode 100644 index 000000000..c6582eb72 --- /dev/null +++ b/src/datasource/components/Divider.tsx @@ -0,0 +1,21 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +// this custom component is necessary because the Grafana UI component is not backwards compatible with Grafana < 10.1.0 +export const Divider = () => { + const styles = useStyles2(getStyles); + return
; +}; + +const getStyles = (theme: GrafanaTheme2) => { + return { + horizontalDivider: css({ + borderTop: `1px solid ${theme.colors.border.weak}`, + margin: theme.spacing(2, 0), + width: '100%', + }), + }; +}; diff --git a/yarn.lock b/yarn.lock index 5677c5f2b..825f3e9de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -897,6 +897,15 @@ eslint-plugin-react-hooks "4.6.0" typescript "4.8.4" +"@grafana/experimental@^1.7.4": + version "1.7.4" + resolved "https://registry.yarnpkg.com/@grafana/experimental/-/experimental-1.7.4.tgz#5b5efe89abf38b1d3358251148d42b9111de539e" + integrity sha512-uYkv9HRx+cqJRktsY43ApG0+kgG4fNR8lv+bkaFvGyCg46dcTeNqokujoPnHp6lt9MEn+0Y3jKEQbvCXjcz2bA== + dependencies: + "@types/uuid" "^8.3.3" + semver "^7.5.4" + uuid "^8.3.2" + "@grafana/faro-core@^1.1.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@grafana/faro-core/-/faro-core-1.2.1.tgz#a95fd1376a928917f855068f101d356db067a0f4" @@ -2267,6 +2276,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.3.tgz#3d06b6769518450871fbc40770b7586334bdfd90" integrity sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg== +"@types/uuid@^8.3.3": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -8838,6 +8852,11 @@ uuid@9.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"