Обзор блочной системы
Как устроена универсальная система контента в Timelix
Блок — базовая единица контента в Timelix. По концепции близко к Notion: каждый блок имеет тип, данные и может содержать дочерние блоки, образуя дерево.
Основные принципы
Иерархическая структура
Каждый блок имеет parentId. Единственное исключение — корневой блок (parentId: null), который создаётся автоматически при первом входе пользователя. У каждого пользователя ровно один корневой блок.
Три режима отображения
Один и тот же набор дочерних блоков можно отображать в трёх режимах: list, flow, grid. Режимы не исключают друг друга — система запоминает настройки для каждого и переключает без потерь.
Оптимистичные обновления
Все изменения применяются мгновенно в UI через React Query optimistic updates. Если запрос к серверу упал — UI откатывается автоматически.
Автосинхронизация
Данные синхронизируются с сервером через Server Actions в фоне, без явных refresh.
Архитектурные слои
Вся бизнес-логика инкапсулирована в хуках. Компоненты только рендерят и вызывают функции из хуков — никакой логики создания, синхронизации или состояния внутри компонентов нет.
Схема базы данных
Индексы: block_parent_idx, block_type_idx, block_user_idx.
Ключевые хуки
| Хук | Назначение |
|---|---|
useBlocksPage | Композитный хук для страниц с полным набором возможностей |
useRootBlock | Управление корневым блоком пользователя |
useGridEditMode | Drag & drop редактирование в Grid-режиме |
useViewSettings | Сохранение настроек отображения между сессиями |
useBreadcrumbs | Навигационные хлебные крошки по иерархии |
useInlineEdit | Редактирование блока на месте без модалки |
Пример использования
Server Actions
Все CRUD-операции находятся в entities/block/api/blockActions.ts:
| Action | Описание |
|---|---|
createBlock | Создание нового блока |
updateBlock | Обновление данных блока |
deleteBlock | Удаление блока (мягкое, через deleted_at) |
getBlocks | Список дочерних блоков по parentId |
getBlock | Один блок по id |