From aff559882fcc8ef1e11aaa3a0ae963d052c4eaca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A2=AB=E9=9B=A8=E6=B0=B4=E8=BF=87=E6=BB=A4=E7=9A=84?=
=?UTF-8?q?=E7=A9=BA=E6=B0=94-Rain?= <958414905@qq.com>
Date: Mon, 4 Sep 2023 16:25:49 +0800
Subject: [PATCH] fix(RangePicker): fix shortcut invalid (#2586)
* chore: upgrade antd to v5.8.4
* test: add test
* chore: fix build
* chore: upgrade @formily/antd-v5 to v1.1.1
* fix: should not close Popover when selected option
* fix: add a new Popover and to replace old Popover with new Popover
* refactor: remove useless code
* fix: fix dark theme
* chore: fix build
* chore: antd version
* fix: uniformly use the latest version of antd
---
package.json | 3 +-
packages/core/client/package.json | 8 +-
.../templates/components/PreviewFields.tsx | 4 +-
packages/core/client/src/global-theme/type.ts | 2 +-
packages/core/client/src/pm/style.ts | 3 +
.../schema-component/antd/action/Action.tsx | 3 +-
.../InternalPopoverNester.tsx | 8 +-
.../__tests__/date-picker.test.tsx | 42 +++-
.../antd/date-picker/demos/demo11.tsx | 65 +++++
.../antd/filter/FilterAction.tsx | 13 +-
.../antd/icon-picker/IconPicker.tsx | 3 +-
.../client/src/schema-component/antd/index.ts | 1 +
.../antd/input/EllipsisWithTooltip.tsx | 4 +-
.../src/schema-component/antd/page/style.ts | 3 +
.../schema-component/antd/popover/Popover.tsx | 16 ++
.../schema-component/antd/popover/index.ts | 1 +
.../antd/quick-edit/QuickEdit.tsx | 2 +-
.../charts/src/client/select/CustomSelect.tsx | 16 +-
.../src/client/GraphDrawPage.tsx | 11 +-
.../src/client/components/Entity.tsx | 7 +-
.../src/client/Localization.tsx | 3 +-
packages/plugins/mobile-client/package.json | 2 +-
.../token-panel-pro/TokenContent.tsx | 10 +-
yarn.lock | 229 +++++++++++-------
24 files changed, 323 insertions(+), 136 deletions(-)
create mode 100644 packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx
create mode 100644 packages/core/client/src/schema-component/antd/popover/Popover.tsx
create mode 100644 packages/core/client/src/schema-component/antd/popover/index.ts
diff --git a/package.json b/package.json
index 7ca10425b1..4a77e50132 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,8 @@
"react-router-dom": "^6.11.2",
"react-router": "^6.11.2",
"react": "^18.0.0",
- "react-dom": "^18.0.0"
+ "react-dom": "^18.0.0",
+ "antd": "5.8.6"
},
"config": {
"ghooks": {
diff --git a/packages/core/client/package.json b/packages/core/client/package.json
index ebf716aa9a..fae992244a 100644
--- a/packages/core/client/package.json
+++ b/packages/core/client/package.json
@@ -8,14 +8,14 @@
"dependencies": {
"@ant-design/cssinjs": "^1.11.1",
"@ant-design/icons": "^5.1.4",
- "@ant-design/pro-layout": "^7.14.3",
+ "@ant-design/pro-layout": "^7.16.11",
"@antv/g2plot": "^2.4.18",
"@ctrl/tinycolor": "^3.6.0",
"@dnd-kit/core": "^5.0.1",
"@dnd-kit/modifiers": "^6.0.0",
"@dnd-kit/sortable": "^6.0.0",
"@emotion/css": "^11.7.1",
- "@formily/antd-v5": "^1.1.0",
+ "@formily/antd-v5": "1.1.1",
"@formily/core": "^2.2.27",
"@formily/grid": "^2.2.27",
"@formily/json-schema": "^2.2.27",
@@ -30,8 +30,8 @@
"@nocobase/utils": "0.13.0-alpha.5",
"@types/requirejs": "^2.1.34",
"ahooks": "^3.7.2",
- "antd": "^5.7.3",
- "antd-style": "^3.3.0",
+ "antd": "5.8.6",
+ "antd-style": "3.x",
"axios": "^0.26.1",
"classnames": "^2.3.1",
"cron-parser": "^4.6.0",
diff --git a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx
index e6a7dc0cd0..09d063f07a 100644
--- a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx
+++ b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx
@@ -1,8 +1,6 @@
-import { Cascader } from '@formily/antd-v5';
import { useField, useForm } from '@formily/react';
-import { Input, Select, Spin, Table, Tag } from 'antd';
+import { Cascader, Input, Select, Spin, Table, Tag } from 'antd';
import { last } from 'lodash';
-import { boolean } from 'mathjs';
import React, { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ResourceActionContext, useCompile } from '../../../';
diff --git a/packages/core/client/src/global-theme/type.ts b/packages/core/client/src/global-theme/type.ts
index 014de53441..40779b727d 100644
--- a/packages/core/client/src/global-theme/type.ts
+++ b/packages/core/client/src/global-theme/type.ts
@@ -1,4 +1,4 @@
-import { MappingAlgorithm } from 'antd/es/config-provider/context';
+import { MappingAlgorithm } from 'antd-style';
import { OverrideToken } from 'antd/es/theme/interface';
import { AliasToken } from 'antd/es/theme/internal';
diff --git a/packages/core/client/src/pm/style.ts b/packages/core/client/src/pm/style.ts
index 5d5790b18e..dc1ddd4167 100644
--- a/packages/core/client/src/pm/style.ts
+++ b/packages/core/client/src/pm/style.ts
@@ -11,6 +11,9 @@ export const useStyles = createStyles(({ token }) => {
'& .ant-tabs-nav': {
marginBottom: 0,
},
+ '.ant-page-header-heading-title': {
+ color: token.colorText,
+ },
},
pageContent: {
diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx
index 1f75d11c65..bcea781d6a 100644
--- a/packages/core/client/src/schema-component/antd/action/Action.tsx
+++ b/packages/core/client/src/schema-component/antd/action/Action.tsx
@@ -1,5 +1,5 @@
import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react';
-import { App, Button, Popover } from 'antd';
+import { App, Button } from 'antd';
import classnames from 'classnames';
import lodash from 'lodash';
import React, { useEffect, useState } from 'react';
@@ -11,6 +11,7 @@ import { useRecord } from '../../../record-provider';
import { SortableItem } from '../../common';
import { useCompile, useComponent, useDesigner } from '../../hooks';
import { useProps } from '../../hooks/useProps';
+import { Popover } from '../popover';
import ActionContainer from './Action.Container';
import { ActionDesigner } from './Action.Designer';
import { ActionDrawer } from './Action.Drawer';
diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx
index ec090f5c91..7b68398587 100644
--- a/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx
+++ b/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx
@@ -1,13 +1,13 @@
-import { Popover } from 'antd';
-import { css } from '@emotion/css';
import { EditOutlined } from '@ant-design/icons';
+import { css } from '@emotion/css';
import { observer } from '@formily/react';
import React, { useContext, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
-import { ReadPrettyInternalViewer } from './InternalViewer';
+import { ActionContext, ActionContextProvider } from '../action/context';
+import { Popover } from '../popover';
import { InternalNester } from './InternalNester';
+import { ReadPrettyInternalViewer } from './InternalViewer';
import { useAssociationFieldContext } from './hooks';
-import { ActionContextProvider, ActionContext } from '../action/context';
export const InternaPopoverNester = observer(
(props) => {
diff --git a/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx b/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx
index 95ab97a60e..6f9a07d020 100644
--- a/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx
+++ b/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import { render, screen, sleep, userEvent, waitFor } from 'testUtils';
import App1 from '../demos/demo1';
+import App11 from '../demos/demo11';
import App2 from '../demos/demo2';
import App3 from '../demos/demo3';
import App4 from '../demos/demo4';
@@ -68,8 +69,11 @@ describe('DatePicker', () => {
await userEvent.click(picker);
await userEvent.type(input, '2023/05/01');
- const selected = document.querySelector('.ant-picker-cell-selected') as HTMLElement;
- expect(selected).toBeInTheDocument();
+ let selected;
+ await waitFor(() => {
+ selected = document.querySelector('.ant-picker-cell-selected') as HTMLElement;
+ expect(selected).toBeInTheDocument();
+ });
await userEvent.click(selected);
expect(input).toHaveValue('2023/05/01');
@@ -138,15 +142,20 @@ describe('RangePicker', () => {
const endInput = getByPlaceholderText('End date');
await userEvent.click(picker);
+ await sleep();
await userEvent.click(document.querySelector('[title="2023-05-01"]') as HTMLElement);
await userEvent.click(document.querySelector('[title="2023-05-02"]') as HTMLElement);
- expect(startInput).toHaveValue('2023-05-01');
- expect(endInput).toHaveValue('2023-05-02');
+ await waitFor(() => expect(startInput).toHaveValue('2023-05-01'));
+ await waitFor(() => expect(endInput).toHaveValue('2023-05-02'));
+
// Read pretty
- expect(screen.getByText('2023-05-01~2023-05-02', { selector: '.ant-description-text' })).toBeInTheDocument();
+ await waitFor(() =>
+ expect(screen.getByText('2023-05-01~2023-05-02', { selector: '.ant-description-text' })).toBeInTheDocument(),
+ );
+
// Value
- expect(screen.getByText('2023-05-01 ~ 2023-05-02')).toBeInTheDocument();
+ await waitFor(() => expect(screen.getByText('2023-05-01 ~ 2023-05-02')).toBeInTheDocument());
});
it('showTime=false,gmt=true,utc=true', async () => {
@@ -219,4 +228,25 @@ describe('RangePicker', () => {
expect(screen.getByText(`${currentDateString}T00:00:00.000Z`)).toBeInTheDocument();
});
});
+
+ // fix T-1506
+ it('shortcut', async () => {
+ const { container } = render();
+
+ await sleep();
+
+ const picker = container.querySelector('.ant-picker') as HTMLElement;
+ const startInput = screen.getByPlaceholderText('Start date');
+ const endInput = screen.getByPlaceholderText('End date');
+
+ await userEvent.click(picker);
+
+ // shortcut: Today
+ await userEvent.click(screen.getByText(/today/i));
+ await sleep();
+
+ // 因为 Today 快捷键的值是动态生成的,所以这里没有断言具体的值
+ await waitFor(() => expect(startInput.getAttribute('value')).toBeTruthy());
+ await waitFor(() => expect(endInput.getAttribute('value')).toBeTruthy());
+ });
});
diff --git a/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx b/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx
new file mode 100644
index 0000000000..1cd60ac4d6
--- /dev/null
+++ b/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx
@@ -0,0 +1,65 @@
+/**
+ * title: DatePicker.RangePicker
+ */
+import { FormItem } from '@formily/antd-v5';
+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.RangePicker',
+ 'x-component-props': {
+ gmt: true,
+ },
+ 'x-reactions': [
+ {
+ target: 'read1',
+ fulfill: {
+ state: {
+ value: '{{$self.value}}',
+ },
+ },
+ },
+ {
+ target: 'read2',
+ fulfill: {
+ state: {
+ value: '{{$self.value && $self.value.join(" ~ ")}}',
+ },
+ },
+ },
+ ],
+ },
+ read1: {
+ type: 'boolean',
+ title: `Read pretty`,
+ 'x-read-pretty': true,
+ 'x-decorator': 'FormItem',
+ 'x-component': 'DatePicker.RangePicker',
+ 'x-component-props': {
+ gmt: true,
+ },
+ },
+ read2: {
+ type: 'string',
+ title: `Value`,
+ 'x-read-pretty': true,
+ 'x-decorator': 'FormItem',
+ 'x-component': 'Input',
+ 'x-component-props': {},
+ },
+ },
+};
+
+export default () => {
+ return (
+
+
+
+ );
+};
diff --git a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx
index 2faac33c20..2edc93f6a5 100644
--- a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx
+++ b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx
@@ -1,13 +1,14 @@
import { css } from '@emotion/css';
import { createForm, Field, Form } from '@formily/core';
import { observer, useField, useFieldSchema, useForm } from '@formily/react';
-import { Button, Popover, Space } from 'antd';
-import React, { createContext, useContext, useMemo, useState } from 'react';
+import { Button, Space } from 'antd';
+import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FormProvider, SchemaComponent } from '../../core';
import { useDesignable } from '../../hooks';
import { useProps } from '../../hooks/useProps';
import { Action } from '../action';
+import { Popover } from '../popover';
export const FilterActionContext = createContext(null);
@@ -20,15 +21,17 @@ export const FilterAction = observer(
const fieldSchema = useFieldSchema();
const form = useMemo