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
pull/101958/head^2
Tobias Skarhed 4 months ago committed by GitHub
parent 5d2ba10113
commit 9cc6c596af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 34
      .betterer.results
  2. 2
      e2e/old-arch/utils/flows/addDataSource.ts
  3. 2
      e2e/utils/flows/addDataSource.ts
  4. 2
      packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.story.tsx
  5. 423
      packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx
  6. 68
      packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx
  7. 4
      packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx
  8. 3
      packages/grafana-ui/src/components/FormField/FormField.tsx
  9. 21
      public/locales/en-US/grafana.json
  10. 3714
      public/locales/pseudo-LOCALE/grafana.json

@ -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"],

@ -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(() => {

@ -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(() => {

@ -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> = {

@ -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,246 +170,235 @@ 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 = (
<Input
id={fromFieldId}
className={inputStyle}
placeholder={defaultUrl}
value={dataSourceConfig.url}
data-testid={selectors.components.DataSource.DataSourceHttpSettings.urlInput}
onChange={(event) => onSettingsChange({ url: event.currentTarget.value })}
disabled={dataSourceConfig.readOnly}
/>
);
return ( return (
<div className="gf-form-group"> <Stack direction="column" gap={5}>
<> <section>
<h3 className="page-heading"> <h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.heading">HTTP</Trans> <Trans i18nKey="grafana-ui.data-source-http-settings.heading">HTTP</Trans>
</h3> </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 && ( <Field
<> label={urlLabel ?? 'URL'}
<div className="gf-form-inline"> description={urlTooltip}
<div className="gf-form"> invalid={!isValidUrl}
<FormField error={!isValidUrl && t('grafana-ui.data-source-http-settings.invalid-url-error', 'Invalid URL')}
label={t('grafana-ui.data-source-http-settings.access-label', 'Access')} disabled={dataSourceConfig.readOnly}
labelWidth={13} >
inputWidth={20} <Input
inputEl={accessSelect} id={fromFieldId}
/> width={40}
</div> placeholder={defaultUrl}
<div className="gf-form"> value={dataSourceConfig.url}
<button data-testid={selectors.components.DataSource.DataSourceHttpSettings.urlInput}
type="button" onChange={(event) => onSettingsChange({ url: event.currentTarget.value })}
className="gf-form-label query-keyword pointer" />
onClick={() => setIsAccessHelpVisible((isVisible) => !isVisible)} </Field>
>
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help"> {showAccessOptions && (
Help&nbsp; <>
<Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} style={{ marginBottom: 0 }} /> <Field
</Trans> label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
</button> disabled={dataSourceConfig.readOnly}
</div> >
</div> <Stack direction="row" gap={0.5}>
{isAccessHelpVisible && <HttpAccessHelp />} <RadioButtonGroup
</> aria-label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
)} options={ACCESS_OPTIONS}
{dataSourceConfig.access === 'proxy' && ( value={
<div className="gf-form-group"> ACCESS_OPTIONS.find((o) => o.value === dataSourceConfig.access)?.value ||
<div className="gf-form"> DEFAULT_ACCESS_OPTION.value
<InlineFormLabel
width={13}
tooltip={t(
'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.'
)}
>
<Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans>
</InlineFormLabel>
<TagsInput
tags={dataSourceConfig.jsonData.keepCookies}
width={40}
onChange={(cookies) =>
onSettingsChange({ jsonData: { ...dataSourceConfig.jsonData, keepCookies: cookies } })
} }
disabled={dataSourceConfig.readOnly} onChange={(selectedValue) => onSettingsChange({ access: selectedValue })}
/> />
</div> <Button
<div className="gf-form"> type="button"
<FormField variant="secondary"
label={t('grafana-ui.data-source-http-settings.timeout-form-label', 'Timeout')} size="md"
type="number" fill="outline"
labelWidth={13} onClick={() => setIsAccessHelpVisible((isVisible) => !isVisible)}
inputWidth={20} aria-expanded={isAccessHelpVisible}
tooltip={t('grafana-ui.data-source-http-settings.timeout-tooltip', 'HTTP request timeout in seconds')} aria-controls={ACCESS_HELP_ID}
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')} <Trans i18nKey="grafana-ui.data-source-http-settings.access-help">
value={dataSourceConfig.jsonData.timeout} Help&nbsp;
onChange={(event) => { <Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} />
onSettingsChange({ </Trans>
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) }, </Button>
}); </Stack>
}} </Field>
disabled={dataSourceConfig.readOnly}
/>
</div>
</div>
)}
</div>
</>
<> {isAccessHelpVisible && <HttpAccessHelp />}
<h3 className="page-heading"> </>
<Trans i18nKey="grafana-ui.data-source-http-settings.auth">Auth</Trans> )}
</h3> {dataSourceConfig.access === 'proxy' && (
<div className="gf-form-group"> <>
<div className="gf-form-inline"> <Field
<InlineField label={t('grafana-ui.data-source-http-settings.allowed-cookies', 'Allowed cookies')}
label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')} description={t(
labelWidth={LABEL_WIDTH} 'grafana-ui.data-source-http-settings.allowed-cookies-description',
disabled={dataSourceConfig.readOnly} 'Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.'
)}
> >
<InlineSwitch <TagsInput
id="http-settings-basic-auth" tags={dataSourceConfig.jsonData.keepCookies}
value={dataSourceConfig.basicAuth} width={40}
onChange={(event) => { onChange={(cookies) =>
onSettingsChange({ basicAuth: event!.currentTarget.checked }); onSettingsChange({ jsonData: { ...dataSourceConfig.jsonData, keepCookies: cookies } })
}} }
disabled={dataSourceConfig.readOnly}
/> />
</InlineField> </Field>
<InlineField <Field
label={t('grafana-ui.data-source-http-settings.with-credential-label', 'With Credentials')} label={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout')}
tooltip={t( description={t(
'grafana-ui.data-source-http-settings.with-credential-tooltip', 'grafana-ui.data-source-http-settings.timeout-description',
'Whether credentials such as cookies or auth headers should be sent with cross-site requests.' 'HTTP request timeout in seconds'
)} )}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
<InlineSwitch <Input
id="http-settings-with-credentials" type="number"
value={dataSourceConfig.withCredentials} width={40}
placeholder={t('grafana-ui.data-source-http-settings.timeout-placeholder', 'Timeout in seconds')}
value={dataSourceConfig.jsonData.timeout}
onChange={(event) => { onChange={(event) => {
onSettingsChange({ withCredentials: event!.currentTarget.checked }); onSettingsChange({
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) },
});
}} }}
/> />
</InlineField> </Field>
</div> </>
)}
</section>
{azureAuthSettings?.azureAuthSupported && ( <section>
<div className="gf-form-inline"> <h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.auth">Auth</Trans>
</h3>
<Stack direction="column" gap={4}>
<div>
<div className={gridLayout}>
<InlineField <InlineField
label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')} label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')}
tooltip={t(
'grafana-ui.data-source-http-settings.azure-auth-tooltip',
'Use Azure authentication for Azure endpoint.'
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
<InlineSwitch <InlineSwitch
id="http-settings-azure-auth" id="http-settings-basic-auth"
value={azureAuthEnabled} value={dataSourceConfig.basicAuth}
onChange={(event) => { onChange={(event) => {
onSettingsChange( onSettingsChange({ basicAuth: event!.currentTarget.checked });
azureAuthSettings.setAzureAuthEnabled(dataSourceConfig, event!.currentTarget.checked)
);
}} }}
/> />
</InlineField> </InlineField>
</div>
)}
{sigV4AuthToggleEnabled && (
<div className="gf-form-inline">
<InlineField <InlineField
// eslint-disable-next-line @grafana/no-untranslated-strings label={t('grafana-ui.data-source-http-settings.with-credentials-label', 'With Credentials')}
label="SigV4 auth" tooltip={t(
'grafana-ui.data-source-http-settings.with-credentials-tooltip',
'Whether credentials such as cookies or auth headers should be sent with cross-site requests.'
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
<InlineSwitch <InlineSwitch
id="http-settings-sigv4-auth" id="http-settings-with-credentials"
value={dataSourceConfig.jsonData.sigV4Auth || false} value={dataSourceConfig.withCredentials}
onChange={(event) => { onChange={(event) => {
onSettingsChange({ onSettingsChange({ withCredentials: event!.currentTarget.checked });
jsonData: { ...dataSourceConfig.jsonData, sigV4Auth: event!.currentTarget.checked },
});
}} }}
/> />
</InlineField> </InlineField>
{azureAuthSettings?.azureAuthSupported && (
<InlineField
label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')}
tooltip={t(
'grafana-ui.data-source-http-settings.azure-auth-tooltip',
'Use Azure authentication for Azure endpoint.'
)}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch
id="http-settings-azure-auth"
value={azureAuthEnabled}
onChange={(event) => {
onSettingsChange(
azureAuthSettings.setAzureAuthEnabled(dataSourceConfig, event!.currentTarget.checked)
);
}}
/>
</InlineField>
)}
{sigV4AuthToggleEnabled && (
<InlineField
label={t('grafana-ui.data-source-http-settings.sigv4-auth-label', 'SigV4 auth')}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch
id="http-settings-sigv4-auth"
value={dataSourceConfig.jsonData.sigV4Auth || false}
onChange={(event) => {
onSettingsChange({
jsonData: { ...dataSourceConfig.jsonData, sigV4Auth: event!.currentTarget.checked },
});
}}
/>
</InlineField>
)}
</div> </div>
)}
{dataSourceConfig.access === 'proxy' && ( {dataSourceConfig.access === 'proxy' && (
<HttpProxySettings <HttpProxySettings
dataSourceConfig={dataSourceConfig} dataSourceConfig={dataSourceConfig}
onChange={(jsonData) => onSettingsChange({ jsonData })} onChange={(jsonData) => onSettingsChange({ jsonData })}
showForwardOAuthIdentityOption={azureAuthEnabled ? false : showForwardOAuthIdentityOption} showForwardOAuthIdentityOption={azureAuthEnabled ? false : showForwardOAuthIdentityOption}
/> />
)} )}
</div> </div>
{dataSourceConfig.basicAuth && (
<> {dataSourceConfig.basicAuth && (
<h6> <section>
<Trans i18nKey="grafana-ui.data-source-http-settings.basic-auth">Basic Auth Details</Trans> <Text variant="h6" element="h4">
</h6> <Trans i18nKey="grafana-ui.data-source-http-settings.basic-auth">Basic Auth Details</Trans>
<div className="gf-form-group"> </Text>
<BasicAuthSettings {...props} /> <BasicAuthSettings {...props} />
</div> </section>
</> )}
)}
{azureAuthSettings?.azureAuthSupported && azureAuthEnabled && azureAuthSettings.azureSettingsUI && ( {azureAuthSettings?.azureAuthSupported && azureAuthEnabled && azureAuthSettings.azureSettingsUI && (
<azureAuthSettings.azureSettingsUI dataSourceConfig={dataSourceConfig} onChange={onChange} /> <azureAuthSettings.azureSettingsUI dataSourceConfig={dataSourceConfig} onChange={onChange} />
)} )}
{dataSourceConfig.jsonData.sigV4Auth && sigV4AuthToggleEnabled && renderSigV4Editor} {dataSourceConfig.jsonData.sigV4Auth && sigV4AuthToggleEnabled && renderSigV4Editor}
{(dataSourceConfig.jsonData.tlsAuth || dataSourceConfig.jsonData.tlsAuthWithCACert) && ( {(dataSourceConfig.jsonData.tlsAuth || dataSourceConfig.jsonData.tlsAuthWithCACert) && (
<TLSAuthSettings dataSourceConfig={dataSourceConfig} onChange={onChange} /> <TLSAuthSettings dataSourceConfig={dataSourceConfig} onChange={onChange} />
)} )}
{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>
); );
}; };

@ -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,43 +49,44 @@ export const HttpProxySettings = ({
} }
/> />
</InlineField> </InlineField>
</div> </Stack>
<div className="gf-form-inline"> <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.skip-tls-verify-label', 'Skip TLS Verify')}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch
id="http-settings-skip-tls-verify"
value={dataSourceConfig.jsonData.tlsSkipVerify || false}
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked })}
/>
</InlineField>
{showForwardOAuthIdentityOption && (
<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.oauth-identity-label', 'Forward OAuth Identity')}
tooltip={t(
'grafana-ui.data-source-http-proxy-settings.oauth-identity-tooltip',
"Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
<InlineSwitch <InlineSwitch
id="http-settings-skip-tls-verify" id="http-settings-forward-oauth"
value={dataSourceConfig.jsonData.tlsSkipVerify || false} value={dataSourceConfig.jsonData.oauthPassThru || false}
onChange={(event) => onChange={(event) =>
onChange({ ...dataSourceConfig.jsonData, tlsSkipVerify: event!.currentTarget.checked }) onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })
} }
/> />
</InlineField> </InlineField>
</div>
{showForwardOAuthIdentityOption && (
<div className="gf-form-inline">
<InlineField
label={t('grafana-ui.data-source-http-proxy-settings.oauth-identity-label', 'Forward OAuth Identity')}
tooltip={t(
'grafana-ui.data-source-http-proxy-settings.oauth-identity-tooltip',
"Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
)}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch
id="http-settings-forward-oauth"
value={dataSourceConfig.jsonData.oauthPassThru || false}
onChange={(event) =>
onChange({ ...dataSourceConfig.jsonData, oauthPassThru: event!.currentTarget.checked })
}
/>
</InlineField>
</div>
)} )}
</> </div>
); );
}; };
const getGridLayout = (theme: GrafanaTheme2) =>
css({
display: 'grid',
gridTemplateColumns: 'auto',
gap: 0, // Inline field has a margin
});

@ -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>
); );
} }

@ -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,

@ -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
Loading…
Cancel
Save