ENTITY_NAME в пути — placeholder каталога вашей сущности, например product для Product; EntityName — её тип в коде. Подставьте фактические имена своего проекта. Примеры Article ниже показывают отдельную сущность, а не обязательный модуль любого приложения.
Всё, что относится к Article, находится в одной feature: типы, колонки, форма, страницы и custom-расширения. Общие механизмы вынесены в shared, а app собирает сущности в систему администрирования.
Для доработки отдельной ячейки или элемента формы не нужно заменять всю страницу. Остальные стандартные части продолжают обновляться из модели.
Дерево показывает основные пути на примере Article, а не полный список файлов. Набор файлов зависит от модели и возможностей проекта.
admin/src/ · пример Article с CRUD
src/
├── main.tsx
├── App.tsx
├── app/
│ ├── providers.tsx
│ ├── router.tsx
│ ├── menu.ts
│ ├── layout.tsx
│ └── theme.ts
├── features/ENTITY_NAME/
│ ├── generated/
│ │ ├── model.ts
│ │ ├── schema.ts
│ │ ├── columns.tsx
│ │ ├── form.tsx
│ │ ├── list-page.tsx
│ │ ├── edit-page.tsx
│ │ ├── routes.tsx
│ │ └── ui-extension.tsx
│ └── custom/
│ ├── extension.tsx
│ └── ui-extension.tsx
└── shared/
├── api/
│ ├── client.ts
│ └── generated/client.ts
├── forms/field-controls.tsx
└── list-state.tsx
app — сборка интерфейса
Провайдеры, layout, тема, меню и маршруты объединяют интерфейсы сущностей. Это место подключения общих механизмов: отдельной feature не нужно знать устройство всего приложения.
features — интерфейс конкретной сущности
Типы, схема, колонки, форма и страницы Article лежат вместе со своими расширениями. Когда меняется сущность, связанный с ней код можно найти в одной feature, вместо поиска по общим папкам всех форм и таблиц.
shared — общие механизмы
HTTP-клиент, элементы форм, состояние списков и работа с media используются повторно. Сгенерированные формы следуют общим правилам загрузки, проверки и сохранения. Custom-компонент, подключённый в предусмотренный слот, должен соблюдать тот же контракт.
generated задаёт контракт, custom — реализацию
generated/ui-extension.tsx содержит типы точечных расширений. В custom/ui-extension.tsx ты реализуете ячейки, колонки, действия, элементы управления и обёртки. В custom/extension.tsx находятся hooks страниц и полные замены через PageOverride.
У точечных расширений есть конкретные контракты для редактируемых string/text-полей, обёрток и media. Слоты не позволяют произвольно заменить любой элемент интерфейса. Дополнительная колонка работает с уже загруженной страницей данных; сама по себе она не добавляет серверную сортировку или фильтрацию всего списка.
Два способа изменить интерфейс
| Подход | Что обновляет генератор | Что поддерживает разработчик |
|---|---|---|
| Точечное расширение | Страницу, стандартные элементы управления и новые поля, которые ты не переопределил | Свой компонент, действие или представление ячейки |
| Полная замена PageOverride | Сгенерированная страница остаётся отдельно | Всё содержимое и поведение выбранной страницы |
Маршрут использует выражение ArticleListPageOverride ?? ArticleListPage: если custom-компонент не задан, открывается сгенерированная страница. PageOverride подключается в коде; переключателя для него в Generator UI нет.