mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
import {useState} from 'react';
|
|
|
|
import type {
|
|
Result,
|
|
SelectAsyncControlProps,
|
|
} from 'sentry/components/forms/controls/selectAsyncControl';
|
|
import SelectAsyncControl from 'sentry/components/forms/controls/selectAsyncControl';
|
|
// projects can be passed as a direct prop as well
|
|
import type {GeneralSelectValue} from 'sentry/components/forms/controls/selectControl';
|
|
import FormField from 'sentry/components/forms/formField';
|
|
|
|
// XXX(epurkhiser): This is wrong, it should not be inheriting these props
|
|
import type {InputFieldProps} from './inputField';
|
|
|
|
export interface SelectAsyncFieldProps
|
|
extends Omit<InputFieldProps, 'highlighted' | 'visible' | 'required' | 'value'>,
|
|
SelectAsyncControlProps {
|
|
/**
|
|
* Similar to onChange, except it provides the entire option object (including label) when a
|
|
* change is made to the field. Occurs after onChange.
|
|
*/
|
|
onChangeOption?: (option: GeneralSelectValue, event: any) => void;
|
|
}
|
|
|
|
function SelectAsyncField({onChangeOption, ...props}: SelectAsyncFieldProps) {
|
|
const [results, setResults] = useState<Result[]>([]);
|
|
const [latestSelection, setLatestSelection] = useState<
|
|
GeneralSelectValue | undefined
|
|
>();
|
|
|
|
return (
|
|
<FormField {...props}>
|
|
{({
|
|
required: _required,
|
|
children: _children,
|
|
onBlur,
|
|
onChange,
|
|
onResults,
|
|
value,
|
|
...fieldProps
|
|
}) => {
|
|
const {defaultOptions} = props;
|
|
// We don't use defaultOptions if it is undefined or a boolean
|
|
const options = typeof defaultOptions === 'object' ? defaultOptions : [];
|
|
// The propsValue is the `id` of the object (user, team, etc), and
|
|
// react-select expects a full value object: {value: "id", label: "name"}
|
|
const resolvedValue =
|
|
// When rendering the selected value, first look at the API results...
|
|
results.find(({value: v}) => v === value) ??
|
|
// Then at the defaultOptions passed in props...
|
|
options?.find(({value: v}) => v === value) ??
|
|
// Then at the latest value selected in the form
|
|
(latestSelection as GeneralSelectValue);
|
|
|
|
return (
|
|
<SelectAsyncControl
|
|
{...fieldProps}
|
|
onChange={(option, e) => {
|
|
const resultValue = !option
|
|
? option
|
|
: props.multiple && Array.isArray(option)
|
|
? // List of optionObjs
|
|
option.map(({value: val}) => val)
|
|
: !Array.isArray(option)
|
|
? option.value
|
|
: option;
|
|
|
|
setLatestSelection(option);
|
|
onChange?.(resultValue, e);
|
|
onChangeOption?.(option, e);
|
|
onBlur?.(resultValue, e);
|
|
}}
|
|
onResults={data => {
|
|
const newResults = onResults(data);
|
|
const resultSelection = newResults.find(result => result.value === value);
|
|
|
|
setResults(newResults);
|
|
if (resultSelection) {
|
|
setLatestSelection(resultSelection);
|
|
}
|
|
|
|
return newResults;
|
|
}}
|
|
onSelectResetsInput
|
|
onCloseResetsInput={false}
|
|
onBlurResetsInput={false}
|
|
value={resolvedValue}
|
|
/>
|
|
);
|
|
}}
|
|
</FormField>
|
|
);
|
|
}
|
|
|
|
export default SelectAsyncField;
|