fix: dateTime format configured in table is invalid (#3630)

* fix: datetime format configured in the table is invalid

* test: date display format

* refactor: default timeformat

* test: datetime display format
This commit is contained in:
katherinehhh 2024-03-07 10:48:49 +08:00 committed by GitHub
parent 4bbce06d5e
commit 30b4ed77a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 407 additions and 13 deletions

View File

@ -0,0 +1,54 @@
import { expect, expectSettingsMenu, test } from '@nocobase/test/e2e';
import dayjs from 'dayjs';
import { oneTableBlockWithDatetimeFields, oneFormBlockWithDatetimeFields } from './utils';
test('Date display format in form', async ({ page, mockPage }) => {
await mockPage(oneFormBlockWithDatetimeFields).goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByPlaceholder('Select date').hover();
await page.getByLabel('block-item-CollectionField').hover();
await page.getByLabel('designer-schema-settings-CollectionField-fieldSettings:FormItem-general').hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Edit tooltip',
'Required',
'Set default value',
'Pattern',
'Date display format',
'Delete',
],
});
await page.getByText('Date display format').click();
await page.getByLabel('Show time').check();
await page.getByRole('button', { name: 'HH:mm:ss', exact: true }).click();
await page.getByRole('button', { name: 'OK' }).click();
await page.getByPlaceholder('Select date').click();
await page.getByText('Now').click();
const value = await page.getByPlaceholder('Select date').inputValue();
expect(value).toBe(dayjs(value).format('YYYY-MM-DD HH:mm:ss'));
});
test('Date display format in table', async ({ page, mockPage, mockRecord }) => {
await mockPage(oneTableBlockWithDatetimeFields).goto();
const date = new Date().toDateString();
await mockRecord('general', { datetime: date });
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'datetime' }).hover();
await page.getByLabel('designer-schema-settings-TableV2.Column-fieldSettings:TableColumn-general').hover();
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Date display format', 'Delete'],
});
await page.getByText('Date display format').click();
await page.getByLabel('Show time').check();
await page.getByRole('button', { name: 'hh:mm:ss a' }).click();
await page.getByRole('button', { name: 'OK' }).click();
await expect(page.getByRole('button', { name: dayjs(date).format('YYYY-MM-DD hh:mm:ss a') })).toBeVisible();
});

View File

@ -0,0 +1,331 @@
import { generalWithDatetime, PageConfig } from '@nocobase/test/e2e';
/**
* 1. Table
* 5. datetime
*/
export const oneTableBlockWithDatetimeFields: PageConfig = {
collections: generalWithDatetime,
pageSchema: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Page',
properties: {
rzvrcrafmff: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
properties: {
irc4mhtog83: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
bv65e6wkcef: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
gq797u6o8ti: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'TableBlockProvider',
'x-acl-action': 'general:list',
'x-decorator-props': {
collection: 'general',
dataSource: 'main',
resource: 'general',
action: 'list',
params: {
pageSize: 20,
},
rowKey: 'id',
showIndex: true,
dragSort: false,
disableTemplate: false,
},
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:table',
'x-component': 'CardItem',
'x-filter-targets': [],
properties: {
actions: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-component': 'ActionBar',
'x-component-props': {
style: {
marginBottom: 'var(--nb-spacing)',
},
},
'x-uid': 'nd5jqapjy3w',
'x-async': false,
'x-index': 1,
},
pkdf64ojs4s: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
rowSelection: {
type: 'checkbox',
},
useProps: '{{ useTableBlockProps }}',
},
properties: {
actions: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
title: '{{ t("Actions") }}',
'x-action-column': 'actions',
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
properties: {
gk4b4e4wp8b: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'DndContext',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
'x-uid': 'cj0u0c1ajp7',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'bqjujfh7zdw',
'x-async': false,
'x-index': 1,
},
nlf077nijaa: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'TableV2.Column.Decorator',
'x-toolbar': 'TableColumnSchemaToolbar',
'x-settings': 'fieldSettings:TableColumn',
'x-component': 'TableV2.Column',
properties: {
datetime: {
_isJSONSchemaObject: true,
version: '2.0',
'x-collection-field': 'general.datetime',
'x-component': 'CollectionField',
'x-component-props': {},
'x-read-pretty': true,
'x-decorator': null,
'x-decorator-props': {
labelStyle: {
display: 'none',
},
},
'x-uid': 'uv26aslikjn',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '1eten1jj0gt',
'x-async': false,
'x-index': 2,
},
},
'x-uid': 't47ph1tmsa0',
'x-async': false,
'x-index': 2,
},
},
'x-uid': '7zqek220iua',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'jh19krqxftf',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'lbfsv3pz0qi',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'xlc7hd8s8az',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'ml7rypfikcm',
'x-async': true,
'x-index': 1,
},
};
/**
* 1. Form
* 5. datetime
*/
export const oneFormBlockWithDatetimeFields: PageConfig = {
collections: generalWithDatetime,
pageSchema: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Page',
properties: {
rzvrcrafmff: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
properties: {
annx4g65mtu: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
ov02gf15cw5: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
qx7c4utyugy: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-acl-action-props': {
skipScopeCheck: true,
},
'x-acl-action': 'general:create',
'x-decorator': 'FormBlockProvider',
'x-decorator-props': {
dataSource: 'main',
resource: 'general',
collection: 'general',
},
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:createForm',
'x-component': 'CardItem',
'x-component-props': {},
properties: {
'00mj93xz46e': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'FormV2',
'x-component-props': {
useProps: '{{ useFormBlockProps }}',
},
properties: {
grid: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
properties: {
'269bdhc35j2': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
'7nkbge7b0bo': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
datetime: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
'x-toolbar': 'FormItemSchemaToolbar',
'x-settings': 'fieldSettings:FormItem',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.datetime',
'x-component-props': {},
'x-uid': 'lpcbskripdi',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'ykx953ujfur',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'bnz69w2wylm',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'rf04idbxdeo',
'x-async': false,
'x-index': 1,
},
'0vnfo3li57v': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
marginTop: 24,
},
},
'x-uid': '0m3zbok6yhn',
'x-async': false,
'x-index': 2,
},
},
'x-uid': 'gusa79tzjit',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'ntdpcoeszfh',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '4qk0nzqrmtn',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'hoxpqzqrumd',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'xlc7hd8s8az',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'ml7rypfikcm',
'x-async': true,
'x-index': 1,
},
};

View File

@ -1,6 +1,7 @@
import { useFieldSchema } from '@formily/react';
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
import { SchemaSettingsDateFormat } from '../../../../schema-settings/SchemaSettingsDateFormat';
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
export const datePickerComponentFieldSettings = new SchemaSettings({
name: 'fieldSettings:component:DatePicker',
@ -9,7 +10,9 @@ export const datePickerComponentFieldSettings = new SchemaSettings({
name: 'dateDisplayFormat',
Component: SchemaSettingsDateFormat as any,
useComponentProps() {
const fieldSchema = useFieldSchema();
const schema = useFieldSchema();
const { fieldSchema: tableColumnSchema } = useColumnSchema();
const fieldSchema = tableColumnSchema || schema;
return {
fieldSchema,
};

View File

@ -84,8 +84,10 @@ const InternalExpiresRadio = (props) => {
);
}
return (
<Radio value={v.value} key={v.value}>
{v.label}
<Radio value={v.value} key={v.value} aria-label={v.value}>
<span role="button" aria-label={v.value}>
{v.label}
</span>
</Radio>
);
})}

View File

@ -19,7 +19,9 @@ export const SchemaSettingsDateFormat = function DateFormatConfig(props: { field
collectionField?.uiSchema?.['x-component-props']?.dateFormat ||
'YYYY-MM-DD';
const timeFormatDefaultValue =
fieldSchema?.['x-component-props']?.timeFormat || collectionField?.uiSchema?.['x-component-props']?.timeFormat;
fieldSchema?.['x-component-props']?.timeFormat ||
collectionField?.uiSchema?.['x-component-props']?.timeFormat ||
'HH:mm:ss';
return (
<SchemaSettingsModalItem
title={t('Date display format')}
@ -143,7 +145,9 @@ export const SchemaSettingsDateFormat = function DateFormatConfig(props: { field
parts.pop();
const modifiedString = parts.join('.');
field.query(`${modifiedString}.*[0:].${fieldSchema.name}`).forEach((f) => {
f.setComponentProps({ ...data });
if (f.props.name === fieldSchema.name) {
f.setComponentProps({ ...data });
}
});
dn.emit('patch', {
schema,

View File

@ -126,7 +126,7 @@ test.describe('form item & create form', () => {
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'DD/MM/YYYY' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 输入一个值,然后验证格式是否正确
@ -140,7 +140,7 @@ test.describe('form item & create form', () => {
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs().format('YYYY/MM/DD'));
).toHaveValue(dayjs().format('DD/MM/YYYY'));
});
});
@ -236,14 +236,14 @@ test.describe('form item & edit form', () => {
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'DD/MM/YYYY' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs(record.datetime).format('YYYY/MM/DD'));
).toHaveValue(dayjs(record.datetime).format('DD/MM/YYYY'));
});
});
@ -285,11 +285,11 @@ test.describe('form item & view form', () => {
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'DD/MM/YYYY' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs(record.datetime).format('YYYY/MM/DD')}`,
`datetime:${dayjs(record.datetime).format('DD/MM/YYYY')}`,
);
});
});
@ -318,10 +318,10 @@ test.describe('table column & table', () => {
await createColumnItem(page, 'datetime');
await showSettingsMenu(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('MM/DD/YY').click();
await page.getByRole('button', { name: 'DD/MM/YYYY' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('cell', { name: dayjs(records[0].datetime).format('MM/DD/YY'), exact: true }),
page.getByRole('cell', { name: dayjs(records[0].datetime).format('DD/MM/YYYY'), exact: true }),
).toBeVisible();
});
});