groupOpenPeriods.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {DateTime} from 'sentry/components/dateTime';
  4. import Duration from 'sentry/components/duration';
  5. import GridEditable, {
  6. COL_WIDTH_UNDEFINED,
  7. type GridColumnOrder,
  8. } from 'sentry/components/gridEditable';
  9. import LoadingError from 'sentry/components/loadingError';
  10. import LoadingIndicator from 'sentry/components/loadingIndicator';
  11. import {t} from 'sentry/locale';
  12. import {useParams} from 'sentry/utils/useParams';
  13. import {useGroup} from 'sentry/views/issueDetails/useGroup';
  14. interface OpenPeriodDisplayData {
  15. duration: React.ReactNode;
  16. end: React.ReactNode;
  17. start: React.ReactNode;
  18. title: React.ReactNode;
  19. }
  20. // TODO(snigdha): make this work for the old UI
  21. // TODO(snigdha): support pagination
  22. function IssueOpenPeriodsList() {
  23. const [now] = useState(() => new Date());
  24. const params = useParams<{groupId: string}>();
  25. const {
  26. data: group,
  27. isPending: isGroupPending,
  28. isError: isGroupError,
  29. refetch: refetchGroup,
  30. } = useGroup({groupId: params.groupId});
  31. if (isGroupError) {
  32. return <LoadingError onRetry={refetchGroup} />;
  33. }
  34. if (isGroupPending) {
  35. return <LoadingIndicator />;
  36. }
  37. // update the open periods to have date objects
  38. const openPeriods = group.openPeriods?.map(period => ({
  39. ...period,
  40. start: new Date(period.start),
  41. end: period.end ? new Date(period.end) : null,
  42. }));
  43. const getDuration = (start: Date, end?: Date) => {
  44. const duration = end
  45. ? (end.getTime() - start.getTime()) / 1000
  46. : (now.getTime() - start.getTime()) / 1000;
  47. return <Duration seconds={duration} precision="minutes" exact />;
  48. };
  49. if (!openPeriods) {
  50. return <LoadingError onRetry={refetchGroup} />;
  51. }
  52. const data: OpenPeriodDisplayData[] = openPeriods.map(period => ({
  53. title: <DateTime date={period.start} />,
  54. start: <DateTime date={period.start} />,
  55. end: period.end ? <DateTime date={period.end} /> : '—',
  56. duration: getDuration(period.start, period.end ?? undefined),
  57. }));
  58. const renderHeadCell = (col: GridColumnOrder) => {
  59. return <AlignLeft>{col.name}</AlignLeft>;
  60. };
  61. const renderBodyCell = (
  62. col: GridColumnOrder<string>,
  63. dataRow: OpenPeriodDisplayData
  64. ) => {
  65. const column = col.key as keyof OpenPeriodDisplayData;
  66. return <AlignLeft>{dataRow[column]}</AlignLeft>;
  67. };
  68. return (
  69. <GridEditable
  70. isLoading={isGroupPending}
  71. data={data}
  72. columnOrder={[
  73. {key: 'title', width: COL_WIDTH_UNDEFINED, name: t('Title')},
  74. {key: 'start', width: COL_WIDTH_UNDEFINED, name: t('Start')},
  75. {key: 'end', width: COL_WIDTH_UNDEFINED, name: t('End')},
  76. {key: 'duration', width: COL_WIDTH_UNDEFINED, name: t('Duration')},
  77. ]}
  78. columnSortBy={[]}
  79. grid={{
  80. renderHeadCell,
  81. renderBodyCell,
  82. }}
  83. />
  84. );
  85. }
  86. const AlignLeft = styled('span')`
  87. text-align: left;
  88. width: 100%;
  89. `;
  90. export default IssueOpenPeriodsList;