import {Component, Fragment} from 'react'; import styled from '@emotion/styled'; import {Observer} from 'mobx-react'; import FieldGroup from 'sentry/components/forms/fieldGroup'; import NumberField from 'sentry/components/forms/fields/numberField'; import SelectField from 'sentry/components/forms/fields/selectField'; import SentryProjectSelectorField from 'sentry/components/forms/fields/sentryProjectSelectorField'; import TextField from 'sentry/components/forms/fields/textField'; import Form, {FormProps} from 'sentry/components/forms/form'; import FormModel from 'sentry/components/forms/model'; import ExternalLink from 'sentry/components/links/externalLink'; import {Panel, PanelAlert, PanelBody, PanelHeader} from 'sentry/components/panels'; import TextCopyInput from 'sentry/components/textCopyInput'; import TimeSince from 'sentry/components/timeSince'; import {t, tct, tn} from 'sentry/locale'; import {PageFilters, Project, SelectValue} from 'sentry/types'; import commonTheme from 'sentry/utils/theme'; import withPageFilters from 'sentry/utils/withPageFilters'; import withProjects from 'sentry/utils/withProjects'; import {Monitor, MonitorConfig, MonitorTypes, ScheduleType} from './types'; const SCHEDULE_TYPES: SelectValue[] = [ {value: 'crontab', label: 'Crontab'}, {value: 'interval', label: 'Interval'}, ]; const DEFAULT_MONITOR_TYPE = 'cron_job'; const getIntervals = (n: number): SelectValue[] => [ {value: 'minute', label: tn('minute', 'minutes', n)}, {value: 'hour', label: tn('hour', 'hours', n)}, {value: 'day', label: tn('day', 'days', n)}, {value: 'week', label: tn('week', 'weeks', n)}, {value: 'month', label: tn('month', 'months', n)}, {value: 'year', label: tn('year', 'years', n)}, ]; type Props = { apiEndpoint: string; apiMethod: FormProps['apiMethod']; onSubmitSuccess: FormProps['onSubmitSuccess']; projects: Project[]; selection: PageFilters; monitor?: Monitor; submitLabel?: string; }; type TransformedData = { config?: Partial; }; function transformData(_data: Record, model: FormModel) { return model.fields.toJSON().reduce((data, [k, v]) => { if (k.indexOf('config.') !== 0) { data[k] = v; return data; } if (!data.config) { data.config = {}; } if (k === 'config.schedule.frequency' || k === 'config.schedule.interval') { if (!Array.isArray(data.config.schedule)) { data.config.schedule = [null, null]; } } if (k === 'config.schedule.frequency') { data.config!.schedule![0] = parseInt(v as string, 10); } else if (k === 'config.schedule.interval') { data.config!.schedule![1] = v; } else { data.config[k.substr(7)] = v; } return data; }, {}); } class MonitorForm extends Component { form = new FormModel({transformData}); formDataFromConfig(type: MonitorTypes, config: MonitorConfig) { const rv = {}; switch (type) { case 'cron_job': rv['config.schedule_type'] = config.schedule_type; rv['config.checkin_margin'] = config.checkin_margin; rv['config.max_runtime'] = config.max_runtime; switch (config.schedule_type) { case 'interval': rv['config.schedule.frequency'] = config.schedule[0]; rv['config.schedule.interval'] = config.schedule[1]; break; case 'crontab': default: rv['config.schedule'] = config.schedule; } break; default: } return rv; } render() { const {monitor, submitLabel} = this.props; const selectedProjectId = this.props.selection.projects[0]; const selectedProject = selectedProjectId ? this.props.projects.find(p => p.id === selectedProjectId + '') : null; return (
{t('Details')} {monitor && (
{monitor.id}
)} project.isMember)} valueIsSlug help={t( "Select the project which contains the recurring job you'd like to monitor." )} required />
{t('Config')} {monitor !== undefined && ( {tct( 'Any changes you make to the execution schedule will only be applied after the next expected check-in [nextCheckin].', { nextCheckin: ( ), } )} )} {() => { switch (this.form.getValue('config.schedule_type')) { case 'crontab': return ( ), } )} css={{input: {fontFamily: commonTheme.text.familyMono}}} /> ); case 'interval': return ( ); default: return null; } }}
); } } const CombinedField = styled('div')` display: grid; grid-template-columns: 50% 1fr 1fr; align-items: center; border-bottom: 1px solid ${p => p.theme.innerBorder}; `; const StyledNumberField = styled(NumberField)` padding: 0; border-bottom: none; `; const StyledSelectField = styled(SelectField)` padding-left: 0; `; export default withPageFilters(withProjects(MonitorForm));