Улучшена типизация таблиц и методов работы с ними

This commit is contained in:
goodmice 2022-10-06 11:46:48 +05:00
parent c33674c6c5
commit 443f14c0a8
No known key found for this signature in database
GPG Key ID: 63EA771203189CF1
5 changed files with 39 additions and 26 deletions

View File

@ -10,18 +10,17 @@ import { tryAddKeys } from './EditableTable'
import '@styles/index.css'
export type BaseTableColumn<T = any> = ColumnGroupType<T> | ColumnType<T>
export type TableColumns<T = any> = OmitExtends<BaseTableColumn<T>, TableColumnSettings>[]
export type BaseTableColumn<T> = ColumnGroupType<T> | ColumnType<T>
export type TableColumns<T> = OmitExtends<BaseTableColumn<T>, TableColumnSettings>[]
export type TableContainer = TableProps<any> & {
columns: TableColumns
dataSource: any[]
export type TableContainer<T> = TableProps<T> & {
columns: TableColumns<T>
tableName?: string
showSettingsChanger?: boolean
}
export const Table = memo<TableContainer>(({ columns, dataSource, tableName, showSettingsChanger, ...other }) => {
const [newColumns, setNewColumns] = useState<TableColumns>([])
const _Table = <T extends object>({ columns, dataSource, tableName, showSettingsChanger, ...other }: TableContainer<T>) => {
const [newColumns, setNewColumns] = useState<TableColumns<T>>([])
const [settings, setSettings] = useState<TableSettings>({})
const onSettingsChanged = useCallback((settings?: TableSettings | null) => {
@ -52,6 +51,8 @@ export const Table = memo<TableContainer>(({ columns, dataSource, tableName, sho
{...other}
/>
)
})
}
export const Table = memo(_Table) as typeof _Table
export default Table

View File

@ -7,7 +7,7 @@ import { TableColumnSettings, makeTableSettings, mergeTableSettings, TableSettin
import { TableColumns } from './Table'
import { makeColumn } from '.'
const parseSettings = (columns?: TableColumns, settings?: TableSettings | null): TableColumnSettings[] => {
const parseSettings = <T extends object>(columns?: TableColumns<T>, settings?: TableSettings | null): TableColumnSettings[] => {
const newSettings = mergeTableSettings(makeTableSettings(columns ?? []), settings ?? {})
return Object.values(newSettings).map((set, i) => ({ ...set, key: i }))
}
@ -15,14 +15,14 @@ const parseSettings = (columns?: TableColumns, settings?: TableSettings | null):
const unparseSettings = (columns: TableColumnSettings[]): TableSettings =>
Object.fromEntries(columns.map((column) => [column.columnName, column]))
export type TableSettingsChangerProps = {
export type TableSettingsChangerProps<T extends object> = {
title?: string
columns?: TableColumns
columns?: TableColumns<T>
settings?: TableSettings | null
onChange: (settings: TableSettings | null) => void
}
export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, columns, settings, onChange }) => {
const _TableSettingsChanger = <T extends object>({ title, columns, settings, onChange }: TableSettingsChangerProps<T>) => {
const [visible, setVisible] = useState<boolean>(false)
const [newSettings, setNewSettings] = useState<TableColumnSettings[]>(parseSettings(columns, settings))
const [tableColumns, setTableColumns] = useState<ColumnsType<TableColumnSettings>>([])
@ -36,10 +36,12 @@ export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, co
}, [])
const toogleAll = useCallback((show: boolean) => {
setNewSettings((oldSettings) => oldSettings.map((column) => {
column.visible = show
return column
}))
setNewSettings((oldSettings) =>
oldSettings.map((column) => {
column.visible = show
return column
})
)
}, [])
useEffect(() => {
@ -49,7 +51,9 @@ export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, co
title: () => (
<>
Показать
<Button type={'link'} onClick={() => toogleAll(true)}>Показать все</Button>
<Button type={'link'} onClick={() => toogleAll(true)}>
Показать все
</Button>
</>
),
render: (visible: boolean, _?: TableColumnSettings, index: number = NaN) => (
@ -59,7 +63,7 @@ export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, co
unCheckedChildren={'Скрыт'}
onChange={(visible) => onVisibilityChange(index, visible)}
/>
)
),
}),
])
}, [toogleAll, onVisibilityChange])
@ -88,9 +92,17 @@ export const TableSettingsChanger = memo<TableSettingsChangerProps>(({ title, co
>
<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 />}/>
<Button
size={'small'}
style={{ position: 'absolute', left: 0, top: 0, opacity: 0.5 }}
type={'link'}
onClick={() => setVisible(true)}
icon={<SettingOutlined />}
/>
</>
)
})
}
export const TableSettingsChanger = memo(_TableSettingsChanger) as typeof _TableSettingsChanger
export default TableSettingsChanger

View File

@ -8,7 +8,7 @@
* @param data Копируемые данные
* @returns Полная копия `data`
*/
export const deepCopy = <T extends any>(data: T): T => JSON.parse(JSON.stringify(data ?? null))
export const deepCopy = <T,>(data: T): T => JSON.parse(JSON.stringify(data ?? null))
/**
* Маппинг полей объекта

View File

@ -21,7 +21,7 @@ export const getArrayFromLocalStorage = <T extends string = string>(name: string
return raw.split(sep).map<T>(elm => elm as T)
}
export const getJSON = <T extends any>(name: StorageNames): T | null => {
export const getJSON = <T,>(name: StorageNames): T | null => {
const raw = localStorage.getItem(name)
if (!raw) return null
try {
@ -30,7 +30,7 @@ export const getJSON = <T extends any>(name: StorageNames): T | null => {
return null
}
export const setJSON = <T extends any>(name: StorageNames, data: T | null): boolean => {
export const setJSON = <T,>(name: StorageNames, data: T | null): boolean => {
try {
localStorage.setItem(name, JSON.stringify(data))
return true

View File

@ -9,7 +9,7 @@ export type TableColumnSettings = {
export type TableSettings = Record<string, TableColumnSettings>
export type TableSettingsStore = Record<string, TableSettings | null>
export const makeTableSettings = (columns: TableColumns): TableSettings => {
export const makeTableSettings = <T extends object>(columns: TableColumns<T>): TableSettings => {
const settings: TableSettings = {}
columns.forEach((column) => {
if (!column.key) return
@ -47,8 +47,8 @@ export const optimizeTableColumn = (column: TableColumnSettings): TableColumnSet
visible: column.visible ?? true,
})
export const applyTableSettings = (columns: TableColumns, settings: TableSettings): TableColumns => {
let newColumns: TableColumns = columns.map((column) => ({ ...column }))
export const applyTableSettings = <T extends object>(columns: TableColumns<T>, settings: TableSettings): TableColumns<T> => {
let newColumns: TableColumns<T> = columns.map((column) => ({ ...column }))
newColumns = newColumns.filter((column) => {
const name = String(column.key)
return !(name in settings) || settings[name]?.visible