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 { InterpolateFunction } from './panel';
import { SelectableValue } from './select'; import { SelectableValue } from './select';
export interface Action<T = ActionType.Fetch, TOptions = FetchOptions> { export enum ActionType {
type: T; Fetch = 'fetch',
}
export interface Action {
type: ActionType;
title: string; 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]>; headers?: Array<[string, string]>;
} }
export enum ActionType {
Fetch = 'fetch',
}
export enum HttpRequestMethod { export enum HttpRequestMethod {
POST = 'POST', POST = 'POST',
PUT = 'PUT', PUT = 'PUT',
@ -51,7 +55,7 @@ export const contentTypeOptions: SelectableValue[] = [
export const defaultActionConfig: Action = { export const defaultActionConfig: Action = {
type: ActionType.Fetch, type: ActionType.Fetch,
title: '', title: '',
options: { fetch: {
url: '', url: '',
method: HttpRequestMethod.POST, method: HttpRequestMethod.POST,
body: '{}', body: '{}',

View File

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

View File

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

View File

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

View File

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