StackdriverPicker.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React from 'react';
  2. import _ from 'lodash';
  3. import Select from 'app/core/components/Select/Select';
  4. export interface Props {
  5. onChange: (value: string) => void;
  6. options: any[];
  7. searchable: boolean;
  8. selected: string;
  9. placeholder?: string;
  10. className?: string;
  11. groupName?: string;
  12. templateVariables?: any[];
  13. }
  14. interface State {
  15. options: any[];
  16. }
  17. export class StackdriverPicker extends React.Component<Props, State> {
  18. static defaultProps = {
  19. templateVariables: [],
  20. options: [],
  21. groupName: 'Options',
  22. };
  23. constructor(props) {
  24. super(props);
  25. this.state = { options: [] };
  26. }
  27. componentDidMount() {
  28. this.setState({ options: this.buildOptions(this.props) });
  29. }
  30. componentWillReceiveProps(nextProps: Props) {
  31. if (nextProps.options.length > 0 || nextProps.templateVariables.length) {
  32. this.setState({ options: this.buildOptions(nextProps) });
  33. }
  34. }
  35. shouldComponentUpdate(nextProps: Props) {
  36. return (
  37. nextProps.selected !== this.props.selected ||
  38. !_.isEqual(nextProps.options, this.props.options) ||
  39. !_.isEqual(nextProps.templateVariables, this.props.templateVariables)
  40. );
  41. }
  42. buildOptions({ templateVariables = [], groupName = '', options }) {
  43. return templateVariables.length > 0
  44. ? [
  45. this.getTemplateVariablesGroup(),
  46. {
  47. label: groupName,
  48. expanded: true,
  49. options,
  50. },
  51. ]
  52. : options;
  53. }
  54. getTemplateVariablesGroup() {
  55. return {
  56. label: 'Template Variables',
  57. options: this.props.templateVariables.map(v => ({
  58. label: `$${v.name}`,
  59. value: `$${v.name}`,
  60. })),
  61. };
  62. }
  63. getSelectedOption() {
  64. const { options } = this.state;
  65. const allOptions = options.every(o => o.options) ? _.flatten(options.map(o => o.options)) : options;
  66. return allOptions.find(option => option.value === this.props.selected);
  67. }
  68. render() {
  69. const { placeholder, className, searchable, onChange } = this.props;
  70. const { options } = this.state;
  71. const selectedOption = this.getSelectedOption();
  72. return (
  73. <Select
  74. className={className}
  75. isMulti={false}
  76. isClearable={false}
  77. backspaceRemovesValue={false}
  78. onChange={item => onChange(item.value)}
  79. options={options}
  80. autoFocus={false}
  81. isSearchable={searchable}
  82. openMenuOnFocus={true}
  83. maxMenuHeight={500}
  84. placeholder={placeholder}
  85. noOptionsMessage={() => 'No options found'}
  86. value={selectedOption}
  87. />
  88. );
  89. }
  90. }