actionTargetSelector.tsx 2.9 KB

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