fix: datepicker with timezone

This commit is contained in:
chenos 2022-06-16 16:38:12 +08:00
parent bf11cff804
commit 7a9bab9bab
4 changed files with 152 additions and 8 deletions

View File

@ -2,7 +2,7 @@
* title: DatePicker * title: DatePicker
*/ */
import { FormItem } from '@formily/antd'; import { FormItem } from '@formily/antd';
import { DatePicker, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import { DatePicker, Input, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
import React from 'react'; import React from 'react';
const schema = { const schema = {
@ -15,10 +15,10 @@ const schema = {
'x-component': 'DatePicker', 'x-component': 'DatePicker',
'x-component-props': { 'x-component-props': {
dateFormat: 'YYYY/MM/DD', dateFormat: 'YYYY/MM/DD',
// showTime: true, showTime: true,
}, },
'x-reactions': { 'x-reactions': {
target: 'read', target: '*(read1,read2)',
fulfill: { fulfill: {
state: { state: {
value: '{{$self.value}}', value: '{{$self.value}}',
@ -26,7 +26,7 @@ const schema = {
}, },
}, },
}, },
read: { read1: {
type: 'boolean', type: 'boolean',
title: `Read pretty`, title: `Read pretty`,
'x-read-pretty': true, 'x-read-pretty': true,
@ -34,15 +34,23 @@ const schema = {
'x-component': 'DatePicker', 'x-component': 'DatePicker',
'x-component-props': { 'x-component-props': {
dateFormat: 'YYYY/MM/DD', dateFormat: 'YYYY/MM/DD',
// showTime: true, showTime: true,
}, },
}, },
read2: {
type: 'string',
title: `Value`,
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {},
},
}, },
}; };
export default () => { export default () => {
return ( return (
<SchemaComponentProvider components={{ DatePicker, FormItem }}> <SchemaComponentProvider components={{ Input, DatePicker, FormItem }}>
<SchemaComponent schema={schema} /> <SchemaComponent schema={schema} />
</SchemaComponentProvider> </SchemaComponentProvider>
); );

View File

@ -0,0 +1,59 @@
/**
* title: DatePicker (with timezone)
*/
import { FormItem } from '@formily/antd';
import { DatePicker, Input, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
import React from 'react';
const schema = {
type: 'object',
properties: {
input: {
type: 'boolean',
title: `Editable`,
'x-decorator': 'FormItem',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY/MM/DD',
showTime: true,
withTz: true,
},
default: '2022-06-04T15:00:00.000Z',
'x-reactions': {
target: '*(read1,read2)',
fulfill: {
state: {
value: '{{$self.value}}',
},
},
},
},
read1: {
type: 'string',
title: `Read pretty`,
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY/MM/DD',
// showTime: true,
},
},
read2: {
type: 'string',
title: `Value`,
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {},
},
},
};
export default () => {
return (
<SchemaComponentProvider components={{ Input, DatePicker, FormItem }}>
<SchemaComponent schema={schema} />
</SchemaComponentProvider>
);
};

View File

@ -13,6 +13,10 @@ group:
<code src="./demos/demo1.tsx" /> <code src="./demos/demo1.tsx" />
### DatePicker (with timezone)
<code src="./demos/demo3.tsx" />
### RangePicker ### RangePicker
<code src="./demos/demo2.tsx" /> <code src="./demos/demo2.tsx" />

View File

@ -1,4 +1,4 @@
import { formatMomentValue } from '@formily/antd/lib/__builtins__'; import { isArr, isEmpty, isFn } from '@formily/shared';
import type { DatePickerProps } from 'antd/lib/date-picker'; import type { DatePickerProps } from 'antd/lib/date-picker';
import moment from 'moment'; import moment from 'moment';
@ -24,6 +24,70 @@ export const getDefaultFormat = (props: DatePickerProps & { dateFormat: string;
return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'; return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
}; };
const toMoment = (val, format) => {
if (moment.isMoment(val)) {
return val;
}
if (typeof val === 'string' && val.includes('T')) {
return moment(val);
}
return moment(val, format);
};
export const momentable = (value: any, format?: string) => {
return Array.isArray(value)
? value.map((val) => {
return toMoment(val, format);
})
: value
? toMoment(value, format)
: value;
};
export const formatMomentValue = (value: any, format: any, placeholder?: string): string | string[] => {
const formatDate = (date: any, format: any, i = 0) => {
if (!date) return placeholder;
if (isArr(format)) {
const _format = format[i];
if (isFn(_format)) {
return _format(date);
}
if (isEmpty(_format)) {
return date;
}
return moment(date).format(_format);
} else {
if (isFn(format)) {
return format(date);
}
if (isEmpty(format)) {
return date;
}
return moment(date).format(format);
}
};
if (isArr(value)) {
return value.map((val, index) => {
return formatDate(val, format, index);
});
} else {
return value ? formatDate(value, format) : value || placeholder;
}
};
const momentToString = (value: moment.Moment | moment.Moment[]) => {
if (!value) {
return value;
}
if (Array.isArray(value)) {
return value.map(val => val.toISOString());
}
if (moment.isMoment(value)) {
return value.toISOString();
}
}
export const mapDateFormat = function () { export const mapDateFormat = function () {
return (props: any) => { return (props: any) => {
const format = getDefaultFormat(props) as any; const format = getDefaultFormat(props) as any;
@ -31,7 +95,16 @@ export const mapDateFormat = function () {
return { return {
...props, ...props,
format: format, format: format,
value: props.value && moment(props.value).isValid() ? moment(props.value) : undefined, value: momentable(props.value, format === 'YYYY-wo' ? 'YYYY-w' : format),
onChange: (value: moment.Moment | moment.Moment[]) => {
if (onChange) {
if (props.withTz) {
onChange(momentToString(value));
} else {
onChange(formatMomentValue(value, format));
}
}
},
}; };
}; };
}; };