forked from ddrilling/asb_cloud_front
97 lines
3.6 KiB
TypeScript
97 lines
3.6 KiB
TypeScript
|
import { memo, useCallback, useEffect, useState } from 'react'
|
|||
|
import { ColumnsType } from 'antd/lib/table'
|
|||
|
import { Button, Modal, Switch, Table } from 'antd'
|
|||
|
import { SettingOutlined } from '@ant-design/icons'
|
|||
|
|
|||
|
import { ColumnSettings, makeSettings, mergeSettings, TableSettings } from '@utils/table_settings'
|
|||
|
import { TableColumns } from './Table'
|
|||
|
import { makeColumn } from '.'
|
|||
|
|
|||
|
const parseSettings = (columns?: TableColumns, settings?: TableSettings | null): ColumnSettings[] => {
|
|||
|
const newSettings = mergeSettings(makeSettings(columns ?? []), settings ?? {})
|
|||
|
return Object.values(newSettings).map((set, i) => ({ ...set, key: i }))
|
|||
|
}
|
|||
|
|
|||
|
const unparseSettings = (columns: ColumnSettings[]): TableSettings =>
|
|||
|
Object.fromEntries(columns.map((column) => [column.columnName, column]))
|
|||
|
|
|||
|
export type TableSettingsChangerProps = {
|
|||
|
title?: string
|
|||
|
columns?: TableColumns
|
|||
|
settings?: TableSettings | null
|
|||
|
onChange: (settings: TableSettings | null) => void
|
|||
|
}
|
|||
|
|
|||
|
export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, columns, settings, onChange }) => {
|
|||
|
const [visible, setVisible] = useState<boolean>(false)
|
|||
|
const [newSettings, setNewSettings] = useState<ColumnSettings[]>(parseSettings(columns, settings))
|
|||
|
const [tableColumns, setTableColumns] = useState<ColumnsType<ColumnSettings>>([])
|
|||
|
|
|||
|
const onVisibilityChange = useCallback((index: number, visible: boolean) => {
|
|||
|
setNewSettings((oldSettings) => {
|
|||
|
const newSettings = [...oldSettings]
|
|||
|
newSettings[index].visible = visible
|
|||
|
return newSettings
|
|||
|
})
|
|||
|
}, [])
|
|||
|
|
|||
|
const toogleAll = useCallback((show: boolean) => {
|
|||
|
setNewSettings((oldSettings) => oldSettings.map((column) => {
|
|||
|
column.visible = show
|
|||
|
return column
|
|||
|
}))
|
|||
|
}, [])
|
|||
|
|
|||
|
useEffect(() => {
|
|||
|
setTableColumns([
|
|||
|
makeColumn('Название', 'title'),
|
|||
|
makeColumn(null, 'visible', {
|
|||
|
title: () => (
|
|||
|
<>
|
|||
|
Показать
|
|||
|
<Button type={'link'} onClick={() => toogleAll(true)}>Показать все</Button>
|
|||
|
</>
|
|||
|
),
|
|||
|
render: (visible: boolean, _?: ColumnSettings, index: number = NaN) => (
|
|||
|
<Switch
|
|||
|
checked={visible}
|
|||
|
checkedChildren={'Отображён'}
|
|||
|
unCheckedChildren={'Скрыт'}
|
|||
|
onChange={(visible) => onVisibilityChange(index, visible)}
|
|||
|
/>
|
|||
|
)
|
|||
|
}),
|
|||
|
])
|
|||
|
}, [toogleAll, onVisibilityChange])
|
|||
|
|
|||
|
useEffect(() => setNewSettings(parseSettings(columns, settings)), [columns, settings])
|
|||
|
|
|||
|
const onModalOk = useCallback(() => {
|
|||
|
onChange(unparseSettings(newSettings))
|
|||
|
setVisible(false)
|
|||
|
}, [newSettings, onChange])
|
|||
|
|
|||
|
const onModalCancel = useCallback(() => {
|
|||
|
setNewSettings(parseSettings(columns, settings))
|
|||
|
setVisible(false)
|
|||
|
}, [columns, settings])
|
|||
|
|
|||
|
return (
|
|||
|
<>
|
|||
|
<Modal
|
|||
|
centered
|
|||
|
visible={visible}
|
|||
|
onCancel={onModalCancel}
|
|||
|
onOk={onModalOk}
|
|||
|
title={title ?? 'Настройка отображения таблицы'}
|
|||
|
width={1000}
|
|||
|
>
|
|||
|
<Table columns={tableColumns} dataSource={newSettings} />
|
|||
|
</Modal>
|
|||
|
<Button size={'small'} style={{ position: 'absolute', left: 0, top: 0, opacity: .5 }} type={'link'} onClick={() => setVisible(true)} icon={<SettingOutlined />}/>
|
|||
|
</>
|
|||
|
)
|
|||
|
})
|
|||
|
|
|||
|
export default TableSettingsChanger
|