/*
* <<
* Davinci
* ==
* Copyright (C) 2016 - 2017 EDP
* ==
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* >>
*/
import React, {
useEffect,
useState,
useCallback,
useMemo,
useImperativeHandle,
forwardRef
} from 'react'
import moment, { Moment } from 'moment'
import { Form, Row, Col, Input, Select, DatePicker, Spin, Checkbox } from 'antd'
const FormItem = Form.Item
const { TextArea } = Input
const { Option } = Select
const { RangePicker } = DatePicker
import { FormComponentProps } from 'antd/lib/form'
import {
SchedulePeriodUnit,
ISchedule,
ICronExpressionPartition,
JobType
} from '../types'
import { CheckboxChangeEvent } from 'antd/lib/checkbox'
import { FormItemStyle, LongFormItemStyle } from '../constants'
import Styles from './ScheduleBaseConfig.less'
const periodUnitList: SchedulePeriodUnit[] = [
'Minute',
'Hour',
'Day',
'Week',
'Month',
'Year'
]
const periodUnitListLocale: { [key in SchedulePeriodUnit]: string } = {
Minute: '分钟',
Hour: '小时',
Day: '天',
Week: '周',
Month: '月',
Year: '年'
}
const minutePeriodOptions = [...Array(50).keys()].map((s) => (
))
const minuteOptions = [...Array(60).keys()].map((m) => (
))
const hourOptions = [...Array(24).keys()].map((h) => (
))
const dayOptions = [...Array(31).keys()].map((d) => (
))
const weekOptions = [
'星期天',
'星期一',
'星期二',
'星期三',
'星期四',
'星期五',
'星期六'
].map((w, idx) => (
))
const monthOptions = [...Array(12).keys()].map((m) => (
))
export type ScheduleBaseFormProps = ISchedule &
ICronExpressionPartition & {
dateRange: [Moment, Moment]
setCronExpressionManually: boolean
}
interface IScheduleBaseConfigProps
extends FormComponentProps {
schedule: ISchedule
loading: boolean
onCheckUniqueName: (
data: any,
resolve: () => any,
reject: (error: string) => any
) => any
onChangeJobType: (data: any) => any
}
const computePeriodUnit = (cronExpression: string) => {
const partitions = cronExpression.split(' ')
const stars = partitions.filter((item) => item === '*').length
let periodUnit: SchedulePeriodUnit = 'Minute'
switch (stars) {
case 3:
periodUnit = partitions[1].includes('/') ? 'Minute' : 'Hour'
break
case 2:
periodUnit = 'Day'
break
case 1:
periodUnit = partitions[partitions.length - 1] === '?' ? 'Month' : 'Week'
break
case 0:
periodUnit = 'Year'
break
}
return periodUnit
}
export const ScheduleBaseConfig: React.FC = (
props,
ref
) => {
const { form, schedule, loading, onCheckUniqueName, onChangeJobType } = props
const { cronExpression, config } = schedule
const [currentPeriodUnit, setCurrentPeriodUnit] = useState<
SchedulePeriodUnit
>(computePeriodUnit(cronExpression))
const [manual, setManual] = useState(config.setCronExpressionManually)
const checkNameUnique = useCallback(
(_, name = '', callback) => {
const { id, projectId } = schedule
const data = { id, name, projectId }
if (!name) {
callback()
}
onCheckUniqueName(
data,
() => {
callback()
},
(err) => callback(err)
)
},
[onCheckUniqueName, schedule]
)
const changeJobType = useCallback(
(value: JobType) => {
onChangeJobType(value)
},
[onChangeJobType]
)
const changeManual = useCallback((e: CheckboxChangeEvent) => {
setManual(e.target.checked)
}, [])
useEffect(() => {
const periodUnit = computePeriodUnit(cronExpression)
setCurrentPeriodUnit(periodUnit)
}, [cronExpression])
useEffect(() => {
setManual(config.setCronExpressionManually)
}, [config.setCronExpressionManually])
let { minute, hour, day, month, weekDay } = useMemo<
Partial
>(() => {
const partitions = cronExpression.split(' ')
let minute =
form.getFieldValue('minute') ||
+(partitions[1].includes('/')
? partitions[1].slice(2) // slice(2) to remove */
: partitions[1])
// min minute duration is 10
if (currentPeriodUnit === 'Minute' && minute < 10) {
minute = 10
form.setFieldsValue({ minute })
}
const hour = +partitions[2] || 0
const day = +partitions[3] || 1
const month = +partitions[4] || 1
const weekDay = +partitions[5] || 1
return { minute, hour, day, month, weekDay }
}, [cronExpression, currentPeriodUnit])
const { getFieldDecorator } = form
const { startDate, endDate } = schedule
useImperativeHandle(ref, () => ({ form }))
return (
)
}
export default Form.create()(
forwardRef(ScheduleBaseConfig)
)