Skip to content

Commit

Permalink
feat: add useFormTable
Browse files Browse the repository at this point in the history
  • Loading branch information
brickspert committed Feb 6, 2020
1 parent c2aac01 commit bfc804a
Show file tree
Hide file tree
Showing 25 changed files with 1,123 additions and 36 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/node-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: npm intall, build, and test
run: |
npm install
npm run bootstrap
npm run build
npm run init
npm run test
env:
CI: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ coverage
.umi
page
lerna-debug.log
tsconfig.tsbuildinfo
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"start": "npm run dev",
"dev": "father-doc dev",
"bootstrap": "lerna bootstrap",
"clean": "lerna clean",
"compile": "tsc -b packages/use-request packages/hooks",
"build": "father build && npm run compile",
"clean": "lerna clean --yes",
"compile": "lerna run --scope @umijs/use-request compile && lerna run --scope @umijs/hooks compile",
"build": "node ./scripts/clean-old-build.js && father build && npm run compile && node ./scripts/build-wind-up.js",
"test": "father test",
"cov": "father test --coverage",
"help": "father help",
Expand All @@ -33,6 +33,7 @@
"now": "^16.2.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"typescript": "^3.3.3"
"typescript": "^3.3.3",
"umi-request": "^1.2.18"
}
}
2 changes: 1 addition & 1 deletion packages/hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"repository": "https://github.com/umijs/hooks",
"homepage": "https://github.com/umijs/hooks",
"scripts": {
"build": "node ./scripts/clean-old-build.js && father build && node ./scripts/build-wind-up.js"
"compile": "tsc --declarationDir lib && tsc --declarationDir es"
},
"files": [
"dist",
Expand Down
4 changes: 3 additions & 1 deletion packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import useInViewport from './useInViewport';
import useKeyPress from './useKeyPress';
import useEventListener from './useEventListener';
import useHover from './useHover';
import useFormTable from './useFormTable';

const useControlledValue: typeof useControllableValue = function (...args) {
console.warn(
Expand Down Expand Up @@ -75,5 +76,6 @@ export {
useKeyPress,
useEventListener,
useHover,
useRequest
useRequest,
useFormTable
};
2 changes: 1 addition & 1 deletion packages/hooks/src/useAntdTable/demo/demo2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { Table } from 'antd';
import React from 'react';
import { useAntdTable } from '@umijs/hooks'
import {FnParams} from '@umijs/hooks/es/useAntdTable';
import { FnParams } from '@umijs/hooks/es/useAntdTable';

interface Item {
name: {
Expand Down
10 changes: 8 additions & 2 deletions packages/hooks/src/useAntdTable/index.en-US.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
---
title: useAntdTable
group:
title: Async Hooks
path: /async
title: Deprecated
path: /deprecated
---

# useAntdTable

<div style={{color: 'red'}}>
WARNING: useAntdTable is deprecated and will be removed in the next major version. <br />
Simple AntD Table(<a href="#default-usage">demo1</a>, <a href="#filter-and-sorter">demo2</a>, <a href="#table-with-filter-and-pager">demo3</a>),you can use <a href="https://hooks.umijs.org/async?anchor=pagination">useRequest pagination mode</a> instead. <br />
Complex AntD Table with Form(<a href="#search-form-and-table-data-binding">demo4</a>, <a href="#data-cache">demo5</a>),you can use useFormTable instead.
</div>

Encapsulates common logic to make it easier to manage [Antd Table](https://ant.design/components/table/)

**Core Characteristics**
Expand Down
10 changes: 8 additions & 2 deletions packages/hooks/src/useAntdTable/index.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
---
title: useAntdTable
group:
title: Async Hooks
path: /async
title: Deprecated
path: /deprecated
---


# useAntdTable

<div style={{color: 'red'}}>
警告: useAntdTable 已经被废弃了,将在下一个大版本时移除。<br />
一般的 AntD Table(<a href="#基本用法">demo1</a>, <a href="#排序与筛选">demo2</a>, <a href="#带筛选和分页器的-table">demo3</a>),你可以使用 <a href="https://hooks.umijs.org/async?anchor=pagination">useRequest 分页模式</a>代替。<br />
复杂的与 Form 联动的 Table(<a href="#搜索表单与列表联动">demo4</a>, <a href="#数据缓存">demo5</a>),你可以使用 useFormTable 代替。
</div>

封装了常用的逻辑,让你更轻松的管理 [Antd Table](https://ant.design/components/table/)

**核心特性**
Expand Down
262 changes: 262 additions & 0 deletions packages/hooks/src/useFormTable/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks';
import useFormTable, { BaseOptions, Result } from '../index';

interface Query {
current: number;
pageSize: number;
[key: string]: any;
}

describe('useFormTable', () => {
const originalError = console.error;
beforeAll(() => {
console.error = (...args: any) => {
if (/Warning.*not wrapped in act/.test(args[0])) {
return;
}
originalError.call(console, ...args);
};
});
afterAll(() => {
console.error = originalError;
});
// jest.useFakeTimers();
let queryArgs: any;
const asyncFn = (query: Query, formData: any = {}) => {
queryArgs = { ...query, ...formData };
return Promise.resolve({
current: query.current,
total: 20,
pageSize: query.pageSize,
data: [],
});
};

let searchType = 'simple';

const form: any = {
initialValue: {
name: 'default name',
},
fieldsValue: {
name: 'default name',
},
getFieldsValue() {
return this.fieldsValue;
},
getFieldInstance(key: string) {
// 根据不同的 type 返回不同的 fieldsValues
if (searchType === 'simple') {
return ['name'].includes(key);
}
return ['name', 'email', 'phone'].includes(key);
},
setFieldsValue(values: object) {
this.fieldsValue = {
...this.fieldsValue,
...values
};
},
resetFields() {
this.fieldsValue = { ...this.initialValue };
},
};

const changeSearchType = (type: any) => {
searchType = type;
};

const setUp = ({ asyncFn: fn, options }: any) =>
renderHook(() => useFormTable(fn, options));

let hook: RenderHookResult<
{ func: (...args: any[]) => Promise<{}>; opt: BaseOptions<any> },
Result<any>
>;

it('should be defined', () => {
expect(useFormTable).toBeDefined();
});

it('should fetch after first render', async () => {
queryArgs = undefined;
act(() => {
hook = setUp({
asyncFn,
options: { form },
});
});
await hook.waitForNextUpdate();
expect(hook.result.current.tableProps.loading).toEqual(false);
expect(hook.result.current.tableProps.pagination.current).toEqual(1);
expect(hook.result.current.tableProps.pagination.pageSize).toEqual(10);
expect(hook.result.current.tableProps.pagination.total).toEqual(20);
});
it('should form, defaultPageSize, id work', async () => {
queryArgs = undefined;
act(() => {
hook = setUp({
asyncFn,
options: { form, defaultPageSize: 5, cacheKey: 'tableId' },
});
});
await hook.waitForNextUpdate();
const { search } = hook.result.current;
expect(hook.result.current.tableProps.loading).toEqual(false);
expect(queryArgs.current).toEqual(1);
expect(queryArgs.pageSize).toEqual(5);
expect(queryArgs.name).toEqual('default name');
expect(search).toBeDefined();
if (search) {
expect(search.type).toEqual('simple');
}

// /* 切换 分页 */
act(() => {
hook.result.current.tableProps.onChange({
current: 2,
pageSize: 5,
});
});
await hook.waitForNextUpdate();
expect(queryArgs.current).toEqual(2);
expect(queryArgs.pageSize).toEqual(5);
expect(queryArgs.name).toEqual('default name');

/* 改变 name, 提交表单 */
form.fieldsValue.name = 'change name';
act(() => {
if (search) {
search.submit();
}
});
await hook.waitForNextUpdate();
expect(queryArgs.current).toEqual(1);
expect(queryArgs.pageSize).toEqual(5);
expect(queryArgs.name).toEqual('change name');

// /* 切换 searchType 到 advance */
act(() => {
if (search) {
search.changeType();
changeSearchType('advance');
}
});
if (hook.result.current.search) {
expect(hook.result.current.search.type).toEqual('advance');
}
act(() => {
if (hook.result.current.search) {
hook.result.current.search.submit();
}
});
await hook.waitForNextUpdate();

expect(queryArgs.current).toEqual(1);
expect(queryArgs.name).toEqual('change name');

// /* 手动改变其他两个字段的值 */
form.fieldsValue.phone = '13344556677';
form.fieldsValue.email = 'x@qq.com';

act(() => {
if (hook.result.current.search) {
hook.result.current.search.submit();
}
});
await hook.waitForNextUpdate();
expect(queryArgs.current).toEqual(1);
expect(queryArgs.name).toEqual('change name');
expect(queryArgs.phone).toEqual('13344556677');
expect(queryArgs.email).toEqual('x@qq.com');

// /* 改变 name,但是不提交,切换到 simple 去 */
form.fieldsValue.name = 'change name 2';
act(() => {
if (hook.result.current.search) {
hook.result.current.search.changeType();
changeSearchType('simple');
}
});

if (hook.result.current.search) {
expect(hook.result.current.search.type).toEqual('simple');
}
expect(form.fieldsValue.name).toEqual('change name 2');

// /* 提交 */
act(() => {
if (hook.result.current.search) {
hook.result.current.search.submit();
}
});
await hook.waitForNextUpdate();

expect(queryArgs.name).toEqual('change name 2');
expect(queryArgs.phone).toBeUndefined();
expect(queryArgs.email).toBeUndefined();

// /* 切换回 advance,恢复之前的条件 */
act(() => {
if (hook.result.current.search) {
hook.result.current.search.changeType();
}
changeSearchType('advance');
});

if (hook.result.current.search) {
expect(hook.result.current.search.type).toEqual('advance');
}
expect(form.fieldsValue.name).toEqual('change name 2');
expect(form.fieldsValue.phone).toEqual('13344556677');
expect(form.fieldsValue.email).toEqual('x@qq.com');

act(() => {
hook.result.current.tableProps.onChange({
current: 3,
pageSize: 5,
});
});
await hook.waitForNextUpdate();
// /* 卸载重装 */
form.fieldsValue = {
name: '',
phone: '',
email: '',
};
act(() => {
hook.unmount();
});
act(() => {
hook = setUp({
asyncFn,
options: { form, defaultPageSize: 5, cacheKey: 'tableId' },
});
});
await hook.waitForNextUpdate();
if (hook.result.current.search) {
expect(hook.result.current.search.type).toEqual('simple');
}
expect(hook.result.current.tableProps.pagination.current).toEqual(3);
expect(form.fieldsValue.name).toEqual('change name 2');
expect(form.fieldsValue.phone).toEqual('13344556677');
expect(form.fieldsValue.email).toEqual('x@qq.com');

/* refresh */
act(() => {
hook.result.current.refresh();
});
expect(hook.result.current.tableProps.loading).toEqual(true);
await hook.waitForNextUpdate();
/* reset */
act(() => {
if (hook.result.current.search) {
hook.result.current.search.reset();
}
});

expect(form.fieldsValue.name).toEqual('default name');
expect(form.fieldsValue.phone).toBeUndefined();
expect(form.fieldsValue.email).toBeUndefined();
});
});
Loading

0 comments on commit bfc804a

Please sign in to comment.