detectorListRow.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import styled from '@emotion/styled';
  2. import {Flex} from 'sentry/components/container/flex';
  3. import {Checkbox} from 'sentry/components/core/checkbox';
  4. import InteractionStateLayer from 'sentry/components/interactionStateLayer';
  5. import {
  6. ConnectionCell,
  7. type Item,
  8. } from 'sentry/components/workflowEngine/gridCell/connectionCell';
  9. import {EmptyCell} from 'sentry/components/workflowEngine/gridCell/emptyCell';
  10. import {IssueCell} from 'sentry/components/workflowEngine/gridCell/issueCell';
  11. import {NumberCell} from 'sentry/components/workflowEngine/gridCell/numberCell';
  12. import {TitleCell} from 'sentry/components/workflowEngine/gridCell/titleCell';
  13. import {tn} from 'sentry/locale';
  14. import {space} from 'sentry/styles/space';
  15. import type {Group} from 'sentry/types/group';
  16. import type {AvatarProject} from 'sentry/types/project';
  17. export type Detector = {
  18. automations: Item[];
  19. groups: Group[];
  20. id: string;
  21. link: string;
  22. name: string;
  23. project: AvatarProject;
  24. details?: string[];
  25. disabled?: boolean;
  26. };
  27. type DetectorListRowProps = Detector & {
  28. handleSelect: (id: string, checked: boolean) => void;
  29. selected: boolean;
  30. };
  31. export function DetectorListRow({
  32. automations,
  33. groups,
  34. id,
  35. link,
  36. name,
  37. project,
  38. details,
  39. handleSelect,
  40. selected,
  41. disabled,
  42. }: DetectorListRowProps) {
  43. return (
  44. <RowWrapper disabled={disabled}>
  45. <InteractionStateLayer />
  46. <Flex justify="space-between">
  47. <StyledCheckbox
  48. checked={selected}
  49. onChange={() => {
  50. handleSelect(id, !selected);
  51. }}
  52. />
  53. <CellWrapper>
  54. <StyledTitleCell
  55. name={name}
  56. project={project}
  57. link={link}
  58. details={details}
  59. disabled={disabled}
  60. />
  61. </CellWrapper>
  62. <StyledGraphCell />
  63. </Flex>
  64. <CellWrapper className="last-issue">
  65. <StyledIssueCell
  66. group={groups.length > 0 ? groups[0] : undefined}
  67. disabled={disabled}
  68. />
  69. </CellWrapper>
  70. <CellWrapper className="open-issues">
  71. <NumberCell number={groups.length} />
  72. </CellWrapper>
  73. <CellWrapper className="connected-automations">
  74. <ConnectionCell
  75. items={automations}
  76. renderText={count => tn('%s automation', '%s automations', count)}
  77. disabled={disabled}
  78. />
  79. </CellWrapper>
  80. </RowWrapper>
  81. );
  82. }
  83. const StyledCheckbox = styled(Checkbox)<{checked?: boolean}>`
  84. visibility: ${p => (p.checked ? 'visible' : 'hidden')};
  85. align-self: flex-start;
  86. opacity: 1;
  87. `;
  88. const StyledGraphCell = styled(EmptyCell)`
  89. width: 35%;
  90. `;
  91. const CellWrapper = styled(Flex)`
  92. padding: 0 ${space(2)};
  93. flex: 1;
  94. `;
  95. const StyledTitleCell = styled(TitleCell)`
  96. padding: ${space(2)};
  97. margin: -${space(2)};
  98. `;
  99. const StyledIssueCell = styled(IssueCell)`
  100. padding: ${space(2)};
  101. margin: -${space(2)};
  102. `;
  103. const RowWrapper = styled('div')<{disabled?: boolean}>`
  104. display: grid;
  105. position: relative;
  106. align-items: center;
  107. padding: ${space(2)};
  108. ${p =>
  109. p.disabled &&
  110. `
  111. ${CellWrapper}, ${StyledGraphCell} {
  112. opacity: 0.6;
  113. }
  114. `}
  115. &:hover {
  116. ${StyledCheckbox} {
  117. visibility: visible;
  118. }
  119. }
  120. .open-issues,
  121. .last-issue,
  122. .connected-automations {
  123. display: none;
  124. }
  125. @media (min-width: ${p => p.theme.breakpoints.xsmall}) {
  126. grid-template-columns: 3fr 1fr;
  127. .open-issues {
  128. display: flex;
  129. }
  130. }
  131. @media (min-width: ${p => p.theme.breakpoints.small}) {
  132. grid-template-columns: 3fr 1fr 0.6fr;
  133. .last-issue {
  134. display: flex;
  135. }
  136. }
  137. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  138. grid-template-columns: 2.5fr 1fr 0.75fr 1fr;
  139. .connected-automations {
  140. display: flex;
  141. }
  142. }
  143. @media (min-width: ${p => p.theme.breakpoints.large}) {
  144. grid-template-columns: 3fr 1fr 0.75fr 1fr;
  145. }
  146. `;