# Main Pages — Step 15: JSX Render, MainTable & Optional Features
> **Part of:** [Main Pages guide](../main-pages.md)
> **See also:** [Steps 9–14: Selection & Toolbar](04-walkthrough-selection-toolbar.md) | [Checklist & Types](06-checklist-and-types.md)
### 15. JSX Render
```tsx
return (
{batchError !== undefined && batchError ? (
) : (
/* Table goes here — see "Table" section below */
)}
{/* Modals */}
setShowAddModal(!showAddModal)}
onOpenAddModal={() => setShowAddModal(true)}
onCloseAddModal={() => setShowAddModal(false)}
onRefresh={refreshData}
/>
setShowDeleteModal(false)}
elementsToDelete={selectedEntities}
clearSelectedElements={() => clearSelectedEntities()}
columnNames={columnNames}
keyNames={keyNames}
onRefresh={refreshData}
updateIsDeleteButtonDisabled={setIsDeleteButtonDisabled}
updateIsDeletion={setIsDeletion}
/>
);
};
export default MyEntities;
```
## Table Component
New pages **must** use the `MainTable` component (`src/components/tables/MainTable.tsx`). **Do not** create custom table components (e.g. `MyEntitiesTable.tsx`) — some older pages (ActiveUsers, Hosts, Netgroups, HBACRules) use custom tables, but that pattern is legacy and should not be followed for new pages.
`MainTable` is a generic, reusable table component that handles checkboxes, shift+click multi-select, enable/disable status styling, skeleton loading, and linking to detail pages. It is used by DnsZones, Trusts, and all newer pages.
**Important:** When generating a new main page from scratch, `showLink` must default to `false` unless explicitly requested. This prevents linking to a settings/detail page that doesn't exist yet. Set it to `true` only when the corresponding `Tabs`/`Settings` components have been implemented.
```tsx
```
## Optional Features
### Kebab Dropdown Menu
For extra actions like "Rebuild auto membership". Used by ActiveUsers and Hosts.
```tsx
const [kebabIsOpen, setKebabIsOpen] = useState(false);
const dropdownItems = [
{ /* action handler */ }}
>
Some action
,
];
// Add to toolbar items:
{
key: N,
element: (
setKebabIsOpen(!kebabIsOpen)}
onKebabToggle={() => setKebabIsOpen(!kebabIsOpen)}
idKebab="main-dropdown-kebab"
isKebabOpen={kebabIsOpen}
dropdownItems={showTableRows ? dropdownItems : []}
isDisabled={!showTableRows}
/>
),
},
```
### Enable/Disable Buttons
For entities that support toggling status (Active Users, HBAC Rules, DNS Zones).
```tsx
// Add buttons to toolbar:
{
key: N,
element: (
onEnableDisableHandler(true)}
>
Disable
),
},
{
key: N+1,
element: (
onEnableDisableHandler(false)}
>
Enable
),
},
```
### Contextual Help Panel
Used by ActiveUsers, Hosts. Wraps the entire page content.
```tsx
const [isContextualPanelExpanded, setIsContextualPanelExpanded] = useState(false);
// In the toolbar, pass onClick to HelpTextWithIconLayout:
setIsContextualPanelExpanded(!isContextualPanelExpanded)}
/>
// Wrap the return JSX:
return (
setIsContextualPanelExpanded(false)}
>
{/* ...normal page content... */}
);
```