[InfluxDB] Config design improvements (#108562)

This commit is contained in:
Alyssa Joyner 2025-08-12 14:23:51 -06:00 committed by GitHub
parent 08501677e3
commit 1ce333a572
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 191 additions and 98 deletions

View File

@ -12,15 +12,16 @@ interface Props {
label: string;
hasCert: boolean;
placeholder: string;
useGrow?: boolean;
onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;
onClick: (event: MouseEvent<HTMLButtonElement>) => void;
}
export const CertificationKey = ({ hasCert, label, onChange, onClick, placeholder }: Props) => {
export const CertificationKey = ({ hasCert, label, onChange, onClick, placeholder, useGrow }: Props) => {
return (
<InlineFieldRow>
<InlineField label={label} labelWidth={14} disabled={hasCert}>
<InlineField label={label} labelWidth={14} disabled={hasCert} grow={useGrow}>
{hasCert ? (
<Input type="text" value="configured" width={24} />
) : (

View File

@ -11,7 +11,7 @@ import { InlineFieldRow, InlineField, Combobox, InlineSwitch, Input, Space, useS
import { InfluxVersion } from '../../../types';
import { getInlineLabelStyles, HTTP_MODES } from './constants';
import { DB_SETTINGS_LABEL_WIDTH, getInlineLabelStyles, HTTP_MODES } from './constants';
import {
trackInfluxDBConfigV2AdvancedDbConnectionSettingsAutocompleteClicked,
trackInfluxDBConfigV2AdvancedDbConnectionSettingsHTTPMethodClicked,
@ -55,13 +55,13 @@ export const AdvancedDbConnectionSettings = (props: Props) => {
<InlineFieldRow>
<InlineField
label="HTTP Method"
labelWidth={30}
labelWidth={DB_SETTINGS_LABEL_WIDTH}
tooltip="You can use either GET or POST HTTP method to query your InfluxDB database. The POST
method allows you to perform heavy requests (with a lots of WHERE clause) while the GET method
will restrict you and return an error if the query is too large."
grow
>
<Combobox
width={30}
value={HTTP_MODES.find((httpMode) => httpMode.value === options.jsonData.httpMode)}
options={HTTP_MODES}
onChange={onUpdateDatasourceJsonDataOptionSelect(props, 'httpMode')}
@ -72,28 +72,15 @@ export const AdvancedDbConnectionSettings = (props: Props) => {
</InlineFieldRow>
)}
{options.jsonData.version === InfluxVersion.SQL && (
<InlineFieldRow>
<InlineField label="Insecure Connection" labelWidth={30}>
<InlineSwitch
data-testid="influxdb-v2-config-insecure-switch"
value={options.jsonData.insecureGrpc ?? false}
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'insecureGrpc')}
onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsInsecureConnectClicked}
/>
</InlineField>
</InlineFieldRow>
)}
{(options.jsonData.version === InfluxVersion.InfluxQL || options.jsonData.version === InfluxVersion.Flux) && (
<InlineFieldRow>
<InlineField
label="Min time interval"
labelWidth={30}
labelWidth={DB_SETTINGS_LABEL_WIDTH}
tooltip="A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example 1m if your data is written every minute."
grow
>
<Input
className="width-15"
data-testid="influxdb-v2-config-time-interval"
onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsMinTimeClicked}
onChange={onUpdateDatasourceJsonDataOption(props, 'timeInterval')}
@ -108,11 +95,11 @@ export const AdvancedDbConnectionSettings = (props: Props) => {
<InlineFieldRow>
<InlineField
label="Autocomplete Range"
labelWidth={30}
labelWidth={DB_SETTINGS_LABEL_WIDTH}
tooltip="This time range is used in the query editor's autocomplete to reduce the execution time of tag filter queries."
grow
>
<Input
className="width-15"
data-testid="influxdb-v2-config-autocomplete-range"
onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsAutocompleteClicked}
onChange={onUpdateDatasourceJsonDataOption(props, 'showTagTime')}
@ -126,11 +113,11 @@ export const AdvancedDbConnectionSettings = (props: Props) => {
<InlineFieldRow>
<InlineField
label="Max series"
labelWidth={30}
labelWidth={DB_SETTINGS_LABEL_WIDTH}
tooltip="Limit the number of series/tables that Grafana will process. Lower this number to prevent abuse, and increase it if you have lots of small time series and not all are shown. Defaults to 1000."
grow
>
<Input
className="width-15"
data-testid="influxdb-v2-config-max-series"
onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsMaxSeriesClicked}
onChange={onMaxSeriesChange}
@ -140,6 +127,18 @@ export const AdvancedDbConnectionSettings = (props: Props) => {
/>
</InlineField>
</InlineFieldRow>
{options.jsonData.version === InfluxVersion.SQL && (
<InlineFieldRow>
<InlineField label="Insecure Connection" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<InlineSwitch
data-testid="influxdb-v2-config-insecure-switch"
value={options.jsonData.insecureGrpc ?? false}
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'insecureGrpc')}
onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsInsecureConnectClicked}
/>
</InlineField>
</InlineFieldRow>
)}
</>
)}
</>

View File

@ -26,9 +26,14 @@ export type Props = DataSourcePluginOptionsEditorProps<InfluxOptions>;
export const AdvancedHttpSettings = ({ options, onOptionsChange }: Props) => {
const styles = useStyles2(getInlineLabelStyles);
const [advancedHttpSettingsIsOpen, setAdvancedHttpSettingsIsOpen] = useState(
() => 'keepCookies' in options.jsonData || 'timeout' in options.jsonData
);
const [advancedHttpSettingsIsOpen, setAdvancedHttpSettingsIsOpen] = useState(() => {
const keys = Object.keys(options.jsonData);
return (
'keepCookies' in options.jsonData ||
'timeout' in options.jsonData ||
keys.some((key) => key.includes('httpHeaderName'))
);
});
return (
<>

View File

@ -127,5 +127,22 @@ describe('AuthSettings', () => {
expect(skipSwitch).not.toBeChecked();
});
});
describe('With Credentials toggle', () => {
it('toggles checked state of the switch', () => {
const withCredentialsSwitch = screen.getByTestId('influxdb-v2-config-auth-settings-with-credentials');
// Default unchecked
expect(withCredentialsSwitch).not.toBeChecked();
// Enable
fireEvent.click(withCredentialsSwitch);
expect(withCredentialsSwitch).toBeChecked();
// Disable
fireEvent.click(withCredentialsSwitch);
expect(withCredentialsSwitch).not.toBeChecked();
});
});
});
});

View File

@ -1,5 +1,6 @@
import { cx } from '@emotion/css';
import { useCallback, useMemo, useState } from 'react';
import { useWindowSize } from 'react-use';
import {
onUpdateDatasourceOption,
@ -7,6 +8,7 @@ import {
updateDatasourcePluginResetOption,
} from '@grafana/data';
import { AuthMethod, convertLegacyAuthProps } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime';
import {
Box,
CertificationKey,
@ -20,9 +22,15 @@ import {
useStyles2,
Text,
Stack,
InlineLabel,
} from '@grafana/ui';
import { AUTH_RADIO_BUTTON_OPTIONS, getInlineLabelStyles, RADIO_BUTTON_OPTIONS } from './constants';
import {
AUTH_RADIO_BUTTON_OPTIONS,
DB_SETTINGS_LABEL_WIDTH,
getInlineLabelStyles,
RADIO_BUTTON_OPTIONS,
} from './constants';
import {
trackInfluxDBConfigV2AuthSettingsAuthMethodSelected,
trackInfluxDBConfigV2AuthSettingsToggleClicked,
@ -30,6 +38,7 @@ import {
import { Props } from './types';
type AuthOptionState = {
noAuth: boolean;
basicAuth: boolean;
tlsClientAuth: boolean;
caCert: boolean;
@ -41,10 +50,8 @@ type AuthOptionState = {
export const AuthSettings = (props: Props) => {
const { options, onOptionsChange } = props;
const styles = useStyles2(getInlineLabelStyles);
const { width } = useWindowSize();
/**
* Derived props from legacy helpers
*/
const authProps = useMemo(
() =>
convertLegacyAuthProps({
@ -54,36 +61,38 @@ export const AuthSettings = (props: Props) => {
[options, onOptionsChange]
);
/**
* Selected authentication method. Fallback to the most common if the selected one is missing.
*/
const isAuthMethod = (v: unknown): v is AuthMethod =>
v === AuthMethod.NoAuth || v === AuthMethod.BasicAuth || v === AuthMethod.OAuthForward;
const selectedMethod = useMemo<AuthMethod | undefined>(() => {
if (isAuthMethod(authProps.selectedMethod)) {
return authProps.selectedMethod;
}
return isAuthMethod(authProps.mostCommonMethod) ? authProps.mostCommonMethod : undefined;
}, [authProps.selectedMethod, authProps.mostCommonMethod]);
/**
* Local UI state
*/
const [authOptions, setAuthOptions] = useState<AuthOptionState>({
basicAuth: selectedMethod === AuthMethod.BasicAuth,
noAuth: (!options.basicAuth && !options.jsonData.oauthPassThru) ?? false,
basicAuth: options.basicAuth ?? false,
tlsClientAuth: authProps.TLS?.TLSClientAuth.enabled ?? false,
caCert: authProps.TLS?.selfSignedCertificate.enabled ?? false,
skipTLS: authProps.TLS?.skipTLSVerification.enabled ?? false,
oAuthForward: selectedMethod === AuthMethod.OAuthForward,
oAuthForward: options.jsonData.oauthPassThru ?? false,
withCredentials: options.withCredentials ?? false,
});
/**
* Expand/collapse toplevel section
*/
const [authenticationSettingsIsOpen, setAuthenticationSettingsIsOpen] = useState(
Object.values(authOptions).some(Boolean)
const selectedMethod = useMemo<AuthMethod | undefined>(() => {
if (isAuthMethod(authProps.selectedMethod) && authProps.selectedMethod !== AuthMethod.CrossSiteCredentials) {
return authProps.selectedMethod;
}
switch (!!authOptions) {
case authOptions.basicAuth:
return AuthMethod.BasicAuth;
case authOptions.oAuthForward:
return AuthMethod.OAuthForward;
case authOptions.noAuth:
return AuthMethod.NoAuth;
default:
return undefined;
}
}, [authProps.selectedMethod, authOptions]);
const [authenticationSettingsIsOpen, setAuthenticationSettingsIsOpen] = useState(() =>
Object.entries(authOptions).some(([key, value]) => key !== 'noAuth' && Boolean(value))
);
const toggleOpen = useCallback(() => {
@ -98,8 +107,10 @@ export const AuthSettings = (props: Props) => {
authProps.onAuthMethodSelect(option);
setAuthOptions((prev) => ({
...prev,
noAuth: option === AuthMethod.NoAuth,
basicAuth: option === AuthMethod.BasicAuth,
oAuthForward: option === AuthMethod.OAuthForward,
withCredentials: prev.withCredentials,
}));
trackInfluxDBConfigV2AuthSettingsAuthMethodSelected({ authMethod: option });
},
@ -121,7 +132,6 @@ export const AuthSettings = (props: Props) => {
return (
<Stack direction="column">
{/* Header toggle */}
<Box alignItems="center">
<InlineField label={<div className={cx(styles.label)}>Auth and TLS/SSL Settings</div>} labelWidth={35}>
<InlineSwitch
@ -132,35 +142,33 @@ export const AuthSettings = (props: Props) => {
</InlineField>
</Box>
{/* Collapsible settings body */}
{authenticationSettingsIsOpen && (
<Box paddingLeft={1}>
{/* Authentication Method */}
<Box marginBottom={2}>
<Box marginBottom={1}>
<Field label={<Text element="h5">Authentication Method</Text>} noMargin>
<Box width="50%" marginY={2}>
<RadioButtonGroup
options={AUTH_RADIO_BUTTON_OPTIONS}
value={selectedMethod}
onChange={handleAuthMethodChange}
size={width < 1100 ? 'sm' : 'md'}
/>
</Box>
</Field>
</Box>
<Box marginBottom={2}>
{/* Basic Auth settings */}
{authOptions.basicAuth && (
{authOptions.basicAuth && (
<Box marginBottom={2}>
<>
<Box display="flex" direction="column" width="60%" marginBottom={2}>
<InlineField label="User" labelWidth={14} grow>
<Box display="flex" direction="column" marginBottom={2}>
<InlineField label="User" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<Input
placeholder="User"
onChange={onUpdateDatasourceOption(props, 'basicAuthUser')}
value={options.basicAuthUser || ''}
/>
</InlineField>
<InlineField label="Password" labelWidth={14} grow>
<InlineField label="Password" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<SecretInput
placeholder="Password"
isConfigured={options.secureJsonFields.basicAuthPassword || false}
@ -171,10 +179,38 @@ export const AuthSettings = (props: Props) => {
</InlineField>
</Box>
</>
)}
</Box>
)}
<Box display="flex" direction="row" alignItems="center" marginBottom={2}>
<InlineLabel
style={{ width: '150px' }}
tooltip={'Whether credentials such as cookies or auth headers should be sent with cross-site requests.'}
>
With Credentials
</InlineLabel>
<InlineSwitch
data-testid="influxdb-v2-config-auth-settings-with-credentials"
value={authOptions.withCredentials}
onChange={(e) => {
authProps.onAuthMethodSelect(selectedMethod!);
onOptionsChange({
...options,
withCredentials: e.currentTarget.checked,
jsonData: {
...options.jsonData,
oauthPassThru: selectedMethod === AuthMethod.OAuthForward,
},
});
setAuthOptions({
...authOptions,
noAuth: selectedMethod === AuthMethod.NoAuth,
basicAuth: selectedMethod === AuthMethod.BasicAuth,
oAuthForward: selectedMethod === AuthMethod.OAuthForward,
withCredentials: e.currentTarget.checked,
});
}}
/>
</Box>
{/* TLS Client Auth */}
<Box marginBottom={2}>
<Field noMargin>
<>
@ -209,6 +245,7 @@ export const AuthSettings = (props: Props) => {
onChange={(e) => authProps.TLS?.TLSClientAuth.onClientCertificateChange(e.currentTarget.value)}
hasCert={!!authProps.TLS?.TLSClientAuth.clientCertificateConfigured}
onClick={() => authProps.TLS?.TLSClientAuth.onClientCertificateReset()}
useGrow={config.featureToggles.newInfluxDSConfigPageDesign}
/>
<CertificationKey
label="Client Key"
@ -216,6 +253,7 @@ export const AuthSettings = (props: Props) => {
onChange={(e) => authProps.TLS?.TLSClientAuth.onClientKeyChange(e.currentTarget.value)}
hasCert={!!authProps.TLS?.TLSClientAuth.clientKeyConfigured}
onClick={() => authProps.TLS?.TLSClientAuth.onClientKeyReset()}
useGrow={config.featureToggles.newInfluxDSConfigPageDesign}
/>
</Box>
)}
@ -223,7 +261,6 @@ export const AuthSettings = (props: Props) => {
</Field>
</Box>
{/* CA Cert */}
<Box marginBottom={2}>
<Field noMargin>
<>
@ -244,6 +281,7 @@ export const AuthSettings = (props: Props) => {
onChange={(e) => authProps.TLS?.selfSignedCertificate.onCertificateChange(e.currentTarget.value)}
hasCert={!!authProps.TLS?.selfSignedCertificate.certificateConfigured}
onClick={() => authProps.TLS?.selfSignedCertificate.onCertificateReset()}
useGrow={config.featureToggles.newInfluxDSConfigPageDesign}
/>
</Box>
)}
@ -251,9 +289,8 @@ export const AuthSettings = (props: Props) => {
</Field>
</Box>
{/* Skip TLS verify */}
<Box display="flex" direction="row" alignItems="center">
<Label style={{ width: '125px' }}>Skip TLS Verify</Label>
<InlineLabel style={{ width: '150px' }}>Skip TLS Verify</InlineLabel>
<InlineSwitch
data-testid="influxdb-v2-config-auth-settings-skip-tls-verify"
value={authOptions.skipTLS}

View File

@ -1,32 +1,37 @@
import { css } from '@emotion/css';
import React from 'react';
import { Alert, Box, Stack, TextLink } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
import { Alert, Box, Stack, TextLink, useStyles2 } from '@grafana/ui';
import { DatabaseConnectionSection } from './DatabaseConnectionSection';
import { LeftSideBar } from './LeftSideBar';
import { UrlAndAuthenticationSection } from './UrlAndAuthenticationSection';
import { CONTAINER_MIN_WIDTH } from './constants';
import { trackInfluxDBConfigV2FeedbackButtonClicked } from './tracking';
import { Props } from './types';
export const ConfigEditor: React.FC<Props> = ({ onOptionsChange, options }: Props) => {
const styles = useStyles2(getStyles);
return (
<Stack justifyContent="space-between">
<Box width="250px" flex="0 0 250px">
<LeftSideBar pdcInjected={options?.jsonData?.pdcInjected!!} />
</Box>
<Box width="60%" flex="1 1 auto">
<div className={styles.hideOnSmallScreen}>
<Box width="100%" flex="1 1 auto">
<LeftSideBar pdcInjected={options?.jsonData?.pdcInjected!!} />
</Box>
</div>
<Box width="60%" flex="1 1 auto" minWidth={CONTAINER_MIN_WIDTH}>
<Stack direction="column">
<Alert severity="info" title="You are viewing a new design for the InfluxDB configuration settings.">
<>
If something isn't working correctly, you can revert to the original configuration page design by
disabling the <code>newInfluxDSConfigPageDesign</code> feature flag.{' '}
<TextLink
href="https://docs.google.com/forms/d/e/1FAIpQLSdi-zyX3c51vh937UKhNYYxhljUnFi6dQSlZv50mES9NrK-ig/viewform"
external
onClick={trackInfluxDBConfigV2FeedbackButtonClicked}
>
Submit feedback.
</TextLink>
Share your thoughts
</TextLink>{' '}
to help us make it even better.
</>
</Alert>
<UrlAndAuthenticationSection options={options} onOptionsChange={onOptionsChange} />
@ -39,3 +44,15 @@ export const ConfigEditor: React.FC<Props> = ({ onOptionsChange, options }: Prop
</Stack>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
hideOnSmallScreen: css({
width: '250px',
flex: '0 0 250px',
[theme.breakpoints.down('sm')]: {
display: 'none',
},
}),
};
};

View File

@ -6,12 +6,19 @@ import { AdvancedDbConnectionSettings } from './AdvancedDBConnectionSettings';
import { InfluxFluxDBConnection } from './InfluxFluxDBConnection';
import { InfluxInfluxQLDBConnection } from './InfluxInfluxQLDBConnection';
import { InfluxSQLDBConnection } from './InfluxSQLDBConnection';
import { CONFIG_SECTION_HEADERS } from './constants';
import { CONFIG_SECTION_HEADERS, CONTAINER_MIN_WIDTH } from './constants';
import { Props } from './types';
export const DatabaseConnectionSection = ({ options, onOptionsChange }: Props) => (
<>
<Box borderStyle="solid" borderColor="weak" padding={2} marginBottom={4} id={`${CONFIG_SECTION_HEADERS[1].id}`}>
<Box
borderStyle="solid"
borderColor="weak"
padding={2}
marginBottom={4}
id={`${CONFIG_SECTION_HEADERS[1].id}`}
minWidth={CONTAINER_MIN_WIDTH}
>
<CollapsableSection
label={<Text element="h3">2. {CONFIG_SECTION_HEADERS[1].label}</Text>}
isOpen={CONFIG_SECTION_HEADERS[1].isOpen}
@ -26,12 +33,8 @@ export const DatabaseConnectionSection = ({ options, onOptionsChange }: Props) =
<Alert severity="info" title="Database Access">
<p>
Setting the database for this datasource does not deny access to other databases. The InfluxDB query
syntax allows switching the database in the query. For example:
<code>SHOW MEASUREMENTS ON _internal</code> or
<code>SELECT * FROM &quot;_internal&quot;..&quot;database&quot; LIMIT 10</code>
<br />
<br />
To support data isolation and security, make sure appropriate permissions are configured in InfluxDB.
syntax allows switching the database in the query. To support data isolation and security, make sure
appropriate permissions are configured in InfluxDB.
</p>
</Alert>
</>

View File

@ -5,6 +5,7 @@ import {
} from '@grafana/data';
import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui';
import { DB_SETTINGS_LABEL_WIDTH } from './constants';
import {
trackInfluxDBConfigV2FluxDBDetailsDefaultBucketInputField,
trackInfluxDBConfigV2FluxDBDetailsOrgInputField,
@ -20,7 +21,7 @@ export const InfluxFluxDBConnection = (props: Props) => {
return (
<>
<InlineFieldRow>
<InlineField label="Organization" labelWidth={30} grow>
<InlineField label="Organization" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<Input
id="organization"
placeholder="myorg"
@ -31,7 +32,7 @@ export const InfluxFluxDBConnection = (props: Props) => {
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField labelWidth={30} label="Default Bucket" grow>
<InlineField labelWidth={DB_SETTINGS_LABEL_WIDTH} label="Default Bucket" grow>
<Input
id="default-bucket"
onBlur={trackInfluxDBConfigV2FluxDBDetailsDefaultBucketInputField}
@ -42,7 +43,7 @@ export const InfluxFluxDBConnection = (props: Props) => {
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField labelWidth={30} label="Token" grow>
<InlineField labelWidth={DB_SETTINGS_LABEL_WIDTH} label="Token" grow>
<SecretInput
id="token"
isConfigured={Boolean(secureJsonFields && secureJsonFields.token)}

View File

@ -6,6 +6,7 @@ import {
} from '@grafana/data';
import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui';
import { DB_SETTINGS_LABEL_WIDTH } from './constants';
import {
trackInfluxDBConfigV2InfluxQLDBDetailsDatabaseInputField,
trackInfluxDBConfigV2InfluxQLDBDetailsPasswordInputField,
@ -19,7 +20,7 @@ export const InfluxInfluxQLDBConnection = (props: Props) => {
return (
<>
<InlineFieldRow>
<InlineField label="Database" labelWidth={30} grow>
<InlineField label="Database" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<Input
id="database"
placeholder="mydb"
@ -30,7 +31,7 @@ export const InfluxInfluxQLDBConnection = (props: Props) => {
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField label="User" labelWidth={30} grow>
<InlineField label="User" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<Input
id="user"
placeholder="myuser"
@ -41,7 +42,7 @@ export const InfluxInfluxQLDBConnection = (props: Props) => {
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField label="Password" labelWidth={30} grow>
<InlineField label="Password" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<SecretInput
id="password"
isConfigured={Boolean(options.secureJsonFields && options.secureJsonFields.password)}

View File

@ -5,6 +5,7 @@ import {
} from '@grafana/data';
import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui';
import { DB_SETTINGS_LABEL_WIDTH } from './constants';
import {
trackInfluxDBConfigV2SQLDBDetailsDatabaseInputField,
trackInfluxDBConfigV2SQLDBDetailsTokenInputField,
@ -18,7 +19,7 @@ export const InfluxSQLDBConnection = (props: Props) => {
return (
<>
<InlineFieldRow>
<InlineField label="Database" labelWidth={30} grow>
<InlineField label="Database" labelWidth={DB_SETTINGS_LABEL_WIDTH} grow>
<Input
id="database"
placeholder="mydb"
@ -29,7 +30,7 @@ export const InfluxSQLDBConnection = (props: Props) => {
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField labelWidth={30} label="Token" grow>
<InlineField labelWidth={DB_SETTINGS_LABEL_WIDTH} label="Token" grow>
<SecretInput
id="token"
isConfigured={Boolean(secureJsonFields && secureJsonFields.token)}

View File

@ -10,7 +10,7 @@ export const LeftSideBar = ({ pdcInjected }: LeftSideBarProps) => {
const headers = pdcInjected ? CONFIG_SECTION_HEADERS_WITH_PDC : CONFIG_SECTION_HEADERS;
return (
<Stack>
<Box flex={1} marginY={5}>
<Box flex={1} marginY={10}>
<Text element="h4">InfluxDB</Text>
<Box paddingTop={2}>
{headers.map((header, index) => (

View File

@ -17,7 +17,7 @@ import { InfluxVersion } from '../../../types';
import { AdvancedHttpSettings } from './AdvancedHttpSettings';
import { AuthSettings } from './AuthSettings';
import { CONFIG_SECTION_HEADERS } from './constants';
import { CONFIG_SECTION_HEADERS, CONTAINER_MIN_WIDTH } from './constants';
import {
trackInfluxDBConfigV2ProductSelected,
trackInfluxDBConfigV2QueryLanguageSelected,
@ -66,7 +66,14 @@ export const UrlAndAuthenticationSection = (props: Props) => {
const onUrlChange = (event: React.ChangeEvent<HTMLInputElement>) => onUpdateDatasourceOption(props, 'url')(event);
return (
<Box borderStyle="solid" borderColor="weak" padding={2} marginBottom={4} id={`${CONFIG_SECTION_HEADERS[0].id}`}>
<Box
borderStyle="solid"
borderColor="weak"
padding={2}
marginBottom={4}
id={`${CONFIG_SECTION_HEADERS[0].id}`}
minWidth={CONTAINER_MIN_WIDTH}
>
<CollapsableSection
label={<Text element="h3">1. {CONFIG_SECTION_HEADERS[0].label}</Text>}
isOpen={CONFIG_SECTION_HEADERS[0].isOpen}
@ -76,7 +83,7 @@ export const UrlAndAuthenticationSection = (props: Props) => {
available settings and authentication methods in the next steps. If you are unsure what product you are using,
view the{' '}
<TextLink href="https://docs.influxdata.com/" external>
InfluxDB Docs.
InfluxDB Docs
</TextLink>
.
</Text>
@ -85,7 +92,7 @@ export const UrlAndAuthenticationSection = (props: Props) => {
<Field label={<div style={{ marginBottom: '5px' }}>URL</div>} noMargin>
<Input
data-testid="influxdb-v2-config-url-input"
placeholder="http://localhost:3000/"
placeholder="http://localhost:8086/"
onChange={onUrlChange}
value={options.url || ''}
onBlur={trackInfluxDBConfigV2URLInputField}

View File

@ -50,8 +50,11 @@ export const getInlineLabelStyles = (theme: GrafanaTheme2, transparent = false,
marginRight: theme.spacing(0.5),
borderRadius: theme.shape.radius.default,
border: 'none',
width: '240px',
width: '220px',
color: theme.colors.text.primary,
}),
};
};
export const DB_SETTINGS_LABEL_WIDTH = 18;
export const CONTAINER_MIN_WIDTH = '450px';

View File

@ -18,6 +18,7 @@ export interface InfluxOptions extends DataSourceJsonData {
dbName?: string;
product?: string;
pdcInjected?: boolean;
oauthPassThru?: boolean;
// With Flux
organization?: string;