core/panel/context/sort.tsx
Untone 82111ed0f6
All checks were successful
Deploy on push / deploy (push) Successful in 7s
Squashed new RBAC
2025-07-02 22:30:21 +03:00

151 lines
4.3 KiB
TypeScript

import { createContext, createSignal, ParentComponent, useContext } from 'solid-js'
/**
* Типы полей сортировки для разных вкладок
*/
export type AuthorsSortField = 'id' | 'email' | 'name' | 'created_at' | 'last_seen'
export type ShoutsSortField = 'id' | 'title' | 'slug' | 'created_at' | 'published_at' | 'updated_at'
export type TopicsSortField =
| 'id'
| 'title'
| 'slug'
| 'created_at'
| 'authors'
| 'shouts'
| 'followers'
| 'authors'
export type CommunitiesSortField =
| 'id'
| 'name'
| 'slug'
| 'created_at'
| 'created_by'
| 'shouts'
| 'followers'
| 'authors'
export type CollectionsSortField = 'id' | 'title' | 'slug' | 'created_at' | 'published_at'
export type InvitesSortField = 'inviter_name' | 'author_name' | 'shout_title' | 'status'
/**
* Общий тип для всех полей сортировки
*/
export type SortField =
| AuthorsSortField
| ShoutsSortField
| TopicsSortField
| CommunitiesSortField
| CollectionsSortField
| InvitesSortField
/**
* Направление сортировки
*/
export type SortDirection = 'asc' | 'desc'
/**
* Состояние сортировки
*/
export interface SortState {
field: SortField
direction: SortDirection
}
/**
* Конфигурация сортировки для разных вкладок
*/
export interface TabSortConfig {
allowedFields: SortField[]
defaultField: SortField
defaultDirection: SortDirection
}
/**
* Контекст для управления сортировкой таблиц
*/
interface TableSortContextType {
sortState: () => SortState
setSortState: (state: SortState) => void
handleSort: (field: SortField, allowedFields?: SortField[]) => void
getSortIcon: (field: SortField) => string
isFieldAllowed: (field: SortField, allowedFields?: SortField[]) => boolean
}
/**
* Создаем контекст
*/
const TableSortContext = createContext<TableSortContextType>()
/**
* Провайдер контекста сортировки
*/
export const TableSortProvider: ParentComponent = (props) => {
// Состояние сортировки - по умолчанию сортировка по ID по возрастанию
const [sortState, setSortState] = createSignal<SortState>({
field: 'id',
direction: 'asc'
})
/**
* Проверяет, разрешено ли поле для сортировки
*/
const isFieldAllowed = (field: SortField, allowedFields?: SortField[]) => {
if (!allowedFields) return true
return allowedFields.includes(field)
}
/**
* Обработчик клика по заголовку колонки для сортировки
*/
const handleSort = (field: SortField, allowedFields?: SortField[]) => {
// Проверяем, разрешено ли поле для сортировки
if (!isFieldAllowed(field, allowedFields)) {
console.warn(`Поле ${field} не разрешено для сортировки`)
return
}
const current = sortState()
let newDirection: SortDirection = 'asc'
if (current.field === field) {
// Если кликнули по той же колонке, меняем направление
newDirection = current.direction === 'asc' ? 'desc' : 'asc'
}
const newState = { field, direction: newDirection }
console.log('Изменение сортировки:', { from: current, to: newState })
setSortState(newState)
}
/**
* Получает иконку сортировки для колонки
*/
const getSortIcon = (field: SortField) => {
const current = sortState()
if (current.field !== field) {
return '⇅' // Неактивная сортировка
}
return current.direction === 'asc' ? '▲' : '▼'
}
const contextValue: TableSortContextType = {
sortState,
setSortState,
handleSort,
getSortIcon,
isFieldAllowed
}
return <TableSortContext.Provider value={contextValue}>{props.children}</TableSortContext.Provider>
}
/**
* Хук для использования контекста сортировки
*/
export const useTableSort = () => {
const context = useContext(TableSortContext)
if (!context) {
throw new Error('useTableSort должен использоваться внутри TableSortProvider')
}
return context
}