feat: support date range field (#828)

Co-authored-by: sealday <sealday@gmail.com>
Reviewed-on: daoyoucloud/tachybase#828
This commit is contained in:
sealday 2024-04-24 20:56:07 +08:00
parent a5f865c112
commit c82fe54fe4
7 changed files with 63 additions and 2 deletions

View File

@ -8,6 +8,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReadPretty } from './ReadPretty'; import { ReadPretty } from './ReadPretty';
import { getDateRanges, mapDatePicker, mapRangePicker } from './util'; import { getDateRanges, mapDatePicker, mapRangePicker } from './util';
import dayjs from 'dayjs';
interface IDatePickerProps { interface IDatePickerProps {
utc?: boolean; utc?: boolean;
@ -47,6 +48,22 @@ DatePicker.ReadPretty = ReadPretty.DatePicker;
DatePicker.RangePicker = function RangePicker(props) { DatePicker.RangePicker = function RangePicker(props) {
const { t } = useTranslation(); const { t } = useTranslation();
const { utc = true } = useDatePickerContext(); 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 rangesValue = getDateRanges();
const presets = [ const presets = [
{ label: t('Today'), value: rangesValue.today }, { label: t('Today'), value: rangesValue.today },

View File

@ -34,6 +34,7 @@ ReadPretty.DatePicker = function DatePicker(props: any) {
ReadPretty.DateRangePicker = function DateRangePicker(props: any) { ReadPretty.DateRangePicker = function DateRangePicker(props: any) {
const prefixCls = usePrefixCls('description-text', props); const prefixCls = usePrefixCls('description-text', props);
const format = getDefaultFormat(props); const format = getDefaultFormat(props);
const getLabels = () => { const getLabels = () => {
const m = str2moment(props.value, props); const m = str2moment(props.value, props);

View File

@ -75,8 +75,8 @@ export const str2moment = (value?: string | string[], options: Str2momentOptions
return toMoment(val, options); return toMoment(val, options);
}) })
: value : value
? toMoment(value, options) ? toMoment(value, options)
: value; : value;
}; };
const toStringByPicker = (value, picker) => { const toStringByPicker = (value, picker) => {

View File

@ -79,6 +79,7 @@ import { DepartmentsPlugin } from './features/departments';
import { PluginPageStyle } from './features/page-style'; import { PluginPageStyle } from './features/page-style';
import { PluginHeraVersion } from './features/hera-version'; import { PluginHeraVersion } from './features/hera-version';
import { PluginAssistant } from './features/assistant'; import { PluginAssistant } from './features/assistant';
import { TstzrangeFieldInterface } from './interfaces/TstzrangeFieldInterface';
export { usePDFViewerRef } from './schema-initializer'; export { usePDFViewerRef } from './schema-initializer';
export * from './components/custom-components/custom-components'; export * from './components/custom-components/custom-components';
@ -288,6 +289,7 @@ export class PluginCoreClient extends Plugin {
CustomAssociatedFieldInterface, CustomAssociatedFieldInterface,
SignaturePadFieldInterface, SignaturePadFieldInterface,
ExcelFieldInterface, ExcelFieldInterface,
TstzrangeFieldInterface,
]); ]);
} }

View File

@ -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,
};
}

View File

@ -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);
}
}

View File

@ -9,6 +9,7 @@ import { WebControllerService as WebService } from './services/web-service';
import './actions'; import './actions';
import { Container } from '@nocobase/utils'; import { Container } from '@nocobase/utils';
import { DepartmentsPlugin } from './features/departments'; import { DepartmentsPlugin } from './features/departments';
import TstzrangeField from './fields/tstzrange';
export class PluginCoreServer extends Plugin { export class PluginCoreServer extends Plugin {
pluginDepartments: DepartmentsPlugin; pluginDepartments: DepartmentsPlugin;
@ -19,6 +20,7 @@ export class PluginCoreServer extends Plugin {
async afterAdd() { async afterAdd() {
this.db.registerFieldTypes({ this.db.registerFieldTypes({
calc: CalcField, calc: CalcField,
tstzrange: TstzrangeField,
}); });
} }
beforeLoad() { beforeLoad() {