Main Pages — Routing, Naming Conventions & Common Pitfalls

Part of: Main Pages guide See also: Checklist | RPC Service

Routing

Both files below must be updated for the new page to appear in the WebUI and be accessible via the navigation bar. Missing either one is the most common cause of “my page doesn’t show up.”

AppRoutes.tsx (src/navigation/AppRoutes.tsx)

This file defines the React Router <Route> tree. Every main page needs at least two entries: one for the list view and one for the detail/settings view.

Step 1: Import the new components at the top of the file:

import MyEntities from "src/pages/MyEntities/MyEntities";
import MyEntitiesTabs from "src/pages/MyEntities/MyEntitiesTabs";

Step 2: Add the <Route> block inside the logged-in section ({userLoggedIn ? ( ... )}). The route path segment must use kebab-case and match the pathname passed to useUpdateRoute:

<Route path="my-entities">
  <Route path="" element={<MyEntities />} />
  <Route path=":cn">
    <Route path="" element={<MyEntitiesTabs section="settings" />} />
    {/* Add more sub-routes for member/memberof tabs as needed */}
  </Route>
</Route>

The :cn parameter name should match the primary key field (e.g. :uid for users, :fqdn for hosts, :cn for most other entities, :idnsname for DNS zones, :ipauniqueid for subordinate IDs).

Note on conditional routes: Some routes are conditionally rendered based on configuration. For example, DNS zones are only shown when DNS is enabled:

{dnsIsEnabled && (
  <Route path="dns-zones">
    ...
  </Route>
)}

data-cy Naming Convention

Follow the project’s kebab-case naming convention for test attributes:

{page-name}-button-{action}      →  my-entities-button-add
{page-name}-button-{action}      →  my-entities-button-delete
{page-name}-button-{action}      →  my-entities-button-refresh
{page-name}-kebab                →  my-entities-kebab
{page-name}-kebab-{action}       →  my-entities-kebab-some-action
{page-name}-modal-error          →  my-entities-modal-error
search                           →  search (always just "search")

See cypress/README.md for the full naming guide.

Post-Generation Validation

After generating a new main page, run the following checks to catch formatting issues, lint violations, and unused exports before committing:

npx prettier --write .     # Fix code formatting
npm run lint               # ESLint (max-warnings threshold)
npm run knip               # Detect unused files, exports, and dependencies

These are the same checks that run in CI, so catching them locally avoids failed pipelines.

Common Pitfalls

  1. Forgetting to register the route: The page won’t render if not added to both AppRoutes.tsx and NavRoutes.ts.

  2. Missing entryType: If using useSearchEntriesMutation, the entryType must exist in GenericPayload’s union type and be handled in the mutation’s switch logic.

  3. Wrong pathname in useUpdateRoute: Must exactly match the route key in NavRoutes.ts.

  4. Not calling refetch() on mount: Include the useEffect(() => { dataResponse.refetch(); }, []) pattern to ensure fresh data.

  5. Primary key mismatch: The pk / nameAttr in MainTable and BulkSelectorPrep must match the actual field name in the data type (e.g. "cn", "uid", "fqdn", "idnsname").