# Page Layouts Feature ## Overview The Page Layouts feature allows administrators to customize how fields are displayed in detail and edit views using a visual drag-and-drop interface based on GridStack.js with a 6-column grid system. ## Architecture ### Backend Components 1. **Database Schema** (`migrations/tenant/20250126000008_create_page_layouts.js`) - `page_layouts` table stores layout configurations - Fields: `id`, `name`, `object_id`, `is_default`, `layout_config`, `description` - JSON-based `layout_config` stores field positions and sizes 2. **API Endpoints** (`src/page-layout/`) - `POST /page-layouts` - Create a new page layout - `GET /page-layouts?objectId={id}` - Get all layouts for an object - `GET /page-layouts/:id` - Get a specific layout - `GET /page-layouts/default/:objectId` - Get the default layout for an object - `PATCH /page-layouts/:id` - Update a layout - `DELETE /page-layouts/:id` - Delete a layout ### Frontend Components 1. **PageLayoutEditor.vue** - Visual editor for creating/editing layouts - 6-column grid system using GridStack.js - Drag and drop fields from sidebar - Resize fields horizontally (1-6 columns width) - Default width: 3 columns (2-column template effect) - Save layout configuration 2. **PageLayoutRenderer.vue** - Renders fields based on saved layouts - Used in detail and edit views - Falls back to traditional 2-column layout if no layout configured - Supports all field types 3. **DetailViewEnhanced.vue** & **EditViewEnhanced.vue** - Enhanced versions of views with page layout support - Automatically fetch and use default page layout - Maintain backward compatibility with section-based layouts ### Types - **PageLayout** (`types/page-layout.ts`) - Layout metadata and configuration - Field position and size definitions - Grid configuration options ## Usage ### 1. Run Database Migration ```bash cd backend npm run migrate:tenant ``` ### 2. Configure Page Layouts Navigate to **Setup → Objects → [Object Name] → Page Layouts** tab: 1. Click "New Layout" to create a layout 2. Enter a layout name 3. Drag fields from the right sidebar onto the 6-column grid 4. Resize fields by dragging their edges (width only) 5. Rearrange fields by dragging them to new positions 6. Click "Save Layout" to persist changes ### 3. Use in Views #### Option A: Use Enhanced Views (Recommended) Replace existing views in your page: ```vue ``` #### Option B: Use PageLayoutRenderer Directly ```vue ``` ### 4. Composable API ```typescript const { getPageLayouts, // Get all layouts for an object getPageLayout, // Get a specific layout getDefaultPageLayout, // Get default layout for an object createPageLayout, // Create new layout updatePageLayout, // Update existing layout deletePageLayout // Delete layout } = usePageLayouts() // Example: Create a layout await createPageLayout({ name: 'Sales Layout', objectId: 'uuid-here', isDefault: true, layoutConfig: { fields: [ { fieldId: 'field-1', x: 0, y: 0, w: 3, h: 1 }, { fieldId: 'field-2', x: 3, y: 0, w: 3, h: 1 }, ] } }) ``` ## Grid System ### Configuration - **Columns**: 6 - **Default field width**: 3 columns (50% width) - **Min width**: 1 column (16.67%) - **Max width**: 6 columns (100%) - **Height**: Fixed at 1 unit (80px), uniform across all fields ### Layout Example ``` ┌─────────────────────┬─────────────────────┐ │ Field 1 (w:3) │ Field 2 (w:3) │ ← Two 3-column fields ├─────────────────────┴─────────────────────┤ │ Field 3 (w:6) │ ← One full-width field ├──────────┬──────────┬──────────┬──────────┤ │ F4 (w:2) │ F5 (w:2) │ F6 (w:2) │ (empty) │ ← Three 2-column fields └──────────┴──────────┴──────────┴──────────┘ ``` ## Features ### Editor - ✅ 6-column responsive grid - ✅ Drag fields from sidebar to grid - ✅ Drag to reposition fields on grid - ✅ Resize fields horizontally (1-6 columns) - ✅ Remove fields from layout - ✅ Save layout configuration - ✅ Clear all fields ### Renderer - ✅ Renders fields based on saved layout - ✅ Respects field positioning and sizing - ✅ Supports all field types - ✅ Falls back to 2-column layout if no layout configured - ✅ Works in both readonly (detail) and edit modes ### Layout Management - ✅ Multiple layouts per object - ✅ Default layout designation - ✅ Create, read, update, delete layouts - ✅ Tab-based interface in object setup ## Backward Compatibility The system maintains full backward compatibility: - Objects without page layouts use traditional section-based views - Existing DetailView and EditView components continue to work - Enhanced views automatically detect and use page layouts when available ## Technical Details ### Layout Storage Format ```json { "fields": [ { "fieldId": "uuid-of-field", "x": 0, // Column start (0-5) "y": 0, // Row start (0-based) "w": 3, // Width in columns (1-6) "h": 1 // Height in rows (fixed at 1) } ] } ``` ### Field Component Mapping The renderer automatically maps field types to appropriate components: - TEXT → TextFieldView - NUMBER → NumberFieldView - DATE/DATETIME → DateFieldView - BOOLEAN → BooleanFieldView - PICKLIST → SelectFieldView - EMAIL → EmailFieldView - PHONE → PhoneFieldView - URL → UrlFieldView - CURRENCY → CurrencyFieldView - PERCENT → PercentFieldView - TEXTAREA → TextareaFieldView ## Development ### Adding New Field Types 1. Create field view component in `components/fields/` 2. Add mapping in `PageLayoutRenderer.vue`: ```typescript const componentMap: Record = { // ... existing mappings NEW_TYPE: NewFieldView, } ``` ### Customizing Grid Settings Edit `PageLayoutEditor.vue`: ```typescript grid = GridStack.init({ column: 6, // Change column count cellHeight: 80, // Change cell height minRow: 1, // Minimum rows float: true, // Allow floating acceptWidgets: true, animate: true, }) ``` ## Troubleshooting ### Layout not appearing - Ensure migration has been run - Check that a default layout is set - Verify objectId is passed to enhanced views ### Fields not draggable - Check GridStack CSS is loaded - Verify draggable attribute on sidebar fields - Check browser console for errors ### Layout not saving - Verify API endpoints are accessible - Check authentication token - Review backend logs for errors ## Future Enhancements - [ ] Variable field heights - [ ] Field-level permissions in layouts - [ ] Clone/duplicate layouts - [ ] Layout templates - [ ] Layout preview mode - [ ] Responsive breakpoints - [ ] Related list sections - [ ] Custom components in layouts