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:
parent
5d725d22ad
commit
220ee3d1d4
@ -19,7 +19,7 @@ export function AlertingSettings<T extends AlertingConfig>({ options, onOptionsC
|
|||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
<InlineField labelWidth={26} label="Manage alerts via Alerting UI">
|
<InlineField labelWidth={26} label="Manage alerts via Alerting UI" disabled={options.readOnly}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
value={options.jsonData.manageAlerts !== false}
|
value={options.jsonData.manageAlerts !== false}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
|
@ -35,7 +35,7 @@ export const BasicAuthSettings: React.FC<HttpSettingsProps> = ({ dataSourceConfi
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InlineField>
|
<InlineField disabled={dataSourceConfig.readOnly}>
|
||||||
<FormField
|
<FormField
|
||||||
label="User"
|
label="User"
|
||||||
labelWidth={10}
|
labelWidth={10}
|
||||||
@ -45,7 +45,7 @@ export const BasicAuthSettings: React.FC<HttpSettingsProps> = ({ dataSourceConfi
|
|||||||
onChange={(event) => onChange({ ...dataSourceConfig, basicAuthUser: event.currentTarget.value })}
|
onChange={(event) => onChange({ ...dataSourceConfig, basicAuthUser: event.currentTarget.value })}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField>
|
<InlineField disabled={dataSourceConfig.readOnly}>
|
||||||
<SecretFormField
|
<SecretFormField
|
||||||
isConfigured={!!(dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.basicAuthPassword)}
|
isConfigured={!!(dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.basicAuthPassword)}
|
||||||
value={password || ''}
|
value={password || ''}
|
||||||
|
@ -32,7 +32,7 @@ const setup = (propOverrides?: object) => {
|
|||||||
password: true,
|
password: true,
|
||||||
},
|
},
|
||||||
secureJsonFields: {},
|
secureJsonFields: {},
|
||||||
readOnly: true,
|
readOnly: false,
|
||||||
},
|
},
|
||||||
onChange,
|
onChange,
|
||||||
...propOverrides,
|
...propOverrides,
|
||||||
|
@ -196,6 +196,8 @@ export class CustomHeadersSettings extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { headers } = this.state;
|
const { headers } = this.state;
|
||||||
|
const { dataSourceConfig } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'gf-form-group'}>
|
<div className={'gf-form-group'}>
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
@ -215,18 +217,20 @@ export class CustomHeadersSettings extends PureComponent<Props, State> {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="gf-form">
|
{!dataSourceConfig.readOnly && (
|
||||||
<Button
|
<div className="gf-form">
|
||||||
variant="secondary"
|
<Button
|
||||||
icon="plus"
|
variant="secondary"
|
||||||
type="button"
|
icon="plus"
|
||||||
onClick={(e) => {
|
type="button"
|
||||||
this.onHeaderAdd();
|
onClick={(e) => {
|
||||||
}}
|
this.onHeaderAdd();
|
||||||
>
|
}}
|
||||||
Add header
|
>
|
||||||
</Button>
|
Add header
|
||||||
</div>
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
options={ACCESS_OPTIONS}
|
options={ACCESS_OPTIONS}
|
||||||
value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION}
|
value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION}
|
||||||
onChange={(selectedValue) => onSettingsChange({ access: selectedValue.value })}
|
onChange={(selectedValue) => onSettingsChange({ access: selectedValue.value })}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -133,6 +134,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
value={dataSourceConfig.url}
|
value={dataSourceConfig.url}
|
||||||
aria-label={selectors.components.DataSource.DataSourceHttpSettings.urlInput}
|
aria-label={selectors.components.DataSource.DataSourceHttpSettings.urlInput}
|
||||||
onChange={(event) => onSettingsChange({ url: event.currentTarget.value })}
|
onChange={(event) => onSettingsChange({ url: event.currentTarget.value })}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -183,6 +185,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
onChange={(cookies) =>
|
onChange={(cookies) =>
|
||||||
onSettingsChange({ jsonData: { ...dataSourceConfig.jsonData, keepCookies: cookies } })
|
onSettingsChange({ jsonData: { ...dataSourceConfig.jsonData, keepCookies: cookies } })
|
||||||
}
|
}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
@ -200,6 +203,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) },
|
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -211,7 +215,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
<h3 className="page-heading">Auth</h3>
|
<h3 className="page-heading">Auth</h3>
|
||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
<InlineField label="Basic auth" labelWidth={LABEL_WIDTH}>
|
<InlineField label="Basic auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-basic-auth"
|
id="http-settings-basic-auth"
|
||||||
value={dataSourceConfig.basicAuth}
|
value={dataSourceConfig.basicAuth}
|
||||||
@ -225,6 +229,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
label="With Credentials"
|
label="With Credentials"
|
||||||
tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests."
|
tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests."
|
||||||
labelWidth={LABEL_WIDTH}
|
labelWidth={LABEL_WIDTH}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
>
|
>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-with-credentials"
|
id="http-settings-with-credentials"
|
||||||
@ -242,6 +247,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
label="Azure Authentication"
|
label="Azure Authentication"
|
||||||
tooltip="Use Azure authentication for Azure endpoint."
|
tooltip="Use Azure authentication for Azure endpoint."
|
||||||
labelWidth={LABEL_WIDTH}
|
labelWidth={LABEL_WIDTH}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
>
|
>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-azure-auth"
|
id="http-settings-azure-auth"
|
||||||
@ -258,7 +264,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
|
|
||||||
{sigV4AuthToggleEnabled && (
|
{sigV4AuthToggleEnabled && (
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
<InlineField label="SigV4 auth" labelWidth={LABEL_WIDTH}>
|
<InlineField label="SigV4 auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-sigv4-auth"
|
id="http-settings-sigv4-auth"
|
||||||
value={dataSourceConfig.jsonData.sigV4Auth || false}
|
value={dataSourceConfig.jsonData.sigV4Auth || false}
|
||||||
|
@ -15,14 +15,19 @@ export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
<InlineField label="TLS Client Auth" labelWidth={LABEL_WIDTH}>
|
<InlineField label="TLS Client Auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-tls-client-auth"
|
id="http-settings-tls-client-auth"
|
||||||
value={dataSourceConfig.jsonData.tlsAuth || false}
|
value={dataSourceConfig.jsonData.tlsAuth || false}
|
||||||
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsAuth: event!.currentTarget.checked })}
|
onChange={(event) => onChange({ ...dataSourceConfig.jsonData, tlsAuth: event!.currentTarget.checked })}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField label="With CA Cert" tooltip="Needed for verifying self-signed TLS Certs" labelWidth={LABEL_WIDTH}>
|
<InlineField
|
||||||
|
label="With CA Cert"
|
||||||
|
tooltip="Needed for verifying self-signed TLS Certs"
|
||||||
|
labelWidth={LABEL_WIDTH}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
|
>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-ca-cert"
|
id="http-settings-ca-cert"
|
||||||
value={dataSourceConfig.jsonData.tlsAuthWithCACert || false}
|
value={dataSourceConfig.jsonData.tlsAuthWithCACert || false}
|
||||||
@ -33,7 +38,7 @@ export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({
|
|||||||
</InlineField>
|
</InlineField>
|
||||||
</div>
|
</div>
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
<InlineField label="Skip TLS Verify" labelWidth={LABEL_WIDTH}>
|
<InlineField label="Skip TLS Verify" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-skip-tls-verify"
|
id="http-settings-skip-tls-verify"
|
||||||
value={dataSourceConfig.jsonData.tlsSkipVerify || false}
|
value={dataSourceConfig.jsonData.tlsSkipVerify || false}
|
||||||
@ -49,6 +54,7 @@ export const HttpProxySettings: React.FC<HttpSettingsBaseProps> = ({
|
|||||||
label="Forward OAuth Identity"
|
label="Forward OAuth Identity"
|
||||||
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
||||||
labelWidth={LABEL_WIDTH}
|
labelWidth={LABEL_WIDTH}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
>
|
>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="http-settings-forward-oauth"
|
id="http-settings-forward-oauth"
|
||||||
|
@ -41,7 +41,12 @@ export const FormField: FunctionComponent<Props> = ({
|
|||||||
{label}
|
{label}
|
||||||
</InlineFormLabel>
|
</InlineFormLabel>
|
||||||
{inputEl || (
|
{inputEl || (
|
||||||
<input type="text" className={`gf-form-input ${inputWidth ? `width-${inputWidth}` : ''}`} {...inputProps} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className={`gf-form-input ${inputWidth ? `width-${inputWidth}` : ''}`}
|
||||||
|
{...inputProps}
|
||||||
|
disabled={inputProps.disabled}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -14,7 +14,7 @@ export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value'> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Switch = React.forwardRef<HTMLInputElement, Props>(
|
export const Switch = React.forwardRef<HTMLInputElement, Props>(
|
||||||
({ value, checked, disabled, onChange, id, label, ...inputProps }, ref) => {
|
({ value, checked, onChange, id, label, disabled, ...inputProps }, ref) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
deprecationWarning('Switch', 'checked prop', 'value');
|
deprecationWarning('Switch', 'checked prop', 'value');
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ export const Switch = React.forwardRef<HTMLInputElement, Props>(
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
checked={value}
|
checked={value}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
onChange?.(event);
|
!disabled && onChange?.(event);
|
||||||
}}
|
}}
|
||||||
id={switchIdRef.current}
|
id={switchIdRef.current}
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
@ -52,8 +52,9 @@ export const InlineSwitch = React.forwardRef<HTMLInputElement, InlineSwitchProps
|
|||||||
({ transparent, className, showLabel, label, value, id, ...props }, ref) => {
|
({ transparent, className, showLabel, label, value, id, ...props }, ref) => {
|
||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const styles = getSwitchStyles(theme, transparent);
|
const styles = getSwitchStyles(theme, transparent);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx(styles.inlineContainer, className)}>
|
<div className={cx(styles.inlineContainer, className, props.disabled && styles.disabled)}>
|
||||||
{showLabel && (
|
{showLabel && (
|
||||||
<label
|
<label
|
||||||
htmlFor={id}
|
htmlFor={id}
|
||||||
@ -158,6 +159,11 @@ const getSwitchStyles = stylesFactory((theme: GrafanaTheme2, transparent?: boole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
disabled: css`
|
||||||
|
background-color: rgba(204, 204, 220, 0.04);
|
||||||
|
color: rgba(204, 204, 220, 0.6);
|
||||||
|
border: 1px solid rgba(204, 204, 220, 0.04);
|
||||||
|
`,
|
||||||
inlineLabel: css`
|
inlineLabel: css`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding-right: ${theme.spacing(1)};
|
padding-right: ${theme.spacing(1)};
|
||||||
|
@ -11,12 +11,21 @@ export interface Props {
|
|||||||
onNameChange: (name: string) => void;
|
onNameChange: (name: string) => void;
|
||||||
onDefaultChange: (value: boolean) => void;
|
onDefaultChange: (value: boolean) => void;
|
||||||
alertingSupported: boolean;
|
alertingSupported: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNameChange, alertingSupported }: Props) {
|
export function BasicSettings({
|
||||||
|
dataSourceName,
|
||||||
|
isDefault,
|
||||||
|
onDefaultChange,
|
||||||
|
onNameChange,
|
||||||
|
alertingSupported,
|
||||||
|
disabled,
|
||||||
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{<AlertingEnabled enabled={alertingSupported} />}
|
<AlertingEnabled enabled={alertingSupported} />
|
||||||
|
|
||||||
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
|
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
{/* Name */}
|
{/* 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
|
tooltip="The name is used when you select the data source in panels. The default data source is
|
||||||
'preselected in new panels."
|
'preselected in new panels."
|
||||||
grow
|
grow
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="basic-settings-name"
|
id="basic-settings-name"
|
||||||
@ -40,7 +50,7 @@ export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNa
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Is Default */}
|
{/* Is Default */}
|
||||||
<InlineField label="Default" labelWidth={8}>
|
<InlineField label="Default" labelWidth={8} disabled={disabled}>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id="basic-settings-default"
|
id="basic-settings-default"
|
||||||
value={isDefault}
|
value={isDefault}
|
||||||
|
@ -159,6 +159,7 @@ export function EditDataSourceView({
|
|||||||
onDefaultChange={onDefaultChange}
|
onDefaultChange={onDefaultChange}
|
||||||
onNameChange={onNameChange}
|
onNameChange={onNameChange}
|
||||||
alertingSupported={alertingSupported}
|
alertingSupported={alertingSupported}
|
||||||
|
disabled={readOnly || !hasWriteRights}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{plugin && (
|
{plugin && (
|
||||||
|
@ -51,19 +51,20 @@ export const AzureAuthSettings: FunctionComponent<HttpSettingsBaseProps> = (prop
|
|||||||
credentials={credentials}
|
credentials={credentials}
|
||||||
azureCloudOptions={KnownAzureClouds}
|
azureCloudOptions={KnownAzureClouds}
|
||||||
onCredentialsChange={onCredentialsChange}
|
onCredentialsChange={onCredentialsChange}
|
||||||
|
disabled={dataSourceConfig.readOnly}
|
||||||
/>
|
/>
|
||||||
{overrideAudienceAllowed && (
|
{overrideAudienceAllowed && (
|
||||||
<>
|
<>
|
||||||
<h6>Azure Configuration</h6>
|
<h6>Azure Configuration</h6>
|
||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField labelWidth={26} label="Override AAD audience">
|
<InlineField labelWidth={26} label="Override AAD audience" disabled={dataSourceConfig.readOnly}>
|
||||||
<InlineSwitch value={overrideAudienceChecked} onChange={onOverrideAudienceChange} />
|
<InlineSwitch value={overrideAudienceChecked} onChange={onOverrideAudienceChange} />
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
{overrideAudienceChecked && (
|
{overrideAudienceChecked && (
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField labelWidth={26} label="Resource ID">
|
<InlineField labelWidth={26} label="Resource ID" disabled={dataSourceConfig.readOnly}>
|
||||||
<Input
|
<Input
|
||||||
className="width-30"
|
className="width-30"
|
||||||
value={dataSourceConfig.jsonData.azureEndpointResourceId || ''}
|
value={dataSourceConfig.jsonData.azureEndpointResourceId || ''}
|
||||||
|
@ -13,6 +13,7 @@ export interface Props {
|
|||||||
azureCloudOptions?: SelectableValue[];
|
azureCloudOptions?: SelectableValue[];
|
||||||
onCredentialsChange: (updatedCredentials: AzureCredentials) => void;
|
onCredentialsChange: (updatedCredentials: AzureCredentials) => void;
|
||||||
getSubscriptions?: () => Promise<SelectableValue[]>;
|
getSubscriptions?: () => Promise<SelectableValue[]>;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
||||||
@ -27,7 +28,7 @@ const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) => {
|
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 hasRequiredFields = isCredentialsComplete(credentials);
|
||||||
|
|
||||||
const [subscriptions, setSubscriptions] = useState<Array<SelectableValue<string>>>([]);
|
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)}
|
value={authTypeOptions.find((opt) => opt.value === credentials.authType)}
|
||||||
options={authTypeOptions}
|
options={authTypeOptions}
|
||||||
onChange={onAuthTypeChange}
|
onChange={onAuthTypeChange}
|
||||||
|
isDisabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -178,6 +180,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
value={azureCloudOptions.find((opt) => opt.value === credentials.azureCloud)}
|
value={azureCloudOptions.find((opt) => opt.value === credentials.azureCloud)}
|
||||||
options={azureCloudOptions}
|
options={azureCloudOptions}
|
||||||
onChange={onAzureCloudChange}
|
onChange={onAzureCloudChange}
|
||||||
|
isDisabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -191,6 +194,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||||
value={credentials.tenantId || ''}
|
value={credentials.tenantId || ''}
|
||||||
onChange={onTenantIdChange}
|
onChange={onTenantIdChange}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -204,6 +208,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||||
value={credentials.clientId || ''}
|
value={credentials.clientId || ''}
|
||||||
onChange={onClientIdChange}
|
onChange={onClientIdChange}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -214,15 +219,17 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
<InlineFormLabel htmlFor="azure-client-secret" className="width-12">
|
<InlineFormLabel htmlFor="azure-client-secret" className="width-12">
|
||||||
Client Secret
|
Client Secret
|
||||||
</InlineFormLabel>
|
</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>
|
||||||
<div className="gf-form">
|
{!disabled && (
|
||||||
<div className="max-width-30 gf-form-inline">
|
<div className="gf-form">
|
||||||
<Button variant="secondary" type="button" onClick={onClientSecretReset}>
|
<div className="max-width-30 gf-form-inline">
|
||||||
reset
|
<Button variant="secondary" type="button" onClick={onClientSecretReset}>
|
||||||
</Button>
|
reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="gf-form-inline">
|
<div className="gf-form-inline">
|
||||||
@ -234,6 +241,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||||
value={credentials.clientSecret || ''}
|
value={credentials.clientSecret || ''}
|
||||||
onChange={onClientSecretChange}
|
onChange={onClientSecretChange}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -255,6 +263,7 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
|||||||
}
|
}
|
||||||
options={subscriptions}
|
options={subscriptions}
|
||||||
onChange={onSubscriptionChange}
|
onChange={onSubscriptionChange}
|
||||||
|
isDisabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,32 +11,35 @@ type Props = {
|
|||||||
value: ExemplarTraceIdDestination;
|
value: ExemplarTraceIdDestination;
|
||||||
onChange: (value: ExemplarTraceIdDestination) => void;
|
onChange: (value: ExemplarTraceIdDestination) => void;
|
||||||
onDelete: () => 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));
|
const [isInternalLink, setIsInternalLink] = useState(Boolean(value.datasourceUid));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<InlineField label="Internal link" labelWidth={24}>
|
<InlineField label="Internal link" labelWidth={24} disabled={disabled}>
|
||||||
<>
|
<>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
value={isInternalLink}
|
value={isInternalLink}
|
||||||
aria-label={selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch}
|
aria-label={selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch}
|
||||||
onChange={(ev) => setIsInternalLink(ev.currentTarget.checked)}
|
onChange={(ev) => setIsInternalLink(ev.currentTarget.checked)}
|
||||||
/>
|
/>
|
||||||
<Button
|
{!disabled && (
|
||||||
variant="destructive"
|
<Button
|
||||||
title="Remove link"
|
variant="destructive"
|
||||||
icon="times"
|
title="Remove link"
|
||||||
onClick={(event) => {
|
icon="times"
|
||||||
event.preventDefault();
|
onClick={(event) => {
|
||||||
onDelete();
|
event.preventDefault();
|
||||||
}}
|
onDelete();
|
||||||
className={css`
|
}}
|
||||||
margin-left: 8px;
|
className={css`
|
||||||
`}
|
margin-left: 8px;
|
||||||
/>
|
`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
|||||||
label="Data source"
|
label="Data source"
|
||||||
labelWidth={24}
|
labelWidth={24}
|
||||||
tooltip="The data source the exemplar is going to navigate to."
|
tooltip="The data source the exemplar is going to navigate to."
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
tracing={true}
|
tracing={true}
|
||||||
@ -65,6 +69,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
|||||||
label="URL"
|
label="URL"
|
||||||
labelWidth={24}
|
labelWidth={24}
|
||||||
tooltip="The URL of the trace backend the user would go to see its trace."
|
tooltip="The URL of the trace backend the user would go to see its trace."
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="https://example.com/${__value.raw}"
|
placeholder="https://example.com/${__value.raw}"
|
||||||
@ -86,6 +91,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
|||||||
label="URL Label"
|
label="URL Label"
|
||||||
labelWidth={24}
|
labelWidth={24}
|
||||||
tooltip="Use to override the button label on the exemplar traceID field."
|
tooltip="Use to override the button label on the exemplar traceID field."
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Go to example.com"
|
placeholder="Go to example.com"
|
||||||
@ -104,6 +110,7 @@ export default function ExemplarSetting({ value, onChange, onDelete }: Props) {
|
|||||||
label="Label name"
|
label="Label name"
|
||||||
labelWidth={24}
|
labelWidth={24}
|
||||||
tooltip="The name of the field in the labels object that should be used to get the traceID."
|
tooltip="The name of the field in the labels object that should be used to get the traceID."
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="traceID"
|
placeholder="traceID"
|
||||||
|
@ -11,9 +11,10 @@ import ExemplarSetting from './ExemplarSetting';
|
|||||||
type Props = {
|
type Props = {
|
||||||
options?: ExemplarTraceIdDestination[];
|
options?: ExemplarTraceIdDestination[];
|
||||||
onChange: (value: ExemplarTraceIdDestination[]) => void;
|
onChange: (value: ExemplarTraceIdDestination[]) => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ExemplarsSettings({ options, onChange }: Props) {
|
export function ExemplarsSettings({ options, onChange, disabled }: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="page-heading">Exemplars</h3>
|
<h3 className="page-heading">Exemplars</h3>
|
||||||
@ -34,25 +35,28 @@ export function ExemplarsSettings({ options, onChange }: Props) {
|
|||||||
newOptions.splice(index, 1);
|
newOptions.splice(index, 1);
|
||||||
onChange(newOptions);
|
onChange(newOptions);
|
||||||
}}
|
}}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<Button
|
{!disabled && (
|
||||||
variant="secondary"
|
<Button
|
||||||
aria-label={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
variant="secondary"
|
||||||
className={css`
|
aria-label={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
||||||
margin-bottom: 10px;
|
className={css`
|
||||||
`}
|
margin-bottom: 10px;
|
||||||
icon="plus"
|
`}
|
||||||
onClick={(event) => {
|
icon="plus"
|
||||||
event.preventDefault();
|
onClick={(event) => {
|
||||||
const newOptions = [...(options || []), { name: 'traceID' }];
|
event.preventDefault();
|
||||||
onChange(newOptions);
|
const newOptions = [...(options || []), { name: 'traceID' }];
|
||||||
}}
|
onChange(newOptions);
|
||||||
>
|
}}
|
||||||
Add
|
>
|
||||||
</Button>
|
Add
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,7 @@ export const PromSettings = (props: Props) => {
|
|||||||
placeholder="15s"
|
placeholder="15s"
|
||||||
onChange={onChangeHandler('timeInterval', options, onOptionsChange)}
|
onChange={onChangeHandler('timeInterval', options, onOptionsChange)}
|
||||||
validationEvents={promSettingsValidationEvents}
|
validationEvents={promSettingsValidationEvents}
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
tooltip="Set this to the typical scrape and evaluation interval configured in Prometheus. Defaults to 15s."
|
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}
|
spellCheck={false}
|
||||||
placeholder="60s"
|
placeholder="60s"
|
||||||
validationEvents={promSettingsValidationEvents}
|
validationEvents={promSettingsValidationEvents}
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
tooltip="Set the Prometheus query timeout."
|
tooltip="Set the Prometheus query timeout."
|
||||||
@ -198,6 +200,7 @@ export const PromSettings = (props: Props) => {
|
|||||||
value={httpOptions.find((o) => o.value === options.jsonData.httpMethod)}
|
value={httpOptions.find((o) => o.value === options.jsonData.httpMethod)}
|
||||||
onChange={onChangeHandler('httpMethod', options, onOptionsChange)}
|
onChange={onChangeHandler('httpMethod', options, onOptionsChange)}
|
||||||
className="width-6"
|
className="width-6"
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -242,6 +245,7 @@ export const PromSettings = (props: Props) => {
|
|||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
width={20}
|
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."
|
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)}
|
onChange={onChangeHandler('prometheusVersion', options, onOptionsChange)}
|
||||||
width={20}
|
width={20}
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
tooltip={`Use this to set the version of your ${options.jsonData.prometheusType} instance if it is not automatically configured.`}
|
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}
|
labelWidth={28}
|
||||||
label="Disable metrics lookup"
|
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."
|
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
|
<InlineSwitch
|
||||||
value={options.jsonData.disableMetricsLookup ?? false}
|
value={options.jsonData.disableMetricsLookup ?? false}
|
||||||
@ -299,6 +305,7 @@ export const PromSettings = (props: Props) => {
|
|||||||
onChange={onChangeHandler('customQueryParameters', options, onOptionsChange)}
|
onChange={onChangeHandler('customQueryParameters', options, onOptionsChange)}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
placeholder="Example: max_source_resolution=5m&timeout=10"
|
placeholder="Example: max_source_resolution=5m&timeout=10"
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -314,6 +321,7 @@ export const PromSettings = (props: Props) => {
|
|||||||
exemplarOptions
|
exemplarOptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
disabled={options.readOnly}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user