farmcontrol-ui/src/components/Dashboard/common/ObjectKanbanHeader.jsx
Tom Butcher 5e6b4213ab Enhance ObjectKanban and ObjectTable Components with Column Resizing and Drag-and-Drop Functionality
- Implemented dynamic column resizing in ObjectKanban and ObjectKanbanColumn, allowing users to adjust column widths for better layout control.
- Added drag-and-drop support for reordering columns in ObjectKanbanHeader, improving user interaction and customization of the kanban view.
- Updated CSS styles in App.css to accommodate new resizing handles and visual feedback during drag-and-drop actions.
- Refactored ObjectKanban and related components to manage column states and widths effectively, ensuring a responsive and user-friendly experience.
2026-09-03 14:27:34 +01:00

149 lines
5.3 KiB
JavaScript

import { Flex, Skeleton } from 'antd'
import PropTypes from 'prop-types'
import { HolderOutlined, LoadingOutlined } from '@ant-design/icons'
import ObjectProperty from './ObjectProperty'
import { KANBAN_DEFAULT_COLUMN_WIDTH } from './viewModeUtils'
const ObjectKanbanHeader = ({
columns = [],
categoryProperty,
categoryPropertyDef,
trackRef,
skeletonColumnCount = 0,
lazyLoading = false,
loadingColumnKeys = [],
draggedKey = null,
dropTargetKey = null,
onColumnDragStart,
onColumnDragOver,
onColumnDrop,
onColumnDragEnd
}) => {
const showSkeleton = skeletonColumnCount > 0
const loadingColumnKeySet = new Set(loadingColumnKeys)
return (
<div className='objectKanbanHeader'>
<div className='objectKanbanHeaderTrack' ref={trackRef}>
<Flex gap='middle' className='objectKanbanHeaderRow' align='center'>
{showSkeleton
? Array.from({ length: skeletonColumnCount }).map((_, index) => (
<div
key={`skeleton-header-${index}`}
className='objectKanbanHeaderCell'
style={{
width: KANBAN_DEFAULT_COLUMN_WIDTH,
flex: `0 0 ${KANBAN_DEFAULT_COLUMN_WIDTH}px`
}}
>
<Skeleton.Input
active
size='small'
style={{ width: '60%', height: 24 }}
/>
</div>
))
: columns.map(({ key: columnKey, value: categoryValue, width }) => {
const showColumnLoading =
lazyLoading || loadingColumnKeySet.has(columnKey)
const isDragging = draggedKey === columnKey
const isDropTarget =
dropTargetKey === columnKey && draggedKey !== columnKey
return (
<Flex
key={columnKey}
className={[
'objectKanbanHeaderCell',
isDragging ? 'objectKanbanHeaderCell--dragging' : '',
isDropTarget ? 'objectKanbanHeaderCell--dropTarget' : ''
]
.filter(Boolean)
.join(' ')}
align='center'
justify='space-between'
gap={8}
style={{
width,
flex: `0 0 ${width}px`
}}
onDragOver={(event) =>
onColumnDragOver?.(event, columnKey)
}
onDrop={(event) => onColumnDrop?.(event, columnKey)}
>
{categoryPropertyDef ? (
<ObjectProperty
{...categoryPropertyDef}
value={
categoryPropertyDef.type === 'tags' &&
typeof categoryValue === 'string'
? [categoryValue]
: categoryValue
}
objectData={{
[categoryProperty]:
categoryPropertyDef.type === 'tags' &&
typeof categoryValue === 'string'
? [categoryValue]
: categoryValue
}}
name={categoryProperty}
/>
) : null}
<Flex
align='center'
gap={4}
className='objectKanbanHeaderCellActions'
>
{showColumnLoading && (
<LoadingOutlined spin style={{ flexShrink: 0 }} />
)}
<span
className='objectKanbanHeaderDragHandle overview-drag-handle'
draggable
title='Drag to reorder column'
onClick={(event) => event.stopPropagation()}
onMouseDown={(event) => event.stopPropagation()}
onDragStart={(event) =>
onColumnDragStart?.(event, columnKey)
}
onDragEnd={onColumnDragEnd}
>
<HolderOutlined />
</span>
</Flex>
</Flex>
)
})}
</Flex>
</div>
</div>
)
}
ObjectKanbanHeader.displayName = 'ObjectKanbanHeader'
ObjectKanbanHeader.propTypes = {
columns: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string.isRequired,
value: PropTypes.any,
width: PropTypes.number.isRequired
})
),
categoryProperty: PropTypes.string.isRequired,
categoryPropertyDef: PropTypes.object,
trackRef: PropTypes.object,
skeletonColumnCount: PropTypes.number,
lazyLoading: PropTypes.bool,
loadingColumnKeys: PropTypes.arrayOf(PropTypes.string),
draggedKey: PropTypes.string,
dropTargetKey: PropTypes.string,
onColumnDragStart: PropTypes.func,
onColumnDragOver: PropTypes.func,
onColumnDrop: PropTypes.func,
onColumnDragEnd: PropTypes.func
}
export default ObjectKanbanHeader