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 && ( | ||||
|             <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> | ||||
| 
 | ||||
|           {/* TLS Client Auth */} | ||||
|           )} | ||||
|           <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> | ||||
|           <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"> | ||||
|       <div className={styles.hideOnSmallScreen}> | ||||
|         <Box width="100%" flex="1 1 auto"> | ||||
|           <LeftSideBar pdcInjected={options?.jsonData?.pdcInjected!!} /> | ||||
|         </Box> | ||||
|       <Box width="60%" flex="1 1 auto"> | ||||
|       </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