sql: numeric inputs: use it's own simple implementation (#74904)

* sql: numeric inputs: use it's own simple implementation

* simpler approach

* Update connection limit styles (#75226)

* lint fixes

* replace ConfigSection with ConfigSubSection

---------

Co-authored-by: Gareth Dawson <email@garethdawson.xyz>
Co-authored-by: Gareth Dawson <gwdawson.work@gmail.com>
This commit is contained in:
Gábor Farkas
2023-10-03 13:54:51 +02:00
committed by GitHub
co-authored by Gareth Dawson Gareth Dawson
parent 30584dbd8b
commit 523d1b46d4
4 changed files with 144 additions and 64 deletions
@@ -1,20 +1,29 @@
import React from 'react'; import React from 'react';
import { DataSourceSettings } from '@grafana/data'; import { DataSourceSettings } from '@grafana/data';
import { ConfigSubSection, Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { FieldSet, InlineField, InlineFieldRow, InlineSwitch } from '@grafana/ui'; import { Field, Icon, InlineLabel, Input, Label, Switch, Tooltip } from '@grafana/ui';
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
import { SQLConnectionLimits, SQLOptions } from '../../types'; import { SQLConnectionLimits, SQLOptions } from '../../types';
interface Props<T> { interface Props<T> {
onOptionsChange: Function; onOptionsChange: Function;
options: DataSourceSettings<SQLOptions>; options: DataSourceSettings<SQLOptions>;
labelWidth: number; }
function toNumber(text: string): number {
if (text.trim() === '') {
// calling `Number('')` returns zero,
// so we have to handle this case
return NaN;
}
return Number(text);
} }
export const ConnectionLimits = <T extends SQLConnectionLimits>(props: Props<T>) => { export const ConnectionLimits = <T extends SQLConnectionLimits>(props: Props<T>) => {
const { onOptionsChange, options, labelWidth } = props; const { onOptionsChange, options } = props;
const jsonData = options.jsonData; const jsonData = options.jsonData;
const autoIdle = jsonData.maxIdleConnsAuto !== undefined ? jsonData.maxIdleConnsAuto : false; const autoIdle = jsonData.maxIdleConnsAuto !== undefined ? jsonData.maxIdleConnsAuto : false;
@@ -81,67 +90,140 @@ export const ConnectionLimits = <T extends SQLConnectionLimits>(props: Props<T>)
}); });
}; };
const labelWidth = 40;
return ( return (
<FieldSet label="Connection limits"> <ConfigSubSection title="Connection limits">
<InlineField <Field
tooltip={ label={
<span> <Label>
The maximum number of open connections to the database.If <i>Max idle connections</i> is greater than 0 and <Stack gap={0.5}>
the <i>Max open connections</i> is less than <i>Max idle connections</i>, then <span>Max open</span>
<i>Max idle connections</i> will be reduced to match the <i>Max open connections</i> limit. If set to 0, <Tooltip
there is no limit on the number of open connections. content={
</span> <span>
The maximum number of open connections to the database. If <i>Max idle connections</i> is greater
than 0 and the <i>Max open connections</i> is less than <i>Max idle connections</i>, then
<i>Max idle connections</i> will be reduced to match the <i>Max open connections</i> limit. If set
to 0, there is no limit on the number of open connections.
</span>
}
>
<Icon name="info-circle" size="sm" />
</Tooltip>
</Stack>
</Label>
} }
labelWidth={labelWidth}
label="Max open"
> >
<NumberInput placeholder="unlimited" value={jsonData.maxOpenConns} onChange={onMaxConnectionsChanged} /> <Input
</InlineField> type="number"
<InlineFieldRow> placeholder="unlimited"
<InlineField defaultValue={jsonData.maxOpenConns}
tooltip={ onChange={(e) => {
<span> const newVal = toNumber(e.currentTarget.value);
The maximum number of connections in the idle connection pool.If <i>Max open connections</i> is greater if (!Number.isNaN(newVal)) {
than 0 but less than the <i>Max idle connections</i>, then the <i>Max idle connections</i> will be reduced onMaxConnectionsChanged(newVal);
to match the <i>Max open connections</i> limit. If set to 0, no idle connections are retained. }
</span> }}
} width={labelWidth}
labelWidth={labelWidth} />
label="Max idle" </Field>
>
<NumberInput <Field
label={
<Label>
<Stack gap={0.5}>
<span>Auto Max Idle</span>
<Tooltip
content={
<span>
If enabled, automatically set the number of <i>Maximum idle connections</i> to the same value as
<i> Max open connections</i>. If the number of maximum open connections is not set it will be set to
the default ({config.sqlConnectionLimits.maxIdleConns}).
</span>
}
>
<Icon name="info-circle" size="sm" />
</Tooltip>
</Stack>
</Label>
}
>
<Switch value={autoIdle} onChange={onConnectionIdleAutoChanged} />
</Field>
<Field
label={
<Label>
<Stack gap={0.5}>
<span>Max idle</span>
<Tooltip
content={
<span>
The maximum number of connections in the idle connection pool.If <i>Max open connections</i> is
greater than 0 but less than the <i>Max idle connections</i>, then the <i>Max idle connections</i>{' '}
will be reduced to match the <i>Max open connections</i> limit. If set to 0, no idle connections are
retained.
</span>
}
>
<Icon name="info-circle" size="sm" />
</Tooltip>
</Stack>
</Label>
}
>
{autoIdle ? (
<InlineLabel width={labelWidth}>{options.jsonData.maxIdleConns}</InlineLabel>
) : (
<Input
type="number"
placeholder="2" placeholder="2"
value={jsonData.maxIdleConns} defaultValue={jsonData.maxIdleConns}
onChange={onJSONDataNumberChanged('maxIdleConns')} onChange={(e) => {
width={8} const newVal = toNumber(e.currentTarget.value);
fieldDisabled={autoIdle} if (!Number.isNaN(newVal)) {
onJSONDataNumberChanged('maxIdleConns')(newVal);
}
}}
width={labelWidth}
disabled={autoIdle}
/> />
</InlineField> )}
<InlineField </Field>
label="Auto"
labelWidth={8} <Field
tooltip={ label={
<span> <Label>
If enabled, automatically set the number of <i>Maximum idle connections</i> to the same value as <Stack gap={0.5}>
<i> Max open connections</i>. If the number of maximum open connections is not set it will be set to the <span>Max lifetime</span>
default ({config.sqlConnectionLimits.maxIdleConns}). <Tooltip
</span> content={
} <span>
> The maximum amount of time in seconds a connection may be reused. If set to 0, connections are
<InlineSwitch value={autoIdle} onChange={onConnectionIdleAutoChanged} /> reused forever.
</InlineField> </span>
</InlineFieldRow> }
<InlineField >
tooltip="The maximum amount of time in seconds a connection may be reused. If set to 0, connections are reused forever." <Icon name="info-circle" size="sm" />
labelWidth={labelWidth} </Tooltip>
label="Max lifetime" </Stack>
</Label>
}
> >
<NumberInput <Input
type="number"
placeholder="14400" placeholder="14400"
value={jsonData.connMaxLifetime} defaultValue={jsonData.connMaxLifetime}
onChange={onJSONDataNumberChanged('connMaxLifetime')} onChange={(e) => {
></NumberInput> const newVal = toNumber(e.currentTarget.value);
</InlineField> if (!Number.isNaN(newVal)) {
</FieldSet> onJSONDataNumberChanged('connMaxLifetime')(newVal);
}
}}
width={labelWidth}
/>
</Field>
</ConfigSubSection>
); );
}; };
@@ -38,7 +38,6 @@ import {
MssqlSecureOptions, MssqlSecureOptions,
} from '../types'; } from '../types';
const SHORT_WIDTH = 15;
const LONG_WIDTH = 40; const LONG_WIDTH = 40;
export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<MssqlOptions, MssqlSecureOptions>) => { export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<MssqlOptions, MssqlSecureOptions>) => {
@@ -297,7 +296,7 @@ export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<Ms
isCollapsible={true} isCollapsible={true}
isInitiallyOpen={true} isInitiallyOpen={true}
> >
<ConnectionLimits labelWidth={SHORT_WIDTH} options={dsSettings} onOptionsChange={onOptionsChange} /> <ConnectionLimits options={dsSettings} onOptionsChange={onOptionsChange} />
<ConfigSubSection title="Connection details"> <ConfigSubSection title="Connection details">
<Field <Field
@@ -50,7 +50,6 @@ export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<My
}; };
}; };
const WIDTH_SHORT = 15;
const WIDTH_LONG = 40; const WIDTH_LONG = 40;
return ( return (
@@ -228,7 +227,7 @@ export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<My
<Divider /> <Divider />
<ConnectionLimits labelWidth={WIDTH_SHORT} options={options} onOptionsChange={onOptionsChange} /> <ConnectionLimits options={options} onOptionsChange={onOptionsChange} />
<Divider /> <Divider />
@@ -246,7 +246,7 @@ export const PostgresConfigEditor = (props: DataSourcePluginOptionsEditorProps<P
</FieldSet> </FieldSet>
) : null} ) : null}
<ConnectionLimits labelWidth={labelWidthShort} options={options} onOptionsChange={onOptionsChange} /> <ConnectionLimits options={options} onOptionsChange={onOptionsChange} />
<FieldSet label="PostgreSQL details"> <FieldSet label="PostgreSQL details">
<InlineField <InlineField