diff --git a/app/js/hooks/useList.ts b/app/js/hooks/useList.ts index d2c849cd..79706d6a 100644 --- a/app/js/hooks/useList.ts +++ b/app/js/hooks/useList.ts @@ -9,37 +9,46 @@ import usePagingRequest, { Pagination as RequestPagination, Refs as RequestRefs, RequestOptions as RequestInit, - Sorter, Transform } from './usePagingRequest'; import useLatestRef from './useLatestRef'; import { useCallback, useMemo } from 'react'; -import useSearches, { Search } from './useSearches'; import { GetProp, ListProps, PaginationProps } from 'antd'; -import usePagingOptions, { Options as UsePagingOptions } from './usePagingOptions'; +import useSearchFilters, { Filter } from './useSearchFilters'; +import usePagingOptions, { Options as PagingOptions } from './usePagingOptions'; export interface Fetch { (options?: RequestOptions): void; } +export interface Sorter { + orderBy: React.Key[]; + orderType: ('ascend' | 'descend')[]; +} + +type ListPropsPicked = 'dataSource' | 'pagination'; + export interface RequestOptions extends RequestInit { + filter?: Filter | false; sorter?: Sorter | false; pagination?: Pagination; } -export interface Refs extends RequestRefs { - readonly sorter: Sorter | false; -} - export type OnChange = GetProp; export interface Options extends InitOptions { pagination?: Pagination; } -export type Pagination = (UsePagingOptions & Partial) | false; +export interface Refs extends RequestRefs { + readonly filters: [filter: Filter | false, sorter: Sorter | false]; +} + +export type Pagination = (PagingOptions & Partial) | false; -export type DefaultListProps = Required, 'loading' | 'dataSource' | 'pagination'>>; +export interface DefaultListProps extends Required, ListPropsPicked>> { + loading: boolean; +} /** * @function useList @@ -79,7 +88,7 @@ export default function useList( ): [props: DefaultListProps, fetch: Fetch, dispatch: Dispatch, refs: Refs] { const opitonsRef = useLatestRef(options); const getPagingOptions = usePagingOptions(options.pagination); - const [serialize, raw] = useSearches<[Search, Sorter]>([false, false]); + const [serialize, raw] = useSearchFilters<[Filter, Sorter]>([false, false]); const [loading, dataSource, request, dispatch, originRefs] = usePagingRequest( url, @@ -88,10 +97,11 @@ export default function useList( ); const fetch: Fetch = useCallback((options = {}) => { - const { search, sorter } = options; - const query = serialize([search, sorter]); + const { filter, sorter } = options; + const { current: initOptions } = opitonsRef; + const query = { ...initOptions.query, ...serialize([filter, sorter]) }; - request({ ...opitonsRef.current, ...options, search: query }); + request({ ...opitonsRef.current, ...options, query }); }, []); const onChange = useCallback((page, pageSize) => { @@ -120,15 +130,8 @@ export default function useList( const refs = useMemo>(() => { return { - get search() { - const [search] = raw(); - - return search; - }, - get sorter() { - const [, sorter] = raw(); - - return sorter; + get filters() { + return raw(); }, get response() { return originRefs.response; @@ -139,5 +142,11 @@ export default function useList( }; }, []); - return [{ loading, dataSource, pagination }, fetch, dispatch as Dispatch, refs]; + const props: DefaultListProps = { + loading, + dataSource, + pagination + }; + + return [props, fetch, dispatch as Dispatch, refs]; } diff --git a/app/js/hooks/usePagingRequest.ts b/app/js/hooks/usePagingRequest.ts index 703789d0..8fa01611 100644 --- a/app/js/hooks/usePagingRequest.ts +++ b/app/js/hooks/usePagingRequest.ts @@ -4,7 +4,6 @@ import { App } from 'antd'; import useLatestRef from './useLatestRef'; -import useSearches, { Search } from './useSearches'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import useRequest, { Options as InitOptions, RequestOptions as RequestInit } from './useRequest'; @@ -30,13 +29,7 @@ export interface Fetch { (options?: RequestOptions): void; } -export interface Sorter { - orderBy: React.Key[]; - orderType: ('ascend' | 'descend')[]; -} - export interface Refs { - readonly search: Search | false; readonly response: Response; readonly pagination: Pagination | false; } @@ -52,7 +45,6 @@ export interface Options extends Omit>, 'bod } export interface RequestOptions extends Omit { - search?: Search | false; pagination?: Partial | false; } @@ -116,26 +108,21 @@ export default function usePagingRequest( const urlRef = useLatestRef(url); const opitonsRef = useLatestRef(options); const responseRef = useRef>({}); - const [serialize, raw] = useSearches<[Search]>([false]); const [dataSource, setDataSource] = useState([]); const paginationRef = useRef(initPagination); const [loading, request] = useRequest(options, initialLoadingState); const fetch = useCallback((options = {}) => { - const requestInit = { - ...opitonsRef.current, - ...options - }; - - const { query: initQuery } = requestInit; - const hasPagination = hasQuery(paginationRef.current); - const query: Search = { ...initQuery, ...serialize([options.search]) }; + const requestInit = { ...opitonsRef.current, ...options }; + const { current: pagination } = paginationRef; + const hasPagination = hasQuery(pagination); + const { query = {} } = requestInit; if (hasPagination) { const { page, pageSize }: Pagination = { ...DEFAULT_PAGINATION, ...initPagination, - ...paginationRef.current, + ...pagination, ...options.pagination }; @@ -196,11 +183,6 @@ export default function usePagingRequest( const refs = useMemo>(() => { return { - get search() { - const [search] = raw(); - - return search; - }, get response() { return responseRef.current; }, diff --git a/app/js/hooks/useSearchFilters.ts b/app/js/hooks/useSearchFilters.ts new file mode 100644 index 00000000..bc5b64c8 --- /dev/null +++ b/app/js/hooks/useSearchFilters.ts @@ -0,0 +1,41 @@ +/** + * @module useSearchFilters + */ + +import { useCallback, useRef } from 'react'; +import { Query as Filter } from '/js/utils/request'; + +export type { Filter }; + +export type SearchFilters = { + [K in keyof T]: T[K] extends Filter ? T[K] | false : T[K]; +}; + +/** + * @function useSearchFilters + * @description [hook] 可缓存查询过滤条件 + * @param initialValue 初始化查询过滤条件 + */ +export default function useSearchFilters( + initialValue: SearchFilters +): [serialize: (value?: Partial>) => Filter, raw: () => SearchFilters] { + const searchFiltersRef = useRef(initialValue); + + const serialize = useCallback((value?: Partial>) => { + if (value && searchFiltersRef.current !== value) { + searchFiltersRef.current = searchFiltersRef.current.map((search, index) => { + return value[index] ?? search; + }) as SearchFilters; + } + + return searchFiltersRef.current.reduce((values, value) => { + return value ? { ...values, ...value } : values; + }, {}); + }, []); + + const raw = useCallback(() => { + return searchFiltersRef.current; + }, []); + + return [serialize, raw]; +} diff --git a/app/js/hooks/useSearches.ts b/app/js/hooks/useSearches.ts deleted file mode 100644 index f0172474..00000000 --- a/app/js/hooks/useSearches.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @module useSearches - */ - -import { useCallback, useRef } from 'react'; -import { Query as Search } from '/js/utils/request'; - -export type { Search }; - -export type Searches = { - [K in keyof T]: T[K] extends Search ? T[K] | false : T[K]; -}; - -/** - * @function useSearches - * @description [hook] 可缓存查询条件 - * @param initialValue 初始化查询条件 - */ -export default function useSearches( - initialValue: Searches -): [serialize: (value?: Partial>) => Search, raw: () => Searches] { - const searchRef = useRef(initialValue); - - const serialize = useCallback((value?: Partial>) => { - if (value && searchRef.current !== value) { - searchRef.current = searchRef.current.map((search, index) => { - return value[index] ?? search; - }) as Searches; - } - - return searchRef.current.reduce((values, value) => { - return value ? { ...values, ...value } : values; - }, {}); - }, []); - - const raw = useCallback(() => { - return searchRef.current; - }, []); - - return [serialize, raw]; -} diff --git a/app/js/hooks/useTable.ts b/app/js/hooks/useTable.ts index 1e36fa32..1ccc89f0 100644 --- a/app/js/hooks/useTable.ts +++ b/app/js/hooks/useTable.ts @@ -9,41 +9,46 @@ import usePagingRequest, { Pagination as RequestPagination, Refs as RequestRefs, RequestOptions as RequestInit, - Sorter, Transform } from './usePagingRequest'; import useLatestRef from './useLatestRef'; import { GetProp, TableProps } from 'antd'; import React, { useCallback, useMemo } from 'react'; -import useSearches, { Search } from './useSearches'; +import useSearchFilters, { Filter } from './useSearchFilters'; import usePagingOptions, { Options as PagingOptions } from './usePagingOptions'; -export type Filter = Search; - export interface Fetch { (options?: RequestOptions): void; } +export interface Sorter { + orderBy: React.Key[]; + orderType: ('ascend' | 'descend')[]; +} + export interface RequestOptions extends RequestInit { filter?: Filter | false; sorter?: Sorter | false; pagination?: Pagination; } -export interface Refs extends RequestRefs { - readonly filter: Filter | false; - readonly sorter: Sorter | false; -} +export type OnChange = GetProp, 'onChange'>; export interface Options extends InitOptions { pagination?: Pagination; } -export type OnChange = GetProp, 'onChange'>; +export interface Refs extends RequestRefs { + readonly filters: [filter: Filter | false, sorter: Sorter | false]; +} + +type TablePropsPicked = 'size' | 'onChange' | 'dataSource' | 'pagination'; export type Pagination = (PagingOptions & Partial) | false; -export type DefaultTableProps = Required, 'size' | 'loading' | 'onChange' | 'dataSource' | 'pagination'>>; +export interface DefaultTableProps extends Required, TablePropsPicked>> { + loading: boolean; +} /** * @function serializeField @@ -92,7 +97,7 @@ export default function useTable( ): [props: DefaultTableProps, fetch: Fetch, dispatch: Dispatch, refs: Refs] { const opitonsRef = useLatestRef(options); const getPagingOptions = usePagingOptions(options.pagination); - const [serialize, raw] = useSearches<[Search, Filter, Sorter]>([false, false, false]); + const [serialize, raw] = useSearchFilters<[Filter, Sorter]>([false, false]); const [loading, dataSource, request, dispatch, originRefs] = usePagingRequest( url, @@ -101,10 +106,11 @@ export default function useTable( ); const fetch: Fetch = useCallback((options = {}): void => { - const { search, filter, sorter } = options; - const query = serialize([search, filter, sorter]); + const { filter, sorter } = options; + const { current: initOptions } = opitonsRef; + const query = { ...initOptions.query, ...serialize([filter, sorter]) }; - request({ ...opitonsRef.current, ...options, search: query }); + request({ ...opitonsRef.current, ...options, query }); }, []); const onChange = useCallback>((pagination, filter, sorter, { action }) => { @@ -156,20 +162,8 @@ export default function useTable( const refs = useMemo>(() => { return { - get search() { - const [search] = raw(); - - return search; - }, - get filter() { - const [, filter] = raw(); - - return filter; - }, - get sorter() { - const [, , sorter] = raw(); - - return sorter; + get filters() { + return raw(); }, get response() { return originRefs.response;