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
|