Исправлена типизация методов работы с колонками таблиц

This commit is contained in:
goodmice 2022-10-06 14:37:07 +05:00
parent 336fe6e0d4
commit 39c1289d32
No known key found for this signature in database
GPG Key ID: 63EA771203189CF1
4 changed files with 56 additions and 57 deletions

View File

@ -30,7 +30,7 @@ export type DataType<T = any> = Record<string, T>
export type RenderMethod<T = any> = (value: T, dataset?: DataType<T>, index?: number) => ReactNode export type RenderMethod<T = any> = (value: T, dataset?: DataType<T>, index?: number) => ReactNode
export type SorterMethod<T = any> = (a?: DataType<T> | null, b?: DataType<T> | null) => number export type SorterMethod<T = any> = (a?: DataType<T> | null, b?: DataType<T> | null) => number
export type columnPropsOther<T = any> = ColumnProps<T> & { export type columnPropsOther<T = any> = ColumnProps<DataType<T>> & {
// редактируемая колонка // редактируемая колонка
editable?: boolean editable?: boolean
// react компонента редактора // react компонента редактора

View File

@ -2,11 +2,14 @@ import { InputNumber } from 'antd'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import { makeNumericSorter } from '../sorters' import { makeNumericSorter } from '../sorters'
import { columnPropsOther, makeGroupColumn, RenderMethod } from '.' import makeColumn, { columnPropsOther, DataType, makeGroupColumn, RenderMethod } from '.'
import { ColumnFilterItem, CompareFn } from 'antd/lib/table/interface'
export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/ export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/
export const makeNumericRender = <T extends unknown>(fixed?: number): RenderMethod<T> => (value) => { type FilterMethod<T> = (value: string | number | boolean, record: DataType<T>) => boolean
export const makeNumericRender = <T extends unknown>(fixed?: number): RenderMethod<T> => (value: T) => {
let val = '-' let val = '-'
if ((value ?? null) !== null && Number.isFinite(+value)) { if ((value ?? null) !== null && Number.isFinite(+value)) {
val = (fixed ?? null) !== null val = (fixed ?? null) !== null
@ -21,77 +24,74 @@ export const makeNumericRender = <T extends unknown>(fixed?: number): RenderMeth
) )
} }
export const makeNumericColumnOptions = (fixed?: number, sorterKey?: string): columnPropsOther => ({ export const makeNumericColumnOptions = <T extends unknown = any>(fixed?: number, sorterKey?: string): columnPropsOther<T> => ({
editable: true, editable: true,
initialValue: 0, initialValue: 0,
width: 100, width: 100,
sorter: sorterKey ? makeNumericSorter(sorterKey) : undefined, sorter: sorterKey ? makeNumericSorter<T>(sorterKey) : undefined,
formItemRules: [{ formItemRules: [{
required: true, required: true,
message: 'Введите число', message: 'Введите число',
pattern: RegExpIsFloat, pattern: RegExpIsFloat,
}], }],
render: makeNumericRender(fixed), render: makeNumericRender<T>(fixed),
}) })
export const makeNumericColumn = ( export const makeNumericColumn = <T extends unknown = any>(
title: ReactNode, title: ReactNode,
dataIndex: string, key: string,
filters: object[], filters?: ColumnFilterItem[],
filterDelegate: (key: string | number) => any, filterDelegate?: (key: string | number) => FilterMethod<T>,
renderDelegate: (_: any, row: object) => any, renderDelegate?: RenderMethod<T>,
width: string, width?: string | number,
other?: columnPropsOther other?: columnPropsOther,
) => ({ ) => makeColumn(title, key, {
title: title, filters,
dataIndex: dataIndex, onFilter: filterDelegate ? filterDelegate(key) : undefined,
key: dataIndex, sorter: makeNumericSorter(key),
filters: filters, width,
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
sorter: makeNumericSorter(dataIndex),
width: width,
input: <InputNumber style={{ width: '100%' }}/>, input: <InputNumber style={{ width: '100%' }}/>,
render: renderDelegate ?? makeNumericRender(), render: renderDelegate ?? makeNumericRender<T>(2),
align: 'right', align: 'right',
...other ...other
}) })
export const makeNumericColumnPlanFact = ( export const makeNumericColumnPlanFact = <T extends unknown = any>(
title: ReactNode, title: ReactNode,
dataIndex: string, key: string,
filters: object[], filters?: ColumnFilterItem[],
filterDelegate: (key: string | number) => any, filterDelegate?: (key: string | number) => FilterMethod<T>,
renderDelegate: (_: any, row: object) => any, renderDelegate?: RenderMethod<T>,
width: string width?: string | number
) => makeGroupColumn(title, [ ) => makeGroupColumn(title, [
makeNumericColumn('п', dataIndex + 'Plan', filters, filterDelegate, renderDelegate, width), makeNumericColumn<T>('п', key + 'Plan', filters, filterDelegate, renderDelegate, width),
makeNumericColumn('ф', dataIndex + 'Fact', filters, filterDelegate, renderDelegate, width), makeNumericColumn<T>('ф', key + 'Fact', filters, filterDelegate, renderDelegate, width),
]) ])
export const makeNumericStartEnd = ( export const makeNumericStartEnd = <T extends unknown = any>(
title: ReactNode, title: ReactNode,
dataIndex: string, key: string,
fixed: number, fixed: number,
filters: object[], filters?: ColumnFilterItem[],
filterDelegate: (key: string | number) => any, filterDelegate?: (key: string | number) => FilterMethod<T>,
renderDelegate: (_: any, row: object) => any, renderDelegate?: RenderMethod<T>,
width: string, width?: string | number,
) => makeGroupColumn(title, [ ) => makeGroupColumn(title, [
makeNumericColumn('старт', dataIndex + 'Start', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Start')), makeNumericColumn<T>('старт', key + 'Start', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Start')),
makeNumericColumn('конец', dataIndex + 'End', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'End')) makeNumericColumn<T>('конец', key + 'End', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'End'))
]) ])
export const makeNumericMinMax = ( export const makeNumericMinMax = <T extends unknown = any>(
title: ReactNode, title: ReactNode,
dataIndex: string, key: string,
fixed: number, fixed: number,
filters: object[], filters?: ColumnFilterItem[],
filterDelegate: (key: string | number) => any, filterDelegate?: (key: string | number) => FilterMethod<T>,
renderDelegate: (_: any, row: object) => any, renderDelegate?: RenderMethod<T>,
width: string, width?: string | number,
) => makeGroupColumn(title, [ ) => makeGroupColumn(title, [
makeNumericColumn('мин', dataIndex + 'Min', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Min')), makeNumericColumn<T>('мин', key + 'Min', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Min')),
makeNumericColumn('макс', dataIndex + 'Max', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Max')), makeNumericColumn<T>('макс', key + 'Max', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, key + 'Max')),
]) ])
export default makeNumericColumn export default makeNumericColumn

View File

@ -1,6 +1,7 @@
import { ColumnFilterItem } from 'antd/lib/table/interface'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import { columnPropsOther, DataType, RenderMethod, SorterMethod } from '.' import makeColumn, { columnPropsOther, DataType, RenderMethod, SorterMethod } from '.'
import { makeStringSorter } from '../sorters' import { makeStringSorter } from '../sorters'
export const makeFilterTextMatch = <T extends unknown>(key: keyof DataType<T>) => export const makeFilterTextMatch = <T extends unknown>(key: keyof DataType<T>) =>
@ -8,18 +9,15 @@ export const makeFilterTextMatch = <T extends unknown>(key: keyof DataType<T>) =
export const makeTextColumn = <T extends unknown = any>( export const makeTextColumn = <T extends unknown = any>(
title: ReactNode, title: ReactNode,
dataIndex: string, key: string,
filters: object[], filters?: ColumnFilterItem[],
sorter?: SorterMethod<T>, sorter?: SorterMethod<T>,
render?: RenderMethod<T>, render?: RenderMethod<T>,
other?: columnPropsOther other?: columnPropsOther
) => ({ ) => makeColumn(title, key, {
title: title, filters,
dataIndex: dataIndex, onFilter: filters ? makeFilterTextMatch(key) : undefined,
key: dataIndex, sorter: sorter ?? makeStringSorter(key),
filters: filters,
onFilter: filters ? makeFilterTextMatch(dataIndex) : null,
sorter: sorter ?? makeStringSorter(dataIndex),
render: render, render: render,
...other ...other
}) })

View File

@ -3,8 +3,9 @@ import { isRawDate } from '@utils'
import { TimeDto } from '@api' import { TimeDto } from '@api'
import { DataType } from './Columns' import { DataType } from './Columns'
import { CompareFn } from 'antd/lib/table/interface'
export const makeNumericSorter = <T extends unknown>(key: keyof DataType<T>) => export const makeNumericSorter = <T extends unknown>(key: keyof DataType<T>): CompareFn<DataType<T>> =>
(a: DataType<T>, b: DataType<T>) => Number(a[key]) - Number(b[key]) (a: DataType<T>, b: DataType<T>) => Number(a[key]) - Number(b[key])
export const makeNumericObjSorter = (key: [string, string]) => export const makeNumericObjSorter = (key: [string, string]) =>