Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@
* resolves on success or rejects/throws on error.
*/
onSubmit: (values: Record<string, unknown>) => Promise<unknown> | void;
/**
* Override the built-in async query options for specific fields. Map from
* field name to a factory that returns query options for a given search input.
* When provided for a field, this is used instead of the default URL-based
* async loading. Useful when the async endpoint requires a different query
* shape than the built-in `buildAsyncSelectQuery`.
*/
customAsyncQueryOptions?: Record<
string,
(debouncedInput: string) => ReturnType<typeof queryOptions>
>;
/**
* Current values of dynamic fields, passed as query params to async select endpoints.
*/
Expand Down Expand Up @@ -158,6 +169,7 @@
dynamicFieldValues,
onAsyncOptionsFetched,
onFieldChange,
customAsyncQueryOptions,
footer,
}: BackendJsonSubmitFormProps) {
// Ref to avoid including the callback in queryKey (would cause refetches)
Expand Down Expand Up @@ -274,44 +286,50 @@
);
case 'select':
case 'choice': {
if (field.url) {
if (field.url || customAsyncQueryOptions?.[field.name]) {
// Async select: fetch options from URL as user types.
// Show static choices as initial options before any search.
const staticOptions = transformChoices(field.choices);
const asyncQueryOptions = (debouncedInput: string) =>
queryOptions({
queryKey: [
'backend-json-async-select',
field.name,
field.url,
debouncedInput,
dynamicFieldValues,
JSON.stringify(onAsyncOptionsFetchedRef),
],
queryFn: async (): Promise<
Array<SelectValue<string | number>>
> => {
if (!debouncedInput) {
return staticOptions;
}
const response = await API_CLIENT.requestPromise(
field.url!,
{
query: buildAsyncSelectQuery(
field.name,
debouncedInput,
dynamicFieldValues
),
}
);
// API may return non-array responses (e.g. error objects)
const results = Array.isArray(response) ? response : [];
if (results.length > 0) {
onAsyncOptionsFetchedRef.current?.(field.name, results);
}
return results;
},
});
const customQueryOptions = customAsyncQueryOptions?.[field.name];
const asyncQueryOptions = customQueryOptions
? customQueryOptions
: (debouncedInput: string) =>
queryOptions({
queryKey: [
'backend-json-async-select',
field.name,
field.url,
debouncedInput,
dynamicFieldValues,
JSON.stringify(onAsyncOptionsFetchedRef),
],
queryFn: async (): Promise<
Array<SelectValue<string | number>>
> => {
if (!debouncedInput) {
return staticOptions;
}
const response = await API_CLIENT.requestPromise(
field.url!,
{
query: buildAsyncSelectQuery(
field.name,
debouncedInput,
dynamicFieldValues
),
}
);
// API may return non-array responses (e.g. error objects)
const results = Array.isArray(response) ? response : [];
if (results.length > 0) {
onAsyncOptionsFetchedRef.current?.(
field.name,
results
);
}
return results;
},
});
if (field.multiple) {
return (
<fieldApi.Layout.Stack
Expand All @@ -328,7 +346,7 @@
handleChange(value)
}
disabled={field.disabled}
queryOptions={asyncQueryOptions}

Check failure on line 349 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / @typescript/native-preview

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.

Check failure on line 349 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / typescript

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.
/>
</fieldApi.Layout.Stack>
);
Expand All @@ -346,7 +364,7 @@
}
onChange={(value: string | number) => handleChange(value)}
disabled={field.disabled}
queryOptions={asyncQueryOptions}

Check failure on line 367 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / @typescript/native-preview

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.

Check failure on line 367 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / typescript

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.
/>
) : (
<fieldApi.SelectAsync
Expand All @@ -358,7 +376,7 @@
handleChange(value)
}
disabled={field.disabled}
queryOptions={asyncQueryOptions}

Check failure on line 379 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / @typescript/native-preview

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.

Check failure on line 379 in static/app/components/backendJsonFormAdapter/backendJsonSubmitForm.tsx

View workflow job for this annotation

GitHub Actions / typescript

Type '((debouncedInput: string) => UseQueryOptions<unknown, unknown, unknown, readonly unknown[]> & { initialData?: unknown; } & { queryKey: readonly unknown[] & { [dataTagSymbol]: unknown; [dataTagErrorSymbol]: unknown; }; }) | ((debouncedInput: string) => OmitKeyof<...> & ... 1 more ... & { ...; })' is not assignable to type '(debouncedInput: string) => UseQueryOptions<unknown, Error, readonly SelectValue<string | number>[], any>'.
/>
)}
</fieldApi.Layout.Stack>
Expand Down
Loading