import { ReactNode } from 'react'
import { Table as RawTable } from 'antd'
import { tryAddKeys } from './EditableTable'
import { makeNumericSorter, makeStringSorter} from './sorters'
export { makeDateSorter, makeNumericSorter, makeStringSorter} from './sorters'
export { EditableTable } from './EditableTable'
export { DatePickerWrapper } from './DatePickerWrapper'
export { SelectFromDictionary } from './SelectFromDictionary'
export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/
export const formatDate='YYYY.MM.DD HH:mm'
export const makeNumericRender = (fixed?:number) => (value: any, row: object): ReactNode => {
const placeholder = '-'
let val = placeholder
if((value !== null) &&
(value !== undefined) &&
!Number.isNaN(value) &&
Number.isFinite(value)){
val = !!fixed
? (+value).toFixed(fixed)
: (+value).toPrecision(5)
}
return (
{val}
)
}
export const makeNumericColumnOptions = (fixed?:number, sorterKey?:string ) => ({
editable: true,
initialValue: 0,
width:100,
sorter: sorterKey? makeNumericSorter(sorterKey) : null,
formItemRules: [
{
required: true,
message: `Введите число`,
pattern: RegExpIsFloat,
},
],
render: makeNumericRender(fixed),
})
/*
other - объект с дополнительными свойствами колонки
поддерживаются все базовые свойства из описания https://ant.design/components/table/#Column
плю дополнительные для колонок EditableTable: */
interface columnPropsOther {
// редактируемая колонка
editable?: boolean
// react компонента редактора
input?: ReactNode
// значение может быть пустым
isRequired?: boolean
// css класс для , если требуется
formItemClass?: string
// массив правил валидации значений https://ant.design/components/form/#Rule
formItemRules?: any[]
// дефолтное значение при добавлении новой строки
initialValue?: string|number
}
export const makeColumn = (title:string | ReactNode, key:string, other?:columnPropsOther) => ({
title: title,
key: key,
dataIndex: key,
...other,
})
export const makeColumnsPlanFact = (title:string | ReactNode, key:string|string[], columsOther?:any|any[], gruopOther?:any) =>
{
let keyPlanLocal = key
let keyFactLocal = key
if(key instanceof Array){
keyPlanLocal = key[0]
keyFactLocal = key[1]
}else{
keyPlanLocal = key + 'Plan'
keyFactLocal = key + 'Fact'
}
let columsOtherLoacl :any[2]
if(columsOther instanceof Array)
columsOtherLoacl = [columsOther[0], columsOther[1]]
else
columsOtherLoacl = [columsOther, columsOther]
return {
title: title,
...gruopOther,
children: [
makeColumn('план', keyPlanLocal, columsOtherLoacl[0]),
makeColumn('факт', keyFactLocal, columsOtherLoacl[1]),
]
}
}
export const makeFilterTextMatch = (key: string | number) => (filterValue: string | number, dataItem: any) =>
dataItem[key] === filterValue
export const makeGroupColumn = (title: string, children: object[]) => ({
title: title,
children: children,
})
export const makeTextColumn = (
title: string,
dataIndex: string,
filters: object[],
sorter?: (key: string) => any,
render?: any,
other?: any) => ({
title: title,
dataIndex: dataIndex,
key: dataIndex,
filters: filters,
onFilter: filters ? makeFilterTextMatch(dataIndex) : null,
sorter: sorter ?? makeStringSorter(dataIndex),
render: render,
...other
})
export const makeNumericColumn = (title: string, dataIndex: string,
filters: object[], filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any, width: string, other?: columnPropsOther) => ({
title: title,
dataIndex: dataIndex,
key: dataIndex,
filters: filters,
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
sorter: makeNumericSorter(dataIndex),
width: width,
render: renderDelegate??makeNumericRender(),
align: 'right',
...other
})
export const makeNumericColumnPlanFact = (title: string, dataIndex: string, filters: object[],
filterDelegate: (key: string | number) => any, renderDelegate: (_: any, row: object) => any, width: string) =>
makeGroupColumn( title, [
makeNumericColumn('п', dataIndex + 'Plan', filters, filterDelegate, renderDelegate, width),
makeNumericColumn('ф', dataIndex + 'Fact', filters, filterDelegate, renderDelegate, width),
])
export const makeNumericStartEnd = (
title: string,
dataIndex: string,
fixed: number,
filters: object[],
filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any,
width: string,
) => makeGroupColumn( title, [
makeNumericColumn('старт', dataIndex + 'Start', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Start')),
makeNumericColumn('конец', dataIndex + 'End', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'End'))
])
export const makeNumericAvgRange = (
title: string,
dataIndex: string,
fixed: number,
filters: object[],
filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any,
width: string
) => makeGroupColumn( title, [
makeNumericColumn('мин', dataIndex + 'Min', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Min')),
makeNumericColumn('сред', dataIndex + 'Avg', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Avg')),
makeNumericColumn('макс', dataIndex + 'Max', filters, filterDelegate, renderDelegate, width, makeNumericColumnOptions(fixed, dataIndex + 'Max'))
])
type PaginationContainer = {
skip?: number;
take?: number;
count?: number;
items?: any[] | null;
}
export const makePaginationObject = (paginationContainer:PaginationContainer, ...other:any) => {
let page = 1 + Math.floor((paginationContainer.skip??0) /(paginationContainer.take??1));
return {
...other,
pageSize: paginationContainer.take,
total: paginationContainer.count ?? paginationContainer.items?.length ?? 0,
current: page,
}
}
interface TableContainer {
dataSource: any[];
children?: any;
}
export const Table = ({dataSource, children, ...other}: TableContainer) => {
return {children}
}