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} }