selectAsyncField.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import * as React from 'react';
  2. import SelectAsyncControl from 'app/components/forms/selectAsyncControl';
  3. import InputField from 'app/views/settings/components/forms/inputField';
  4. //projects can be passed as a direct prop as well
  5. type Props = Omit<InputField['props'], 'highlighted' | 'visible' | 'required'>;
  6. export type SelectAsyncFieldProps = React.ComponentPropsWithoutRef<
  7. typeof SelectAsyncControl
  8. > &
  9. Props;
  10. class SelectAsyncField extends React.Component<SelectAsyncFieldProps> {
  11. state = {
  12. results: [],
  13. };
  14. // need to map the option object to the value
  15. // this is essentially the same code from ./selectField handleChange()
  16. handleChange = (
  17. onBlur: Props['onBlur'],
  18. onChange: Props['onChange'],
  19. optionObj: {value: string | any[]},
  20. event: React.MouseEvent
  21. ) => {
  22. let {value} = optionObj;
  23. if (!optionObj) {
  24. value = optionObj;
  25. } else if (this.props.multiple && Array.isArray(optionObj)) {
  26. // List of optionObjs
  27. value = optionObj.map(({value: val}) => val);
  28. } else if (!Array.isArray(optionObj)) {
  29. value = optionObj.value;
  30. }
  31. onChange?.(value, event);
  32. onBlur?.(value, event);
  33. };
  34. findValue(propsValue) {
  35. /**
  36. * The propsValue is the `id` of the object (user, team, etc), and
  37. * react-select expects a full value object: {value: "id", label: "name"}
  38. *
  39. * Returning {} here will show the user a dropdown with "No options".
  40. **/
  41. return this.state.results.find(({value}) => value === propsValue) || {};
  42. }
  43. render() {
  44. const {...otherProps} = this.props;
  45. return (
  46. <InputField
  47. {...otherProps}
  48. field={({onChange, onBlur, required: _required, onResults, value, ...props}) => (
  49. <SelectAsyncControl
  50. {...props}
  51. onChange={this.handleChange.bind(this, onBlur, onChange)}
  52. onResults={data => {
  53. const results = onResults(data);
  54. this.setState({results});
  55. return results;
  56. }}
  57. onSelectResetsInput
  58. onCloseResetsInput={false}
  59. onBlurResetsInput={false}
  60. value={this.findValue(value)}
  61. />
  62. )}
  63. />
  64. );
  65. }
  66. }
  67. export default SelectAsyncField;