mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Canvas: Button API Editor support setting content-type (#74682)
This commit is contained in:
parent
db2295bea2
commit
a0e6e76ca6
@ -24,6 +24,7 @@ export const defaultApiConfig: APIEditorConfig = {
|
|||||||
endpoint: '',
|
endpoint: '',
|
||||||
method: HttpRequestMethod.POST,
|
method: HttpRequestMethod.POST,
|
||||||
data: '{}',
|
data: '{}',
|
||||||
|
contentType: 'application/json',
|
||||||
};
|
};
|
||||||
|
|
||||||
class ButtonDisplay extends PureComponent<CanvasElementProps<ButtonConfig, ButtonData>> {
|
class ButtonDisplay extends PureComponent<CanvasElementProps<ButtonConfig, ButtonData>> {
|
||||||
@ -80,7 +81,11 @@ export const buttonItem: CanvasElementItem<ButtonConfig, ButtonData> = {
|
|||||||
prepareData: (ctx: DimensionContext, cfg: ButtonConfig) => {
|
prepareData: (ctx: DimensionContext, cfg: ButtonConfig) => {
|
||||||
const getCfgApi = () => {
|
const getCfgApi = () => {
|
||||||
if (cfg?.api) {
|
if (cfg?.api) {
|
||||||
cfg.api = { ...cfg.api, method: cfg.api.method ?? HttpRequestMethod.POST };
|
cfg.api = {
|
||||||
|
...cfg.api,
|
||||||
|
method: cfg.api.method ?? defaultApiConfig.method,
|
||||||
|
contentType: cfg.api.contentType ?? defaultApiConfig.contentType,
|
||||||
|
};
|
||||||
return cfg.api;
|
return cfg.api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
import { AppEvents, StandardEditorProps, StandardEditorsRegistryItem, StringFieldConfigSettings } from '@grafana/data';
|
import {
|
||||||
import { config, getBackendSrv } from '@grafana/runtime';
|
AppEvents,
|
||||||
import { Button, InlineField, InlineFieldRow, JSONFormatter, RadioButtonGroup } from '@grafana/ui';
|
SelectableValue,
|
||||||
|
StandardEditorProps,
|
||||||
|
StandardEditorsRegistryItem,
|
||||||
|
StringFieldConfigSettings,
|
||||||
|
} from '@grafana/data';
|
||||||
|
import { BackendSrvRequest, config, getBackendSrv } from '@grafana/runtime';
|
||||||
|
import { Button, Field, InlineField, InlineFieldRow, JSONFormatter, RadioButtonGroup, Select } from '@grafana/ui';
|
||||||
import { StringValueEditor } from 'app/core/components/OptionsUI/string';
|
import { StringValueEditor } from 'app/core/components/OptionsUI/string';
|
||||||
import { appEvents } from 'app/core/core';
|
import { appEvents } from 'app/core/core';
|
||||||
import { defaultApiConfig } from 'app/features/canvas/elements/button';
|
import { defaultApiConfig } from 'app/features/canvas/elements/button';
|
||||||
@ -13,20 +19,36 @@ export interface APIEditorConfig {
|
|||||||
method: string;
|
method: string;
|
||||||
endpoint: string;
|
endpoint: string;
|
||||||
data?: string;
|
data?: string;
|
||||||
|
contentType?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dummyStringSettings = {
|
const dummyStringSettings = {
|
||||||
settings: {},
|
settings: {},
|
||||||
} as StandardEditorsRegistryItem<string, StringFieldConfigSettings>;
|
} as StandardEditorsRegistryItem<string, StringFieldConfigSettings>;
|
||||||
|
|
||||||
export const callApi = (api: APIEditorConfig, isTest = false) => {
|
const getRequest = (api: APIEditorConfig) => {
|
||||||
if (api && api.endpoint) {
|
const requestHeaders: HeadersInit = [];
|
||||||
getBackendSrv()
|
|
||||||
.fetch({
|
let request: BackendSrvRequest = {
|
||||||
url: api.endpoint,
|
url: api.endpoint,
|
||||||
method: api.method,
|
method: api.method,
|
||||||
data: getData(api),
|
data: getData(api),
|
||||||
})
|
headers: requestHeaders,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (api.method === HttpRequestMethod.POST) {
|
||||||
|
requestHeaders.push(['Content-Type', api.contentType!]);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.headers = requestHeaders;
|
||||||
|
|
||||||
|
return request;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const callApi = (api: APIEditorConfig, isTest = false) => {
|
||||||
|
if (api && api.endpoint) {
|
||||||
|
getBackendSrv()
|
||||||
|
.fetch(getRequest(api))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
if (isTest) {
|
if (isTest) {
|
||||||
@ -59,6 +81,15 @@ const httpMethodOptions = [
|
|||||||
{ label: HttpRequestMethod.POST, value: HttpRequestMethod.POST },
|
{ label: HttpRequestMethod.POST, value: HttpRequestMethod.POST },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const contentTypeOptions: SelectableValue[] = [
|
||||||
|
{ label: 'JSON', value: 'application/json' },
|
||||||
|
{ label: 'Text', value: 'text/plain' },
|
||||||
|
{ label: 'JavaScript', value: 'application/javascript' },
|
||||||
|
{ label: 'HTML', value: 'text/html' },
|
||||||
|
{ label: 'XML', value: 'application/XML' },
|
||||||
|
{ label: 'x-www-form-urlencoded', value: 'application/x-www-form-urlencoded' },
|
||||||
|
];
|
||||||
|
|
||||||
export function APIEditor({ value, context, onChange }: Props) {
|
export function APIEditor({ value, context, onChange }: Props) {
|
||||||
const LABEL_WIDTH = 9;
|
const LABEL_WIDTH = 9;
|
||||||
|
|
||||||
@ -96,6 +127,20 @@ export function APIEditor({ value, context, onChange }: Props) {
|
|||||||
[onChange, value]
|
[onChange, value]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onContentTypeChange = useCallback(
|
||||||
|
(contentType: SelectableValue<string>) => {
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
contentType: contentType?.value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[onChange, value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const formatCreateLabel = (input: string) => {
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
const renderJSON = (data: string) => {
|
const renderJSON = (data: string) => {
|
||||||
try {
|
try {
|
||||||
const json = JSON.parse(data);
|
const json = JSON.parse(data);
|
||||||
@ -124,12 +169,7 @@ export function APIEditor({ value, context, onChange }: Props) {
|
|||||||
return config.disableSanitizeHtml ? (
|
return config.disableSanitizeHtml ? (
|
||||||
<>
|
<>
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField label="Method" labelWidth={LABEL_WIDTH} grow={true}>
|
<InlineField label="Endpoint" labelWidth={LABEL_WIDTH} grow={true}>
|
||||||
<RadioButtonGroup value={value?.method} options={httpMethodOptions} onChange={onMethodChange} fullWidth />
|
|
||||||
</InlineField>
|
|
||||||
</InlineFieldRow>
|
|
||||||
<InlineFieldRow>
|
|
||||||
<InlineField label={'Endpoint'} labelWidth={LABEL_WIDTH} grow={true}>
|
|
||||||
<StringValueEditor
|
<StringValueEditor
|
||||||
context={context}
|
context={context}
|
||||||
value={value?.endpoint}
|
value={value?.endpoint}
|
||||||
@ -138,21 +178,40 @@ export function APIEditor({ value, context, onChange }: Props) {
|
|||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
{value?.method === HttpRequestMethod.POST && (
|
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField label={'Data'} labelWidth={LABEL_WIDTH} grow={true}>
|
<InlineField label="Method" labelWidth={LABEL_WIDTH} grow={true}>
|
||||||
|
<RadioButtonGroup value={value?.method} options={httpMethodOptions} onChange={onMethodChange} fullWidth />
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
{value?.method === HttpRequestMethod.POST && (
|
||||||
|
<>
|
||||||
|
<Field label="Content-Type">
|
||||||
|
<Select
|
||||||
|
minMenuHeight={200}
|
||||||
|
options={contentTypeOptions}
|
||||||
|
allowCustomValue={true}
|
||||||
|
formatCreateLabel={formatCreateLabel}
|
||||||
|
value={value?.contentType}
|
||||||
|
onChange={onContentTypeChange}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
{value?.contentType && (
|
||||||
|
<Field label="Payload">
|
||||||
<StringValueEditor
|
<StringValueEditor
|
||||||
context={context}
|
context={context}
|
||||||
value={value?.data ?? '{}'}
|
value={value?.data ?? '{}'}
|
||||||
onChange={onDataChange}
|
onChange={onDataChange}
|
||||||
item={dummyStringSettings}
|
item={{ ...dummyStringSettings, settings: { useTextarea: true } }}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</Field>
|
||||||
</InlineFieldRow>
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{renderTestAPIButton(value)}
|
{renderTestAPIButton(value)}
|
||||||
<br />
|
<br />
|
||||||
{value?.method === HttpRequestMethod.POST && renderJSON(value?.data ?? '{}')}
|
{value?.method === HttpRequestMethod.POST &&
|
||||||
|
value?.contentType === defaultApiConfig.contentType &&
|
||||||
|
renderJSON(value?.data ?? '{}')}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>Must enable disableSanitizeHtml feature flag to access</>
|
<>Must enable disableSanitizeHtml feature flag to access</>
|
||||||
|
Loading…
Reference in New Issue
Block a user