From 5b17cd93c54813fefaf8a4e32ade0679004f48c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ida=20=C5=A0tambuk?= Date: Mon, 22 Jul 2024 14:48:17 +0200 Subject: [PATCH] Cloudwatch: Remove awsDatasourcesNewFormStyling feature toggle (#90128) * Remove toggle from cloudwatch plugin * Remove feature toggle from registry --------- Co-authored-by: Kevin Yu --- .betterer.results | 3 - .../feature-toggles/index.md | 1 - .../src/types/featureToggles.gen.ts | 1 - pkg/services/featuremgmt/registry.go | 8 - pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 - pkg/services/featuremgmt/toggles_gen.json | 1 + .../ConfigEditor/ConfigEditor.test.tsx | 454 ++++++++---------- .../components/ConfigEditor/ConfigEditor.tsx | 128 +---- .../VariableQueryEditor.test.tsx | 387 +++++++-------- .../VariableQueryEditor.tsx | 185 +++---- .../VariableQueryField.tsx | 34 +- .../VariableQueryEditor/VariableTextField.tsx | 27 +- 13 files changed, 478 insertions(+), 756 deletions(-) diff --git a/.betterer.results b/.betterer.results index ba808d11d27..49775ede415 100644 --- a/.betterer.results +++ b/.betterer.results @@ -7885,9 +7885,6 @@ exports[`no gf-form usage`] = { [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"], [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"] ], - "public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx:5381": [ - [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"] - ], "public/app/plugins/datasource/cloudwatch/components/ConfigEditor/XrayLinkConfig.tsx:5381": [ [0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"] ], diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index b383ff508ff..2830d8a16cf 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -51,7 +51,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s | Yes | | `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes | | `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes | -| `awsDatasourcesNewFormStyling` | Applies new form styling for configuration and query editors in AWS plugins | Yes | | `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes | | `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes | | `ssoSettingsApi` | Enables the SSO settings API and the OAuth configuration UIs in Grafana | Yes | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 7842e813470..f491717d4d9 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -122,7 +122,6 @@ export interface FeatureToggles { recoveryThreshold?: boolean; lokiStructuredMetadata?: boolean; teamHttpHeaders?: boolean; - awsDatasourcesNewFormStyling?: boolean; cachingOptimizeSerializationMemoryUsage?: boolean; panelTitleSearchInV1?: boolean; managedPluginsInstall?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index eac82ee00e2..361b444ffc7 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -785,14 +785,6 @@ var ( FrontendOnly: false, Owner: identityAccessTeam, }, - { - Name: "awsDatasourcesNewFormStyling", - Description: "Applies new form styling for configuration and query editors in AWS plugins", - Stage: FeatureStageGeneralAvailability, - Expression: "true", - FrontendOnly: true, - Owner: awsDatasourcesSquad, - }, { Name: "cachingOptimizeSerializationMemoryUsage", Description: "If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses.", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 3efd111efb7..bcfb14cd47e 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -103,7 +103,6 @@ cloudWatchBatchQueries,preview,@grafana/aws-datasources,false,false,false recoveryThreshold,GA,@grafana/alerting-squad,false,true,false lokiStructuredMetadata,GA,@grafana/observability-logs,false,false,false teamHttpHeaders,preview,@grafana/identity-access-team,false,false,false -awsDatasourcesNewFormStyling,GA,@grafana/aws-datasources,false,false,true cachingOptimizeSerializationMemoryUsage,experimental,@grafana/grafana-operator-experience-squad,false,false,false panelTitleSearchInV1,experimental,@grafana/search-and-storage,true,false,false managedPluginsInstall,GA,@grafana/plugins-platform-backend,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 8ad40989dd5..e7f97792145 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -423,10 +423,6 @@ const ( // Enables Team LBAC for datasources to apply team headers to the client requests FlagTeamHttpHeaders = "teamHttpHeaders" - // FlagAwsDatasourcesNewFormStyling - // Applies new form styling for configuration and query editors in AWS plugins - FlagAwsDatasourcesNewFormStyling = "awsDatasourcesNewFormStyling" - // FlagCachingOptimizeSerializationMemoryUsage // If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses. FlagCachingOptimizeSerializationMemoryUsage = "cachingOptimizeSerializationMemoryUsage" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 95bf2a293a2..3a012643d6f 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -469,6 +469,7 @@ "name": "awsDatasourcesNewFormStyling", "resourceVersion": "1720021873452", "creationTimestamp": "2023-10-12T08:59:10Z", + "deletionTimestamp": "2024-07-05T10:20:55Z", "annotations": { "grafana.app/updatedTimestamp": "2024-07-03 15:51:13.452477 +0000 UTC" } diff --git a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.test.tsx index 6f31669098f..b7ac8deadb9 100644 --- a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.test.tsx @@ -3,7 +3,6 @@ import userEvent from '@testing-library/user-event'; import { AwsAuthType } from '@grafana/aws-sdk'; import { PluginContextProvider, PluginMeta, PluginMetaInfo, PluginType } from '@grafana/data'; -import { config } from '@grafana/runtime'; import { CloudWatchSettings, @@ -130,258 +129,229 @@ describe('Render', () => { datasource.getVariables = jest.fn().mockReturnValue([]); }); - const originalFormFeatureToggleValue = config.featureToggles.awsDatasourcesNewFormStyling; - - const cleanupFeatureToggle = () => { - config.featureToggles.awsDatasourcesNewFormStyling = originalFormFeatureToggleValue; - }; - - function run() { - it('it should disable access key id field when the datasource has been previously configured', async () => { - setup({ - secureJsonFields: { - secretKey: true, - }, - }); - await waitFor(async () => expect(screen.getByPlaceholderText('Configured')).toBeDisabled()); + it('it should disable access key id field when the datasource has been previously configured', async () => { + setup({ + secureJsonFields: { + secretKey: true, + }, }); + await waitFor(async () => expect(screen.getByPlaceholderText('Configured')).toBeDisabled()); + }); - it('should show credentials profile name field', async () => { - setup({ - jsonData: { - authType: AwsAuthType.Credentials, - }, - }); - await waitFor(async () => expect(screen.getByText('Credentials Profile Name')).toBeInTheDocument()); + it('should show credentials profile name field', async () => { + setup({ + jsonData: { + authType: AwsAuthType.Credentials, + }, }); + await waitFor(async () => expect(screen.getByText('Credentials Profile Name')).toBeInTheDocument()); + }); - it('should show a warning if `credentials` auth type is used without a profile or database configured', async () => { - setup({ - jsonData: { - authType: AwsAuthType.Credentials, - profile: undefined, - database: undefined, - }, - }); - await waitFor(async () => - expect(screen.getByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).toBeInTheDocument() - ); + it('should show a warning if `credentials` auth type is used without a profile or database configured', async () => { + setup({ + jsonData: { + authType: AwsAuthType.Credentials, + profile: undefined, + database: undefined, + }, }); + await waitFor(async () => expect(screen.getByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).toBeInTheDocument()); + }); - it('should not show a warning if `credentials` auth type is used and a profile is configured', async () => { - setup({ - jsonData: { - authType: AwsAuthType.Credentials, - profile: 'profile', - database: undefined, - }, - }); - await waitFor(async () => - expect(screen.queryByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).not.toBeInTheDocument() - ); + it('should not show a warning if `credentials` auth type is used and a profile is configured', async () => { + setup({ + jsonData: { + authType: AwsAuthType.Credentials, + profile: 'profile', + database: undefined, + }, }); + await waitFor(async () => + expect(screen.queryByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).not.toBeInTheDocument() + ); + }); - it('should not show a warning if `credentials` auth type is used and a database is configured', async () => { - setup({ - jsonData: { - authType: AwsAuthType.Credentials, - profile: undefined, - database: 'database', - }, - }); - await waitFor(async () => - expect(screen.queryByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).not.toBeInTheDocument() - ); + it('should not show a warning if `credentials` auth type is used and a database is configured', async () => { + setup({ + jsonData: { + authType: AwsAuthType.Credentials, + profile: undefined, + database: 'database', + }, }); + await waitFor(async () => + expect(screen.queryByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).not.toBeInTheDocument() + ); + }); - it('should show access key and secret access key fields when the datasource has not been configured before', async () => { - setup({ - jsonData: { - authType: AwsAuthType.Keys, - }, - }); - await waitFor(async () => { - expect(screen.getByLabelText('Access Key ID')).toBeInTheDocument(); - expect(screen.getByLabelText('Secret Access Key')).toBeInTheDocument(); - }); + it('should show access key and secret access key fields when the datasource has not been configured before', async () => { + setup({ + jsonData: { + authType: AwsAuthType.Keys, + }, }); - - it('should show arn role field', async () => { - setup({ - jsonData: { - authType: AwsAuthType.ARN, - }, - }); - await waitFor(async () => expect(screen.getByText('Assume Role ARN')).toBeInTheDocument()); - }); - - it('should display namespace field', async () => { - setup(); - await waitFor(async () => expect(screen.getByText('Namespaces of Custom Metrics')).toBeInTheDocument()); - }); - - it('should show a deprecation warning if `arn` auth type is used', async () => { - setup({ - jsonData: { - authType: AwsAuthType.ARN, - }, - }); - await waitFor(async () => expect(screen.getByText(ARN_DEPRECATION_WARNING_MESSAGE)).toBeInTheDocument()); - }); - - it('should display log group selector field', async () => { - setup(); - await waitFor(async () => expect(screen.getByText('Select log groups')).toBeInTheDocument()); - }); - - it('should only display the first two default log groups and show all of them when clicking "Show all" button', async () => { - setup({ - version: 2, - jsonData: { - logGroups: [ - { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-foo:*', name: 'logGroup-foo' }, - { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-bar:*', name: 'logGroup-bar' }, - { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-baz:*', name: 'logGroup-baz' }, - ], - }, - }); - await waitFor(async () => { - expect(await screen.getByText('logGroup-foo')).toBeInTheDocument(); - expect(await screen.getByText('logGroup-bar')).toBeInTheDocument(); - expect(await screen.queryByText('logGroup-baz')).not.toBeInTheDocument(); - - await userEvent.click(screen.getByText('Show all')); - - expect(await screen.getByText('logGroup-baz')).toBeInTheDocument(); - }); - }); - - it('should load the data source if it was saved before', async () => { - const SAVED_VERSION = 2; - setup({ version: SAVED_VERSION }); - await waitFor(async () => expect(loadDataSourceMock).toHaveBeenCalled()); - }); - - it('should not load the data source if it wasnt saved before', async () => { - const SAVED_VERSION = undefined; - setup({ version: SAVED_VERSION }); - await waitFor(async () => expect(loadDataSourceMock).not.toHaveBeenCalled()); - }); - - it('should show error message if Select log group button is clicked when data source is never saved', async () => { - setup({ version: 1 }); - await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); - await userEvent.click(screen.getByText('Select log groups')); - await waitFor(() => - expect(screen.getByText('You need to save the data source before adding log groups.')).toBeInTheDocument() - ); - }); - - it('should show error message if Select log group button is clicked when data source is saved before but have unsaved changes', async () => { - const SAVED_VERSION = 3; - const newProps = { - ...props, - options: { - ...props.options, - version: SAVED_VERSION, - }, - }; - const meta: PluginMeta = { - ...newProps.options, - id: 'cloudwatch', - type: PluginType.datasource, - info: {} as PluginMetaInfo, - module: '', - baseUrl: '', - }; - - const { rerender } = render( - - - - ); - await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); - const rerenderProps = { - ...newProps, - options: { - ...newProps.options, - jsonData: { - ...newProps.options.jsonData, - authType: AwsAuthType.Default, - }, - }, - }; - rerender( - - - - ); - await waitFor(() => expect(screen.getByText('AWS SDK Default')).toBeInTheDocument()); - await userEvent.click(screen.getByText('Select log groups')); - await waitFor(() => - expect( - screen.getByText( - 'You have unsaved connection detail changes. You need to save the data source before adding log groups.' - ) - ).toBeInTheDocument() - ); - }); - - it('should open log group selector if Select log group button is clicked when data source has saved changes', async () => { - const newProps = { - ...props, - options: { - ...props.options, - version: 1, - }, - }; - const meta: PluginMeta = { - ...newProps.options, - id: 'cloudwatch', - type: PluginType.datasource, - info: {} as PluginMetaInfo, - module: '', - baseUrl: '', - }; - const { rerender } = render( - - - - ); - await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); - const rerenderProps = { - ...newProps, - options: { - ...newProps.options, - version: 2, - }, - }; - rerender( - - - - ); - await userEvent.click(screen.getByText('Select log groups')); - await waitFor(() => expect(screen.getByText('Log group name prefix')).toBeInTheDocument()); - }); - } - - describe('QueryEditor with awsDatasourcesNewFormStyling feature toggle enabled', () => { - beforeAll(() => { - config.featureToggles.awsDatasourcesNewFormStyling = false; - }); - afterAll(() => { - cleanupFeatureToggle(); - }); - run(); - describe('QueryEditor with awsDatasourcesNewFormStyling feature toggle enabled', () => { - beforeAll(() => { - config.featureToggles.awsDatasourcesNewFormStyling = true; - }); - afterAll(() => { - cleanupFeatureToggle(); - }); - run(); + await waitFor(async () => { + expect(screen.getByLabelText('Access Key ID')).toBeInTheDocument(); + expect(screen.getByLabelText('Secret Access Key')).toBeInTheDocument(); }); }); + + it('should show arn role field', async () => { + setup({ + jsonData: { + authType: AwsAuthType.ARN, + }, + }); + await waitFor(async () => expect(screen.getByText('Assume Role ARN')).toBeInTheDocument()); + }); + + it('should display namespace field', async () => { + setup(); + await waitFor(async () => expect(screen.getByText('Namespaces of Custom Metrics')).toBeInTheDocument()); + }); + + it('should show a deprecation warning if `arn` auth type is used', async () => { + setup({ + jsonData: { + authType: AwsAuthType.ARN, + }, + }); + await waitFor(async () => expect(screen.getByText(ARN_DEPRECATION_WARNING_MESSAGE)).toBeInTheDocument()); + }); + + it('should display log group selector field', async () => { + setup(); + await waitFor(async () => expect(screen.getByText('Select log groups')).toBeInTheDocument()); + }); + + it('should only display the first two default log groups and show all of them when clicking "Show all" button', async () => { + setup({ + version: 2, + jsonData: { + logGroups: [ + { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-foo:*', name: 'logGroup-foo' }, + { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-bar:*', name: 'logGroup-bar' }, + { arn: 'arn:aws:logs:us-east-2:123456789012:log-group:logGroup-baz:*', name: 'logGroup-baz' }, + ], + }, + }); + await waitFor(async () => { + expect(await screen.getByText('logGroup-foo')).toBeInTheDocument(); + expect(await screen.getByText('logGroup-bar')).toBeInTheDocument(); + expect(await screen.queryByText('logGroup-baz')).not.toBeInTheDocument(); + + await userEvent.click(screen.getByText('Show all')); + + expect(await screen.getByText('logGroup-baz')).toBeInTheDocument(); + }); + }); + + it('should load the data source if it was saved before', async () => { + const SAVED_VERSION = 2; + setup({ version: SAVED_VERSION }); + await waitFor(async () => expect(loadDataSourceMock).toHaveBeenCalled()); + }); + + it('should not load the data source if it wasnt saved before', async () => { + const SAVED_VERSION = undefined; + setup({ version: SAVED_VERSION }); + await waitFor(async () => expect(loadDataSourceMock).not.toHaveBeenCalled()); + }); + + it('should show error message if Select log group button is clicked when data source is never saved', async () => { + setup({ version: 1 }); + await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); + await userEvent.click(screen.getByText('Select log groups')); + await waitFor(() => + expect(screen.getByText('You need to save the data source before adding log groups.')).toBeInTheDocument() + ); + }); + + it('should show error message if Select log group button is clicked when data source is saved before but have unsaved changes', async () => { + const SAVED_VERSION = 3; + const newProps = { + ...props, + options: { + ...props.options, + version: SAVED_VERSION, + }, + }; + const meta: PluginMeta = { + ...newProps.options, + id: 'cloudwatch', + type: PluginType.datasource, + info: {} as PluginMetaInfo, + module: '', + baseUrl: '', + }; + + const { rerender } = render( + + + + ); + await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); + const rerenderProps = { + ...newProps, + options: { + ...newProps.options, + jsonData: { + ...newProps.options.jsonData, + authType: AwsAuthType.Default, + }, + }, + }; + rerender( + + + + ); + await waitFor(() => expect(screen.getByText('AWS SDK Default')).toBeInTheDocument()); + await userEvent.click(screen.getByText('Select log groups')); + await waitFor(() => + expect( + screen.getByText( + 'You have unsaved connection detail changes. You need to save the data source before adding log groups.' + ) + ).toBeInTheDocument() + ); + }); + + it('should open log group selector if Select log group button is clicked when data source has saved changes', async () => { + const newProps = { + ...props, + options: { + ...props.options, + version: 1, + }, + }; + const meta: PluginMeta = { + ...newProps.options, + id: 'cloudwatch', + type: PluginType.datasource, + info: {} as PluginMetaInfo, + module: '', + baseUrl: '', + }; + const { rerender } = render( + + + + ); + await waitFor(() => expect(screen.getByText('Select log groups')).toBeInTheDocument()); + const rerenderProps = { + ...newProps, + options: { + ...newProps.options, + version: 2, + }, + }; + rerender( + + + + ); + await userEvent.click(screen.getByText('Select log groups')); + await waitFor(() => expect(screen.getByText('Log group name prefix')).toBeInTheDocument()); + }); }); diff --git a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx index 2722ce628fa..dc28e7913cf 100644 --- a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx @@ -1,3 +1,4 @@ +import { css } from '@emotion/css'; import { useEffect, useState } from 'react'; import { useDebounce } from 'react-use'; @@ -9,10 +10,11 @@ import { updateDatasourcePluginJsonDataOption, DataSourceTestSucceeded, DataSourceTestFailed, + GrafanaTheme2, } from '@grafana/data'; import { ConfigSection } from '@grafana/experimental'; import { getAppEvents, usePluginInteractionReporter, getDataSourceSrv, config } from '@grafana/runtime'; -import { Alert, Input, InlineField, FieldProps, SecureSocksProxySettings, Field, Divider } from '@grafana/ui'; +import { Alert, Input, FieldProps, Field, Divider, useStyles2 } from '@grafana/ui'; import { CloudWatchDatasource } from '../../datasource'; import { SelectableResourceValue } from '../../resources/types'; @@ -42,7 +44,7 @@ export const ConfigEditor = (props: Props) => { const [logGroupFieldState, setLogGroupFieldState] = useState({ invalid: false, }); - const newFormStylingEnabled = config.featureToggles.awsDatasourcesNewFormStyling; + useEffect(() => setLogGroupFieldState({ invalid: false }), [props.options]); const report = usePluginInteractionReporter(); useEffect(() => { @@ -83,8 +85,10 @@ export const ConfigEditor = (props: Props) => { } }, [options.jsonData.authType, options.jsonData.database, options.jsonData.profile]); - return newFormStylingEnabled ? ( -
+ const styles = useStyles2(getStyles); + + return ( +
{warning && ( {warning} @@ -192,116 +196,6 @@ export const ConfigEditor = (props: Props) => { datasourceUid={options.jsonData.tracingDatasourceUid} />
- ) : ( - <> - {warning && ( - - {warning} - - )} - { - return datasource.resources - .getRegions() - .then((regions) => - regions.reduce( - (acc: string[], curr: SelectableResourceValue) => (curr.value ? [...acc, curr.value] : acc), - [] - ) - ); - }) - } - externalId={externalId} - > - - - - - - {config.secureSocksDSProxyEnabled && ( - - )} - -

CloudWatch Logs

-
- - - - - {datasource ? ( - { - if (saved) { - return; - } - - let error = 'You need to save the data source before adding log groups.'; - if (props.options.version && props.options.version > 1) { - error = - 'You have unsaved connection detail changes. You need to save the data source before adding log groups.'; - } - setLogGroupFieldState({ - invalid: true, - error, - }); - throw new Error(error); - }} - legacyLogGroupNames={defaultLogGroups} - logGroups={logGroups} - onChange={(updatedLogGroups) => { - onOptionsChange({ - ...props.options, - jsonData: { - ...props.options.jsonData, - logGroups: updatedLogGroups, - defaultLogGroups: undefined, - }, - }); - }} - maxNoOfVisibleLogGroups={2} - //legacy props - legacyOnChange={(logGroups) => { - updateDatasourcePluginJsonDataOption(props, 'defaultLogGroups', logGroups); - }} - /> - ) : ( - <> - )} - -
- updateDatasourcePluginJsonDataOption(props, 'tracingDatasourceUid', uid)} - datasourceUid={options.jsonData.tracingDatasourceUid} - /> - ); }; @@ -367,3 +261,9 @@ function useDataSourceSavedState(props: Props) { return saved; } + +const getStyles = (theme: GrafanaTheme2) => ({ + formStyles: css({ + maxWidth: theme.spacing(50), + }), +}); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx index 9f5c19be7b6..1d871de1da6 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx @@ -2,8 +2,6 @@ import { act, fireEvent, render, screen, waitFor, within } from '@testing-librar import userEvent from '@testing-library/user-event'; import { select } from 'react-select-event'; -import { config } from '@grafana/runtime'; - import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { GetDimensionKeysRequest } from '../../resources/types'; import { VariableQueryType } from '../../types'; @@ -24,12 +22,6 @@ const defaultQuery = { const ds = setupMockedDataSource(); -const originalFormFeatureToggleValue = config.featureToggles.awsDatasourcesNewFormStyling; - -const cleanupFeatureToggle = () => { - config.featureToggles.awsDatasourcesNewFormStyling = originalFormFeatureToggleValue; -}; - ds.datasource.resources.getRegions = jest.fn().mockResolvedValue([ { label: 'a1', value: 'a1' }, { label: 'b1', value: 'b1' }, @@ -82,221 +74,200 @@ describe('VariableEditor', () => { beforeEach(() => { onChange.mockClear(); }); - function run() { - describe('and a new variable is created', () => { - it('should trigger a query using the first query type in the array', async () => { - const props = defaultProps; - props.query = defaultQuery; - render(); + describe('and a new variable is created', () => { + it('should trigger a query using the first query type in the array', async () => { + const props = defaultProps; + props.query = defaultQuery; + render(); - await waitFor(() => { - const querySelect = screen.queryByRole('combobox', { name: 'Query type' }); - expect(querySelect).toBeInTheDocument(); - expect(screen.queryByText('Regions')).toBeInTheDocument(); - // Should not render any fields besides Query Type - const regionSelect = screen.queryByRole('combobox', { name: 'Region' }); - expect(regionSelect).not.toBeInTheDocument(); - }); - }); - }); - - describe('and an existing variable is edited', () => { - it('should trigger new query using the saved query type', async () => { - const props = defaultProps; - props.query = { - ...defaultQuery, - queryType: VariableQueryType.Metrics, - namespace: 'z2', - region: 'a1', - }; - render(); - - await waitFor(() => { - const querySelect = screen.queryByRole('combobox', { name: 'Query type' }); - expect(querySelect).toBeInTheDocument(); - expect(screen.queryByText('Metrics')).toBeInTheDocument(); - const regionSelect = screen.queryByRole('combobox', { name: 'Region' }); - expect(regionSelect).toBeInTheDocument(); - expect(screen.queryByText('a1')).toBeInTheDocument(); - const namespaceSelect = screen.queryByRole('combobox', { name: 'Namespace' }); - expect(namespaceSelect).toBeInTheDocument(); - expect(screen.queryByText('z2')).toBeInTheDocument(); - // Should only render Query Type, Region, and Namespace selectors - const metricSelect = screen.queryByRole('combobox', { name: 'Metric' }); - expect(metricSelect).not.toBeInTheDocument(); - }); - }); - it('should parse dimensionFilters correctly', async () => { - const props = defaultProps; - props.query = { - ...defaultQuery, - queryType: VariableQueryType.DimensionValues, - namespace: 'z2', - region: 'a1', - metricName: 'i3', - dimensionKey: 's4', - dimensionFilters: { s4: 'foo' }, - }; - await act(async () => { - render(); - }); - const filterItem = screen.getByTestId('cloudwatch-dimensions-filter-item'); - expect(filterItem).toBeInTheDocument(); - expect(within(filterItem).getByText('s4')).toBeInTheDocument(); - expect(within(filterItem).getByText('foo')).toBeInTheDocument(); - - // change filter key - const keySelect = screen.getByRole('combobox', { name: 'Dimensions filter key' }); - // confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter - select(keySelect, 'v4', { - container: document.body, - }); - expect(ds.datasource.resources.getDimensionKeys).toHaveBeenCalledWith( - { - namespace: 'z2', - region: 'a1', - metricName: 'i3', - dimensionFilters: undefined, - }, - false - ); - await waitFor(() => { - expect(onChange).toHaveBeenCalledWith({ - ...defaultQuery, - queryType: VariableQueryType.DimensionValues, - namespace: 'z2', - region: 'a1', - metricName: 'i3', - dimensionKey: 's4', - dimensionFilters: { v4: undefined }, - }); - }); - - // set filter value - const valueSelect = screen.getByRole('combobox', { name: 'Dimensions filter value' }); - await select(valueSelect, 'bar', { - container: document.body, - }); - expect(onChange).toHaveBeenCalledWith({ - ...defaultQuery, - queryType: VariableQueryType.DimensionValues, - namespace: 'z2', - region: 'a1', - metricName: 'i3', - dimensionKey: 's4', - dimensionFilters: { v4: 'bar' }, - }); - }); - it('should parse multiFilters correctly', async () => { - const props = defaultProps; - props.query = { - ...defaultQuery, - queryType: VariableQueryType.EC2InstanceAttributes, - region: 'a1', - attributeName: 'Tags.blah', - ec2Filters: { s4: ['foo', 'bar'] }, - }; - render(); - - await waitFor(() => { - expect(screen.getByDisplayValue('Tags.blah')).toBeInTheDocument(); - }); - - const filterItem = screen.getByTestId('cloudwatch-multifilter-item'); - expect(filterItem).toBeInTheDocument(); - expect(within(filterItem).getByDisplayValue('foo, bar')).toBeInTheDocument(); - - // set filter value - const valueElement = screen.getByTestId('cloudwatch-multifilter-item-value'); - expect(valueElement).toBeInTheDocument(); - await userEvent.type(valueElement!, ',baz'); - fireEvent.blur(valueElement!); - - expect(screen.getByDisplayValue('foo, bar, baz')).toBeInTheDocument(); - expect(onChange).toHaveBeenCalledWith({ - ...defaultQuery, - queryType: VariableQueryType.EC2InstanceAttributes, - region: 'a1', - attributeName: 'Tags.blah', - ec2Filters: { s4: ['foo', 'bar', 'baz'] }, - }); - }); - }); - describe('and a different region is selected', () => { - it('should clear invalid fields', async () => { - const props = defaultProps; - props.query = { - ...defaultQuery, - queryType: VariableQueryType.DimensionValues, - namespace: 'z2', - region: 'a1', - metricName: 'i3', - dimensionKey: 's4', - dimensionFilters: { s4: 'foo' }, - }; - render(); - - const querySelect = screen.queryByLabelText('Query type'); + await waitFor(() => { + const querySelect = screen.queryByRole('combobox', { name: 'Query type' }); expect(querySelect).toBeInTheDocument(); - expect(screen.queryByText('Dimension Values')).toBeInTheDocument(); - const regionSelect = screen.getByRole('combobox', { name: 'Region' }); - await waitFor(() => - select(regionSelect, 'b1', { - container: document.body, - }) - ); + expect(screen.queryByText('Regions')).toBeInTheDocument(); + // Should not render any fields besides Query Type + const regionSelect = screen.queryByRole('combobox', { name: 'Region' }); + expect(regionSelect).not.toBeInTheDocument(); + }); + }); + }); - expect(ds.datasource.resources.getMetrics).toHaveBeenCalledWith({ namespace: 'z2', region: 'b1' }); - expect(ds.datasource.resources.getDimensionKeys).toHaveBeenCalledWith({ namespace: 'z2', region: 'b1' }); - expect(props.onChange).toHaveBeenCalledWith({ + describe('and an existing variable is edited', () => { + it('should trigger new query using the saved query type', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.Metrics, + namespace: 'z2', + region: 'a1', + }; + render(); + + await waitFor(() => { + const querySelect = screen.queryByRole('combobox', { name: 'Query type' }); + expect(querySelect).toBeInTheDocument(); + expect(screen.queryByText('Metrics')).toBeInTheDocument(); + const regionSelect = screen.queryByRole('combobox', { name: 'Region' }); + expect(regionSelect).toBeInTheDocument(); + expect(screen.queryByText('a1')).toBeInTheDocument(); + const namespaceSelect = screen.queryByRole('combobox', { name: 'Namespace' }); + expect(namespaceSelect).toBeInTheDocument(); + expect(screen.queryByText('z2')).toBeInTheDocument(); + // Should only render Query Type, Region, and Namespace selectors + const metricSelect = screen.queryByRole('combobox', { name: 'Metric' }); + expect(metricSelect).not.toBeInTheDocument(); + }); + }); + it('should parse dimensionFilters correctly', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { s4: 'foo' }, + }; + await act(async () => { + render(); + }); + const filterItem = screen.getByTestId('cloudwatch-dimensions-filter-item'); + expect(filterItem).toBeInTheDocument(); + expect(within(filterItem).getByText('s4')).toBeInTheDocument(); + expect(within(filterItem).getByText('foo')).toBeInTheDocument(); + + // change filter key + const keySelect = screen.getByRole('combobox', { name: 'Dimensions filter key' }); + // confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter + select(keySelect, 'v4', { + container: document.body, + }); + expect(ds.datasource.resources.getDimensionKeys).toHaveBeenCalledWith( + { + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionFilters: undefined, + }, + false + ); + await waitFor(() => { + expect(onChange).toHaveBeenCalledWith({ ...defaultQuery, - refId: 'CloudWatchVariableQueryEditor-VariableQuery', queryType: VariableQueryType.DimensionValues, namespace: 'z2', - region: 'b1', - // metricName i3 exists in the new region and should not be removed + region: 'a1', metricName: 'i3', - // dimensionKey s4 and valueDimension do not exist in the new region and should be removed - dimensionKey: '', - dimensionFilters: {}, + dimensionKey: 's4', + dimensionFilters: { v4: undefined }, }); }); - }); - describe('LogGroups queryType is selected', () => { - it('should only render region and prefix', async () => { - const props = defaultProps; - props.query = { - ...defaultQuery, - queryType: VariableQueryType.LogGroups, - }; - render(); - await waitFor(() => { - screen.getByLabelText('Log group prefix'); - screen.getByLabelText('Region'); - }); - - expect(screen.queryByLabelText('Namespace')).not.toBeInTheDocument(); + // set filter value + const valueSelect = screen.getByRole('combobox', { name: 'Dimensions filter value' }); + await select(valueSelect, 'bar', { + container: document.body, + }); + expect(onChange).toHaveBeenCalledWith({ + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { v4: 'bar' }, }); }); - } + it('should parse multiFilters correctly', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.EC2InstanceAttributes, + region: 'a1', + attributeName: 'Tags.blah', + ec2Filters: { s4: ['foo', 'bar'] }, + }; + render(); - describe('variable editor with awsDatasourcesNewFormStyling feature toggle enabled', () => { - beforeAll(() => { - config.featureToggles.awsDatasourcesNewFormStyling = false; - }); - afterAll(() => { - cleanupFeatureToggle(); - }); - run(); - describe('variable editor with awsDatasourcesNewFormStyling feature toggle enabled', () => { - beforeAll(() => { - config.featureToggles.awsDatasourcesNewFormStyling = true; + await waitFor(() => { + expect(screen.getByDisplayValue('Tags.blah')).toBeInTheDocument(); }); - afterAll(() => { - cleanupFeatureToggle(); + + const filterItem = screen.getByTestId('cloudwatch-multifilter-item'); + expect(filterItem).toBeInTheDocument(); + expect(within(filterItem).getByDisplayValue('foo, bar')).toBeInTheDocument(); + + // set filter value + const valueElement = screen.getByTestId('cloudwatch-multifilter-item-value'); + expect(valueElement).toBeInTheDocument(); + await userEvent.type(valueElement!, ',baz'); + fireEvent.blur(valueElement!); + + expect(screen.getByDisplayValue('foo, bar, baz')).toBeInTheDocument(); + expect(onChange).toHaveBeenCalledWith({ + ...defaultQuery, + queryType: VariableQueryType.EC2InstanceAttributes, + region: 'a1', + attributeName: 'Tags.blah', + ec2Filters: { s4: ['foo', 'bar', 'baz'] }, }); - run(); + }); + }); + describe('and a different region is selected', () => { + it('should clear invalid fields', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { s4: 'foo' }, + }; + render(); + + const querySelect = screen.queryByLabelText('Query type'); + expect(querySelect).toBeInTheDocument(); + expect(screen.queryByText('Dimension Values')).toBeInTheDocument(); + const regionSelect = screen.getByRole('combobox', { name: 'Region' }); + await waitFor(() => + select(regionSelect, 'b1', { + container: document.body, + }) + ); + + expect(ds.datasource.resources.getMetrics).toHaveBeenCalledWith({ namespace: 'z2', region: 'b1' }); + expect(ds.datasource.resources.getDimensionKeys).toHaveBeenCalledWith({ namespace: 'z2', region: 'b1' }); + expect(props.onChange).toHaveBeenCalledWith({ + ...defaultQuery, + refId: 'CloudWatchVariableQueryEditor-VariableQuery', + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'b1', + // metricName i3 exists in the new region and should not be removed + metricName: 'i3', + // dimensionKey s4 and valueDimension do not exist in the new region and should be removed + dimensionKey: '', + dimensionFilters: {}, + }); + }); + }); + describe('LogGroups queryType is selected', () => { + it('should only render region and prefix', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.LogGroups, + }; + render(); + + await waitFor(() => { + screen.getByLabelText('Log group prefix'); + screen.getByLabelText('Region'); + }); + + expect(screen.queryByLabelText('Namespace')).not.toBeInTheDocument(); }); }); }); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx index e554875ba23..806b431fdef 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx @@ -1,7 +1,9 @@ -import { QueryEditorProps, SelectableValue } from '@grafana/data'; +import { css } from '@emotion/css'; + +import { GrafanaTheme2, QueryEditorProps, SelectableValue } from '@grafana/data'; import { EditorField } from '@grafana/experimental'; import { config } from '@grafana/runtime'; -import { InlineField } from '@grafana/ui'; +import { useStyles2 } from '@grafana/ui'; import { CloudWatchDatasource } from '../../datasource'; import { @@ -50,7 +52,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { const accountState = useAccountOptions(datasource.resources, query.region); const dimensionKeyError = useEnsureVariableHasSingleSelection(datasource, dimensionKey); - const newFormStylingEnabled = config.featureToggles.awsDatasourcesNewFormStyling; const onRegionChange = async (region: string) => { const validatedQuery = await sanitizeQuery({ ...parsedQuery, @@ -119,8 +120,11 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { VariableQueryType.DimensionKeys, VariableQueryType.DimensionValues, ].includes(parsedQuery.queryType); + + const styles = useStyles2(getStyles); + return ( -
+
{ } label="Query type" inputId={`variable-query-type-${query.refId}`} - newFormStylingEnabled={newFormStylingEnabled} /> {hasRegionField && ( { label="Region" isLoading={regionIsLoading} inputId={`variable-query-region-${query.refId}`} - newFormStylingEnabled={newFormStylingEnabled} /> )} {hasAccountIDField && @@ -152,7 +154,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { onChange={(accountId?: string) => onQueryChange({ ...parsedQuery, accountId })} options={[ALL_ACCOUNTS_OPTION, ...accountState?.value]} allowCustomValue={false} - newFormStylingEnabled={newFormStylingEnabled} /> )} {hasNamespaceField && ( @@ -163,7 +164,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { label="Namespace" inputId={`variable-query-namespace-${query.refId}`} allowCustomValue - newFormStylingEnabled={newFormStylingEnabled} /> )} {parsedQuery.queryType === VariableQueryType.DimensionValues && ( @@ -175,7 +175,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { label="Metric" inputId={`variable-query-metric-${query.refId}`} allowCustomValue - newFormStylingEnabled={newFormStylingEnabled} /> { label="Dimension key" inputId={`variable-query-dimension-key-${query.refId}`} allowCustomValue - newFormStylingEnabled={newFormStylingEnabled} error={dimensionKeyError} /> - {newFormStylingEnabled ? ( - - { - onChange({ ...parsedQuery, dimensionFilters: dimensions }); - }} - disableExpressions={true} - datasource={datasource} - /> - - ) : ( - - { - onChange({ ...parsedQuery, dimensionFilters: dimensions }); - }} - disableExpressions={true} - datasource={datasource} - /> - - )} + + { + onChange({ ...parsedQuery, dimensionFilters: dimensions }); + }} + disableExpressions={true} + datasource={datasource} + /> + )} {parsedQuery.queryType === VariableQueryType.EBSVolumeIDs && ( @@ -223,7 +207,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { placeholder="i-XXXXXXXXXXXXXXXXX" onBlur={(value: string) => onQueryChange({ ...parsedQuery, instanceID: value })} label="Instance ID" - newFormStylingEnabled={newFormStylingEnabled} /> )} {parsedQuery.queryType === VariableQueryType.EC2InstanceAttributes && ( @@ -233,7 +216,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { onBlur={(value: string) => onQueryChange({ ...parsedQuery, attributeName: value })} label="Attribute name" interactive={true} - newFormStylingEnabled={newFormStylingEnabled} tooltip={ <> {'Attribute or tag to query on. Tags should be formatted "Tags.". '} @@ -247,60 +229,31 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { } /> - {newFormStylingEnabled ? ( - - - Pre-defined ec2:DescribeInstances filters/tags - - {' and the values to filter on. Tags should be formatted tag:.'} - - } - > - { - onChange({ ...parsedQuery, ec2Filters: filters }); - }} - keyPlaceholder="filter/tag" - datasource={datasource} - /> - - ) : ( - - - Pre-defined ec2:DescribeInstances filters/tags - - {' and the values to filter on. Tags should be formatted tag:.'} - - } - > - { - onChange({ ...parsedQuery, ec2Filters: filters }); - }} - keyPlaceholder="filter/tag" - datasource={datasource} - /> - - )} + + + Pre-defined ec2:DescribeInstances filters/tags + + {' and the values to filter on. Tags should be formatted tag:.'} + + } + > + { + onChange({ ...parsedQuery, ec2Filters: filters }); + }} + keyPlaceholder="filter/tag" + datasource={datasource} + /> + )} {parsedQuery.queryType === VariableQueryType.ResourceArns && ( @@ -309,31 +262,17 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { value={parsedQuery.resourceType} onBlur={(value: string) => onQueryChange({ ...parsedQuery, resourceType: value })} label="Resource type" - newFormStylingEnabled={newFormStylingEnabled} /> - {newFormStylingEnabled ? ( - - { - onChange({ ...parsedQuery, tags: filters }); - }} - keyPlaceholder="tag" - datasource={datasource} - /> - - ) : ( - - { - onChange({ ...parsedQuery, tags: filters }); - }} - keyPlaceholder="tag" - datasource={datasource} - /> - - )} + + { + onChange({ ...parsedQuery, tags: filters }); + }} + keyPlaceholder="tag" + datasource={datasource} + /> + )} {parsedQuery.queryType === VariableQueryType.LogGroups && ( @@ -341,9 +280,17 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { value={query.logGroupPrefix ?? ''} onBlur={(value: string) => onQueryChange({ ...parsedQuery, logGroupPrefix: value })} label="Log group prefix" - newFormStylingEnabled={newFormStylingEnabled} /> )}
); }; + +const getStyles = (theme: GrafanaTheme2) => ({ + formStyles: css({ + maxWidth: theme.spacing(30), + }), + dimensionsWidth: css({ + width: theme.spacing(50), + }), +}); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx index eb1399ce9c9..500a069c9da 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx @@ -1,14 +1,10 @@ -import { css } from '@emotion/css'; - -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { SelectableValue } from '@grafana/data'; import { EditorField } from '@grafana/experimental'; -import { Alert, InlineField, Select, useStyles2 } from '@grafana/ui'; +import { Alert, Select } from '@grafana/ui'; import { VariableQueryType } from '../../types'; import { removeMarginBottom } from '../styles'; -const LABEL_WIDTH = 20; - interface VariableQueryFieldProps { onChange: (value: T) => void; options: SelectableValue[]; @@ -17,7 +13,6 @@ interface VariableQueryFieldProps { inputId?: string; allowCustomValue?: boolean; isLoading?: boolean; - newFormStylingEnabled?: boolean; error?: string; } @@ -29,11 +24,9 @@ export const VariableQueryField = ({ allowCustomValue = false, isLoading = false, inputId = label, - newFormStylingEnabled, error, }: VariableQueryFieldProps) => { - const styles = useStyles2(getStyles); - return newFormStylingEnabled ? ( + return ( <> onChange(value!)} - options={options} - isLoading={isLoading} - inputId={inputId} - /> - - {error && } - ); }; - -const getStyles = (theme: GrafanaTheme2) => ({ - // width set to InlineField labelWidth + Select width + 0.5 for margin on the label - inlineFieldAlert: css({ maxWidth: theme.spacing(LABEL_WIDTH + 25 + 0.5) }), -}); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx index 4313f440275..ed9c2dee2ec 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx @@ -1,12 +1,10 @@ import { useState } from 'react'; import { EditorField } from '@grafana/experimental'; -import { InlineField, Input, PopoverContent } from '@grafana/ui'; +import { Input, PopoverContent } from '@grafana/ui'; import { removeMarginBottom } from '../styles'; -const LABEL_WIDTH = 20; - interface Props { onBlur: (value: string) => void; value: string; @@ -17,17 +15,9 @@ interface Props { newFormStylingEnabled?: boolean; } -export const VariableTextField = ({ - interactive, - label, - onBlur, - placeholder, - value, - tooltip, - newFormStylingEnabled, -}: Props) => { +export const VariableTextField = ({ interactive, label, onBlur, placeholder, value, tooltip }: Props) => { const [localValue, setLocalValue] = useState(value); - return newFormStylingEnabled ? ( + return ( onBlur(localValue)} /> - ) : ( - - setLocalValue(e.currentTarget.value)} - onBlur={() => onBlur(localValue)} - width={25} - /> - ); };