123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- import {Fragment} from 'react';
- import {RouteComponentProps} from 'react-router';
- import styled from '@emotion/styled';
- import sortBy from 'lodash/sortBy';
- import DatePageFilter from 'sentry/components/datePageFilter';
- import * as Layout from 'sentry/components/layouts/thirds';
- import LoadingIndicator from 'sentry/components/loadingIndicator';
- import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
- import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
- import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
- import {space} from 'sentry/styles/space';
- import {setApiQueryData, useApiQuery, useQueryClient} from 'sentry/utils/queryClient';
- import useOrganization from 'sentry/utils/useOrganization';
- import usePageFilters from 'sentry/utils/usePageFilters';
- import {CronDetailsTimeline} from 'sentry/views/monitors/components/cronDetailsTimeline';
- import DetailsSidebar from 'sentry/views/monitors/components/detailsSidebar';
- import MonitorCheckIns from './components/monitorCheckIns';
- import MonitorHeader from './components/monitorHeader';
- import MonitorIssues from './components/monitorIssues';
- import MonitorStats from './components/monitorStats';
- import MonitorOnboarding from './components/onboarding';
- import {Monitor} from './types';
- const DEFAULT_POLL_INTERVAL_MS = 5000;
- type Props = RouteComponentProps<{monitorSlug: string}, {}>;
- function hasLastCheckIn(monitor: Monitor) {
- return monitor.environments.some(e => e.lastCheckIn);
- }
- function MonitorDetails({params, location}: Props) {
- const {selection} = usePageFilters();
- const organization = useOrganization();
- const queryClient = useQueryClient();
- // TODO(epurkhiser): For now we just use the fist environment OR production
- // if we have all environments selected
- const environment = selection.environments[0];
- const queryKey = [
- `/organizations/${organization.slug}/monitors/${params.monitorSlug}/`,
- {query: {...location.query, environment}},
- ] as const;
- const {data: monitor} = useApiQuery<Monitor>(queryKey, {
- staleTime: 0,
- // Refetches while we are waiting for the user to send their first check-in
- refetchInterval: data => {
- if (!data) {
- return false;
- }
- const [monitorData] = data;
- return hasLastCheckIn(monitorData) ? false : DEFAULT_POLL_INTERVAL_MS;
- },
- });
- function onUpdate(data: Monitor) {
- const updatedMonitor = {
- ...data,
- // TODO(davidenwang): This is a bit of a hack, due to the PUT request
- // which pauses/unpauses a monitor not returning monitor environments
- // we should reuse the environments retrieved from the initial request
- environments: monitor?.environments,
- };
- setApiQueryData(queryClient, queryKey, updatedMonitor);
- }
- if (!monitor) {
- return (
- <Layout.Page>
- <LoadingIndicator />
- </Layout.Page>
- );
- }
- const envsSortedByLastCheck = sortBy(monitor.environments, e => e.lastCheckIn);
- return (
- <SentryDocumentTitle title={`Crons — ${monitor.name}`}>
- <Layout.Page>
- <MonitorHeader monitor={monitor} orgId={organization.slug} onUpdate={onUpdate} />
- <Layout.Body>
- <Layout.Main>
- <StyledPageFilterBar condensed>
- <DatePageFilter alignDropdown="left" />
- <EnvironmentPageFilter />
- </StyledPageFilterBar>
- {!hasLastCheckIn(monitor) ? (
- <MonitorOnboarding monitor={monitor} />
- ) : (
- <Fragment>
- <CronDetailsTimeline organization={organization} monitor={monitor} />
- <MonitorStats
- orgSlug={organization.slug}
- monitor={monitor}
- monitorEnvs={monitor.environments}
- />
- <MonitorIssues
- orgSlug={organization.slug}
- monitor={monitor}
- monitorEnvs={monitor.environments}
- />
- <MonitorCheckIns
- orgSlug={organization.slug}
- monitor={monitor}
- monitorEnvs={monitor.environments}
- />
- </Fragment>
- )}
- </Layout.Main>
- <Layout.Side>
- <DetailsSidebar
- monitorEnv={envsSortedByLastCheck[envsSortedByLastCheck.length - 1]}
- monitor={monitor}
- />
- </Layout.Side>
- </Layout.Body>
- </Layout.Page>
- </SentryDocumentTitle>
- );
- }
- const StyledPageFilterBar = styled(PageFilterBar)`
- margin-bottom: ${space(2)};
- `;
- export default MonitorDetails;
|