diff --git a/scss/_utilities.scss b/scss/_utilities.scss index 62e701769..e3426ff1a 100644 --- a/scss/_utilities.scss +++ b/scss/_utilities.scss @@ -1195,6 +1195,14 @@ height: 360px; } +.w-xxxl { + width: 420px; +} + +.h-xxxl { + height: 420px; +} + .w-full { width: 100%; } diff --git a/src/components/DatePicker.tsx b/src/components/DatePicker.tsx index 691411a93..3e0f73a27 100644 --- a/src/components/DatePicker.tsx +++ b/src/components/DatePicker.tsx @@ -4,85 +4,85 @@ * @author fex */ -import React from "react"; -import cx from "classnames"; -import moment from "moment"; -import "moment/locale/zh-cn"; -import { Icon } from "./icons"; -import PopOver from "./PopOver"; -import Overlay from "./Overlay"; -import { ClassNamesFn, themeable } from "../theme"; -import { PlainObject } from "../types"; -import Calendar from "./calendar/Calendar"; +import React from 'react'; +import cx from 'classnames'; +import moment from 'moment'; +import 'moment/locale/zh-cn'; +import {Icon} from './icons'; +import PopOver from './PopOver'; +import Overlay from './Overlay'; +import {ClassNamesFn, themeable} from '../theme'; +import {PlainObject} from '../types'; +import Calendar from './calendar/Calendar'; -const availableShortcuts: { [propName: string]: any } = { +const availableShortcuts: {[propName: string]: any} = { today: { - label: "今天", + label: '今天', date: (now: moment.Moment) => { - return now.startOf("day"); + return now.startOf('day'); } }, yesterday: { - label: "昨天", + label: '昨天', date: (now: moment.Moment) => { - return now.add(-1, "days").startOf("day"); + return now.add(-1, 'days').startOf('day'); } }, thisweek: { - label: "本周一", + label: '本周一', date: (now: moment.Moment) => { - return now.startOf("week").add(-1, "weeks"); + return now.startOf('week').add(-1, 'weeks'); } }, thismonth: { - label: "本月初", + label: '本月初', date: (now: moment.Moment) => { - return now.startOf("month"); + return now.startOf('month'); } }, prevmonth: { - label: "上个月初", + label: '上个月初', date: (now: moment.Moment) => { - return now.startOf("month").add(-1, "month"); + return now.startOf('month').add(-1, 'month'); } }, prevquarter: { - label: "上个季节初", + label: '上个季节初', date: (now: moment.Moment) => { - return now.startOf("quarter").add(-1, "quarter"); + return now.startOf('quarter').add(-1, 'quarter'); } }, thisquarter: { - label: "本季度初", + label: '本季度初', date: (now: moment.Moment) => { - return now.startOf("quarter"); + return now.startOf('quarter'); } }, tomorrow: { - label: "明天", + label: '明天', date: (now: moment.Moment) => { - return now.add(1, "days").startOf("day"); + return now.add(1, 'days').startOf('day'); } }, endofthisweek: { - label: "本周日", + label: '本周日', date: (now: moment.Moment) => { - return now.endOf("week"); + return now.endOf('week'); } }, endofthismonth: { - label: "本月底", + label: '本月底', date: (now: moment.Moment) => { - return now.endOf("month"); + return now.endOf('month'); } } }; @@ -94,7 +94,7 @@ const advancedShortcuts = [ return { label: `${days}天前`, date: (now: moment.Moment) => { - return now.subtract(days, "days"); + return now.subtract(days, 'days'); } }; } @@ -105,7 +105,7 @@ const advancedShortcuts = [ return { label: `${days}天后`, date: (now: moment.Moment) => { - return now.add(days, "days"); + return now.add(days, 'days'); } }; } @@ -116,7 +116,7 @@ const advancedShortcuts = [ return { label: `${weeks}周前`, date: (now: moment.Moment) => { - return now.subtract(weeks, "weeks"); + return now.subtract(weeks, 'weeks'); } }; } @@ -127,7 +127,7 @@ const advancedShortcuts = [ return { label: `${weeks}周后`, date: (now: moment.Moment) => { - return now.add(weeks, "weeks"); + return now.add(weeks, 'weeks'); } }; } @@ -138,7 +138,7 @@ const advancedShortcuts = [ return { label: `${months}月前`, date: (now: moment.Moment) => { - return now.subtract(months, "months"); + return now.subtract(months, 'months'); } }; } @@ -149,7 +149,7 @@ const advancedShortcuts = [ return { label: `${months}月后`, date: (now: moment.Moment) => { - return now.add(months, "months"); + return now.add(months, 'months'); } }; } @@ -160,7 +160,7 @@ const advancedShortcuts = [ return { label: `${quarters}季度前`, date: (now: moment.Moment) => { - return now.subtract(quarters, "quarters"); + return now.subtract(quarters, 'quarters'); } }; } @@ -171,7 +171,7 @@ const advancedShortcuts = [ return { label: `${quarters}季度后`, date: (now: moment.Moment) => { - return now.add(quarters, "quarters"); + return now.add(quarters, 'quarters'); } }; } @@ -198,7 +198,7 @@ export type ShortCuts = | ShortCutDateRange; export interface DateProps { - viewMode: "years" | "months" | "days" | "time"; + viewMode: 'years' | 'months' | 'days' | 'time'; className?: string; classPrefix: string; classnames: ClassNamesFn; @@ -211,8 +211,6 @@ export interface DateProps { disabled?: boolean; minDate?: moment.Moment; maxDate?: moment.Moment; - minTime?: moment.Moment; - maxTime?: moment.Moment; clearable?: boolean; defaultValue?: any; utc?: boolean; @@ -232,21 +230,18 @@ export interface DatePickerState { export class DatePicker extends React.Component { static defaultProps: Pick< DateProps, - "viewMode" | "shortcuts" | "closeOnSelect" | "overlayPlacement" + 'viewMode' | 'shortcuts' | 'closeOnSelect' | 'overlayPlacement' > = { - viewMode: "days", - shortcuts: "", + viewMode: 'days', + shortcuts: '', closeOnSelect: true, - overlayPlacement: "auto" + overlayPlacement: 'auto' }; state: DatePickerState = { isOpened: false, isFocused: false, value: this.props.value - ? (this.props.utc ? moment.utc : moment)( - this.props.value, - this.props.format - ) + ? moment(this.props.value, this.props.format) : undefined }; constructor(props: DateProps) { @@ -274,10 +269,7 @@ export class DatePicker extends React.Component { if (this.props.value !== nextProps.value) { this.setState({ value: nextProps.value - ? (nextProps.utc ? moment.utc : moment)( - nextProps.value, - nextProps.format - ) + ? moment(nextProps.value, nextProps.format) : undefined }); } @@ -304,7 +296,7 @@ export class DatePicker extends React.Component { } handleKeyPress(e: React.KeyboardEvent) { - if (e.key === " ") { + if (e.key === ' ') { this.handleClick(); } } @@ -338,7 +330,7 @@ export class DatePicker extends React.Component { e.preventDefault(); e.stopPropagation(); const onChange = this.props.onChange; - onChange(""); + onChange(''); } handleChange(value: moment.Moment) { @@ -349,20 +341,21 @@ export class DatePicker extends React.Component { maxTime, dateFormat, timeFormat, - closeOnSelect + closeOnSelect, + utc } = this.props; if (!moment.isMoment(value)) { return; } - if (minTime && value && value.isBefore(minTime, "second")) { + if (minTime && value && value.isBefore(minTime, 'second')) { value = minTime; - } else if (maxTime && value && value.isAfter(maxTime, "second")) { + } else if (maxTime && value && value.isAfter(maxTime, 'second')) { value = maxTime; } - onChange(value.format(format)); + onChange(utc ? moment.utc(value).format(format) : value.format(format)); if (closeOnSelect && dateFormat && !timeFormat) { this.close(); @@ -370,7 +363,7 @@ export class DatePicker extends React.Component { } selectRannge(item: any) { - const { closeOnSelect } = this.props; + const {closeOnSelect} = this.props; const now = moment(); this.handleChange(item.date(now)); @@ -378,11 +371,11 @@ export class DatePicker extends React.Component { } checkIsValidDate(currentDate: moment.Moment) { - const { minDate, maxDate } = this.props; + const {minDate, maxDate} = this.props; - if (minDate && currentDate.isBefore(minDate, "day")) { + if (minDate && currentDate.isBefore(minDate, 'day')) { return false; - } else if (maxDate && currentDate.isAfter(maxDate, "day")) { + } else if (maxDate && currentDate.isAfter(maxDate, 'day')) { return false; } @@ -422,10 +415,10 @@ export class DatePicker extends React.Component { if (!shortcuts) { return null; } - const { classPrefix: ns } = this.props; + const {classPrefix: ns} = this.props; let shortcutArr: Array; - if (typeof shortcuts === "string") { - shortcutArr = shortcuts.split(","); + if (typeof shortcuts === 'string') { + shortcutArr = shortcuts.split(','); } else { shortcutArr = shortcuts; } @@ -436,7 +429,7 @@ export class DatePicker extends React.Component { return null; } let shortcut: PlainObject = {}; - if (typeof item === "string") { + if (typeof item === 'string') { shortcut = this.getAvailableShortcuts(item); shortcut.key = item; } else if ((item as ShortCutDate).date) { @@ -490,8 +483,8 @@ export class DatePicker extends React.Component { className={cx( `${ns}DatePicker`, { - "is-disabled": disabled, - "is-focused": this.state.isFocused + 'is-disabled': disabled, + 'is-focused': this.state.isFocused }, className )} @@ -542,7 +535,7 @@ export class DatePicker extends React.Component { timeConstraints={timeConstraints} input={false} onClose={this.close} - utc={utc} + // utc={utc} /> diff --git a/src/components/DateRangePicker.tsx b/src/components/DateRangePicker.tsx index 6812c42df..124fd34fd 100644 --- a/src/components/DateRangePicker.tsx +++ b/src/components/DateRangePicker.tsx @@ -4,18 +4,18 @@ * @author fex */ -import React = require("react"); -import moment = require("moment"); -import { findDOMNode } from "react-dom"; -import cx from "classnames"; -import { Icon } from "./icons"; -import Overlay from "./Overlay"; -import { ShortCuts, ShortCutDateRange } from "./DatePicker"; -import Calendar from "./calendar/Calendar"; -import PopOver from "./PopOver"; -import { ClassNamesFn, themeable } from "../theme"; -import { PlainObject } from "../types"; -import { noop } from "../utils/helper"; +import React = require('react'); +import moment = require('moment'); +import {findDOMNode} from 'react-dom'; +import cx from 'classnames'; +import {Icon} from './icons'; +import Overlay from './Overlay'; +import {ShortCuts, ShortCutDateRange} from './DatePicker'; +import Calendar from './calendar/Calendar'; +import PopOver from './PopOver'; +import {ClassNamesFn, themeable} from '../theme'; +import {PlainObject} from '../types'; +import {noop} from '../utils/helper'; export interface DateRangePickerProps { className?: string; @@ -24,6 +24,7 @@ export interface DateRangePickerProps { placeholder?: string; theme?: any; format: string; + utc?: boolean; inputFormat?: string; ranges?: string | Array; clearable?: boolean; @@ -48,110 +49,110 @@ export interface DateRangePickerState { endDate?: moment.Moment; } -const availableRanges: { [propName: string]: any } = { - today: { - label: "今天", +const availableRanges: {[propName: string]: any} = { + 'today': { + label: '今天', startDate: (now: moment.Moment) => { - return now.startOf("day"); + return now.startOf('day'); }, endDate: (now: moment.Moment) => { return now; } }, - yesterday: { - label: "昨天", + 'yesterday': { + label: '昨天', startDate: (now: moment.Moment) => { - return now.add(-1, "days").startOf("day"); + return now.add(-1, 'days').startOf('day'); }, endDate: (now: moment.Moment) => { - return now.add(-1, "days").endOf("day"); + return now.add(-1, 'days').endOf('day'); } }, - "1dayago": { - label: "最近1天", + '1dayago': { + label: '最近1天', startDate: (now: moment.Moment) => { - return now.add(-1, "days"); + return now.add(-1, 'days'); }, endDate: (now: moment.Moment) => { return now; } }, - "7daysago": { - label: "最近7天", + '7daysago': { + label: '最近7天', startDate: (now: moment.Moment) => { - return now.add(-7, "days").startOf("day"); + return now.add(-7, 'days').startOf('day'); }, endDate: (now: moment.Moment) => { - return now.add(-1, "days").endOf("day"); + return now.add(-1, 'days').endOf('day'); } }, - "90daysago": { - label: "最近90天", + '90daysago': { + label: '最近90天', startDate: (now: moment.Moment) => { - return now.add(-90, "days").startOf("day"); + return now.add(-90, 'days').startOf('day'); }, endDate: (now: moment.Moment) => { - return now.add(-1, "days").endOf("day"); + return now.add(-1, 'days').endOf('day'); } }, - prevweek: { - label: "上周", + 'prevweek': { + label: '上周', startDate: (now: moment.Moment) => { - return now.startOf("week").add(-1, "weeks"); + return now.startOf('week').add(-1, 'weeks'); }, endDate: (now: moment.Moment) => { return now - .startOf("week") - .add(-1, "days") - .endOf("day"); + .startOf('week') + .add(-1, 'days') + .endOf('day'); } }, - thismonth: { - label: "本月", + 'thismonth': { + label: '本月', startDate: (now: moment.Moment) => { - return now.startOf("month"); + return now.startOf('month'); }, endDate: (now: moment.Moment) => { return now; } }, - prevmonth: { - label: "上个月", + 'prevmonth': { + label: '上个月', startDate: (now: moment.Moment) => { - return now.startOf("month").add(-1, "month"); + return now.startOf('month').add(-1, 'month'); }, endDate: (now: moment.Moment) => { return now - .startOf("month") - .add(-1, "day") - .endOf("day"); + .startOf('month') + .add(-1, 'day') + .endOf('day'); } }, - prevquarter: { - label: "上个季节", + 'prevquarter': { + label: '上个季节', startDate: (now: moment.Moment) => { - return now.startOf("quarter").add(-1, "quarter"); + return now.startOf('quarter').add(-1, 'quarter'); }, endDate: (now: moment.Moment) => { return now - .startOf("quarter") - .add(-1, "day") - .endOf("day"); + .startOf('quarter') + .add(-1, 'day') + .endOf('day'); } }, - thisquarter: { - label: "本季度", + 'thisquarter': { + label: '本季度', startDate: (now: moment.Moment) => { - return now.startOf("quarter"); + return now.startOf('quarter'); }, endDate: (now: moment.Moment) => { return now; @@ -164,17 +165,17 @@ export class DateRangePicker extends React.Component< DateRangePickerState > { static defaultProps = { - placeholder: "请选择日期范围", - format: "X", - inputFormat: "YYYY-MM-DD", + placeholder: '请选择日期范围', + format: 'X', + inputFormat: 'YYYY-MM-DD', joinValues: true, clearable: true, - delimiter: ",", - ranges: "yesterday,7daysago,prevweek,thismonth,prevmonth,prevquarter", - iconClassName: "fa fa-calendar", - resetValue: "", + delimiter: ',', + ranges: 'yesterday,7daysago,prevweek,thismonth,prevmonth,prevquarter', + iconClassName: 'fa fa-calendar', + resetValue: '', closeOnSelect: true, - overlayPlacement: "auto" + overlayPlacement: 'auto' }; innerDom: any; @@ -185,11 +186,14 @@ export class DateRangePicker extends React.Component< newValue: any, format: string, joinValues: boolean, - delimiter: string + delimiter: string, + utc = false ) { newValue = [ - newValue.startDate.format(format), - newValue.endDate.format(format) + (utc ? moment.utc(newValue.startDate) : newValue.startDate).format( + format + ), + (utc ? moment.utc(newValue.endDate) : newValue.endDate).format(format) ]; if (joinValues) { @@ -212,7 +216,7 @@ export class DateRangePicker extends React.Component< }; } - if (joinValues && typeof value === "string") { + if (joinValues && typeof value === 'string') { value = value.split(delimiter); } @@ -223,7 +227,7 @@ export class DateRangePicker extends React.Component< } dom: React.RefObject; - nextMonth = moment().add(1, "months"); + nextMonth = moment().add(1, 'months'); constructor(props: DateRangePickerProps) { super(props); @@ -243,7 +247,7 @@ export class DateRangePicker extends React.Component< this.handleKeyPress = this.handleKeyPress.bind(this); this.handlePopOverClick = this.handlePopOverClick.bind(this); this.renderDay = this.renderDay.bind(this); - const { format, joinValues, delimiter, value } = this.props; + const {format, joinValues, delimiter, value} = this.props; this.state = { isOpened: false, @@ -254,7 +258,7 @@ export class DateRangePicker extends React.Component< componentWillReceiveProps(nextProps: DateRangePickerProps) { const props = this.props; - const { value, format, joinValues, delimiter } = nextProps; + const {value, format, joinValues, delimiter} = nextProps; if (props.value !== value) { this.setState({ @@ -320,7 +324,7 @@ export class DateRangePicker extends React.Component< } handleKeyPress(e: React.KeyboardEvent) { - if (e.key === " ") { + if (e.key === ' ') { this.handleClick(); } } @@ -340,7 +344,8 @@ export class DateRangePicker extends React.Component< }, this.props.format, this.props.joinValues, - this.props.delimiter + this.props.delimiter, + this.props.utc ) ); this.close(); @@ -365,7 +370,7 @@ export class DateRangePicker extends React.Component< handleEndChange(newValue: moment.Moment) { newValue = !this.state.endDate && !this.props.timeFormat - ? newValue.endOf("day") + ? newValue.endOf('day') : newValue; if ( @@ -384,7 +389,7 @@ export class DateRangePicker extends React.Component< } selectRannge(range: PlainObject) { - const { closeOnSelect } = this.props; + const {closeOnSelect} = this.props; const now = moment(); this.setState( { @@ -399,10 +404,10 @@ export class DateRangePicker extends React.Component< if (!ranges) { return null; } - const { classPrefix: ns } = this.props; + const {classPrefix: ns} = this.props; let rangeArr: Array; - if (typeof ranges === "string") { - rangeArr = ranges.split(","); + if (typeof ranges === 'string') { + rangeArr = ranges.split(','); } else { rangeArr = ranges; } @@ -413,7 +418,7 @@ export class DateRangePicker extends React.Component< return null; } let range: PlainObject = {}; - if (typeof item === "string") { + if (typeof item === 'string') { range = availableRanges[item]; range.key = item; } else if ( @@ -443,15 +448,15 @@ export class DateRangePicker extends React.Component< clearValue(e: React.MouseEvent) { e.preventDefault(); e.stopPropagation(); - const { resetValue, onChange } = this.props; + const {resetValue, onChange} = this.props; onChange(resetValue); } checkStartIsValidDate(currentDate: moment.Moment) { - let { endDate } = this.state; + let {endDate} = this.state; - let { minDate, maxDate } = this.props; + let {minDate, maxDate} = this.props; maxDate = maxDate && endDate @@ -460,9 +465,9 @@ export class DateRangePicker extends React.Component< : endDate : maxDate || endDate; - if (minDate && currentDate.isBefore(minDate, "day")) { + if (minDate && currentDate.isBefore(minDate, 'day')) { return false; - } else if (maxDate && currentDate.isAfter(maxDate, "day")) { + } else if (maxDate && currentDate.isAfter(maxDate, 'day')) { return false; } @@ -470,9 +475,9 @@ export class DateRangePicker extends React.Component< } checkEndIsValidDate(currentDate: moment.Moment) { - let { startDate } = this.state; + let {startDate} = this.state; - let { minDate, maxDate } = this.props; + let {minDate, maxDate} = this.props; minDate = minDate && startDate @@ -481,9 +486,9 @@ export class DateRangePicker extends React.Component< : startDate : minDate || startDate; - if (minDate && currentDate.isBefore(minDate, "day")) { + if (minDate && currentDate.isBefore(minDate, 'day')) { return false; - } else if (maxDate && currentDate.isAfter(maxDate, "day")) { + } else if (maxDate && currentDate.isAfter(maxDate, 'day')) { return false; } @@ -491,14 +496,14 @@ export class DateRangePicker extends React.Component< } renderDay(props: any, currentDate: moment.Moment) { - let { startDate, endDate } = this.state; + let {startDate, endDate} = this.state; if ( startDate && endDate && - currentDate.isBetween(startDate, endDate, "day", "[]") + currentDate.isBetween(startDate, endDate, 'day', '[]') ) { - props.className += " rdtBetween"; + props.className += ' rdtBetween'; } return {currentDate.date()}; @@ -513,6 +518,7 @@ export class DateRangePicker extends React.Component< popOverContainer, inputFormat, format, + dateFormat, joinValues, delimiter, clearable, @@ -523,7 +529,7 @@ export class DateRangePicker extends React.Component< overlayPlacement } = this.props; - const { isOpened, isFocused, startDate, endDate } = this.state; + const {isOpened, isFocused, startDate, endDate} = this.state; const selectedDate = DateRangePicker.unFormatValue( value, @@ -533,10 +539,10 @@ export class DateRangePicker extends React.Component< ); const startViewValue = selectedDate.startDate ? selectedDate.startDate.format(inputFormat) - : ""; + : ''; const endViewValue = selectedDate.endDate ? selectedDate.endDate.format(inputFormat) - : ""; + : ''; const arr = []; startViewValue && arr.push(startViewValue); endViewValue && arr.push(endViewValue); @@ -550,8 +556,8 @@ export class DateRangePicker extends React.Component< className={cx( `${ns}DateRangePicker`, { - "is-disabled": disabled, - "is-focused": isFocused + 'is-disabled': disabled, + 'is-focused': isFocused }, className )} @@ -560,7 +566,7 @@ export class DateRangePicker extends React.Component< > {arr.length ? ( - {arr.join(" 至 ")} + {arr.join(' 至 ')} ) : ( @@ -602,7 +608,7 @@ export class DateRangePicker extends React.Component< value={startDate} onChange={this.handleStartChange} requiredConfirm={false} - dateFormat={format} + dateFormat={dateFormat} timeFormat={timeFormat} isValidDate={this.checkStartIsValidDate} viewMode="days" @@ -616,7 +622,7 @@ export class DateRangePicker extends React.Component< value={endDate} onChange={this.handleEndChange} requiredConfirm={false} - dateFormat={format} + dateFormat={dateFormat} timeFormat={timeFormat} viewDate={this.nextMonth} isEndDate @@ -629,8 +635,8 @@ export class DateRangePicker extends React.Component<
{ } render() { - const {multiple, className, classPrefix: ns, classnames: cx, disabled} = this.props; + const {formInited, multiple, className, classPrefix: ns, classnames: cx, disabled} = this.props; - return ( + return formInited ? (
{multiple ? this.renderMultipe() : this.renderSingle()}
- ); + ) : null; } } diff --git a/src/renderers/Form/Date.tsx b/src/renderers/Form/Date.tsx index 3aa98c82b..819014eb8 100644 --- a/src/renderers/Form/Date.tsx +++ b/src/renderers/Form/Date.tsx @@ -1,10 +1,10 @@ -import React from "react"; -import { FormItem, FormControlProps } from "./Item"; -import cx from "classnames"; -import { filterDate } from "../../utils/tpl-builtin"; -import moment from "moment"; -import "moment/locale/zh-cn"; -import DatePicker from "../../components/DatePicker"; +import React from 'react'; +import {FormItem, FormControlProps} from './Item'; +import cx from 'classnames'; +import {filterDate} from '../../utils/tpl-builtin'; +import moment from 'moment'; +import 'moment/locale/zh-cn'; +import DatePicker from '../../components/DatePicker'; export interface DateProps extends FormControlProps { placeholder?: string; @@ -15,6 +15,9 @@ export interface DateProps extends FormControlProps { closeOnSelect?: boolean; disabled: boolean; iconClassName?: string; + utc?: boolean; // 设定是否存储 utc 时间。 + minDate?: string; + maxDate?: string; } interface DateControlState { @@ -27,16 +30,16 @@ export default class DateControl extends React.PureComponent< DateControlState > { static defaultProps = { - format: "X", - viewMode: "days", - inputFormat: "YYYY-MM-DD", + format: 'X', + viewMode: 'days', + inputFormat: 'YYYY-MM-DD', timeConstrainst: { minutes: { step: 1 } }, clearable: true, - iconClassName: "fa fa-calendar" + iconClassName: 'fa fa-calendar' }; componentWillMount() { @@ -47,11 +50,13 @@ export default class DateControl extends React.PureComponent< defaultValue, setPrinstineValue, data, - format + format, + utc } = this.props; if (defaultValue && value === defaultValue) { - setPrinstineValue(filterDate(defaultValue, data, format).format(format)); + const date = filterDate(defaultValue, data, format); + setPrinstineValue((utc ? moment.utc(date) : date).format(format)); } this.setState({ @@ -64,8 +69,13 @@ export default class DateControl extends React.PureComponent< const props = this.props; if (props.defaultValue !== nextProps.defaultValue) { + const date = filterDate( + nextProps.defaultValue, + nextProps.data, + nextProps.format + ); nextProps.setPrinstineValue( - filterDate(nextProps.defaultValue, nextProps.data) + (nextProps.utc ? moment.utc(date) : date).format(nextProps.format) ); } @@ -103,45 +113,45 @@ export default class DateControl extends React.PureComponent< } @FormItem({ - type: "date", + type: 'date', weight: -150 }) export class DateControlRenderer extends DateControl { static defaultProps = { ...DateControl.defaultProps, - placeholder: "请选择日期", - dateFormat: "YYYY-MM-DD", - timeFormat: "", + placeholder: '请选择日期', + dateFormat: 'YYYY-MM-DD', + timeFormat: '', strictMode: false }; } @FormItem({ - type: "datetime" + type: 'datetime' }) export class DatetimeControlRenderer extends DateControl { static defaultProps = { ...DateControl.defaultProps, - placeholder: "请选择日期以及时间", - inputFormat: "YYYY-MM-DD HH:mm:ss", - dateFormat: "LL", - timeFormat: "HH:mm:ss", + placeholder: '请选择日期以及时间', + inputFormat: 'YYYY-MM-DD HH:mm:ss', + dateFormat: 'LL', + timeFormat: 'HH:mm:ss', closeOnSelect: false, strictMode: false }; } @FormItem({ - type: "time" + type: 'time' }) export class TimeControlRenderer extends DateControl { static defaultProps = { ...DateControl.defaultProps, - placeholder: "请选择时间", - inputFormat: "HH:mm", - dateFormat: "", - timeFormat: "HH:mm", - viewMode: "time", + placeholder: '请选择时间', + inputFormat: 'HH:mm', + dateFormat: '', + timeFormat: 'HH:mm', + viewMode: 'time', closeOnSelect: false }; } diff --git a/src/renderers/Form/DateRange.tsx b/src/renderers/Form/DateRange.tsx index 08d18b25f..95b689aff 100644 --- a/src/renderers/Form/DateRange.tsx +++ b/src/renderers/Form/DateRange.tsx @@ -36,11 +36,11 @@ export default class DateRangeControl extends React.Component< constructor(props: DateRangeProps) { super(props); - const {minDate, maxDate, data} = props; + const {minDate, maxDate, data, format} = props; this.state = { - minDate: minDate ? filterDate(minDate, data) : undefined, - maxDate: maxDate ? filterDate(maxDate, data) : undefined + minDate: minDate ? filterDate(minDate, data, format) : undefined, + maxDate: maxDate ? filterDate(maxDate, data, format) : undefined }; } @@ -52,7 +52,8 @@ export default class DateRangeControl extends React.Component< format, data, value, - joinValues + joinValues, + utc } = this.props; if (defaultValue && value === defaultValue) { @@ -63,19 +64,20 @@ export default class DateRangeControl extends React.Component< setPrinstineValue( BaseDateRangePicker.formatValue( { - startDate: filterDate(arr[0], data), - endDate: filterDate(arr[1], data) + startDate: filterDate(arr[0], data, format), + endDate: filterDate(arr[1], data, format) }, format, joinValues, - delimiter + delimiter, + utc ) ); } } componentWillReceiveProps(nextProps: DateRangeProps) { - const {data, minDate, maxDate} = nextProps; + const {data, minDate, maxDate, format} = nextProps; const props = this.props; if ( @@ -84,8 +86,8 @@ export default class DateRangeControl extends React.Component< props.data !== data ) { this.setState({ - minDate: minDate ? filterDate(minDate, data) : undefined, - maxDate: maxDate ? filterDate(maxDate, data) : undefined + minDate: minDate ? filterDate(minDate, data, format) : undefined, + maxDate: maxDate ? filterDate(maxDate, data, format) : undefined }); } } @@ -94,10 +96,11 @@ export default class DateRangeControl extends React.Component< const { defaultValue, delimiter, - format, joinValues, setPrinstineValue, - data + data, + utc, + format } = this.props; if (prevProps.defaultValue !== defaultValue) { @@ -110,12 +113,13 @@ export default class DateRangeControl extends React.Component< arr ? BaseDateRangePicker.formatValue( { - startDate: filterDate(arr[0], data), - endDate: filterDate(arr[1], data) + startDate: filterDate(arr[0], data, format), + endDate: filterDate(arr[1], data, format) }, format, joinValues, - delimiter + delimiter, + utc ) : undefined ); diff --git a/src/renderers/Form/Item.tsx b/src/renderers/Form/Item.tsx index 167258b04..cdaa892cd 100644 --- a/src/renderers/Form/Item.tsx +++ b/src/renderers/Form/Item.tsx @@ -677,6 +677,7 @@ export class FormItemWrap extends React.Component { // 除非配置 strictMode export const detectProps = [ 'formPristine', // 这个千万不能干掉。 + 'formInited', 'addable', 'addButtonClassName', 'addButtonText', diff --git a/src/renderers/Form/Service.tsx b/src/renderers/Form/Service.tsx index 46b3a697f..4fe85d058 100644 --- a/src/renderers/Form/Service.tsx +++ b/src/renderers/Form/Service.tsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Renderer, RendererProps} from '../../factory'; -import BasicService from '../Service'; +import BasicService, {ServiceProps} from '../Service'; import {Schema} from '../../types'; import Scoped, {ScopedContext, IScopedContext} from '../../Scoped'; import {observer} from 'mobx-react'; @@ -22,9 +22,30 @@ export class ServiceRenderer extends BasicService { scoped.registerComponent(this); } + componentDidMount() { + const {formInited, addHook} = this.props; + + if (formInited) { + super.componentDidMount(); + } else { + addHook && addHook(this.initFetch, 'init'); + } + } + + componentDidUpdate(prevProps: ServiceProps) { + const {formInited} = this.props; + if (formInited) { + super.componentDidUpdate(prevProps); + } + } + componentWillUnmount() { const scoped = this.context as IScopedContext; scoped.unRegisterComponent(this); + + const removeHook = this.props.removeHook; + removeHook && removeHook(this.initFetch, 'init'); + super.componentWillUnmount(); } renderBody(): JSX.Element { diff --git a/src/renderers/Form/index.tsx b/src/renderers/Form/index.tsx index 6d47b606d..ef20a8fe3 100644 --- a/src/renderers/Form/index.tsx +++ b/src/renderers/Form/index.tsx @@ -279,7 +279,7 @@ export default class Form extends React.Component { .then(this.initInterval) .then(this.onInit); } else { - this.onInit(); + setTimeout(this.onInit.bind(this), 4); } } diff --git a/src/renderers/Service.tsx b/src/renderers/Service.tsx index b71e86c4f..ed5c0b350 100644 --- a/src/renderers/Service.tsx +++ b/src/renderers/Service.tsx @@ -9,6 +9,7 @@ import Scoped, {ScopedContext, IScopedContext} from '../Scoped'; import {observer} from 'mobx-react'; import {isApiOutdated, isEffectiveApi} from '../utils/api'; import {Spinner} from '../components'; +import {autobind} from '../utils/helper'; export interface ServiceProps extends RendererProps { api?: Api; @@ -48,33 +49,8 @@ export default class Service extends React.Component { } componentDidMount() { - const { - schemaApi, - initFetchSchema, - api, - initFetch, - initFetchOn, - store, - messages: {fetchSuccess, fetchFailed} - } = this.props; - this.mounted = true; - - if (isEffectiveApi(schemaApi, store.data, initFetchSchema)) { - store.fetchSchema(schemaApi, store.data, { - successMessage: fetchSuccess, - errorMessage: fetchFailed - }); - } - - if (isEffectiveApi(api, store.data, initFetch, initFetchOn)) { - store - .fetchInitData(api, store.data, { - successMessage: fetchSuccess, - errorMessage: fetchFailed - }) - .then(this.initInterval); - } + this.initFetch(); } componentDidUpdate(prevProps: ServiceProps) { @@ -112,6 +88,35 @@ export default class Service extends React.Component { clearTimeout(this.timer); } + @autobind + initFetch() { + const { + schemaApi, + initFetchSchema, + api, + initFetch, + initFetchOn, + store, + messages: {fetchSuccess, fetchFailed} + } = this.props; + + if (isEffectiveApi(schemaApi, store.data, initFetchSchema)) { + store.fetchSchema(schemaApi, store.data, { + successMessage: fetchSuccess, + errorMessage: fetchFailed + }); + } + + if (isEffectiveApi(api, store.data, initFetch, initFetchOn)) { + store + .fetchInitData(api, store.data, { + successMessage: fetchSuccess, + errorMessage: fetchFailed + }) + .then(this.initInterval); + } + } + initInterval(value: any) { const {interval, silentPolling, stopAutoRefreshWhen, data} = this.props; diff --git a/src/utils/tpl-builtin.ts b/src/utils/tpl-builtin.ts index 801c6d18e..6a321684b 100644 --- a/src/utils/tpl-builtin.ts +++ b/src/utils/tpl-builtin.ts @@ -83,9 +83,11 @@ export const relativeValueRe = /^(.+)?(\+|-)(\d+)(minute|min|hour|day|week|month export const filterDate = ( value: string, data: object = {}, - format = 'X' + format = 'X', + utc: boolean = false ): moment.Moment => { - let m; + let m, + mm = utc ? moment.utc : moment; if (typeof value === 'string') { value = value.trim(); @@ -97,8 +99,8 @@ export const filterDate = ( const date = new Date(); const step = parseInt(m[3], 10); const from = m[1] - ? filterDate(m[1], data, format) - : moment( + ? filterDate(m[1], data, format, utc) + : mm( /(minute|min|hour|second)s?/.test(m[4]) ? [ date.getFullYear(), @@ -116,12 +118,12 @@ export const filterDate = ( : from.add(step, timeUnitMap[m[4]] as moment.DurationInputArg2); // return from[m[2] === '-' ? 'subtract' : 'add'](step, mapping[m[4]] || m[4]); } else if (value === 'now') { - return moment(); + return mm(); } else if (value === 'today') { const date = new Date(); - return moment([date.getFullYear(), date.getMonth(), date.getDate()]); + return mm([date.getFullYear(), date.getMonth(), date.getDate()]); } else { - return moment(value, format); + return mm(value, format); } };