Browse Source

ref(crons): Extract schedule text utils to modules (#67768)

Evan Purkhiser 11 months ago
parent
commit
962f5f559a

+ 2 - 1
static/app/components/modals/bulkEditMonitorsModal.tsx

@@ -25,7 +25,8 @@ import {
   SortSelector,
 } from 'sentry/views/monitors/components/overviewTimeline/sortSelector';
 import type {Monitor} from 'sentry/views/monitors/types';
-import {makeMonitorListQueryKey, scheduleAsText} from 'sentry/views/monitors/utils';
+import {makeMonitorListQueryKey} from 'sentry/views/monitors/utils';
+import {scheduleAsText} from 'sentry/views/monitors/utils/scheduleAsText';
 
 interface Props extends ModalRenderProps {}
 

+ 1 - 1
static/app/views/monitors/components/detailsSidebar.tsx

@@ -16,7 +16,7 @@ import {DEFAULT_MAX_RUNTIME} from 'sentry/views/monitors/components/monitorForm'
 import {MonitorIndicator} from 'sentry/views/monitors/components/monitorIndicator';
 import type {Monitor, MonitorEnvironment} from 'sentry/views/monitors/types';
 import {ScheduleType} from 'sentry/views/monitors/types';
-import {scheduleAsText} from 'sentry/views/monitors/utils';
+import {scheduleAsText} from 'sentry/views/monitors/utils/scheduleAsText';
 
 interface Props {
   monitor: Monitor;

+ 2 - 1
static/app/views/monitors/components/monitorCreateForm.tsx

@@ -31,7 +31,8 @@ import {
 } from 'sentry/views/monitors/components/monitorForm';
 import type {Monitor} from 'sentry/views/monitors/types';
 import {ScheduleType} from 'sentry/views/monitors/types';
-import {crontabAsText, getScheduleIntervals} from 'sentry/views/monitors/utils';
+import {getScheduleIntervals} from 'sentry/views/monitors/utils';
+import {crontabAsText} from 'sentry/views/monitors/utils/crontabAsText';
 
 const DEFAULT_SCHEDULE_CONFIG = {
   scheduleType: 'crontab',

+ 2 - 1
static/app/views/monitors/components/monitorForm.tsx

@@ -29,7 +29,8 @@ import useOrganization from 'sentry/utils/useOrganization';
 import usePageFilters from 'sentry/utils/usePageFilters';
 import useProjects from 'sentry/utils/useProjects';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
-import {crontabAsText, getScheduleIntervals} from 'sentry/views/monitors/utils';
+import {getScheduleIntervals} from 'sentry/views/monitors/utils';
+import {crontabAsText} from 'sentry/views/monitors/utils/crontabAsText';
 
 import type {IntervalConfig, Monitor, MonitorConfig, MonitorType} from '../types';
 import {ScheduleType} from '../types';

+ 1 - 1
static/app/views/monitors/components/overviewTimeline/timelineTableRow.tsx

@@ -19,7 +19,7 @@ import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 import MonitorEnvironmentLabel from 'sentry/views/monitors/components/overviewTimeline/monitorEnvironmentLabel';
 import {StatusToggleButton} from 'sentry/views/monitors/components/statusToggleButton';
 import type {Monitor} from 'sentry/views/monitors/types';
-import {scheduleAsText} from 'sentry/views/monitors/utils';
+import {scheduleAsText} from 'sentry/views/monitors/utils/scheduleAsText';
 
 import type {CheckInTimelineProps} from './checkInTimeline';
 import {CheckInTimeline} from './checkInTimeline';

+ 1 - 61
static/app/views/monitors/utils.tsx

@@ -1,11 +1,7 @@
-import cronstrue from 'cronstrue';
-
 import {t, tn} from 'sentry/locale';
 import type {Organization, SelectValue} from 'sentry/types';
-import {shouldUse24Hours} from 'sentry/utils/dates';
 import type {ColorOrAlias} from 'sentry/utils/theme';
-import type {MonitorConfig} from 'sentry/views/monitors/types';
-import {CheckInStatus, ScheduleType} from 'sentry/views/monitors/types';
+import {CheckInStatus} from 'sentry/views/monitors/types';
 
 export function makeMonitorListQueryKey(
   organization: Organization,
@@ -42,62 +38,6 @@ export function makeMonitorDetailsQueryKey(
   ] as const;
 }
 
-export function crontabAsText(crontabInput: string | null): string | null {
-  if (!crontabInput) {
-    return null;
-  }
-  let parsedSchedule: string;
-  try {
-    parsedSchedule = cronstrue.toString(crontabInput, {
-      verbose: false,
-      use24HourTimeFormat: shouldUse24Hours(),
-    });
-  } catch (_e) {
-    return null;
-  }
-
-  return parsedSchedule;
-}
-
-export function scheduleAsText(config: MonitorConfig) {
-  // Crontab format uses cronstrue
-  if (config.schedule_type === ScheduleType.CRONTAB) {
-    const parsedSchedule = crontabAsText(config.schedule);
-    return parsedSchedule ?? t('Unknown schedule');
-  }
-
-  if (config.schedule_type === ScheduleType.INTERVAL) {
-    // Interval format is simpler
-    const [value, timeUnit] = config.schedule;
-
-    if (timeUnit === 'minute') {
-      return tn('Every minute', 'Every %s minutes', value);
-    }
-
-    if (timeUnit === 'hour') {
-      return tn('Every hour', 'Every %s hours', value);
-    }
-
-    if (timeUnit === 'day') {
-      return tn('Every day', 'Every %s days', value);
-    }
-
-    if (timeUnit === 'week') {
-      return tn('Every week', 'Every %s weeks', value);
-    }
-
-    if (timeUnit === 'month') {
-      return tn('Every month', 'Every %s months', value);
-    }
-
-    if (timeUnit === 'year') {
-      return tn('Every year', 'Every %s years', value);
-    }
-  }
-
-  return t('Unknown schedule');
-}
-
 export const statusToText: Record<CheckInStatus, string> = {
   [CheckInStatus.OK]: t('Okay'),
   [CheckInStatus.ERROR]: t('Failed'),

+ 28 - 0
static/app/views/monitors/utils/crontabAsText.spec.tsx

@@ -0,0 +1,28 @@
+import {shouldUse24Hours} from 'sentry/utils/dates';
+
+import {crontabAsText} from './crontabAsText';
+
+jest.mock('sentry/utils/dates');
+
+describe('crontabAsText', function () {
+  beforeEach(() => {
+    jest.mocked(shouldUse24Hours).mockReturnValue(false);
+  });
+
+  it('translates simple crontab', function () {
+    expect(crontabAsText('* * * * *')).toBe('Every minute');
+    expect(crontabAsText('10 * * * *')).toBe('At 10 minutes past the hour');
+  });
+
+  it('handles 24 hour clock', function () {
+    expect(crontabAsText('0 5/* * 1-5 *')).toBe(
+      'At 0 minutes past the hour, every * hours, starting at 05:00 AM, January through May'
+    );
+
+    jest.mocked(shouldUse24Hours).mockReturnValue(true);
+
+    expect(crontabAsText('0 5/* * 1-5 *')).toBe(
+      'At 0 minutes past the hour, every * hours, starting at 05:00, January through May'
+    );
+  });
+});

+ 23 - 0
static/app/views/monitors/utils/crontabAsText.tsx

@@ -0,0 +1,23 @@
+import cronstrue from 'cronstrue';
+
+import {shouldUse24Hours} from 'sentry/utils/dates';
+
+/**
+ * Display a human readible label of a crontab expression
+ */
+export function crontabAsText(crontabInput: string | null): string | null {
+  if (!crontabInput) {
+    return null;
+  }
+  let parsedSchedule: string;
+  try {
+    parsedSchedule = cronstrue.toString(crontabInput, {
+      verbose: false,
+      use24HourTimeFormat: shouldUse24Hours(),
+    });
+  } catch (_e) {
+    return null;
+  }
+
+  return parsedSchedule;
+}

+ 3 - 29
static/app/views/monitors/utils.spec.tsx → static/app/views/monitors/utils/scheduleAsText.spec.tsx

@@ -1,33 +1,7 @@
-import {shouldUse24Hours} from 'sentry/utils/dates';
+import type {MonitorConfig} from '../types';
+import {ScheduleType} from '../types';
 
-import type {MonitorConfig} from './types';
-import {ScheduleType} from './types';
-import {crontabAsText, scheduleAsText} from './utils';
-
-jest.mock('sentry/utils/dates');
-
-describe('crontabAsText', function () {
-  beforeEach(() => {
-    jest.mocked(shouldUse24Hours).mockReturnValue(false);
-  });
-
-  it('translates simple crontab', function () {
-    expect(crontabAsText('* * * * *')).toBe('Every minute');
-    expect(crontabAsText('10 * * * *')).toBe('At 10 minutes past the hour');
-  });
-
-  it('handles 24 hour clock', function () {
-    expect(crontabAsText('0 5/* * 1-5 *')).toBe(
-      'At 0 minutes past the hour, every * hours, starting at 05:00 AM, January through May'
-    );
-
-    jest.mocked(shouldUse24Hours).mockReturnValue(true);
-
-    expect(crontabAsText('0 5/* * 1-5 *')).toBe(
-      'At 0 minutes past the hour, every * hours, starting at 05:00, January through May'
-    );
-  });
-});
+import {scheduleAsText} from './scheduleAsText';
 
 describe('scheduleAsText', function () {
   it('uses crontabAsText', function () {

+ 47 - 0
static/app/views/monitors/utils/scheduleAsText.tsx

@@ -0,0 +1,47 @@
+import {t, tn} from 'sentry/locale';
+import type {MonitorConfig} from 'sentry/views/monitors/types';
+import {ScheduleType} from 'sentry/views/monitors/types';
+
+import {crontabAsText} from './crontabAsText';
+
+/**
+ * Display a human readable label for the shedule of a MonitorConfig
+ */
+export function scheduleAsText(config: MonitorConfig) {
+  // Crontab format uses cronstrue
+  if (config.schedule_type === ScheduleType.CRONTAB) {
+    const parsedSchedule = crontabAsText(config.schedule);
+    return parsedSchedule ?? t('Unknown schedule');
+  }
+
+  if (config.schedule_type === ScheduleType.INTERVAL) {
+    // Interval format is simpler
+    const [value, timeUnit] = config.schedule;
+
+    if (timeUnit === 'minute') {
+      return tn('Every minute', 'Every %s minutes', value);
+    }
+
+    if (timeUnit === 'hour') {
+      return tn('Every hour', 'Every %s hours', value);
+    }
+
+    if (timeUnit === 'day') {
+      return tn('Every day', 'Every %s days', value);
+    }
+
+    if (timeUnit === 'week') {
+      return tn('Every week', 'Every %s weeks', value);
+    }
+
+    if (timeUnit === 'month') {
+      return tn('Every month', 'Every %s months', value);
+    }
+
+    if (timeUnit === 'year') {
+      return tn('Every year', 'Every %s years', value);
+    }
+  }
+
+  return t('Unknown schedule');
+}