asb_cloud_front/src/components/Table/TableSettingsChanger.tsx

97 lines
3.7 KiB
TypeScript
Raw Normal View History

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 { TableColumnSettings, makeTableSettings, mergeTableSettings, TableSettings } from '@utils'
import { TableColumns } from './Table'
import { makeColumn } from '.'
const parseSettings = (columns?: TableColumns, settings?: TableSettings | null): TableColumnSettings[] => {
const newSettings = mergeTableSettings(makeTableSettings(columns ?? []), settings ?? {})
return Object.values(newSettings).map((set, i) => ({ ...set, key: i }))
}
const unparseSettings = (columns: TableColumnSettings[]): 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<TableColumnSettings[]>(parseSettings(columns, settings))
const [tableColumns, setTableColumns] = useState<ColumnsType<TableColumnSettings>>([])
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, _?: TableColumnSettings, 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