actionTargetSelector.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import SelectControl from 'sentry/components/forms/controls/selectControl';
  2. import Input from 'sentry/components/input';
  3. import SelectMembers from 'sentry/components/selectMembers';
  4. import TeamSelector from 'sentry/components/teamSelector';
  5. import type {Organization, Project, SelectValue} from 'sentry/types';
  6. import type {Action, MetricActionTemplate} from 'sentry/views/alerts/rules/metric/types';
  7. import {ActionType, TargetType} from 'sentry/views/alerts/rules/metric/types';
  8. const getPlaceholderForType = (type: ActionType) => {
  9. switch (type) {
  10. case ActionType.SLACK:
  11. return '@username or #channel';
  12. case ActionType.MSTEAMS:
  13. // no prefixes for msteams
  14. return 'username or channel';
  15. case ActionType.DISCORD:
  16. return 'Discord channel ID';
  17. case ActionType.PAGERDUTY:
  18. return 'service';
  19. case ActionType.OPSGENIE:
  20. return 'team';
  21. default:
  22. throw Error('Not implemented');
  23. }
  24. };
  25. type Props = {
  26. action: Action;
  27. disabled: boolean;
  28. loading: boolean;
  29. onChange: (value: string) => void;
  30. organization: Organization;
  31. availableAction?: MetricActionTemplate;
  32. project?: Project;
  33. };
  34. export default function ActionTargetSelector(props: Props) {
  35. const {action, availableAction, disabled, loading, onChange, organization, project} =
  36. props;
  37. const handleChangeTargetIdentifier = (value: SelectValue<string>) => {
  38. onChange(value.value);
  39. };
  40. const handleChangeSpecificTargetIdentifier = (
  41. e: React.ChangeEvent<HTMLInputElement>
  42. ) => {
  43. onChange(e.target.value);
  44. };
  45. switch (action.targetType) {
  46. case TargetType.TEAM:
  47. case TargetType.USER:
  48. const isTeam = action.targetType === TargetType.TEAM;
  49. return isTeam ? (
  50. <TeamSelector
  51. disabled={disabled}
  52. key="team"
  53. project={project}
  54. value={action.targetIdentifier}
  55. onChange={handleChangeTargetIdentifier}
  56. useId
  57. />
  58. ) : (
  59. <SelectMembers
  60. disabled={disabled}
  61. key="member"
  62. organization={organization}
  63. value={action.targetIdentifier}
  64. onChange={handleChangeTargetIdentifier}
  65. />
  66. );
  67. case TargetType.SPECIFIC:
  68. return availableAction?.options ? (
  69. <SelectControl
  70. isDisabled={disabled || loading}
  71. value={action.targetIdentifier}
  72. options={availableAction.options}
  73. onChange={handleChangeTargetIdentifier}
  74. />
  75. ) : (
  76. <Input
  77. type="text"
  78. autoComplete="off"
  79. disabled={disabled}
  80. required={action.type === 'discord'} // Only required for discord channel ID
  81. key={action.type}
  82. value={action.targetIdentifier || ''}
  83. onChange={handleChangeSpecificTargetIdentifier}
  84. placeholder={getPlaceholderForType(action.type)}
  85. />
  86. );
  87. default:
  88. return null;
  89. }
  90. }