mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Disabled inputs when settings are read-only (#60354)
This commit is contained in:
@@ -11,12 +11,21 @@ export interface Props {
|
||||
onNameChange: (name: string) => void;
|
||||
onDefaultChange: (value: boolean) => void;
|
||||
alertingSupported: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNameChange, alertingSupported }: Props) {
|
||||
export function BasicSettings({
|
||||
dataSourceName,
|
||||
isDefault,
|
||||
onDefaultChange,
|
||||
onNameChange,
|
||||
alertingSupported,
|
||||
disabled,
|
||||
}: Props) {
|
||||
return (
|
||||
<>
|
||||
{<AlertingEnabled enabled={alertingSupported} />}
|
||||
<AlertingEnabled enabled={alertingSupported} />
|
||||
|
||||
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
|
||||
<div className="gf-form-inline">
|
||||
{/* Name */}
|
||||
@@ -26,6 +35,7 @@ export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNa
|
||||
tooltip="The name is used when you select the data source in panels. The default data source is
|
||||
'preselected in new panels."
|
||||
grow
|
||||
disabled={disabled}
|
||||
>
|
||||
<Input
|
||||
id="basic-settings-name"
|
||||
@@ -40,7 +50,7 @@ export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNa
|
||||
</div>
|
||||
|
||||
{/* Is Default */}
|
||||
<InlineField label="Default" labelWidth={8}>
|
||||
<InlineField label="Default" labelWidth={8} disabled={disabled}>
|
||||
<InlineSwitch
|
||||
id="basic-settings-default"
|
||||
value={isDefault}
|
||||
|
||||
@@ -159,6 +159,7 @@ export function EditDataSourceView({
|
||||
onDefaultChange={onDefaultChange}
|
||||
onNameChange={onNameChange}
|
||||
alertingSupported={alertingSupported}
|
||||
disabled={readOnly || !hasWriteRights}
|
||||
/>
|
||||
|
||||
{plugin && (
|
||||
|
||||
@@ -51,19 +51,20 @@ export const AzureAuthSettings: FunctionComponent<HttpSettingsBaseProps> = (prop
|
||||
credentials={credentials}
|
||||
azureCloudOptions={KnownAzureClouds}
|
||||
onCredentialsChange={onCredentialsChange}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
/>
|
||||
{overrideAudienceAllowed && (
|
||||
<>
|
||||
<h6>Azure Configuration</h6>
|
||||
<div className="gf-form-group">
|
||||
<InlineFieldRow>
|
||||
<InlineField labelWidth={26} label="Override AAD audience">
|
||||
<InlineField labelWidth={26} label="Override AAD audience" disabled={dataSourceConfig.readOnly}>
|
||||
<InlineSwitch value={overrideAudienceChecked} onChange={onOverrideAudienceChange} />
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
{overrideAudienceChecked && (
|
||||
<InlineFieldRow>
|
||||
<InlineField labelWidth={26} label="Resource ID">
|
||||
<InlineField labelWidth={26} label="Resource ID" disabled={dataSourceConfig.readOnly}>
|
||||
<Input
|
||||
className="width-30"
|
||||
value={dataSourceConfig.jsonData.azureEndpointResourceId || ''}
|
||||
|
||||
@@ -13,6 +13,7 @@ export interface Props {
|
||||
azureCloudOptions?: SelectableValue[];
|
||||
onCredentialsChange: (updatedCredentials: AzureCredentials) => void;
|
||||
getSubscriptions?: () => Promise<SelectableValue[]>;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
||||
@@ -27,7 +28,7 @@ const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
||||
];
|
||||
|
||||
export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) => {
|
||||
const { credentials, azureCloudOptions, onCredentialsChange, getSubscriptions } = props;
|
||||
const { credentials, azureCloudOptions, onCredentialsChange, getSubscriptions, disabled } = props;
|
||||
const hasRequiredFields = isCredentialsComplete(credentials);
|
||||
|
||||
const [subscriptions, setSubscriptions] = useState<Array<SelectableValue<string>>>([]);
|
||||
@@ -161,6 +162,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
value={authTypeOptions.find((opt) => opt.value === credentials.authType)}
|
||||
options={authTypeOptions}
|
||||
onChange={onAuthTypeChange}
|
||||
isDisabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -178,6 +180,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
value={azureCloudOptions.find((opt) => opt.value === credentials.azureCloud)}
|
||||
options={azureCloudOptions}
|
||||
onChange={onAzureCloudChange}
|
||||
isDisabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -191,6 +194,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.tenantId || ''}
|
||||
onChange={onTenantIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,6 +208,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientId || ''}
|
||||
onChange={onClientIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -214,15 +219,17 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
<InlineFormLabel htmlFor="azure-client-secret" className="width-12">
|
||||
Client Secret
|
||||
</InlineFormLabel>
|
||||
<Input id="azure-client-secret" className="width-25" placeholder="configured" disabled={true} />
|
||||
<Input id="azure-client-secret" className="width-25" placeholder="configured" disabled />
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<div className="max-width-30 gf-form-inline">
|
||||
<Button variant="secondary" type="button" onClick={onClientSecretReset}>
|
||||
reset
|
||||
</Button>
|
||||
{!disabled && (
|
||||
<div className="gf-form">
|
||||
<div className="max-width-30 gf-form-inline">
|
||||
<Button variant="secondary" type="button" onClick={onClientSecretReset}>
|
||||
reset
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="gf-form-inline">
|
||||
@@ -234,6 +241,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientSecret || ''}
|
||||
onChange={onClientSecretChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -255,6 +263,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
}
|
||||
options={subscriptions}
|
||||
onChange={onSubscriptionChange}
|
||||
isDisabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,32 +11,35 @@ type Props = {
|
||||
value: ExemplarTraceIdDestination;
|
||||
onChange: (value: ExemplarTraceIdDestination) => void;
|
||||
onDelete: () => void;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
||||
export default function ExemplarSetting({ value, onChange, onDelete, disabled }: Props) {
|
||||
const [isInternalLink, setIsInternalLink] = useState(Boolean(value.datasourceUid));
|
||||
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<InlineField label="Internal link" labelWidth={24}>
|
||||
<InlineField label="Internal link" labelWidth={24} disabled={disabled}>
|
||||
<>
|
||||
<InlineSwitch
|
||||
value={isInternalLink}
|
||||
aria-label={selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch}
|
||||
onChange={(ev) => setIsInternalLink(ev.currentTarget.checked)}
|
||||
/>
|
||||
<Button
|
||||
variant="destructive"
|
||||
title="Remove link"
|
||||
icon="times"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
onDelete();
|
||||
}}
|
||||
className={css`
|
||||
margin-left: 8px;
|
||||
`}
|
||||
/>
|
||||
{!disabled && (
|
||||
<Button
|
||||
variant="destructive"
|
||||
title="Remove link"
|
||||
icon="times"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
onDelete();
|
||||
}}
|
||||
className={css`
|
||||
margin-left: 8px;
|
||||
`}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</InlineField>
|
||||
|
||||
@@ -45,6 +48,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
||||
label="Data source"
|
||||
labelWidth={24}
|
||||
tooltip="The data source the exemplar is going to navigate to."
|
||||
disabled={disabled}
|
||||
>
|
||||
<DataSourcePicker
|
||||
tracing={true}
|
||||
@@ -65,6 +69,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
||||
label="URL"
|
||||
labelWidth={24}
|
||||
tooltip="The URL of the trace backend the user would go to see its trace."
|
||||
disabled={disabled}
|
||||
>
|
||||
<Input
|
||||
placeholder="https://example.com/${__value.raw}"
|
||||
@@ -86,6 +91,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
||||
label="URL Label"
|
||||
labelWidth={24}
|
||||
tooltip="Use to override the button label on the exemplar traceID field."
|
||||
disabled={disabled}
|
||||
>
|
||||
<Input
|
||||
placeholder="Go to example.com"
|
||||
@@ -104,6 +110,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
||||
label="Label name"
|
||||
labelWidth={24}
|
||||
tooltip="The name of the field in the labels object that should be used to get the traceID."
|
||||
disabled={disabled}
|
||||
>
|
||||
<Input
|
||||
placeholder="traceID"
|
||||
|
||||
@@ -11,9 +11,10 @@ import ExemplarSetting from './ExemplarSetting';
|
||||
type Props = {
|
||||
options?: ExemplarTraceIdDestination[];
|
||||
onChange: (value: ExemplarTraceIdDestination[]) => void;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export function ExemplarsSettings({ options, onChange }: Props) {
|
||||
export function ExemplarsSettings({ options, onChange, disabled }: Props) {
|
||||
return (
|
||||
<>
|
||||
<h3 className="page-heading">Exemplars</h3>
|
||||
@@ -34,25 +35,28 @@ export function ExemplarsSettings({ options, onChange }: Props) {
|
||||
newOptions.splice(index, 1);
|
||||
onChange(newOptions);
|
||||
}}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
aria-label={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
||||
className={css`
|
||||
margin-bottom: 10px;
|
||||
`}
|
||||
icon="plus"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
const newOptions = [...(options || []), { name: 'traceID' }];
|
||||
onChange(newOptions);
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
{!disabled && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
aria-label={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
||||
className={css`
|
||||
margin-bottom: 10px;
|
||||
`}
|
||||
icon="plus"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
const newOptions = [...(options || []), { name: 'traceID' }];
|
||||
onChange(newOptions);
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ export const PromSettings = (props: Props) => {
|
||||
placeholder="15s"
|
||||
onChange={onChangeHandler('timeInterval', options, onOptionsChange)}
|
||||
validationEvents={promSettingsValidationEvents}
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
}
|
||||
tooltip="Set this to the typical scrape and evaluation interval configured in Prometheus. Defaults to 15s."
|
||||
@@ -178,6 +179,7 @@ export const PromSettings = (props: Props) => {
|
||||
spellCheck={false}
|
||||
placeholder="60s"
|
||||
validationEvents={promSettingsValidationEvents}
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
}
|
||||
tooltip="Set the Prometheus query timeout."
|
||||
@@ -198,6 +200,7 @@ export const PromSettings = (props: Props) => {
|
||||
value={httpOptions.find((o) => o.value === options.jsonData.httpMethod)}
|
||||
onChange={onChangeHandler('httpMethod', options, onOptionsChange)}
|
||||
className="width-6"
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -242,6 +245,7 @@ export const PromSettings = (props: Props) => {
|
||||
}
|
||||
)}
|
||||
width={20}
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
}
|
||||
tooltip="Set this to the type of your prometheus database, e.g. Prometheus, Cortex, Mimir or Thanos. Changing this field will save your current settings, and attempt to detect the version."
|
||||
@@ -263,6 +267,7 @@ export const PromSettings = (props: Props) => {
|
||||
)}
|
||||
onChange={onChangeHandler('prometheusVersion', options, onOptionsChange)}
|
||||
width={20}
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
}
|
||||
tooltip={`Use this to set the version of your ${options.jsonData.prometheusType} instance if it is not automatically configured.`}
|
||||
@@ -279,6 +284,7 @@ export const PromSettings = (props: Props) => {
|
||||
labelWidth={28}
|
||||
label="Disable metrics lookup"
|
||||
tooltip="Checking this option will disable the metrics chooser and metric/label support in the query field's autocomplete. This helps if you have performance issues with bigger Prometheus instances."
|
||||
disabled={options.readOnly}
|
||||
>
|
||||
<InlineSwitch
|
||||
value={options.jsonData.disableMetricsLookup ?? false}
|
||||
@@ -299,6 +305,7 @@ export const PromSettings = (props: Props) => {
|
||||
onChange={onChangeHandler('customQueryParameters', options, onOptionsChange)}
|
||||
spellCheck={false}
|
||||
placeholder="Example: max_source_resolution=5m&timeout=10"
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -314,6 +321,7 @@ export const PromSettings = (props: Props) => {
|
||||
exemplarOptions
|
||||
)
|
||||
}
|
||||
disabled={options.readOnly}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user