details.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import {Fragment} from 'react';
  2. import {RouteComponentProps} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import DatePageFilter from 'sentry/components/datePageFilter';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  7. import {space} from 'sentry/styles/space';
  8. import {Organization} from 'sentry/types';
  9. import withRouteAnalytics, {
  10. WithRouteAnalyticsProps,
  11. } from 'sentry/utils/routeAnalytics/withRouteAnalytics';
  12. import withOrganization from 'sentry/utils/withOrganization';
  13. import AsyncView from 'sentry/views/asyncView';
  14. import MonitorCheckIns from './components/monitorCheckIns';
  15. import MonitorHeader from './components/monitorHeader';
  16. import MonitorIssues from './components/monitorIssues';
  17. import MonitorStats from './components/monitorStats';
  18. import MonitorOnboarding from './components/onboarding';
  19. import {Monitor} from './types';
  20. type Props = AsyncView['props'] &
  21. WithRouteAnalyticsProps &
  22. RouteComponentProps<{monitorSlug: string}, {}> & {
  23. organization: Organization;
  24. };
  25. type State = AsyncView['state'] & {
  26. monitor: Monitor | null;
  27. };
  28. class MonitorDetails extends AsyncView<Props, State> {
  29. get orgSlug() {
  30. return this.props.organization.slug;
  31. }
  32. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  33. const {params, location} = this.props;
  34. return [
  35. [
  36. 'monitor',
  37. `/organizations/${this.orgSlug}/monitors/${params.monitorSlug}/`,
  38. {query: location.query},
  39. ],
  40. ];
  41. }
  42. getTitle() {
  43. if (this.state.monitor) {
  44. return `${this.state.monitor.name} - Monitors - ${this.orgSlug}`;
  45. }
  46. return `Monitors - ${this.orgSlug}`;
  47. }
  48. onUpdate = (data: Monitor) =>
  49. this.setState(state => ({monitor: {...state.monitor, ...data}}));
  50. onRequestSuccess(response) {
  51. this.props.setEventNames(
  52. 'monitors.details_page_viewed',
  53. 'Monitors: Details Page Viewed'
  54. );
  55. this.props.setRouteAnalyticsParams({
  56. empty_state: !response.data?.lastCheckIn,
  57. });
  58. }
  59. renderBody() {
  60. const {monitor} = this.state;
  61. if (monitor === null) {
  62. return null;
  63. }
  64. return (
  65. <Layout.Page>
  66. <MonitorHeader monitor={monitor} orgId={this.orgSlug} onUpdate={this.onUpdate} />
  67. <Layout.Body>
  68. <Layout.Main fullWidth>
  69. {!monitor.lastCheckIn ? (
  70. <MonitorOnboarding />
  71. ) : (
  72. <Fragment>
  73. <StyledPageFilterBar condensed>
  74. <DatePageFilter alignDropdown="left" />
  75. </StyledPageFilterBar>
  76. <MonitorStats monitor={monitor} orgId={this.orgSlug} />
  77. <MonitorIssues monitor={monitor} orgId={this.orgSlug} />
  78. <MonitorCheckIns monitor={monitor} orgId={this.orgSlug} />
  79. </Fragment>
  80. )}
  81. </Layout.Main>
  82. </Layout.Body>
  83. </Layout.Page>
  84. );
  85. }
  86. }
  87. const StyledPageFilterBar = styled(PageFilterBar)`
  88. margin-bottom: ${space(2)};
  89. `;
  90. export default withRouteAnalytics(withOrganization(MonitorDetails));