mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Cloudwatch: Remove awsDatasourcesNewFormStyling feature toggle (#90128)
* Remove toggle from cloudwatch plugin * Remove feature toggle from registry --------- Co-authored-by: Kevin Yu <kevinwcyu@users.noreply.github.com>
This commit is contained in:
@@ -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"]
|
||||
],
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -122,7 +122,6 @@ export interface FeatureToggles {
|
||||
recoveryThreshold?: boolean;
|
||||
lokiStructuredMetadata?: boolean;
|
||||
teamHttpHeaders?: boolean;
|
||||
awsDatasourcesNewFormStyling?: boolean;
|
||||
cachingOptimizeSerializationMemoryUsage?: boolean;
|
||||
panelTitleSearchInV1?: boolean;
|
||||
managedPluginsInstall?: boolean;
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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,13 +129,6 @@ 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: {
|
||||
@@ -163,9 +155,7 @@ describe('Render', () => {
|
||||
database: undefined,
|
||||
},
|
||||
});
|
||||
await waitFor(async () =>
|
||||
expect(screen.getByText(CREDENTIALS_AUTHENTICATION_WARNING_MESSAGE)).toBeInTheDocument()
|
||||
);
|
||||
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 () => {
|
||||
@@ -364,24 +354,4 @@ describe('Render', () => {
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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<LogGroupFieldState>({
|
||||
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 ? (
|
||||
<div className="width-30">
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<div className={styles.formStyles}>
|
||||
{warning && (
|
||||
<Alert title="CloudWatch Authentication" severity="warning" onRemove={dismissWarning}>
|
||||
{warning}
|
||||
@@ -192,116 +196,6 @@ export const ConfigEditor = (props: Props) => {
|
||||
datasourceUid={options.jsonData.tracingDatasourceUid}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{warning && (
|
||||
<Alert title="CloudWatch Authentication" severity="warning" onRemove={dismissWarning}>
|
||||
{warning}
|
||||
</Alert>
|
||||
)}
|
||||
<ConnectionConfig
|
||||
{...props}
|
||||
labelWidth={29}
|
||||
loadRegions={
|
||||
datasource &&
|
||||
(async () => {
|
||||
return datasource.resources
|
||||
.getRegions()
|
||||
.then((regions) =>
|
||||
regions.reduce(
|
||||
(acc: string[], curr: SelectableResourceValue) => (curr.value ? [...acc, curr.value] : acc),
|
||||
[]
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
externalId={externalId}
|
||||
>
|
||||
<InlineField label="Namespaces of Custom Metrics" labelWidth={29} tooltip="Namespaces of Custom Metrics.">
|
||||
<Input
|
||||
width={60}
|
||||
placeholder="Namespace1,Namespace2"
|
||||
value={options.jsonData.customMetricsNamespaces || ''}
|
||||
onChange={onUpdateDatasourceJsonDataOption(props, 'customMetricsNamespaces')}
|
||||
/>
|
||||
</InlineField>
|
||||
</ConnectionConfig>
|
||||
|
||||
{config.secureSocksDSProxyEnabled && (
|
||||
<SecureSocksProxySettings options={options} onOptionsChange={onOptionsChange} />
|
||||
)}
|
||||
|
||||
<h3 className="page-heading">CloudWatch Logs</h3>
|
||||
<div className="gf-form-group">
|
||||
<InlineField
|
||||
label="Query Result Timeout"
|
||||
labelWidth={28}
|
||||
tooltip='Grafana will poll for Cloudwatch Logs query results every second until Done status is returned from AWS or timeout is exceeded, in which case Grafana will return an error. The default period is 30 minutes. Note: For Alerting, the timeout defined in the config file will take precedence. Must be a valid duration string, such as "15m" "30s" "2000ms" etc.'
|
||||
invalid={Boolean(logsTimeoutError)}
|
||||
>
|
||||
<Input
|
||||
width={60}
|
||||
placeholder="30m"
|
||||
value={options.jsonData.logsTimeout || ''}
|
||||
onChange={onUpdateDatasourceJsonDataOption(props, 'logsTimeout')}
|
||||
title={'The timeout must be a valid duration string, such as "15m" "30s" "2000ms" etc.'}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
shrink={true}
|
||||
{...logGroupFieldState}
|
||||
>
|
||||
{datasource ? (
|
||||
<LogGroupsFieldWrapper
|
||||
region={defaultRegion ?? ''}
|
||||
datasource={datasource}
|
||||
onBeforeOpen={() => {
|
||||
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);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={(uid) => 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),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -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,7 +74,6 @@ 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;
|
||||
@@ -279,24 +270,4 @@ describe('VariableEditor', () => {
|
||||
expect(screen.queryByLabelText('Namespace')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
});
|
||||
afterAll(() => {
|
||||
cleanupFeatureToggle();
|
||||
});
|
||||
run();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
<div className={newFormStylingEnabled ? 'width-15' : ''}>
|
||||
<div className={styles.formStyles}>
|
||||
<VariableQueryField
|
||||
value={parsedQuery.queryType}
|
||||
options={queryTypes}
|
||||
@@ -129,7 +133,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
}
|
||||
label="Query type"
|
||||
inputId={`variable-query-type-${query.refId}`}
|
||||
newFormStylingEnabled={newFormStylingEnabled}
|
||||
/>
|
||||
{hasRegionField && (
|
||||
<VariableQueryField
|
||||
@@ -139,7 +142,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
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}
|
||||
/>
|
||||
<VariableQueryField
|
||||
value={dimensionKey || null}
|
||||
@@ -184,25 +183,11 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
label="Dimension key"
|
||||
inputId={`variable-query-dimension-key-${query.refId}`}
|
||||
allowCustomValue
|
||||
newFormStylingEnabled={newFormStylingEnabled}
|
||||
error={dimensionKeyError}
|
||||
/>
|
||||
{newFormStylingEnabled ? (
|
||||
<EditorField label="Dimensions" className="width-30" tooltip="Dimensions to filter the returned values on">
|
||||
<Dimensions
|
||||
metricStat={{ ...parsedQuery, dimensions: parsedQuery.dimensionFilters }}
|
||||
onChange={(dimensions) => {
|
||||
onChange({ ...parsedQuery, dimensionFilters: dimensions });
|
||||
}}
|
||||
disableExpressions={true}
|
||||
datasource={datasource}
|
||||
/>
|
||||
</EditorField>
|
||||
) : (
|
||||
<InlineField
|
||||
<EditorField
|
||||
label="Dimensions"
|
||||
labelWidth={20}
|
||||
shrink
|
||||
className={styles.dimensionsWidth}
|
||||
tooltip="Dimensions to filter the returned values on"
|
||||
>
|
||||
<Dimensions
|
||||
@@ -213,8 +198,7 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
disableExpressions={true}
|
||||
datasource={datasource}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
</EditorField>
|
||||
</>
|
||||
)}
|
||||
{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.<name>". '}
|
||||
@@ -247,7 +229,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{newFormStylingEnabled ? (
|
||||
<EditorField
|
||||
label="Filters"
|
||||
tooltipInteractive
|
||||
@@ -273,34 +254,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
datasource={datasource}
|
||||
/>
|
||||
</EditorField>
|
||||
) : (
|
||||
<InlineField
|
||||
label="Filters"
|
||||
labelWidth={20}
|
||||
shrink
|
||||
tooltip={
|
||||
<>
|
||||
<a
|
||||
href="https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/template-queries-cloudwatch/#selecting-attributes"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Pre-defined ec2:DescribeInstances filters/tags
|
||||
</a>
|
||||
{' and the values to filter on. Tags should be formatted tag:<name>.'}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<MultiFilter
|
||||
filters={parsedQuery.ec2Filters ?? {}}
|
||||
onChange={(filters) => {
|
||||
onChange({ ...parsedQuery, ec2Filters: filters });
|
||||
}}
|
||||
keyPlaceholder="filter/tag"
|
||||
datasource={datasource}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{parsedQuery.queryType === VariableQueryType.ResourceArns && (
|
||||
@@ -309,9 +262,7 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
value={parsedQuery.resourceType}
|
||||
onBlur={(value: string) => onQueryChange({ ...parsedQuery, resourceType: value })}
|
||||
label="Resource type"
|
||||
newFormStylingEnabled={newFormStylingEnabled}
|
||||
/>
|
||||
{newFormStylingEnabled ? (
|
||||
<EditorField label="Tags" tooltip="Tags to filter the returned values on.">
|
||||
<MultiFilter
|
||||
filters={parsedQuery.tags}
|
||||
@@ -322,18 +273,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
datasource={datasource}
|
||||
/>
|
||||
</EditorField>
|
||||
) : (
|
||||
<InlineField label="Tags" shrink labelWidth={20} tooltip="Tags to filter the returned values on.">
|
||||
<MultiFilter
|
||||
filters={parsedQuery.tags}
|
||||
onChange={(filters) => {
|
||||
onChange({ ...parsedQuery, tags: filters });
|
||||
}}
|
||||
keyPlaceholder="tag"
|
||||
datasource={datasource}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{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}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
formStyles: css({
|
||||
maxWidth: theme.spacing(30),
|
||||
}),
|
||||
dimensionsWidth: css({
|
||||
width: theme.spacing(50),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -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<T> {
|
||||
onChange: (value: T) => void;
|
||||
options: SelectableValue[];
|
||||
@@ -17,7 +13,6 @@ interface VariableQueryFieldProps<T> {
|
||||
inputId?: string;
|
||||
allowCustomValue?: boolean;
|
||||
isLoading?: boolean;
|
||||
newFormStylingEnabled?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@@ -29,11 +24,9 @@ export const VariableQueryField = <T extends string | VariableQueryType>({
|
||||
allowCustomValue = false,
|
||||
isLoading = false,
|
||||
inputId = label,
|
||||
newFormStylingEnabled,
|
||||
error,
|
||||
}: VariableQueryFieldProps<T>) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
return newFormStylingEnabled ? (
|
||||
return (
|
||||
<>
|
||||
<EditorField label={label} htmlFor={inputId} className={removeMarginBottom}>
|
||||
<Select
|
||||
@@ -48,26 +41,5 @@ export const VariableQueryField = <T extends string | VariableQueryType>({
|
||||
</EditorField>
|
||||
{error && <Alert title={error} severity="error" topSpacing={1} />}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<InlineField label={label} labelWidth={LABEL_WIDTH} htmlFor={inputId}>
|
||||
<Select
|
||||
aria-label={label}
|
||||
width={25}
|
||||
allowCustomValue={allowCustomValue}
|
||||
value={value}
|
||||
onChange={({ value }) => onChange(value!)}
|
||||
options={options}
|
||||
isLoading={isLoading}
|
||||
inputId={inputId}
|
||||
/>
|
||||
</InlineField>
|
||||
{error && <Alert className={styles.inlineFieldAlert} title={error} severity="error" topSpacing={1} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
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) }),
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
<EditorField label={label} tooltip={tooltip} tooltipInteractive={interactive} className={removeMarginBottom}>
|
||||
<Input
|
||||
aria-label={label}
|
||||
@@ -37,16 +27,5 @@ export const VariableTextField = ({
|
||||
onBlur={() => onBlur(localValue)}
|
||||
/>
|
||||
</EditorField>
|
||||
) : (
|
||||
<InlineField interactive={interactive} label={label} labelWidth={LABEL_WIDTH} tooltip={tooltip} grow>
|
||||
<Input
|
||||
aria-label={label}
|
||||
placeholder={placeholder}
|
||||
value={localValue}
|
||||
onChange={(e) => setLocalValue(e.currentTarget.value)}
|
||||
onBlur={() => onBlur(localValue)}
|
||||
width={25}
|
||||
/>
|
||||
</InlineField>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user