mirror of https://github.com/grafana/grafana.git
[InfluxDB] Config design improvements (#108562)
This commit is contained in:
parent
08501677e3
commit
1ce333a572
|
|
@ -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 "_internal".."database" 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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue