monitorHeader.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import styled from '@emotion/styled';
  2. import Breadcrumbs from 'sentry/components/breadcrumbs';
  3. import {SectionHeading} from 'sentry/components/charts/styles';
  4. import IdBadge from 'sentry/components/idBadge';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import TimeSince from 'sentry/components/timeSince';
  7. import {t} from 'sentry/locale';
  8. import space from 'sentry/styles/space';
  9. import MonitorHeaderActions from './monitorHeaderActions';
  10. import MonitorIcon from './monitorIcon';
  11. import {Status} from './types';
  12. type Props = React.ComponentProps<typeof MonitorHeaderActions>;
  13. const statusToLabel: Record<Status, string> = {
  14. ok: t('Ok'),
  15. error: t('Failed'),
  16. disabled: t('Disabled'),
  17. active: t('Active'),
  18. missed_checkin: t('Missed'),
  19. };
  20. const MonitorHeader = ({monitor, orgId, onUpdate}: Props) => {
  21. const crumbs = [
  22. {
  23. label: t('Monitors'),
  24. to: `/organizations/${orgId}/monitors`,
  25. },
  26. {
  27. label: t('Monitor Details'),
  28. },
  29. ];
  30. return (
  31. <Layout.Header>
  32. <Layout.HeaderContent>
  33. <Breadcrumbs crumbs={crumbs} />
  34. <Layout.Title>
  35. <MonitorName>
  36. <IdBadge
  37. project={monitor.project}
  38. avatarSize={28}
  39. hideName
  40. avatarProps={{hasTooltip: true, tooltip: monitor.project.slug}}
  41. />
  42. {monitor.name}
  43. </MonitorName>
  44. </Layout.Title>
  45. <MonitorId>{monitor.id}</MonitorId>
  46. </Layout.HeaderContent>
  47. <Layout.HeaderActions>
  48. <MonitorHeaderActions orgId={orgId} monitor={monitor} onUpdate={onUpdate} />
  49. <MonitorStats>
  50. <MonitorStatLabel>{t('Last Check-in')}</MonitorStatLabel>
  51. <MonitorStatLabel>{t('Next Check-in')}</MonitorStatLabel>
  52. <MonitorStatLabel>{t('Status')}</MonitorStatLabel>
  53. <div>{monitor.lastCheckIn && <TimeSince date={monitor.lastCheckIn} />}</div>
  54. <div>{monitor.nextCheckIn && <TimeSince date={monitor.nextCheckIn} />}</div>
  55. <MonitorStatus>
  56. <MonitorIcon status={monitor.status} size={16} />
  57. <MonitorStatusLabel>{statusToLabel[monitor.status]}</MonitorStatusLabel>
  58. </MonitorStatus>
  59. </MonitorStats>
  60. </Layout.HeaderActions>
  61. </Layout.Header>
  62. );
  63. };
  64. const MonitorName = styled('div')`
  65. display: grid;
  66. grid-template-columns: max-content 1fr;
  67. grid-column-gap: ${space(1)};
  68. align-items: center;
  69. `;
  70. const MonitorId = styled('div')`
  71. margin-top: ${space(1)};
  72. color: ${p => p.theme.subText};
  73. `;
  74. const MonitorStats = styled('div')`
  75. display: grid;
  76. align-self: flex-end;
  77. grid-template-columns: repeat(3, max-content);
  78. grid-column-gap: ${space(4)};
  79. grid-row-gap: ${space(0.5)};
  80. margin-bottom: ${space(2)};
  81. `;
  82. const MonitorStatLabel = styled(SectionHeading)`
  83. text-transform: uppercase;
  84. font-size: ${p => p.theme.fontSizeSmall};
  85. text-align: center;
  86. `;
  87. const MonitorStatus = styled('div')`
  88. display: flex;
  89. align-items: center;
  90. `;
  91. const MonitorStatusLabel = styled('div')`
  92. margin-left: ${space(1)};
  93. `;
  94. export default MonitorHeader;