asb_cloud_front/src/components/Table/index.ts

186 lines
5.3 KiB
TypeScript
Raw Normal View History

import { ReactNode } from 'react'
2021-08-20 12:31:24 +05:00
export { Table } from 'antd'
export { EditableTable } from './EditableTable'
export { DatePickerWrapper } from './DatePickerWrapper'
2021-08-20 12:31:24 +05:00
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,
},
],
};
2021-08-30 10:04:44 +05:00
/*
other - объект с дополнительными свойствами колонки
поддерживаются все базовые свойства из описания https://ant.design/components/table/#Column
2021-08-30 10:04:44 +05:00
плю дополнительные для колонок EditableTable: */
interface columnPropsOther {
// редактируемая колонка
editable?: boolean
// react компонента редактора
input?: ReactNode
2021-08-30 10:04:44 +05:00
// значение может быть пустым
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
2021-08-30 12:39:46 +05:00
export const makeNumericSorter = (key: string) => (a: any, b: any) => a[key] - b[key]
2021-08-30 12:39:46 +05:00
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]
2021-08-30 12:39:46 +05:00
for (let i = 0; i < a.length; i++) {
if (isNaN(aValue.charCodeAt(i)) || (aValue.charCodeAt(i) > bValue.charCodeAt(i)))
2021-08-30 12:39:46 +05:00
return 1
if (aValue.charCodeAt(i) > bValue.charCodeAt(i))
2021-08-30 12:39:46 +05:00
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()
}
2021-08-30 12:39:46 +05:00
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) => ({
2021-08-30 12:39:46 +05:00
title: title,
dataIndex: dataIndex,
key: dataIndex,
filters: filters,
onFilter: filters ? makeFilterTextMatch(dataIndex) : null,
sorter: sorter ?? makeStringSorter(dataIndex),
2021-08-30 12:39:46 +05:00
render: render,
...other
})
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)
}
2021-08-30 12:39:46 +05:00
export const makeNumericColumn = (title: string, dataIndex: string,
filters: object[], filterDelegate: (key: string | number) => any,
renderDelegate: (_: any, row: object) => any, width: string) => ({
2021-08-30 12:39:46 +05:00
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),
])
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,
}
2021-08-20 12:31:24 +05:00
}