Page Layouts
Design form, detail, and list layouts for every entity — assign per role, group, or user
Overview
Page Layouts control how records appear across OptiCRM. Every create form, detail page, and list view is rendered from a layout configuration — not hardcoded UI. This means admins can customize exactly which fields appear, how they're grouped into sections, and who sees which layout.
OptiCRM supports 41 entities (18 standard + 23 dynamic), and every one of them can have custom layouts.
The layout system follows the Salesforce/Oracle enterprise CRM model:
- Layouts are JSON configurations stored in the database
- A visual designer lets you drag-and-drop sections and widgets
- Layout assignments control which layout a user sees based on their role, group, or profile type
- A resolution engine picks the best layout for each user with caching
Layout Types
| Type | Code | Purpose |
|---|---|---|
| Form | LT_FORM | Create and edit record forms |
| Detail | LT_DETAIL | Read-only record detail pages |
| List | LT_LIST | List/table view column configuration |
| Dashboard | LT_DASHBOARD | Dashboard widget layout |
| Portal | LT_PORTAL | Parent/student portal views |
Most entities ship with default Form and Detail layouts. You can create additional layouts per type and assign them to specific audiences.
Layout Manager
Navigate to Settings → Presentation — Design → Record Layouts to manage all layouts.
What You See
The Layout Manager shows all layouts grouped by entity, with:
- Stats bar — Total layouts, entities covered, layouts with assignments, default count
- Search — Find layouts by name or entity
- Filters — Filter by section (Core, Operations, Finance, Admin), entity, or layout type
- Collapsible groups — Each entity is a collapsible section showing its layouts in a table
Layout Table Columns
| Column | Description |
|---|---|
| Layout Name | The display name |
| Type | Form, Detail, List, Dashboard, or Portal |
| Sections | Number of sections in the layout |
| Widgets | Number of widgets (field groups, notes, attachments) |
| Assigned To | Badges showing current assignments — click to remove, click "+" to add |
| Default | Star icon — toggle to set/unset as the default layout for this entity+type |
| Modified | Last update date |
| Actions | Edit (opens designer), rename, clone, assign, delete |
Creating a Layout
- Click New Layout in the top-right
- Select Entity — Searchable dropdown grouped by section (Core, Operations, Finance, Admin). Shows all 41 registered entities.
- Choose Layout Type — Form, Detail, List, Dashboard, or Portal
- Name — Auto-suggested based on entity + type (e.g., "Vehicle Form"). You can customize it.
- Click Create Layout — opens in the visual designer
Cloning a Layout
To create a variant of an existing layout:
- Click the ... menu on any layout row
- Select Clone
- A copy is created with "(Copy)" suffix and the same configuration
- Edit the clone in the designer to customize it
Setting Defaults
Each entity + layout type combination can have one default layout. The default is used when no specific assignment matches the current user.
- Click the star icon on a layout row to toggle default status
- A filled yellow star means it's the current default
- Only one default per entity + type — setting a new default doesn't automatically unset the old one, so manage this carefully
Deleting Layouts
- Click the ... menu → Delete
- Default layouts cannot be deleted — remove the default flag first
- Layouts with active assignments will warn before deletion
Layout Designer
Click Edit (pencil icon) on any layout to open the visual designer at /settings/layouts/{id}/edit.
Layout Structure
A layout is made of sections, and each section contains widgets:
Layout
├── Section: "Personal Information" (2 columns)
│ └── Widget: FIELD_GROUP ["firstName", "lastName", "dob", "gender"]
├── Section: "Academic Details" (2 columns, collapsible)
│ └── Widget: FIELD_GROUP ["className", "sectionName", "rollNumber"]
├── Section: "Attachments" (1 column)
│ └── Widget: ATTACHMENTS
└── Section: "Notes" (1 column)
└── Widget: NOTESSection Properties
| Property | Description |
|---|---|
| Title | Section heading displayed to users |
| Columns | 1 or 2 column layout for the fields |
| Collapsible | Whether users can expand/collapse the section |
| Default Collapsed | Whether the section starts collapsed |
Widget Types
| Widget | Description |
|---|---|
FIELD_GROUP | A group of entity fields rendered as form inputs or display values |
ATTACHMENTS | Universal file attachment widget (if entity supports attachments) |
NOTES | Threaded notes widget (if entity supports notes) |
Field Configuration
Within a FIELD_GROUP widget, you specify which fields to display by their API names. The rendering engine automatically:
- Shows the correct input type (text, select, date, etc.)
- Applies required/readonly rules from the field definition
- Renders lookup fields with search
- Shows validation errors inline
Layout Assignments
Navigate to Settings → Presentation — Assignments → Record Layout Assignments to control who sees which layout.
Assignment Priority
When a user opens a record, the system resolves the best layout in this order:
- User — Exact match for this specific user (highest priority)
- Group — User belongs to a group with an assigned layout
- Role — User's role definition matches
- Profile Type — User's profile type matches (Student, Parent, Staff, Admin, Super Admin)
- Default — The layout marked as default for this entity + type
- Fallback — If nothing matches, the system shows all non-readonly fields in a single section
Creating an Assignment
- Click Assign Layout in the top-right
- Select Entity — Searchable dropdown with all 41 entities
- Layout Type — Choose which type (Form, Detail, etc.)
- Layout — Select from layouts that exist for this entity + type
- Assignment Type — Choose one:
- Profile Type → Student, Parent, Staff, Admin, or Super Admin
- Role → A specific role definition (e.g., "Finance Officer")
- Group → A user group
- User → A specific individual user
- Click Assign
Quick Assignments from Layout Manager
You can also assign layouts directly from the Layout Manager page:
- In the "Assigned To" column, click + Assign on any layout
- Existing assignments appear as badges — hover and click × to remove
Duplicate Prevention
Only one assignment is allowed per entity + layout type + assignment type + target. For example, you can't assign two different Detail layouts to the same role for the Student entity. Delete the existing assignment first.
Viewing Assignments
The Layout Assignments page shows:
- Stats — Total assignments, entities covered, entities without assignments
- Search + filters — Search by layout name, entity, role, or group name
- Grouped by entity — Each entity shows its assignments in a table with layout name, type, assigned to, and assignment level
Resolution Cache
Layout resolution results are cached in Redis for 5 minutes to avoid repeated database lookups.
- Cache key format:
layout_resolve:{institutionId}:{entity}:{layoutType}:{userId} - Cache is automatically invalidated when assignments are created or deleted
NONEresults (no layout found) are never cached — so newly created assignments take effect immediately
Default Layouts
OptiCRM ships with multi-section default layouts for all entities. These are created during institution setup and can be regenerated.
Regenerating Better Defaults
If your institution was created before the improved layouts were available, an admin can regenerate them:
POST /api/admin/seed-better-layoutsThis replaces single-section field dumps with properly grouped layouts. For example, the Vehicle form gets 4 sections:
- Vehicle Information (registration, type, make, model, capacity)
- Personnel (driver, conductor)
- Compliance & Expiry (insurance, fitness, permit, PUC dates)
- Tracking (GPS device, active status)
Every entity gets a thoughtful section grouping based on the domain.
What Gets Updated
- Existing default Form layouts are updated with the new multi-section config
- Existing default Detail layouts are updated similarly
- If a default layout doesn't exist, it's created
- Non-default layouts (custom ones you created) are never touched
Which Forms Use the Layout System?
The layout system drives all create and edit forms across OptiCRM. When you change a layout in Settings > Layouts, the form updates immediately for all users — no code deployment needed.
Fully Layout-Driven Forms
These entities render their create/edit forms entirely from the layout configuration. Admins can add fields, remove fields, reorder them, create sections, and assign different layouts per role.
Dynamic Objects (19) — accessed via /o/[apiName]:
| Module | Entities |
|---|---|
| Transport | Vehicle, Transport Route, Route Stop, Student Transport |
| Library | Library Category, Library Item, Library Copy, Library Member, Library Issue, Library Reservation |
| Health | Health Profile, Health Screening, Sick Bay Visit, Vaccination, Medication |
| Hostel | Hostel Room, Hostel Allotment, Gate Pass, Hostel Visitor |
Standard Entities with Layout-Driven Forms (12):
| Entity | Page | What Changed |
|---|---|---|
| Student | /o/Student | Create + edit forms from layout |
| Staff | /o/Staff | Create + edit forms from layout |
| Enquiry | /o/Enquiry | Create + edit forms from layout |
| Fee Head | Finance > Fee Structure | Create form from layout (was hardcoded 3-field dialog) |
| Expense | Finance > Expenses | Create form from layout (was hardcoded 6-field dialog) |
| Scholarship | Finance > Scholarships | Create form from layout (was hardcoded 5-field dialog) |
| Announcement | Communication > Announcements | Create form from layout (was hardcoded 6-field dialog) |
| Subject | Academic > Subjects | Create form from layout (was hardcoded 7-field dialog) |
| Exam | Academic > Exams | Create form from layout (was hardcoded 7-field dialog) |
| User | Admin > Users | Create form from layout (edit kept custom for metadata panel) |
| Contact | Admin > Contacts | Create form from layout (was hardcoded 6-field dialog) |
| Webhook | Admin > Webhooks | Create form from layout (was hardcoded 4-field dialog) |
| Holiday | Settings > Holidays | Create form from layout (was hardcoded 6-field dialog) |
| Template | Communication > Templates | Create form from layout (edit kept custom for body editing) |
Custom UI Forms (Not Layout-Driven)
Some entities have specialized UIs that can't be represented as a flat field layout. These use purpose-built forms:
| Entity | Page | Reason |
|---|---|---|
| Fee Plan | Finance > Fee Structure | Multi-step wizard with nested fee items and instalments. Each item has a fee head, amount, and multiple instalment rows with due dates, late fees, and grace periods. |
| Academic Year | Academic > Years | Hierarchical management — year contains classes, each class contains sections, year also contains terms. Master-detail UI. |
| Invoice / Payment | Finance > Invoices | Payment recording requires invoice context, payment mode selection, and amount validation against outstanding balance. |
| Calendar Event | Calendar | Date range picker with color selector and all-day toggle. |
| User (edit) | Admin > Users | Edit dialog shows user metadata panel (last login, created date, institution) alongside the form fields. |
| Template (edit) | Communication > Templates | Edit dialog has a large body textarea with variable placeholder support. |
Even for custom UI forms, the entity's detail page still uses the layout system via LayoutDetailRenderer. So the read-only view of a Fee Plan or Invoice is layout-driven — only the create/edit form is custom.
How It Works
When a layout-driven form opens, it:
- Fetches the entity's field definitions from
/api/settings/entity-fields?entity={name} - Resolves the best matching layout from
/api/settings/layouts/resolve?entity={name}&type=LT_FORMbased on the current user's role, group, or profile type - Renders form fields according to the layout's sections and widgets
- If no layout is found, falls back to showing all non-readonly fields in a 2-column grid
- On submit, sends the form data to the entity's API endpoint
This means:
- Adding a field to a layout immediately shows it in the form
- Removing a field hides it (the data is still in the database, just not shown)
- Reordering fields changes the form order
- Adding sections groups fields with headers
- Assigning layouts per role means Finance Officers can see different fields than Teachers
Entities Covered
All 41 registered entities support layouts:
Core (9): Student, Enquiry, Contact, Guardian, Attendance, Staff, Invoice, User, Institution
Finance (7): Fee Head, Fee Plan, Payment, Receipt, Expense, Scholarship, Concession
Calendar (2): Staff Attendance, Holiday
Transport (4): Vehicle, Transport Route, Route Stop, Student Transport
Library (6): Library Category, Library Item, Library Copy, Library Member, Library Issue, Library Reservation
Health (5): Health Profile, Health Screening, Sick Bay Visit, Vaccination, Medication
Hostel (4): Hostel Room, Hostel Allotment, Gate Pass, Hostel Visitor
Academics (4): Subject, Department, Event, Announcement
Tips
- Start with defaults — The seeded layouts work out of the box. Customize only when roles need different views.
- Use sections — Group related fields together (e.g., "Personal Info", "Financial Details", "Emergency Contact"). This is much better than one long form.
- Two columns for short fields — Use 2-column sections for fields like name, email, phone. Use 1-column for textareas and notes.
- Collapsible for secondary info — Make sections like "System Fields" or "Audit Trail" collapsible so they don't clutter the main view.
- Clone before editing — If you want to customize a default layout, clone it first. Assign the clone to a specific role and keep the original as the fallback default.
- Profile Type vs Role — Profile Type is broader (all staff), Role is specific (only Finance Officers). Use Profile Type for general differences, Role for specialized views.