Prometheus: removes props mutation (#105650)
This commit is contained in:
@@ -3,6 +3,7 @@ import { SyntheticEvent, useState } from 'react';
|
||||
|
||||
import {
|
||||
DataSourcePluginOptionsEditorProps,
|
||||
DataSourceSettings,
|
||||
onUpdateDatasourceJsonDataOptionChecked,
|
||||
SelectableValue,
|
||||
updateDatasourcePluginJsonDataOption,
|
||||
@@ -60,14 +61,19 @@ export const NON_NEGATIVE_INTEGER_REGEX = /^(0|[1-9]\d*)(\.\d+)?(e\+?\d+)?$/; //
|
||||
const durationError = 'Value is not valid, you can use number with time unit specifier: y, M, w, d, h, m, s';
|
||||
export const countError = 'Value is not valid, you can use non-negative integers, including scientific notation';
|
||||
|
||||
export const PromSettings = (props: Props) => {
|
||||
const { options, onOptionsChange } = props;
|
||||
const getOptionsWithDefaults = (options: DataSourceSettings<PromOptions>) => {
|
||||
if (options.jsonData.httpMethod) {
|
||||
return options;
|
||||
}
|
||||
|
||||
// We are explicitly adding httpMethod so, it is correctly displayed in dropdown.
|
||||
// This way, it is more predictable for users.
|
||||
if (!options.jsonData.httpMethod) {
|
||||
options.jsonData.httpMethod = 'POST';
|
||||
}
|
||||
return { ...options, jsonData: { ...options.jsonData, httpMethod: 'POST' } };
|
||||
};
|
||||
|
||||
export const PromSettings = (props: Props) => {
|
||||
const { onOptionsChange } = props;
|
||||
const optionsWithDefaults = getOptionsWithDefaults(props.options);
|
||||
|
||||
const theme = useTheme2();
|
||||
const styles = overhaulStyles(theme);
|
||||
@@ -111,15 +117,15 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
className="width-20"
|
||||
value={options.jsonData.timeInterval}
|
||||
value={optionsWithDefaults.jsonData.timeInterval}
|
||||
spellCheck={false}
|
||||
placeholder="15s"
|
||||
onChange={onChangeHandler('timeInterval', options, onOptionsChange)}
|
||||
onChange={onChangeHandler('timeInterval', optionsWithDefaults, onOptionsChange)}
|
||||
onBlur={(e) =>
|
||||
updateValidDuration({
|
||||
...validDuration,
|
||||
@@ -141,13 +147,13 @@ export const PromSettings = (props: Props) => {
|
||||
labelWidth={PROM_CONFIG_LABEL_WIDTH}
|
||||
tooltip={<>Set the Prometheus query timeout. {docsTip()}</>}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
className="width-20"
|
||||
value={options.jsonData.queryTimeout}
|
||||
onChange={onChangeHandler('queryTimeout', options, onOptionsChange)}
|
||||
value={optionsWithDefaults.jsonData.queryTimeout}
|
||||
onChange={onChangeHandler('queryTimeout', optionsWithDefaults, onOptionsChange)}
|
||||
spellCheck={false}
|
||||
placeholder="60s"
|
||||
onBlur={(e) =>
|
||||
@@ -174,16 +180,16 @@ export const PromSettings = (props: Props) => {
|
||||
labelWidth={PROM_CONFIG_LABEL_WIDTH}
|
||||
tooltip={<>Set default editor option for all users of this data source. {docsTip()}</>}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Select
|
||||
aria-label={`Default Editor (Code or Builder)`}
|
||||
options={editorOptions}
|
||||
value={
|
||||
editorOptions.find((o) => o.value === options.jsonData.defaultEditor) ??
|
||||
editorOptions.find((o) => o.value === optionsWithDefaults.jsonData.defaultEditor) ??
|
||||
editorOptions.find((o) => o.value === QueryEditorMode.Builder)
|
||||
}
|
||||
onChange={onChangeHandler('defaultEditor', options, onOptionsChange)}
|
||||
onChange={onChangeHandler('defaultEditor', optionsWithDefaults, onOptionsChange)}
|
||||
width={40}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.defaultEditor}
|
||||
/>
|
||||
@@ -201,11 +207,11 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
className={styles.switchField}
|
||||
>
|
||||
<Switch
|
||||
value={options.jsonData.disableMetricsLookup ?? false}
|
||||
value={optionsWithDefaults.jsonData.disableMetricsLookup ?? false}
|
||||
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'disableMetricsLookup')}
|
||||
id={selectors.components.DataSource.Prometheus.configPage.disableMetricLookup}
|
||||
/>
|
||||
@@ -215,18 +221,20 @@ export const PromSettings = (props: Props) => {
|
||||
</ConfigSubSection>
|
||||
|
||||
<ConfigSubSection title="Performance" className={styles.container}>
|
||||
{!options.jsonData.prometheusType && !options.jsonData.prometheusVersion && options.readOnly && (
|
||||
<div className={styles.versionMargin}>
|
||||
For more information on configuring prometheus type and version in data sources, see the{' '}
|
||||
<a
|
||||
className={styles.textUnderline}
|
||||
href="https://grafana.com/docs/grafana/latest/administration/provisioning/"
|
||||
>
|
||||
provisioning documentation
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
)}
|
||||
{!optionsWithDefaults.jsonData.prometheusType &&
|
||||
!optionsWithDefaults.jsonData.prometheusVersion &&
|
||||
optionsWithDefaults.readOnly && (
|
||||
<div className={styles.versionMargin}>
|
||||
For more information on configuring prometheus type and version in data sources, see the{' '}
|
||||
<a
|
||||
className={styles.textUnderline}
|
||||
href="https://grafana.com/docs/grafana/latest/administration/provisioning/"
|
||||
>
|
||||
provisioning documentation
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
)}
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
@@ -245,13 +253,15 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Select
|
||||
aria-label="Prometheus type"
|
||||
options={prometheusFlavorSelectItems}
|
||||
value={prometheusFlavorSelectItems.find((o) => o.value === options.jsonData.prometheusType)}
|
||||
onChange={onChangeHandler('prometheusType', options, onOptionsChange)}
|
||||
value={prometheusFlavorSelectItems.find(
|
||||
(o) => o.value === optionsWithDefaults.jsonData.prometheusType
|
||||
)}
|
||||
onChange={onChangeHandler('prometheusType', optionsWithDefaults, onOptionsChange)}
|
||||
width={40}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.prometheusType}
|
||||
/>
|
||||
@@ -259,27 +269,27 @@ export const PromSettings = (props: Props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
{options.jsonData.prometheusType && (
|
||||
{optionsWithDefaults.jsonData.prometheusType && (
|
||||
<div className="gf-form">
|
||||
<InlineField
|
||||
label={`${options.jsonData.prometheusType} version`}
|
||||
label={`${optionsWithDefaults.jsonData.prometheusType} version`}
|
||||
labelWidth={PROM_CONFIG_LABEL_WIDTH}
|
||||
tooltip={
|
||||
<>
|
||||
Use this to set the version of your {options.jsonData.prometheusType} instance if it is not
|
||||
automatically configured. {docsTip()}
|
||||
Use this to set the version of your {optionsWithDefaults.jsonData.prometheusType} instance if it
|
||||
is not automatically configured. {docsTip()}
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Select
|
||||
aria-label={`${options.jsonData.prometheusType} type`}
|
||||
options={PromFlavorVersions[options.jsonData.prometheusType]}
|
||||
value={PromFlavorVersions[options.jsonData.prometheusType]?.find(
|
||||
(o) => o.value === options.jsonData.prometheusVersion
|
||||
aria-label={`${optionsWithDefaults.jsonData.prometheusType} type`}
|
||||
options={PromFlavorVersions[optionsWithDefaults.jsonData.prometheusType]}
|
||||
value={PromFlavorVersions[optionsWithDefaults.jsonData.prometheusType]?.find(
|
||||
(o) => o.value === optionsWithDefaults.jsonData.prometheusVersion
|
||||
)}
|
||||
onChange={onChangeHandler('prometheusVersion', options, onOptionsChange)}
|
||||
onChange={onChangeHandler('prometheusVersion', optionsWithDefaults, onOptionsChange)}
|
||||
width={40}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.prometheusVersion}
|
||||
/>
|
||||
@@ -300,14 +310,15 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Select
|
||||
width={40}
|
||||
onChange={onChangeHandler('cacheLevel', options, onOptionsChange)}
|
||||
onChange={onChangeHandler('cacheLevel', optionsWithDefaults, onOptionsChange)}
|
||||
options={cacheValueOptions}
|
||||
value={
|
||||
cacheValueOptions.find((o) => o.value === options.jsonData.cacheLevel) ?? PrometheusCacheLevel.Low
|
||||
cacheValueOptions.find((o) => o.value === optionsWithDefaults.jsonData.cacheLevel) ??
|
||||
PrometheusCacheLevel.Low
|
||||
}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.cacheLevel}
|
||||
/>
|
||||
@@ -328,13 +339,17 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
className="width-20"
|
||||
value={options.jsonData.codeModeMetricNamesSuggestionLimit}
|
||||
onChange={onChangeHandler('codeModeMetricNamesSuggestionLimit', options, onOptionsChange)}
|
||||
value={optionsWithDefaults.jsonData.codeModeMetricNamesSuggestionLimit}
|
||||
onChange={onChangeHandler(
|
||||
'codeModeMetricNamesSuggestionLimit',
|
||||
optionsWithDefaults,
|
||||
onOptionsChange
|
||||
)}
|
||||
spellCheck={false}
|
||||
placeholder={SUGGESTIONS_LIMIT.toString()}
|
||||
onBlur={(e) =>
|
||||
@@ -372,10 +387,10 @@ export const PromSettings = (props: Props) => {
|
||||
}
|
||||
interactive={true}
|
||||
className={styles.switchField}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Switch
|
||||
value={options.jsonData.incrementalQuerying ?? false}
|
||||
value={optionsWithDefaults.jsonData.incrementalQuerying ?? false}
|
||||
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'incrementalQuerying')}
|
||||
id={selectors.components.DataSource.Prometheus.configPage.incrementalQuerying}
|
||||
/>
|
||||
@@ -384,7 +399,7 @@ export const PromSettings = (props: Props) => {
|
||||
</div>
|
||||
|
||||
<div className="gf-form-inline">
|
||||
{options.jsonData.incrementalQuerying && (
|
||||
{optionsWithDefaults.jsonData.incrementalQuerying && (
|
||||
<InlineField
|
||||
label="Query overlap window"
|
||||
labelWidth={PROM_CONFIG_LABEL_WIDTH}
|
||||
@@ -395,7 +410,7 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<>
|
||||
<Input
|
||||
@@ -406,8 +421,10 @@ export const PromSettings = (props: Props) => {
|
||||
})
|
||||
}
|
||||
className="width-20"
|
||||
value={options.jsonData.incrementalQueryOverlapWindow ?? defaultPrometheusQueryOverlapWindow}
|
||||
onChange={onChangeHandler('incrementalQueryOverlapWindow', options, onOptionsChange)}
|
||||
value={
|
||||
optionsWithDefaults.jsonData.incrementalQueryOverlapWindow ?? defaultPrometheusQueryOverlapWindow
|
||||
}
|
||||
onChange={onChangeHandler('incrementalQueryOverlapWindow', optionsWithDefaults, onOptionsChange)}
|
||||
spellCheck={false}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.queryOverlapWindow}
|
||||
/>
|
||||
@@ -425,10 +442,10 @@ export const PromSettings = (props: Props) => {
|
||||
tooltip={<>This feature will disable recording rules Turn this on to improve dashboard performance</>}
|
||||
interactive={true}
|
||||
className={styles.switchField}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Switch
|
||||
value={options.jsonData.disableRecordingRules ?? false}
|
||||
value={optionsWithDefaults.jsonData.disableRecordingRules ?? false}
|
||||
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'disableRecordingRules')}
|
||||
id={selectors.components.DataSource.Prometheus.configPage.disableRecordingRules}
|
||||
/>
|
||||
@@ -452,12 +469,12 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Input
|
||||
className="width-20"
|
||||
value={options.jsonData.customQueryParameters}
|
||||
onChange={onChangeHandler('customQueryParameters', options, onOptionsChange)}
|
||||
value={optionsWithDefaults.jsonData.customQueryParameters}
|
||||
onChange={onChangeHandler('customQueryParameters', optionsWithDefaults, onOptionsChange)}
|
||||
spellCheck={false}
|
||||
placeholder="Example: max_source_resolution=5m&timeout=10"
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.customQueryParameters}
|
||||
@@ -479,14 +496,14 @@ export const PromSettings = (props: Props) => {
|
||||
}
|
||||
interactive={true}
|
||||
label="HTTP method"
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
>
|
||||
<Select
|
||||
width={40}
|
||||
aria-label="Select HTTP method"
|
||||
options={httpOptions}
|
||||
value={httpOptions.find((o) => o.value === options.jsonData.httpMethod)}
|
||||
onChange={onChangeHandler('httpMethod', options, onOptionsChange)}
|
||||
value={httpOptions.find((o) => o.value === optionsWithDefaults.jsonData.httpMethod)}
|
||||
onChange={onChangeHandler('httpMethod', optionsWithDefaults, onOptionsChange)}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.httpMethod}
|
||||
/>
|
||||
</InlineField>
|
||||
@@ -504,11 +521,11 @@ export const PromSettings = (props: Props) => {
|
||||
</>
|
||||
}
|
||||
interactive={true}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
className={styles.switchField}
|
||||
>
|
||||
<Switch
|
||||
value={options.jsonData.seriesEndpoint ?? false}
|
||||
value={optionsWithDefaults.jsonData.seriesEndpoint ?? false}
|
||||
onChange={onUpdateDatasourceJsonDataOptionChecked(props, 'seriesEndpoint')}
|
||||
/>
|
||||
</InlineField>
|
||||
@@ -516,15 +533,15 @@ export const PromSettings = (props: Props) => {
|
||||
</ConfigSubSection>
|
||||
|
||||
<ExemplarsSettings
|
||||
options={options.jsonData.exemplarTraceIdDestinations}
|
||||
options={optionsWithDefaults.jsonData.exemplarTraceIdDestinations}
|
||||
onChange={(exemplarOptions) =>
|
||||
updateDatasourcePluginJsonDataOption(
|
||||
{ onOptionsChange, options },
|
||||
{ onOptionsChange, options: optionsWithDefaults },
|
||||
'exemplarTraceIdDestinations',
|
||||
exemplarOptions
|
||||
)
|
||||
}
|
||||
disabled={options.readOnly}
|
||||
disabled={optionsWithDefaults.readOnly}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user