Architecture overview
Layers, responsibilities, and design constraints in ApiTables
This page maps how frontend pieces connect. Read Key concepts first if you are new.
ApiTables splits configuration (from the API), state (per-table Redux), data fetching (hooks + axios), and presentation (./ApiTables/core/ + ./ApiTables/general-components/). Feature pages only fetch structure and render ReactApiTable — they do not define columns.
Who reads this?
| Reader | Focus on |
|---|---|
| Junior | Component table below + "Two Redux worlds" |
| Mid | Layer diagram + API contracts |
| Senior | Design constraints + directory roles |
Layer diagram
Component responsibilities
| Component | File | Responsibility |
|---|---|---|
ReactApiTable | ./ApiTables/ReactApiTable.tsx | Provider wrapper, loading gate, default controller |
ApiTablesProvider | ./ApiTables/ApiTablesProvider.tsx | Isolated Redux; remount key from global app slice |
ApiTablesController | ./ApiTables/ApiTablesController.tsx | Hydrate slices from structure; orchestrate fetches |
ApiTablesComponent | ./ApiTables/ApiTablesComponent.tsx | Compose toolbar + table + modals mount point |
ApiTablesModals | ./ApiTables/table-modals/ApiTablesModals.tsx | Central modal router (row, bulk, column, custom) |
Two Redux worlds
| Store | Scope | Access |
|---|---|---|
| Table store | One per ApiTablesProvider | useSelector inside table subtree |
| App store | Whole bolesa-app-ui | getExternalState(), store from @/store/store, or useSelector on state.app in provider |
Table state must not leak between tables on the same page — hence createTableStore() per provider.
API contracts
| Phase | Method | Path pattern |
|---|---|---|
| Structure | GET | /api-table/control-tables/load-table/{name} (path varies per feature) |
| Data | POST | /api-table/control-tables/query-table/{tableName} |
| Row/bulk action | POST/PUT/… | Action URL from structure (often /api/..., stripped to path in client) |
Query body shape:
{
"perPage": 25,
"page": 1,
"filters": { },
"sorts": { },
"params": { }
}filters is the object form from _setAppliedFilters (keyed by filter name). sorts is tableSorting from Redux.
Directory roles
| Path | Role |
|---|---|
./ApiTables/core/ | Interactive table UI (filters, sort badge, body, pagination) |
./ApiTables/general-components/ | Cell renderers and row action buttons |
./ApiTables/table-providers/ | Store factory, slices, useUtilsProvider |
./ApiTables/table-modals/ | Modals + custom-controls/ feature forms |
./ApiTables/hooks/ | Structure fetch (local state) and data fetch |
./ApiTables/table-utils/ | Column formatting, filter normalization, downloads |
Design constraints
- Custom controls are not auto-discovered — each API URL is matched manually in
ApiTablesModals.tsx. - Sorting is server-side —
react-data-table-componentcallsonSort; Redux holdssortsfor the query. - Selection clears on every data fetch —
useTableFetchertogglestoggledClearRowsand clearsselectedRows. - Column visibility persists in secure local storage under
{tableName}_tb.