asb_cloud_front/src/components/Table/index.ts

199 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ReactNode } from 'react'
export { Table } from 'antd'
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 numericColumnOptions = {
editable: true,
initialValue: 0,
width:100,
formItemRules: [
{
required: true,
message: `Введите число`,
pattern: RegExpIsFloat,
},
],
};
/*
other - объект с дополнительными свойствами колонки
поддерживаются все базовые свойства из описания https://ant.design/components/table/#Column
плю дополнительные для колонок EditableTable: */
interface columnPropsOther {
// редактируемая колонка
editable?: boolean
// react компонента редактора
input?: ReactNode
// значение может быть пустым
isRequired?: boolean
// css класс для <FormItem/>, если требуется
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 makeNumericSorter = (key: string) => (a: any, b: any) => a[key] - b[key]
export const makeStringSorter = (key: string) => (a: any, b: any) =>
{
if(a == null && b == null)
return 1
if(a == null)
return 1
if(b == null)
return -1
let aValue = a[key]
let bValue = b[key]
for (let i = 0; i < a.length; i++) {
if (isNaN(aValue.charCodeAt(i)) || (aValue.charCodeAt(i) > bValue.charCodeAt(i)))
return 1
if (aValue.charCodeAt(i) > bValue.charCodeAt(i))
return -1
}
return 0
}
export const makeDateSorter = (key: string) => (a: any, b: any) => {
const date = new Date(a[key])
if(Number.isNaN(date.getTime()))
throw new Error('Date column contains not date formatted string(s)')
return date.getTime() - new Date(b[key]).getTime()
}
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 defaultNumericRender = (value: any, row: object) => {
const placeholder = '-'
if((value === null) ||
(value === undefined) ||
Number.isNaN(value) ||
!Number.isFinite(value))
return placeholder
return (+value).toPrecision(5)
}
export const makeNumericColumn = (title: string, dataIndex: string,
filters: object[], filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any, width: string) => ({
title: title,
dataIndex: dataIndex,
key: dataIndex,
filters: filters,
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
sorter: makeNumericSorter(dataIndex),
width: width,
render: renderDelegate??defaultNumericRender,
align: 'right'
})
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 makeNumericAvgRange = (
title: string,
dataIndex: string,
filters: object[],
filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any,
width: string
) => makeGroupColumn( title, [
makeNumericColumn('мин', dataIndex + 'Min', filters, filterDelegate, renderDelegate, width),
makeNumericColumn('макс', dataIndex + 'Max', filters, filterDelegate, renderDelegate, width),
makeNumericColumn('сред', dataIndex + 'Avg', filters, filterDelegate, renderDelegate, width)
])
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,
}
}