fix(web-antdv-next): normalize date picker timestamp handling
Add DatePicker and RangePicker adapter wrappers for numeric timestamp values, route direct value-format="x" usages through the adapter, and keep ShortcutDateRangePicker values as Dayjs.pull/362/head
parent
2fc5575c30
commit
f152217c3c
|
|
@ -0,0 +1,86 @@
|
||||||
|
import type { Component } from 'vue';
|
||||||
|
|
||||||
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
|
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||||
|
|
||||||
|
const RawDatePicker = defineAsyncComponent(
|
||||||
|
() => import('antdv-next/dist/date-picker/index'),
|
||||||
|
);
|
||||||
|
const RawRangePicker = defineAsyncComponent(() =>
|
||||||
|
import('antdv-next/dist/date-picker/index').then(
|
||||||
|
(res) => res.DateRangePicker,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const TIMESTAMP_VALUE_FORMATS = new Set(['x', 'X']);
|
||||||
|
|
||||||
|
function isTimestampValueFormat(valueFormat: unknown) {
|
||||||
|
return (
|
||||||
|
typeof valueFormat === 'string' && TIMESTAMP_VALUE_FORMATS.has(valueFormat)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeTimestampPickerValue(value: any, valueFormat: unknown): any {
|
||||||
|
if (!isTimestampValueFormat(valueFormat)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map((item) => normalizeTimestampPickerValue(item, valueFormat));
|
||||||
|
}
|
||||||
|
return typeof value === 'number' ? String(value) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function withTimestampValueFormat(
|
||||||
|
component: Component,
|
||||||
|
name: 'DatePicker' | 'RangePicker',
|
||||||
|
) {
|
||||||
|
return defineComponent({
|
||||||
|
name,
|
||||||
|
inheritAttrs: false,
|
||||||
|
setup(_, { attrs, expose, slots }) {
|
||||||
|
const innerRef = ref();
|
||||||
|
expose(
|
||||||
|
new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get: (_target, key) => innerRef.value?.[key],
|
||||||
|
has: (_target, key) => key in (innerRef.value || {}),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const pickerAttrs: Recordable<any> = { ...attrs };
|
||||||
|
if (
|
||||||
|
'value-format' in pickerAttrs &&
|
||||||
|
!Reflect.has(pickerAttrs, 'valueFormat')
|
||||||
|
) {
|
||||||
|
pickerAttrs.valueFormat = pickerAttrs['value-format'];
|
||||||
|
}
|
||||||
|
const valueFormat = pickerAttrs.valueFormat;
|
||||||
|
|
||||||
|
for (const key of [
|
||||||
|
'value',
|
||||||
|
'defaultValue',
|
||||||
|
'pickerValue',
|
||||||
|
'defaultPickerValue',
|
||||||
|
]) {
|
||||||
|
if (Reflect.has(pickerAttrs, key)) {
|
||||||
|
pickerAttrs[key] = normalizeTimestampPickerValue(
|
||||||
|
pickerAttrs[key],
|
||||||
|
valueFormat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return h(component, { ...pickerAttrs, ref: innerRef }, slots);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const DatePicker = withTimestampValueFormat(RawDatePicker, 'DatePicker');
|
||||||
|
const RangePicker = withTimestampValueFormat(RawRangePicker, 'RangePicker');
|
||||||
|
|
||||||
|
export { DatePicker, RangePicker };
|
||||||
|
|
@ -75,6 +75,9 @@ import { message, Modal, notification } from 'antdv-next';
|
||||||
import { uploadFile as uploadFileApi } from '#/api/infra/file';
|
import { uploadFile as uploadFileApi } from '#/api/infra/file';
|
||||||
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||||
import { FileUpload, ImageUpload } from '#/components/upload';
|
import { FileUpload, ImageUpload } from '#/components/upload';
|
||||||
|
|
||||||
|
import { DatePicker, RangePicker } from './date-picker';
|
||||||
|
|
||||||
type AdapterUploadProps = UploadProps & {
|
type AdapterUploadProps = UploadProps & {
|
||||||
aspectRatio?: string;
|
aspectRatio?: string;
|
||||||
crop?: boolean;
|
crop?: boolean;
|
||||||
|
|
@ -97,9 +100,6 @@ const Checkbox = defineAsyncComponent(
|
||||||
const CheckboxGroup = defineAsyncComponent(() =>
|
const CheckboxGroup = defineAsyncComponent(() =>
|
||||||
import('antdv-next/dist/checkbox/index').then((res) => res.CheckboxGroup),
|
import('antdv-next/dist/checkbox/index').then((res) => res.CheckboxGroup),
|
||||||
);
|
);
|
||||||
const DatePicker = defineAsyncComponent(
|
|
||||||
() => import('antdv-next/dist/date-picker/index'),
|
|
||||||
);
|
|
||||||
const Divider = defineAsyncComponent(
|
const Divider = defineAsyncComponent(
|
||||||
() => import('antdv-next/dist/divider/index'),
|
() => import('antdv-next/dist/divider/index'),
|
||||||
);
|
);
|
||||||
|
|
@ -117,11 +117,6 @@ const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index'));
|
||||||
const RadioGroup = defineAsyncComponent(() =>
|
const RadioGroup = defineAsyncComponent(() =>
|
||||||
import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
|
import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
|
||||||
);
|
);
|
||||||
const RangePicker = defineAsyncComponent(() =>
|
|
||||||
import('antdv-next/dist/date-picker/index').then(
|
|
||||||
(res) => res.DateRangePicker,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
|
const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
|
||||||
const Select = defineAsyncComponent(
|
const Select = defineAsyncComponent(
|
||||||
() => import('antdv-next/dist/select/index'),
|
() => import('antdv-next/dist/select/index'),
|
||||||
|
|
@ -794,4 +789,4 @@ async function initComponentAdapter() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export { initComponentAdapter };
|
export { DatePicker, initComponentAdapter, RangePicker };
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,6 @@ onMounted(() => {
|
||||||
<DateRangePicker
|
<DateRangePicker
|
||||||
v-model:value="times"
|
v-model:value="times"
|
||||||
:format="rangePickerProps.format"
|
:format="rangePickerProps.format"
|
||||||
:value-format="rangePickerProps.valueFormat"
|
|
||||||
:placeholder="rangePickerProps.placeholder"
|
:placeholder="rangePickerProps.placeholder"
|
||||||
:presets="rangePickerProps.presets"
|
:presets="rangePickerProps.presets"
|
||||||
class="!w-full !max-w-96"
|
class="!w-full !max-w-96"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DatePicker,
|
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
|
|
@ -16,6 +15,7 @@ import {
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
|
|
||||||
|
import { DatePicker } from '#/adapter/component/date-picker';
|
||||||
import {
|
import {
|
||||||
createDemo01Contact,
|
createDemo01Contact,
|
||||||
getDemo01Contact,
|
getDemo01Contact,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DatePicker,
|
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
|
|
@ -16,6 +15,7 @@ import {
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
|
|
||||||
|
import { DatePicker } from '#/adapter/component/date-picker';
|
||||||
import {
|
import {
|
||||||
createDemo03Student,
|
createDemo03Student,
|
||||||
getDemo03Student,
|
getDemo03Student,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DatePicker,
|
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
|
|
@ -17,6 +16,7 @@ import {
|
||||||
Tabs,
|
Tabs,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
|
|
||||||
|
import { DatePicker } from '#/adapter/component/date-picker';
|
||||||
import {
|
import {
|
||||||
createDemo03Student,
|
createDemo03Student,
|
||||||
getDemo03Student,
|
getDemo03Student,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DatePicker,
|
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
|
|
@ -17,6 +16,7 @@ import {
|
||||||
Tabs,
|
Tabs,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
|
|
||||||
|
import { DatePicker } from '#/adapter/component/date-picker';
|
||||||
import {
|
import {
|
||||||
createDemo03Student,
|
createDemo03Student,
|
||||||
getDemo03Student,
|
getDemo03Student,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue