Files
admin/docs/devtools/module-generator/frontend.md
T
2026-06-25 15:53:49 +03:00

7.2 KiB

Module Generator Frontend

The frontend generator UI collects module metadata, selected assets, form layout, and datatable configuration. It converts the configuration into TypeScript/TSX source strings and sends them to the backend generator.

Main Flow

Responsibility Source
Page submission, notifications, and mutation callbacks apps/admin/src/devtools/pages/ModuleGeneratorPage/index.tsx
Payload assembly apps/admin/src/devtools/pages/ModuleGeneratorPage/lib/buildGenerateModulePayload.ts
Form state and initial values apps/admin/src/devtools/view/forms/ModuleGeneratorForm/form.ts
Metadata, form, and datatable sections apps/admin/src/devtools/view/forms/ModuleGeneratorForm/sections/
Payload DTOs apps/admin/src/devtools/data/api/dto.ts
HTTP client apps/admin/src/devtools/data/api/index.ts
React Query hooks apps/admin/src/devtools/data/queries/
Source-code builders apps/admin/src/devtools/data/builders/

The page submits through useGenerateModule. On success it resets the form and shows a success alert; backend or network errors are normalized through the shared React Query error helpers.

Metadata and Assets

The required metadata is:

  • name: frontend folder name, backend module identity, route segment, and permission-slug base.
  • table: existing PostgreSQL source table.
  • generate: selected backend and frontend assets.

Supported asset values are defined by ModuleAsset:

Asset Workspace Output
model Backend Lucid model
controller Backend Authenticated resource controller and test
routes Backend Resource route registration
validator Backend Create and update Vine validators
policy Backend Bouncer policy and permission configuration
api Backend API controller, validators, routes, and test
form Frontend Form definition, component, and modal/sheet trigger
datatable Frontend List page table and menu entry

The default selection includes all backend assets. Form and datatable generation are opt-in.

Schema Queries

The frontend uses two authenticated read endpoints before generation:

  • GET /makeModule/tables populates the table selector.
  • GET /makeModule/columns/:table populates form and datatable field choices.

Table and column requests are cached through React Query. Column queries remain disabled until a table is selected.

Payload Builders

buildGenerateModulePayload delegates source generation to focused builders:

Builder Payload field Generated destination
FormTemplateBuilder.buildComponent form view/forms/MainForm/Component.tsx
FormTemplateBuilder.buildDefinition formDefinition view/forms/MainForm/form.ts
FormDialogTemplateBuilder formDialog view/widgets/ManageTrigger.tsx
DataTableTemplateBuilder dataTable view/widgets/DataTable.tsx
ListPageTemplateBuilder list pages/ListPage/index.tsx
MenuTemplateBuilder menu config/menu.ts
ModuleTemplateBuilder module config/module.ts

If form generation is disabled, form, formDefinition, and formDialog are null. If datatable generation is disabled, dataTable and menu are null, while the list-page builder emits a page without a table.

Generated Frontend Architecture

apps/admin/src/modules/<name>/
├── api/
│   ├── create.ts
│   ├── delete.ts
│   ├── detailed.ts
│   ├── keys.ts
│   ├── list.ts
│   └── update.ts
├── config/
│   ├── translation/
│   ├── menu.ts
│   ├── messages.ts
│   ├── meta.ts
│   ├── module.ts
│   └── routing.tsx
├── entities/
│   └── Entity.ts
├── pages/
│   └── ListPage/
│       └── index.tsx
└── view/
    ├── forms/
    │   └── MainForm/
    │       ├── Component.tsx
    │       ├── constants.ts
    │       ├── form.ts
    │       ├── index.ts
    │       └── submit.ts
    ├── layouts/
    │   └── Layout.tsx
    └── widgets/
        ├── DataTable.tsx
        ├── DeleteTrigger.tsx
        └── ManageTrigger.tsx

The api directory intentionally has no barrel file. Consumers import each operation directly, for example:

import { useCreate } from "../../../api/create";
import { invalidateDetailed } from "../../../api/detailed";
import { invalidateList } from "../../../api/list";
import { useUpdate } from "../../../api/update";

Each CRUD operation remains isolated in its own file. keys.ts owns React Query key builders, while list.ts and detailed.ts own their cache invalidation helpers.

Layer Responsibilities

  • entities/Entity.ts is generated from database columns and is shared by API hooks, forms, and widgets.
  • api/ owns Axios calls, React Query hooks, cache keys, and mutation notifications.
  • pages/ owns route-level composition and permission page gates.
  • view/forms/ owns schema, form values, UI integration, and submission orchestration.
  • view/widgets/ owns stateful table, delete, and manage interactions.
  • config/ integrates routes, menu, translations, metadata, and permissions with the app module registry.

Extending the Frontend Generator

When adding a new generated frontend artifact:

  1. Add its configuration type under apps/admin/src/devtools/entities/.
  2. Add UI controls to ModuleGeneratorForm.
  3. Add a focused builder under data/builders/ if the artifact contains dynamic source.
  4. Add the payload field to GenerateModulePayload and buildGenerateModulePayload.
  5. Accept and write the field in backend/app/controllers/module_controller.ts.
  6. Add the static structure to apps/admin/src/modules/_template/ when every module needs it.
  7. Verify generation with and without the new asset selected.