DataSourceHttpSettings: Replace legacy components and remove gf-form usage (#100583)

* Refactor to remove gf-form

* Change Select to Combobox

* Fix label width

* Add translations

* Fix input and translation keys

* Add aria expanded controls to help button

* Fix dsiabled state for Input

* Fix spacing

* Remove unused import

* Fix spacing for tag selectors

* Change gf-form-label to section

* Update addDataSource e2e flow

* Betterer results

* Use new form component

* Update translations

* Add deprecation notice

* Extract translations

* Update betterer
This commit is contained in:
Tobias Skarhed
2025-03-13 10:20:20 +01:00
committed by GitHub
parent 5d2ba10113
commit 9cc6c596af
10 changed files with 3995 additions and 306 deletions

View File

@ -555,11 +555,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
], ],
"packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx:5381": [
[0, 0, 0, "Do not use the t() function outside of a component or function", "0"],
[0, 0, 0, "Do not use the t() function outside of a component or function", "1"],
[0, 0, 0, "Do not use the t() function outside of a component or function", "2"]
],
"packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [ "packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@ -7635,12 +7630,6 @@ exports[`no undocumented stories`] = {
exports[`no gf-form usage`] = { exports[`no gf-form usage`] = {
value: `{ value: `{
"e2e/old-arch/utils/flows/addDataSource.ts:5381": [
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"]
],
"e2e/utils/flows/addDataSource.ts:5381": [
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"]
],
"packages/grafana-prometheus/src/components/PromExploreExtraField.tsx:5381": [ "packages/grafana-prometheus/src/components/PromExploreExtraField.tsx:5381": [
[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"],
[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"],
@ -7703,29 +7692,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"],
[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"]
], ],
"packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx:5381": [
[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"],
[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"],
[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"],
[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"],
[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"],
[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"],
[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"],
[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"]
],
"packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx:5381": [
[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"],
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"]
],
"packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx:5381": [ "packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx:5381": [
[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"],
[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"],

View File

@ -58,7 +58,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
if (basicAuth) { if (basicAuth) {
cy.contains('label', 'Basic auth').scrollIntoView().click(); cy.contains('label', 'Basic auth').scrollIntoView().click();
cy.contains('.gf-form-group', 'Basic Auth Details') cy.contains('section', 'Basic Auth Details')
.should('be.visible') .should('be.visible')
.scrollIntoView() .scrollIntoView()
.within(() => { .within(() => {

View File

@ -58,7 +58,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
if (basicAuth) { if (basicAuth) {
cy.contains('label', 'Basic auth').scrollIntoView().click(); cy.contains('label', 'Basic auth').scrollIntoView().click();
cy.contains('.gf-form-group', 'Basic Auth Details') cy.contains('section', 'Basic Auth Details')
.should('be.visible') .should('be.visible')
.scrollIntoView() .scrollIntoView()
.within(() => { .within(() => {

View File

@ -32,7 +32,7 @@ const settingsMock: HttpSettingsProps['dataSourceConfig'] = {
password: true, password: true,
}, },
secureJsonFields: {}, secureJsonFields: {},
readOnly: true, readOnly: false,
}; };
const meta: Meta<typeof DataSourceHttpSettings> = { const meta: Meta<typeof DataSourceHttpSettings> = {

View File

@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css } from '@emotion/css';
import { useState, useCallback, useId } from 'react'; import { useState, useCallback, useId, useMemo } from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -7,12 +7,13 @@ import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../themes'; import { useTheme2 } from '../../themes';
import { t, Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { Alert } from '../Alert/Alert'; import { Alert } from '../Alert/Alert';
import { FormField } from '../FormField/FormField'; import { Button } from '../Button';
import { InlineFormLabel } from '../FormLabel/FormLabel'; import { Field } from '../Forms/Field';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
import { Input } from '../Forms/Legacy/Input/Input'; import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
import { Select } from '../Select/Select'; import { Input } from '../Input/Input';
import { Stack } from '../Layout/Stack/Stack';
import { InlineSwitch } from '../Switch/Switch'; import { InlineSwitch } from '../Switch/Switch';
import { TagsInput } from '../TagsInput/TagsInput'; import { TagsInput } from '../TagsInput/TagsInput';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
@ -24,26 +25,16 @@ import { SecureSocksProxySettings } from './SecureSocksProxySettings';
import { TLSAuthSettings } from './TLSAuthSettings'; import { TLSAuthSettings } from './TLSAuthSettings';
import { HttpSettingsProps } from './types'; import { HttpSettingsProps } from './types';
const ACCESS_OPTIONS: Array<SelectableValue<string>> = [ const ACCESS_HELP_ID = 'grafana-http-access-help';
{
label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
value: 'proxy',
},
{
label: t('grafana-ui.data-source-http-settings.access-options-browser', 'Browser'),
value: 'direct',
},
];
const DEFAULT_ACCESS_OPTION = {
label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
value: 'proxy',
};
const HttpAccessHelp = () => { const HttpAccessHelp = () => {
return ( return (
// eslint-disable-next-line @grafana/no-untranslated-strings <Alert
<Alert severity="info" title="" topSpacing={3}> severity="info"
title={t('grafana-ui.data-source-http-settings.access-help-title', 'Access help')}
topSpacing={3}
id={ACCESS_HELP_ID}
>
<p> <p>
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details"> <Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details">
Access mode controls how requests to the data source will be handled. Access mode controls how requests to the data source will be handled.
@ -79,6 +70,9 @@ const HttpAccessHelp = () => {
const LABEL_WIDTH = 26; const LABEL_WIDTH = 26;
/**
* @deprecated Use components from `@grafana/plugin-ui` instead, according to the [migration guide](https://github.com/grafana/plugin-ui/blob/main/src/components/ConfigEditor/migrating-from-datasource-http-settings.md).
*/
export const DataSourceHttpSettings = (props: HttpSettingsProps) => { export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
const { const {
defaultUrl, defaultUrl,
@ -94,6 +88,22 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
urlDocs, urlDocs,
} = props; } = props;
const ACCESS_OPTIONS: Array<SelectableValue<string>> = useMemo(
() => [
{
label: t('grafana-ui.data-source-http-settings.server-mode-label', 'Server (default)'),
value: 'proxy',
},
{
label: t('grafana-ui.data-source-http-settings.browser-mode-label', 'Browser'),
value: 'direct',
},
],
[]
);
const DEFAULT_ACCESS_OPTION = useMemo(() => ACCESS_OPTIONS[0], [ACCESS_OPTIONS]);
const [isAccessHelpVisible, setIsAccessHelpVisible] = useState(false); const [isAccessHelpVisible, setIsAccessHelpVisible] = useState(false);
const [azureAuthEnabled, setAzureAuthEnabled] = useState(false); const [azureAuthEnabled, setAzureAuthEnabled] = useState(false);
const theme = useTheme2(); const theme = useTheme2();
@ -160,97 +170,87 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
); );
} }
const accessSelect = (
<Select
aria-label={t('grafana-ui.data-source-http-settings.default-url-access-select', 'Access')}
className="width-20 gf-form-input"
options={ACCESS_OPTIONS}
value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION}
onChange={(selectedValue) => onSettingsChange({ access: selectedValue.value })}
disabled={dataSourceConfig.readOnly}
/>
);
const isValidUrl = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test( const isValidUrl = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test(
dataSourceConfig.url dataSourceConfig.url
); );
const notValidStyle = css({ const gridLayout = css({
boxShadow: `inset 0 0px 5px ${theme.v1.palette.red}`, display: 'grid',
gridTemplateColumns: 'auto 1fr',
gap: theme.spacing(0.5),
}); });
const inputStyle = cx({ [`width-20`]: true, [notValidStyle]: !isValidUrl });
const fromFieldId = useId(); const fromFieldId = useId();
const urlInput = ( return (
<Stack direction="column" gap={5}>
<section>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.heading">HTTP</Trans>
</h3>
<Field
label={urlLabel ?? 'URL'}
description={urlTooltip}
invalid={!isValidUrl}
error={!isValidUrl && t('grafana-ui.data-source-http-settings.invalid-url-error', 'Invalid URL')}
disabled={dataSourceConfig.readOnly}
>
<Input <Input
id={fromFieldId} id={fromFieldId}
className={inputStyle} width={40}
placeholder={defaultUrl} placeholder={defaultUrl}
value={dataSourceConfig.url} value={dataSourceConfig.url}
data-testid={selectors.components.DataSource.DataSourceHttpSettings.urlInput} data-testid={selectors.components.DataSource.DataSourceHttpSettings.urlInput}
onChange={(event) => onSettingsChange({ url: event.currentTarget.value })} onChange={(event) => onSettingsChange({ url: event.currentTarget.value })}
disabled={dataSourceConfig.readOnly}
/> />
); </Field>
return (
<div className="gf-form-group">
<>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.heading">HTTP</Trans>
</h3>
<div className="gf-form-group">
<div className="gf-form">
<FormField
interactive={urlDocs ? true : false}
label={urlLabel ?? t('grafana-ui.data-source-http-settings.url-label', 'URL')}
labelWidth={13}
tooltip={urlTooltip}
inputEl={urlInput}
/>
</div>
{showAccessOptions && ( {showAccessOptions && (
<> <>
<div className="gf-form-inline"> <Field
<div className="gf-form">
<FormField
label={t('grafana-ui.data-source-http-settings.access-label', 'Access')} label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
labelWidth={13} disabled={dataSourceConfig.readOnly}
inputWidth={20} >
inputEl={accessSelect} <Stack direction="row" gap={0.5}>
<RadioButtonGroup
aria-label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
options={ACCESS_OPTIONS}
value={
ACCESS_OPTIONS.find((o) => o.value === dataSourceConfig.access)?.value ||
DEFAULT_ACCESS_OPTION.value
}
onChange={(selectedValue) => onSettingsChange({ access: selectedValue })}
/> />
</div> <Button
<div className="gf-form">
<button
type="button" type="button"
className="gf-form-label query-keyword pointer" variant="secondary"
size="md"
fill="outline"
onClick={() => setIsAccessHelpVisible((isVisible) => !isVisible)} onClick={() => setIsAccessHelpVisible((isVisible) => !isVisible)}
aria-expanded={isAccessHelpVisible}
aria-controls={ACCESS_HELP_ID}
> >
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help"> <Trans i18nKey="grafana-ui.data-source-http-settings.access-help">
Help&nbsp; Help&nbsp;
<Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} style={{ marginBottom: 0 }} /> <Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} />
</Trans> </Trans>
</button> </Button>
</div> </Stack>
</div> </Field>
{isAccessHelpVisible && <HttpAccessHelp />} {isAccessHelpVisible && <HttpAccessHelp />}
</> </>
)} )}
{dataSourceConfig.access === 'proxy' && ( {dataSourceConfig.access === 'proxy' && (
<div className="gf-form-group"> <>
<div className="gf-form"> <Field
<InlineFormLabel label={t('grafana-ui.data-source-http-settings.allowed-cookies', 'Allowed cookies')}
width={13} description={t(
tooltip={t( 'grafana-ui.data-source-http-settings.allowed-cookies-description',
'grafana-ui.data-source-http-settings.allowed-cookies-tooltip',
'Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.' 'Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.'
)} )}
> >
<Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans>
</InlineFormLabel>
<TagsInput <TagsInput
tags={dataSourceConfig.jsonData.keepCookies} tags={dataSourceConfig.jsonData.keepCookies}
width={40} width={40}
@ -259,36 +259,39 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
} }
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
/> />
</div> </Field>
<div className="gf-form">
<FormField <Field
label={t('grafana-ui.data-source-http-settings.timeout-form-label', 'Timeout')} label={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout')}
description={t(
'grafana-ui.data-source-http-settings.timeout-description',
'HTTP request timeout in seconds'
)}
disabled={dataSourceConfig.readOnly}
>
<Input
type="number" type="number"
labelWidth={13} width={40}
inputWidth={20} placeholder={t('grafana-ui.data-source-http-settings.timeout-placeholder', 'Timeout in seconds')}
tooltip={t('grafana-ui.data-source-http-settings.timeout-tooltip', 'HTTP request timeout in seconds')}
placeholder={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
aria-label={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
value={dataSourceConfig.jsonData.timeout} value={dataSourceConfig.jsonData.timeout}
onChange={(event) => { onChange={(event) => {
onSettingsChange({ onSettingsChange({
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) }, jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) },
}); });
}} }}
disabled={dataSourceConfig.readOnly}
/> />
</div> </Field>
</div>
)}
</div>
</> </>
)}
</section>
<> <section>
<h3 className="page-heading"> <h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.auth">Auth</Trans> <Trans i18nKey="grafana-ui.data-source-http-settings.auth">Auth</Trans>
</h3> </h3>
<div className="gf-form-group"> <Stack direction="column" gap={4}>
<div className="gf-form-inline"> <div>
<div className={gridLayout}>
<InlineField <InlineField
label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')} label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
@ -304,9 +307,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</InlineField> </InlineField>
<InlineField <InlineField
label={t('grafana-ui.data-source-http-settings.with-credential-label', 'With Credentials')} label={t('grafana-ui.data-source-http-settings.with-credentials-label', 'With Credentials')}
tooltip={t( tooltip={t(
'grafana-ui.data-source-http-settings.with-credential-tooltip', 'grafana-ui.data-source-http-settings.with-credentials-tooltip',
'Whether credentials such as cookies or auth headers should be sent with cross-site requests.' 'Whether credentials such as cookies or auth headers should be sent with cross-site requests.'
)} )}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
@ -320,10 +323,8 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
}} }}
/> />
</InlineField> </InlineField>
</div>
{azureAuthSettings?.azureAuthSupported && ( {azureAuthSettings?.azureAuthSupported && (
<div className="gf-form-inline">
<InlineField <InlineField
label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')} label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')}
tooltip={t( tooltip={t(
@ -343,14 +344,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
}} }}
/> />
</InlineField> </InlineField>
</div>
)} )}
{sigV4AuthToggleEnabled && ( {sigV4AuthToggleEnabled && (
<div className="gf-form-inline">
<InlineField <InlineField
// eslint-disable-next-line @grafana/no-untranslated-strings label={t('grafana-ui.data-source-http-settings.sigv4-auth-label', 'SigV4 auth')}
label="SigV4 auth"
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
@ -364,8 +362,8 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
}} }}
/> />
</InlineField> </InlineField>
</div>
)} )}
</div>
{dataSourceConfig.access === 'proxy' && ( {dataSourceConfig.access === 'proxy' && (
<HttpProxySettings <HttpProxySettings
@ -375,15 +373,15 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
/> />
)} )}
</div> </div>
{dataSourceConfig.basicAuth && ( {dataSourceConfig.basicAuth && (
<> <section>
<h6> <Text variant="h6" element="h4">
<Trans i18nKey="grafana-ui.data-source-http-settings.basic-auth">Basic Auth Details</Trans> <Trans i18nKey="grafana-ui.data-source-http-settings.basic-auth">Basic Auth Details</Trans>
</h6> </Text>
<div className="gf-form-group">
<BasicAuthSettings {...props} /> <BasicAuthSettings {...props} />
</div> </section>
</>
)} )}
{azureAuthSettings?.azureAuthSupported && azureAuthEnabled && azureAuthSettings.azureSettingsUI && ( {azureAuthSettings?.azureAuthSupported && azureAuthEnabled && azureAuthSettings.azureSettingsUI && (
@ -398,8 +396,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
{dataSourceConfig.access === 'proxy' && ( {dataSourceConfig.access === 'proxy' && (
<CustomHeadersSettings dataSourceConfig={dataSourceConfig} onChange={onChange} /> <CustomHeadersSettings dataSourceConfig={dataSourceConfig} onChange={onChange} />
)} )}
</> </Stack>
</section>
{secureSocksDSProxyEnabled && <SecureSocksProxySettings options={dataSourceConfig} onOptionsChange={onChange} />} {secureSocksDSProxyEnabled && <SecureSocksProxySettings options={dataSourceConfig} onOptionsChange={onChange} />}
</div> </Stack>
); );
}; };

View File

@ -1,5 +1,11 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { t } from '../../utils/i18n'; import { t } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
import { Stack } from '../Layout/Stack/Stack';
import { InlineSwitch } from '../Switch/Switch'; import { InlineSwitch } from '../Switch/Switch';
import { HttpSettingsBaseProps } from './types'; import { HttpSettingsBaseProps } from './types';
@ -11,9 +17,10 @@ export const HttpProxySettings = ({
onChange, onChange,
showForwardOAuthIdentityOption = true, showForwardOAuthIdentityOption = true,
}: HttpSettingsBaseProps) => { }: HttpSettingsBaseProps) => {
const gridLayout = useStyles2(getGridLayout);
return ( return (
<> <div className={gridLayout}>
<div className="gf-form-inline"> <Stack direction="row" gap={0.5}>
<InlineField <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.ts-client-auth-label', 'TLS Client Auth')} label={t('grafana-ui.data-source-http-proxy-settings.ts-client-auth-label', 'TLS Client Auth')}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
@ -42,8 +49,7 @@ export const HttpProxySettings = ({
} }
/> />
</InlineField> </InlineField>
</div> </Stack>
<div className="gf-form-inline">
<InlineField <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.skip-tls-verify-label', 'Skip TLS Verify')} label={t('grafana-ui.data-source-http-proxy-settings.skip-tls-verify-label', 'Skip TLS Verify')}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
@ -52,14 +58,10 @@ export const HttpProxySettings = ({
<InlineSwitch <InlineSwitch
id="http-settings-skip-tls-verify" id="http-settings-skip-tls-verify"
value={dataSourceConfig.jsonData.tlsSkipVerify || false} value={dataSourceConfig.jsonData.tlsSkipVerify || false}
onChange={(event) => onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked })}
onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked })
}
/> />
</InlineField> </InlineField>
</div>
{showForwardOAuthIdentityOption && ( {showForwardOAuthIdentityOption && (
<div className="gf-form-inline">
<InlineField <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.oauth-identity-label', 'Forward OAuth Identity')} label={t('grafana-ui.data-source-http-proxy-settings.oauth-identity-label', 'Forward OAuth Identity')}
tooltip={t( tooltip={t(
@ -77,8 +79,14 @@ export const HttpProxySettings = ({
} }
/> />
</InlineField> </InlineField>
</div>
)} )}
</> </div>
); );
}; };
const getGridLayout = (theme: GrafanaTheme2) =>
css({
display: 'grid',
gridTemplateColumns: 'auto',
gap: 0, // Inline field has a margin
});

View File

@ -16,7 +16,7 @@ export function SecureSocksProxySettings<T extends SecureSocksProxyConfig>({
onOptionsChange, onOptionsChange,
}: Props<T>): JSX.Element { }: Props<T>): JSX.Element {
return ( return (
<> <div>
<h3 className="page-heading"> <h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-settings.secure-socks-heading">Secure Socks Proxy</Trans> <Trans i18nKey="grafana-ui.data-source-settings.secure-socks-heading">Secure Socks Proxy</Trans>
</h3> </h3>
@ -44,6 +44,6 @@ export function SecureSocksProxySettings<T extends SecureSocksProxyConfig>({
</div> </div>
</div> </div>
</div> </div>
</> </div>
); );
} }

View File

@ -21,8 +21,9 @@ export interface Props extends InputHTMLAttributes<HTMLInputElement> {
/** /**
* Default form field including label used in Grafana UI. Default input element is simple <input />. You can also pass * Default form field including label used in Grafana UI. Default input element is simple <input />. You can also pass
* custom inputEl if required in which case inputWidth and inputProps are ignored. * custom inputEl if required in which case inputWidth and inputProps are ignored.
* @deprecated Please use the {@link Field} component, {@link https://developers.grafana.com/ui/latest/index.html?path=/story/forms-field--simple See Storybook}. *
* For inline fields, use {@link InlineField}, {@link https://developers.grafana.com/ui/latest/index.html?path=/story/forms-inlinefield--basic See Storybook}. * For inline fields, use {@link InlineField}, {@link https://developers.grafana.com/ui/latest/index.html?path=/story/forms-inlinefield--basic See Storybook}.
* @deprecated Please use the {@link Field} component, {@link https://developers.grafana.com/ui/latest/index.html?path=/story/forms-field--simple See Storybook}.
*/ */
export const FormField = ({ export const FormField = ({
label, label,

View File

@ -1858,31 +1858,32 @@
"data-source-http-settings": { "data-source-http-settings": {
"access-help": "Help <1></1>", "access-help": "Help <1></1>",
"access-help-details": "Access mode controls how requests to the data source will be handled.<1> <1>Server</1></1> should be the preferred way if nothing else is stated.", "access-help-details": "Access mode controls how requests to the data source will be handled.<1> <1>Server</1></1> should be the preferred way if nothing else is stated.",
"access-help-title": "Access help",
"access-label": "Access", "access-label": "Access",
"access-options-browser": "Browser",
"access-options-proxy": "Server (default)",
"allowed-cookies": "Allowed cookies", "allowed-cookies": "Allowed cookies",
"allowed-cookies-tooltip": "Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.", "allowed-cookies-description": "Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.",
"auth": "Auth", "auth": "Auth",
"azure-auth-label": "Azure Authentication", "azure-auth-label": "Azure Authentication",
"azure-auth-tooltip": "Use Azure authentication for Azure endpoint.", "azure-auth-tooltip": "Use Azure authentication for Azure endpoint.",
"basic-auth": "Basic Auth Details", "basic-auth": "Basic Auth Details",
"basic-auth-label": "Basic auth", "basic-auth-label": "Basic auth",
"browser-mode-description": "All requests will be made from the browser directly to the data source and may be subject to Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this access mode.", "browser-mode-description": "All requests will be made from the browser directly to the data source and may be subject to Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this access mode.",
"browser-mode-label": "Browser",
"browser-mode-title": "<0>Browser access mode:</0>", "browser-mode-title": "<0>Browser access mode:</0>",
"default-url-access-select": "Access",
"default-url-tooltip": "Specify a complete HTTP URL (for example http://your_server:8080)", "default-url-tooltip": "Specify a complete HTTP URL (for example http://your_server:8080)",
"direct-url-tooltip": "Your access method is <1>Browser</1>, this means the URL needs to be accessible from the browser.", "direct-url-tooltip": "Your access method is <1>Browser</1>, this means the URL needs to be accessible from the browser.",
"heading": "HTTP", "heading": "HTTP",
"invalid-url-error": "Invalid URL",
"proxy-url-tooltip": "Your access method is <1>Server</1>, this means the URL needs to be accessible from the grafana backend/server.", "proxy-url-tooltip": "Your access method is <1>Server</1>, this means the URL needs to be accessible from the grafana backend/server.",
"server-mode-description": "All requests will be made from the browser to Grafana backend/server which in turn will forward the requests to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the grafana backend/server if you select this access mode.", "server-mode-description": "All requests will be made from the browser to Grafana backend/server which in turn will forward the requests to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the grafana backend/server if you select this access mode.",
"server-mode-label": "Server (default)",
"server-mode-title": "<0>Server access mode (Default):</0>", "server-mode-title": "<0>Server access mode (Default):</0>",
"timeout-form-label": "Timeout", "sigv4-auth-label": "SigV4 auth",
"timeout-label": "Timeout in seconds", "timeout-description": "HTTP request timeout in seconds",
"timeout-tooltip": "HTTP request timeout in seconds", "timeout-label": "Timeout",
"url-label": "URL", "timeout-placeholder": "Timeout in seconds",
"with-credential-label": "With Credentials", "with-credentials-label": "With Credentials",
"with-credential-tooltip": "Whether credentials such as cookies or auth headers should be sent with cross-site requests." "with-credentials-tooltip": "Whether credentials such as cookies or auth headers should be sent with cross-site requests."
}, },
"data-source-settings": { "data-source-settings": {
"alerting-settings-heading": "Alerting", "alerting-settings-heading": "Alerting",

File diff suppressed because it is too large Load Diff