Canvas: Button API Editor support setting parameters (#74637)

This commit is contained in:
Adela Almasan 2023-09-18 09:25:35 -05:00 committed by GitHub
parent 4280e31239
commit 0815d7f627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 0 deletions

View File

@ -28,6 +28,8 @@ export const defaultApiConfig: APIEditorConfig = {
method: HttpRequestMethod.POST,
data: '{}',
contentType: 'application/json',
queryParams: [],
headerParams: [],
};
export const defaultStyleConfig: ButtonStyleConfig = {

View File

@ -15,11 +15,15 @@ import { defaultApiConfig } from 'app/features/canvas/elements/button';
import { HttpRequestMethod } from '../../panelcfg.gen';
import { ParamsEditor } from './ParamsEditor';
export interface APIEditorConfig {
method: string;
endpoint: string;
data?: string;
contentType?: string;
queryParams?: Array<[string, string]>;
headerParams?: Array<[string, string]>;
}
const dummyStringSettings = {
@ -36,6 +40,21 @@ const getRequest = (api: APIEditorConfig) => {
headers: requestHeaders,
};
if (api.headerParams) {
api.headerParams.forEach((param) => {
requestHeaders.push([param[0], param[1]]);
});
}
if (api.queryParams) {
const symbol = api.endpoint.match(questionMarkRegex) ? '&' : '?';
request.url = api.endpoint + symbol + api.queryParams?.map((param) => param[0] + '=' + param[1]).join('&');
}
if (api.method === HttpRequestMethod.POST) {
requestHeaders.push(['Content-Type', 'application/json']);
}
if (api.method === HttpRequestMethod.POST) {
requestHeaders.push(['Content-Type', api.contentType!]);
}
@ -45,6 +64,8 @@ const getRequest = (api: APIEditorConfig) => {
return request;
};
const questionMarkRegex = '.+\\?.*';
export const callApi = (api: APIEditorConfig, isTest = false) => {
if (api && api.endpoint) {
getBackendSrv()
@ -141,6 +162,26 @@ export function APIEditor({ value, context, onChange }: Props) {
return input;
};
const onQueryParamsChange = useCallback(
(queryParams: Array<[string, string]>) => {
onChange({
...value,
queryParams,
});
},
[onChange, value]
);
const onHeaderParamsChange = useCallback(
(headerParams: Array<[string, string]>) => {
onChange({
...value,
headerParams,
});
},
[onChange, value]
);
const renderJSON = (data: string) => {
try {
const json = JSON.parse(data);
@ -183,6 +224,12 @@ export function APIEditor({ value, context, onChange }: Props) {
<RadioButtonGroup value={value?.method} options={httpMethodOptions} onChange={onMethodChange} fullWidth />
</InlineField>
</InlineFieldRow>
<Field label="Query parameters">
<ParamsEditor value={value?.queryParams ?? []} onChange={onQueryParamsChange} />
</Field>
<Field label="Header parameters">
<ParamsEditor value={value?.headerParams ?? []} onChange={onHeaderParamsChange} />
</Field>
{value?.method === HttpRequestMethod.POST && (
<>
<InlineFieldRow>

View File

@ -0,0 +1,63 @@
import React, { useState } from 'react';
import { HorizontalGroup, IconButton, Input, VerticalGroup } from '@grafana/ui';
interface Props {
onChange: (v: Array<[string, string]>) => void;
value: Array<[string, string]>;
}
export const ParamsEditor = ({ value, onChange }: Props) => {
const [paramName, setParamName] = useState('');
const [paramValue, setParamValue] = useState('');
const changeParamValue = ({ currentTarget }: React.ChangeEvent<HTMLInputElement>) => {
setParamValue(currentTarget.value);
};
const changeParamName = ({ currentTarget }: React.ChangeEvent<HTMLInputElement>) => {
setParamName(currentTarget.value);
};
const removeParam = (key: string) => () => {
const updatedParams = value.filter((param) => param[0] !== key);
onChange(updatedParams);
};
const addParam = () => {
const key = paramName;
let newParams: Array<[string, string]>;
if (value) {
newParams = value.filter((e) => e[0] !== key);
} else {
newParams = [];
}
newParams.push([key, paramValue]);
newParams.sort((a, b) => a[0].localeCompare(b[0]));
setParamName('');
setParamValue('');
onChange(newParams);
};
const isAddParamsDisabled = !paramName && !paramValue;
return (
<div>
<HorizontalGroup>
<Input placeholder="Key" value={paramName} onChange={changeParamName} />
<Input placeholder="Value" value={paramValue} onChange={changeParamValue} />
<IconButton aria-label="add" name="plus-circle" onClick={addParam} disabled={isAddParamsDisabled} />
</HorizontalGroup>
<VerticalGroup>
{Array.from(value || []).map((entry) => (
<HorizontalGroup key={entry[0]}>
<Input disabled value={entry[0]} />
<Input disabled value={entry[1]} />
<IconButton aria-label="delete" onClick={removeParam(entry[0])} name="trash-alt" />
</HorizontalGroup>
))}
</VerticalGroup>
</div>
);
};