[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
14 changed files with 191 additions and 98 deletions
@@ -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} />
) : (
@@ -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>
)}
</>
)}
</>
@@ -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 (
<>
@@ -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();
});
});
});
});
@@ -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 top–level 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}
@@ -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',
},
}),
};
};
@@ -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>
</>
@@ -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)}
@@ -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)}
@@ -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)}
@@ -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) => (
@@ -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}
@@ -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';
@@ -18,6 +18,7 @@ export interface InfluxOptions extends DataSourceJsonData {
dbName?: string;
product?: string;
pdcInjected?: boolean;
oauthPassThru?: boolean;
// With Flux
organization?: string;