diff --git a/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx b/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx index 142feeb32..74236313c 100644 --- a/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx +++ b/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { ReadPretty } from './ReadPretty'; import { getDateRanges, mapDatePicker, mapRangePicker } from './util'; +import dayjs from 'dayjs'; interface IDatePickerProps { utc?: boolean; @@ -47,6 +48,22 @@ DatePicker.ReadPretty = ReadPretty.DatePicker; DatePicker.RangePicker = function RangePicker(props) { const { t } = useTranslation(); const { utc = true } = useDatePickerContext(); + // value type: range [{value: "2024-04-01T16:00:00.000Z", inclusive: true},{value: "2024-05-01T16:00:00.000Z", inclusive: false}]; + if (props.valueType === 'range') { + const originOnChange = props.onChange; + const originValue = props.value; + // make it writable + props = { ...props }; + if (originValue) { + props.value = [originValue[0].value, dayjs(originValue[1].value).add(-1, 'd').toISOString()]; + } + props.onChange = (value: string[2]) => { + originOnChange([ + { value: dayjs(value[0]).toISOString(), inclusive: true }, + { value: dayjs(value[1]).add(1, 'd').toISOString(), inclusive: false }, + ]); + }; + } const rangesValue = getDateRanges(); const presets = [ { label: t('Today'), value: rangesValue.today }, diff --git a/packages/core/client/src/schema-component/antd/date-picker/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/date-picker/ReadPretty.tsx index bf9216dbc..4bbc37497 100644 --- a/packages/core/client/src/schema-component/antd/date-picker/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/date-picker/ReadPretty.tsx @@ -34,6 +34,7 @@ ReadPretty.DatePicker = function DatePicker(props: any) { ReadPretty.DateRangePicker = function DateRangePicker(props: any) { const prefixCls = usePrefixCls('description-text', props); + const format = getDefaultFormat(props); const getLabels = () => { const m = str2moment(props.value, props); diff --git a/packages/core/utils/src/date.ts b/packages/core/utils/src/date.ts index 458b5d9f2..dcf1c4a41 100644 --- a/packages/core/utils/src/date.ts +++ b/packages/core/utils/src/date.ts @@ -75,8 +75,8 @@ export const str2moment = (value?: string | string[], options: Str2momentOptions return toMoment(val, options); }) : value - ? toMoment(value, options) - : value; + ? toMoment(value, options) + : value; }; const toStringByPicker = (value, picker) => { diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx index 1f239670c..69fe3ee3b 100644 --- a/packages/plugins/@hera/plugin-core/src/client/index.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx @@ -79,6 +79,7 @@ import { DepartmentsPlugin } from './features/departments'; import { PluginPageStyle } from './features/page-style'; import { PluginHeraVersion } from './features/hera-version'; import { PluginAssistant } from './features/assistant'; +import { TstzrangeFieldInterface } from './interfaces/TstzrangeFieldInterface'; export { usePDFViewerRef } from './schema-initializer'; export * from './components/custom-components/custom-components'; @@ -288,6 +289,7 @@ export class PluginCoreClient extends Plugin { CustomAssociatedFieldInterface, SignaturePadFieldInterface, ExcelFieldInterface, + TstzrangeFieldInterface, ]); } diff --git a/packages/plugins/@hera/plugin-core/src/client/interfaces/TstzrangeFieldInterface.ts b/packages/plugins/@hera/plugin-core/src/client/interfaces/TstzrangeFieldInterface.ts new file mode 100644 index 000000000..3d416fa7d --- /dev/null +++ b/packages/plugins/@hera/plugin-core/src/client/interfaces/TstzrangeFieldInterface.ts @@ -0,0 +1,28 @@ +import { defaultProps, CollectionFieldInterface } from '@nocobase/client'; +import { tval } from '../locale'; + +export class TstzrangeFieldInterface extends CollectionFieldInterface { + name = 'tstzrange'; + type = 'object'; + group = 'datetime'; + order = 2; + title = tval('Date range'); + sortable = true; + default = { + type: 'tstzrange', + uiSchema: { + type: 'object', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + utc: false, + valueType: 'range', + }, + }, + }; + availableTypes = ['tstzrange']; + hasDefaultValue = false; + + properties = { + ...defaultProps, + }; +} diff --git a/packages/plugins/@hera/plugin-core/src/server/fields/tstzrange.ts b/packages/plugins/@hera/plugin-core/src/server/fields/tstzrange.ts new file mode 100644 index 000000000..1eb1f4c6f --- /dev/null +++ b/packages/plugins/@hera/plugin-core/src/server/fields/tstzrange.ts @@ -0,0 +1,11 @@ +import { BaseColumnFieldOptions, DataTypes, Field, Model } from '@nocobase/database'; + +export interface TstzrangeFieldOptions extends BaseColumnFieldOptions { + type: 'tstzrange'; +} + +export default class TstzrangeField extends Field { + get dataType() { + return DataTypes.RANGE(DataTypes.DATE); + } +} diff --git a/packages/plugins/@hera/plugin-core/src/server/plugin.ts b/packages/plugins/@hera/plugin-core/src/server/plugin.ts index ecdc92a5e..5c9312083 100644 --- a/packages/plugins/@hera/plugin-core/src/server/plugin.ts +++ b/packages/plugins/@hera/plugin-core/src/server/plugin.ts @@ -9,6 +9,7 @@ import { WebControllerService as WebService } from './services/web-service'; import './actions'; import { Container } from '@nocobase/utils'; import { DepartmentsPlugin } from './features/departments'; +import TstzrangeField from './fields/tstzrange'; export class PluginCoreServer extends Plugin { pluginDepartments: DepartmentsPlugin; @@ -19,6 +20,7 @@ export class PluginCoreServer extends Plugin { async afterAdd() { this.db.registerFieldTypes({ calc: CalcField, + tstzrange: TstzrangeField, }); } beforeLoad() {