File size: 3,447 Bytes
13555f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'

import {Board, IPropertyTemplate} from '../../blocks/board'
import {Constants} from '../../constants'
import {Card} from '../../blocks/card'
import {BoardView} from '../../blocks/boardView'
import SortDownIcon from '../../widgets/icons/sortDown'
import SortUpIcon from '../../widgets/icons/sortUp'
import MenuWrapper from '../../widgets/menuWrapper'
import Label from '../../widgets/label'
import {useSortable} from '../../hooks/sortable'
import {Utils} from '../../utils'

import HorizontalGrip from './horizontalGrip'

import './table.scss'
import TableHeaderMenu from './tableHeaderMenu'
import {useColumnResize} from './tableColumnResizeContext'

type Props = {
    readonly: boolean
    sorted: 'up'|'down'|'none'
    name: React.ReactNode
    board: Board
    activeView: BoardView
    cards: Card[]
    views: BoardView[]
    template: IPropertyTemplate
    onDrop: (template: IPropertyTemplate, container: IPropertyTemplate) => void
    onAutoSizeColumn: (columnID: string, headerWidth: number) => void
}

const TableHeader = (props: Props): JSX.Element => {
    const [isDragging, isOver, columnRef] = useSortable('column', props.template, !props.readonly, props.onDrop)

    const columnResize = useColumnResize()

    const onAutoSizeColumn = (templateId: string) => {
        let width = Constants.minColumnWidth
        if (columnRef.current) {
            const {fontDescriptor, padding} = Utils.getFontAndPaddingFromCell(columnRef.current)
            const textWidth = Utils.getTextWidth(columnRef.current.innerText.toUpperCase(), fontDescriptor)
            width = textWidth + padding
        }
        props.onAutoSizeColumn(templateId, width)
    }

    let className = 'octo-table-cell header-cell'
    if (isOver) {
        className += ' dragover'
    }

    const templateId = props.template.id

    return (
        <div
            className={className}
            style={{
                overflow: 'unset',
                opacity: isDragging ? 0.5 : 1,
                width: columnResize.width(templateId),
            }}
            ref={(ref) => {
                if (ref && templateId !== Constants.titleColumnId) {
                    (columnRef as React.MutableRefObject<HTMLDivElement>).current = ref
                }
                columnResize.updateRef(Constants.tableHeaderId, templateId, ref)
            }}
        >
            <MenuWrapper disabled={props.readonly}>
                <Label>
                    {props.name}
                    {props.sorted === 'up' && <SortUpIcon/>}
                    {props.sorted === 'down' && <SortDownIcon/>}
                </Label>
                <TableHeaderMenu
                    board={props.board}
                    activeView={props.activeView}
                    views={props.views}
                    cards={props.cards}
                    templateId={templateId}
                />
            </MenuWrapper>

            <div className='octo-spacer'/>

            {!props.readonly &&
                <HorizontalGrip
                    templateId={templateId}
                    columnWidth={props.activeView.fields.columnWidths[templateId] || 0}
                    onAutoSizeColumn={onAutoSizeColumn}
                />
            }
        </div>
    )
}

export default React.memo(TableHeader)