Chore: Update Action interface (#93248)

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
Adela Almasan
2024-09-23 09:41:05 -06:00
committed by GitHub
parent 026748a5ab
commit d630e9bcb3
5 changed files with 51 additions and 41 deletions

View File

@ -3,10 +3,18 @@ import { DataFrame, Field, ValueLinkConfig } from './dataFrame';
import { InterpolateFunction } from './panel';
import { SelectableValue } from './select';
export interface Action<T = ActionType.Fetch, TOptions = FetchOptions> {
type: T;
export enum ActionType {
Fetch = 'fetch',
}
export interface Action {
type: ActionType;
title: string;
options: TOptions;
// Options for the selected type
// Currently this is required because there is only one valid type (fetch)
// once multiple types are valid, usage of this will need to be optional
[ActionType.Fetch]: FetchOptions;
}
/**
@ -25,10 +33,6 @@ interface FetchOptions {
headers?: Array<[string, string]>;
}
export enum ActionType {
Fetch = 'fetch',
}
export enum HttpRequestMethod {
POST = 'POST',
PUT = 'PUT',
@ -51,7 +55,7 @@ export const contentTypeOptions: SelectableValue[] = [
export const defaultActionConfig: Action = {
type: ActionType.Fetch,
title: '',
options: {
fetch: {
url: '',
method: HttpRequestMethod.POST,
body: '{}',

View File

@ -32,8 +32,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
const onUrlChange = (url: string) => {
onChange(index, {
...value,
options: {
...value.options,
fetch: {
...value.fetch,
url,
},
});
@ -42,8 +42,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
const onBodyChange = (body: string) => {
onChange(index, {
...value,
options: {
...value.options,
fetch: {
...value.fetch,
body,
},
});
@ -52,8 +52,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
const onMethodChange = (method: HttpRequestMethod) => {
onChange(index, {
...value,
options: {
...value.options,
fetch: {
...value.fetch,
method,
},
});
@ -62,8 +62,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
const onQueryParamsChange = (queryParams: Array<[string, string]>) => {
onChange(index, {
...value,
options: {
...value.options,
fetch: {
...value.fetch,
queryParams,
},
});
@ -72,8 +72,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
const onHeadersChange = (headers: Array<[string, string]>) => {
onChange(index, {
...value,
options: {
...value.options,
fetch: {
...value.fetch,
headers,
},
});
@ -93,8 +93,8 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
};
const shouldRenderJSON =
value.options.method !== HttpRequestMethod.GET &&
value.options.headers?.some(([name, value]) => name === 'Content-Type' && value === 'application/json');
value.fetch.method !== HttpRequestMethod.GET &&
value.fetch.headers?.some(([name, value]) => name === 'Content-Type' && value === 'application/json');
return (
<div className={styles.listItem}>
@ -111,7 +111,7 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
<InlineFieldRow>
<InlineField label="Method" labelWidth={LABEL_WIDTH} grow={true}>
<RadioButtonGroup<HttpRequestMethod>
value={value?.options.method}
value={value?.fetch.method}
options={httpMethodOptions}
onChange={onMethodChange}
fullWidth
@ -122,7 +122,7 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
<InlineFieldRow>
<InlineField label="URL" labelWidth={LABEL_WIDTH} grow={true}>
<SuggestionsInput
value={value.options.url}
value={value.fetch.url}
onChange={onUrlChange}
suggestions={suggestions}
placeholder="URL"
@ -131,26 +131,22 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
</InlineFieldRow>
<Field label="Query parameters" className={styles.fieldGap}>
<ParamsEditor
value={value?.options.queryParams ?? []}
onChange={onQueryParamsChange}
suggestions={suggestions}
/>
<ParamsEditor value={value?.fetch.queryParams ?? []} onChange={onQueryParamsChange} suggestions={suggestions} />
</Field>
<Field label="Headers">
<ParamsEditor
value={value?.options.headers ?? []}
value={value?.fetch.headers ?? []}
onChange={onHeadersChange}
suggestions={suggestions}
contentTypeHeader={true}
/>
</Field>
{value?.options.method !== HttpRequestMethod.GET && (
{value?.fetch.method !== HttpRequestMethod.GET && (
<Field label="Body">
<SuggestionsInput
value={value.options.body}
value={value.fetch.body}
onChange={onBodyChange}
suggestions={suggestions}
type={HTMLElementType.TextAreaElement}
@ -161,7 +157,7 @@ export const ActionEditor = memo(({ index, value, onChange, suggestions }: Actio
{shouldRenderJSON && (
<>
<br />
{renderJSON(value?.options.body)}
{renderJSON(value?.fetch.body)}
</>
)}
</div>

View File

@ -42,7 +42,7 @@ export const ActionEditorModalContent = ({
onClick={() => {
onSave(index, dirtyAction);
}}
disabled={dirtyAction.title.trim() === '' || dirtyAction.options.url.trim() === ''}
disabled={dirtyAction.title.trim() === '' || dirtyAction.fetch.url.trim() === ''}
>
Save
</Button>

View File

@ -68,25 +68,25 @@ export const getActions = (
/** @internal */
const buildActionOnClick = (action: Action, replaceVariables: InterpolateFunction) => {
try {
const url = new URL(getUrl(replaceVariables(action.options.url)));
const url = new URL(getUrl(replaceVariables(action.fetch.url)));
const requestHeaders: Record<string, string> = {};
let request: BackendSrvRequest = {
url: url.toString(),
method: action.options.method,
method: action.fetch.method,
data: getData(action, replaceVariables),
headers: requestHeaders,
};
if (action.options.headers) {
action.options.headers.forEach(([name, value]) => {
if (action.fetch.headers) {
action.fetch.headers.forEach(([name, value]) => {
requestHeaders[replaceVariables(name)] = replaceVariables(value);
});
}
if (action.options.queryParams) {
action.options.queryParams?.forEach(([name, value]) => {
if (action.fetch.queryParams) {
action.fetch.queryParams?.forEach(([name, value]) => {
url.searchParams.append(replaceVariables(name), replaceVariables(value));
});
@ -139,8 +139,8 @@ const getUrl = (endpoint: string) => {
/** @internal */
const getData = (action: Action, replaceVariables: InterpolateFunction) => {
let data: string | undefined = action.options.body ? replaceVariables(action.options.body) : '{}';
if (action.options.method === HttpRequestMethod.GET) {
let data: string | undefined = action.fetch.body ? replaceVariables(action.fetch.body) : '{}';
if (action.fetch.method === HttpRequestMethod.GET) {
data = undefined;
}

View File

@ -68,14 +68,24 @@ export const canvasMigrationHandler = (panel: PanelModel): Partial<Options> => {
}
}
// migrate oneClickLinks to oneClickMode
const root = panel.options?.root;
if (root?.elements) {
for (const element of root.elements) {
// migrate oneClickLinks to oneClickMode
if (element.oneClickLinks) {
element.oneClickMode = OneClickMode.Link;
delete element.oneClickLinks;
}
// migrate action options to new format (fetch)
if (element.actions) {
for (const action of element.actions) {
if (action.options) {
action.fetch = { ...action.options };
delete action.options;
}
}
}
}
}
}