lamassu-server/packages/admin-ui/src/components/editableTable/Header.jsx
2025-05-13 07:30:38 +01:00

127 lines
3.2 KiB
JavaScript

import classnames from 'classnames'
import * as R from 'ramda'
import React, { useContext } from 'react'
import { Td, THead, TDoubleLevelHead, ThDoubleLevel } from '../fake-table/Table'
import { sentenceCase } from '../../utils/string'
import TableCtx from './Context'
const groupSecondHeader = elements => {
const doubleHeader = R.prop('doubleHeader')
const sameDoubleHeader = (a, b) => doubleHeader(a) === doubleHeader(b)
const group = R.pipe(
R.groupWith(sameDoubleHeader),
R.map(group =>
R.isNil(doubleHeader(group[0])) // No doubleHeader
? group
: [
{
width: R.sum(R.map(R.prop('width'), group)),
elements: group,
name: doubleHeader(group[0]),
},
],
),
R.reduce(R.concat, []),
)
return R.all(R.pipe(doubleHeader, R.isNil), elements)
? [elements, THead]
: [group(elements), TDoubleLevelHead]
}
const Header = () => {
const {
elements,
enableEdit,
enableEditText,
editWidth,
enableDelete,
deleteWidth,
enableToggle,
toggleWidth,
orderedBy,
DEFAULT_COL_SIZE,
} = useContext(TableCtx)
const mapElement2 = (it, idx) => {
const { width, elements, name } = it
if (elements && elements.length) {
return (
<ThDoubleLevel key={idx} width={width} title={name}>
{elements.map(mapElement)}
</ThDoubleLevel>
)
}
return mapElement(it, idx)
}
const mapElement = (
{ name, display, width = DEFAULT_COL_SIZE, header, textAlign },
idx,
) => {
const orderClasses = classnames({
'whitespace-nowrap':
R.isNil(header) &&
!R.isNil(orderedBy) &&
R.equals(name, orderedBy.code),
})
const attachOrderedByToComplexHeader = header => {
if (!R.isNil(orderedBy) && R.equals(name, orderedBy.code)) {
try {
const cloneHeader = R.clone(header)
const children = R.path(['props', 'children'], cloneHeader)
const spanChild = R.find(it => R.equals(it.type, 'span'), children)
spanChild.props.children = R.append(' -', spanChild.props.children)
return cloneHeader
} catch (e) {
console.error(e)
return header
}
}
return header
}
return (
<Td header key={idx} width={width} textAlign={textAlign}>
{!R.isNil(header) ? (
<>{attachOrderedByToComplexHeader(header) ?? header}</>
) : (
<span className={orderClasses}>
{!R.isNil(display) ? display : sentenceCase(name)}{' '}
{!R.isNil(orderedBy) && R.equals(name, orderedBy.code) && '-'}
</span>
)}
</Td>
)
}
const [innerElements, HeaderElement] = groupSecondHeader(elements)
return (
<HeaderElement>
{innerElements.map(mapElement2)}
{enableEdit && (
<Td header width={editWidth} textAlign="center">
{enableEditText ?? `Edit`}
</Td>
)}
{enableDelete && (
<Td header width={deleteWidth} textAlign="center">
Delete
</Td>
)}
{enableToggle && (
<Td header width={toggleWidth} textAlign="center">
Enable
</Td>
)}
</HeaderElement>
)
}
export default Header