teamResolutionTime.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import styled from '@emotion/styled';
  2. import AsyncComponent from 'app/components/asyncComponent';
  3. import BarChart from 'app/components/charts/barChart';
  4. import {DateTimeObject} from 'app/components/charts/utils';
  5. import LoadingIndicator from 'app/components/loadingIndicator';
  6. import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
  7. import {t} from 'app/locale';
  8. import space from 'app/styles/space';
  9. import {Organization} from 'app/types';
  10. import {getDuration} from 'app/utils/formatters';
  11. import {convertDaySeriesToWeeks} from './utils';
  12. type TimeToResolution = Record<string, {count: number; avg: number}>;
  13. type Props = AsyncComponent['props'] & {
  14. organization: Organization;
  15. teamSlug: string;
  16. } & DateTimeObject;
  17. type State = AsyncComponent['state'] & {
  18. resolutionTime: TimeToResolution | null;
  19. };
  20. class TeamResolutionTime extends AsyncComponent<Props, State> {
  21. shouldRenderBadRequests = true;
  22. getDefaultState(): State {
  23. return {
  24. ...super.getDefaultState(),
  25. resolutionTime: null,
  26. };
  27. }
  28. getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
  29. const {organization, start, end, period, utc, teamSlug} = this.props;
  30. const datetime = {start, end, period, utc};
  31. return [
  32. [
  33. 'resolutionTime',
  34. `/teams/${organization.slug}/${teamSlug}/time-to-resolution/`,
  35. {
  36. query: {
  37. ...getParams(datetime),
  38. },
  39. },
  40. ],
  41. ];
  42. }
  43. renderLoading() {
  44. return (
  45. <ChartWrapper>
  46. <LoadingIndicator />
  47. </ChartWrapper>
  48. );
  49. }
  50. renderBody() {
  51. const {resolutionTime} = this.state;
  52. const data = Object.entries(resolutionTime ?? {}).map(([bucket, {avg}]) => ({
  53. value: avg,
  54. name: new Date(bucket).getTime(),
  55. }));
  56. const seriesData = convertDaySeriesToWeeks(data);
  57. return (
  58. <ChartWrapper>
  59. <BarChart
  60. style={{height: 190}}
  61. isGroupedByDate
  62. useShortDate
  63. period="7d"
  64. tooltip={{
  65. valueFormatter: (value: number) => getDuration(value, 1),
  66. }}
  67. yAxis={{
  68. // Each yAxis marker will increase by 1 day
  69. minInterval: 86400,
  70. axisLabel: {
  71. formatter: (value: number) => {
  72. if (value === 0) {
  73. return '';
  74. }
  75. return getDuration(value, 0, true, true);
  76. },
  77. },
  78. }}
  79. legend={{right: 0, top: 0}}
  80. xAxis={{
  81. type: 'time',
  82. }}
  83. series={[
  84. {
  85. seriesName: t('Time to Resolution'),
  86. data: seriesData,
  87. },
  88. ].reverse()}
  89. />
  90. </ChartWrapper>
  91. );
  92. }
  93. }
  94. export default TeamResolutionTime;
  95. const ChartWrapper = styled('div')`
  96. padding: ${space(2)} ${space(2)} 0 ${space(2)};
  97. `;