From cd5d5bcbba09f668abfd059b010d0dd97735e99c Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Wed, 8 Jan 2020 08:57:52 -0500 Subject: [PATCH] Cloud Watch: Standardize Config Editor Implementation (#20489) * remove anon funcs, removed options from state, removed update method, static selects as constants * cancellable promise * cancel promise on unmount * use new datasource funcs for dryer component --- .../cloudwatch/components/ConfigEditor.tsx | 218 ++++++------------ 1 file changed, 70 insertions(+), 148 deletions(-) diff --git a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx index 2a443a0af0a..c7f9d67b71c 100644 --- a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx @@ -1,18 +1,26 @@ import React, { PureComponent, ChangeEvent } from 'react'; import { FormLabel, Select, Input, Button } from '@grafana/ui'; -import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data'; +import { + DataSourcePluginOptionsEditorProps, + updateDatasourcePluginJsonDataOption, + updateDatasourcePluginResetKeyOption, + updateDatasourcePluginOption, +} from '@grafana/data'; import { SelectableValue } from '@grafana/data'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import CloudWatchDatasource from '../datasource'; import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types'; +import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise'; -export type Props = DataSourcePluginOptionsEditorProps; +const authProviderOptions = [ + { label: 'Access & secret key', value: 'keys' }, + { label: 'Credentials file', value: 'credentials' }, + { label: 'ARN', value: 'arn' }, +] as SelectableValue[]; -type CloudwatchSettings = DataSourceSettings; +export type Props = DataSourcePluginOptionsEditorProps; export interface State { - config: CloudwatchSettings; - authProviderOptions: SelectableValue[]; regions: SelectableValue[]; } @@ -20,54 +28,39 @@ export class ConfigEditor extends PureComponent { constructor(props: Props) { super(props); - const { options } = this.props; - this.state = { - config: ConfigEditor.defaults(options), - authProviderOptions: [ - { label: 'Access & secret key', value: 'keys' }, - { label: 'Credentials file', value: 'credentials' }, - { label: 'ARN', value: 'arn' }, - ], regions: [], }; - - this.updateDatasource(this.state.config); } - static getDerivedStateFromProps(props: Props, state: State) { - return { - ...state, - config: ConfigEditor.defaults(props.options), - }; + loadRegionsPromise: CancelablePromise = null; + + componentDidMount() { + this.loadRegionsPromise = makePromiseCancelable(this.loadRegions()); + this.loadRegionsPromise.promise.catch(({ isCanceled }) => { + if (isCanceled) { + console.warn('Cloud Watch ConfigEditor has unmounted, intialization was canceled'); + } + }); } - static defaults = (options: any) => { - options.jsonData.authType = options.jsonData.authType || 'credentials'; - options.jsonData.timeField = options.jsonData.timeField || '@timestamp'; - - if (!options.hasOwnProperty('secureJsonData')) { - options.secureJsonData = {}; + componentWillUnmount() { + if (this.loadRegionsPromise) { + this.loadRegionsPromise.cancel(); } + } - if (!options.hasOwnProperty('jsonData')) { - options.jsonData = {}; - } - - if (!options.hasOwnProperty('secureJsonFields')) { - options.secureJsonFields = {}; - } - - return options; + onUpdateOption = (key: string, val: any, secure: boolean) => { + updateDatasourcePluginJsonDataOption(this.props, key, val, secure); }; - async componentDidMount() { - this.loadRegions(); - } + onResetKey = (key: string) => { + updateDatasourcePluginResetKeyOption(this.props, key); + }; - loadRegions() { - getDatasourceSrv() - .loadDatasource(this.state.config.name) + async loadRegions() { + await getDatasourceSrv() + .loadDatasource(this.props.options.name) .then((ds: CloudWatchDatasource) => { return ds.getRegions(); }) @@ -126,113 +119,46 @@ export class ConfigEditor extends PureComponent { ); } - updateDatasource = async (config: any) => { - for (const j in config.jsonData) { - if (config.jsonData[j].length === 0) { - delete config.jsonData[j]; - } - } - - for (const k in config.secureJsonData) { - if (config.secureJsonData[k].length === 0) { - delete config.secureJsonData[k]; - } - } - - this.props.onOptionsChange({ - ...config, - }); - }; - onAuthProviderChange = (authType: SelectableValue) => { - this.updateDatasource({ - ...this.state.config, - jsonData: { - ...this.state.config.jsonData, - authType: authType.value, - }, - }); + this.onUpdateOption('authType', authType.value, false); }; onRegionChange = (defaultRegion: SelectableValue) => { - this.updateDatasource({ - ...this.state.config, - jsonData: { - ...this.state.config.jsonData, - defaultRegion: defaultRegion.value, - }, - }); + this.onUpdateOption('defaultRegion', defaultRegion.value, false); }; onResetAccessKey = () => { - this.updateDatasource({ - ...this.state.config, - secureJsonFields: { - ...this.state.config.secureJsonFields, - accessKey: false, - }, - }); + this.onResetKey('accessKey'); }; - onAccessKeyChange = (accessKey: string) => { - this.updateDatasource({ - ...this.state.config, - secureJsonData: { - ...this.state.config.secureJsonData, - accessKey, - }, - }); + onAccessKeyChange = (event: ChangeEvent) => { + this.onUpdateOption('accessKey', event.target.value, true); }; onResetSecretKey = () => { - this.updateDatasource({ - ...this.state.config, - secureJsonFields: { - ...this.state.config.secureJsonFields, - secretKey: false, - }, - }); + this.onResetKey('secretKey'); }; - onSecretKeyChange = (secretKey: string) => { - this.updateDatasource({ - ...this.state.config, - secureJsonData: { - ...this.state.config.secureJsonData, - secretKey, - }, - }); + onSecretKeyChange = (event: ChangeEvent) => { + this.onUpdateOption('secretKey', event.target.value, true); }; - onCredentialProfileNameChange = (database: string) => { - this.updateDatasource({ - ...this.state.config, - database, - }); + onCredentialProfileNameChange = (event: ChangeEvent) => { + updateDatasourcePluginOption(this.props, 'database', event.target.value); }; - onArnAssumeRoleChange = (assumeRoleArn: string) => { - this.updateDatasource({ - ...this.state.config, - jsonData: { - ...this.state.config.jsonData, - assumeRoleArn, - }, - }); + onArnAssumeRoleChange = (event: ChangeEvent) => { + this.onUpdateOption('assumeRoleArn', event.target.value, false); }; - onCustomMetricsNamespacesChange = (customMetricsNamespaces: string) => { - this.updateDatasource({ - ...this.state.config, - jsonData: { - ...this.state.config.jsonData, - customMetricsNamespaces, - }, - }); + onCustomMetricsNamespacesChange = (event: ChangeEvent) => { + this.onUpdateOption('customMetricsNamespaces', event.target.value, false); }; render() { - const { config, authProviderOptions, regions } = this.state; + const { regions } = this.state; + const { options } = this.props; + const secureJsonData = (options.secureJsonData || {}) as CloudWatchSecureJsonData; return ( <> @@ -243,14 +169,14 @@ export class ConfigEditor extends PureComponent { Auth Provider ) => - this.onCredentialProfileNameChange(event.target.value) - } + value={options.jsonData.database} + onChange={this.onCredentialProfileNameChange} /> )} - {config.jsonData.authType === 'keys' && ( + {options.jsonData.authType === 'keys' && (
- {config.secureJsonFields.accessKey ? ( + {options.secureJsonFields.accessKey ? (
Access Key ID @@ -295,14 +219,14 @@ export class ConfigEditor extends PureComponent {
) => this.onAccessKeyChange(event.target.value)} + value={secureJsonData.accessKey || ''} + onChange={this.onAccessKeyChange} />
)} - {config.secureJsonFields.secretKey ? ( + {options.secureJsonFields.secretKey ? (
Secret Access Key @@ -323,8 +247,8 @@ export class ConfigEditor extends PureComponent {
) => this.onSecretKeyChange(event.target.value)} + value={secureJsonData.secretKey || ''} + onChange={this.onSecretKeyChange} />
@@ -332,7 +256,7 @@ export class ConfigEditor extends PureComponent { )}
)} - {config.jsonData.authType === 'arn' && ( + {options.jsonData.authType === 'arn' && (
@@ -342,8 +266,8 @@ export class ConfigEditor extends PureComponent { ) => this.onArnAssumeRoleChange(event.target.value)} + value={options.jsonData.assumeRoleArn || ''} + onChange={this.onArnAssumeRoleChange} />
@@ -359,9 +283,9 @@ export class ConfigEditor extends PureComponent { ) => - this.onCustomMetricsNamespacesChange(event.target.value) - } + value={options.jsonData.customMetricsNamespaces || ''} + onChange={this.onCustomMetricsNamespacesChange} />