# Layout Preset Migration Guide

## Overview

This document tracks the migration of high-traffic dashboard widgets and core modules to use the shared layout preset registry (`FrontEnd/js/core/layoutPresets.js`). The registry provides consistent DaisyUI/Tailwind layouts with tenant/department override support and responsive breakpoint management.

---

## Migration Status

### ✅ Completed Migrations

| Module/Component | File Path | Status | Notes |
|-----------------|-----------|--------|-------|
| **Dashboard** | `FrontEnd/Dashboard.php` | ✅ Complete | PHP helper integrated; uses preset registry for grid container and card items |
| **Dashboard.js** | `FrontEnd/js/modules/Dashboard.js` | ✅ Complete | Dynamic card rendering uses `getItemClasses()`; drawer preset applied |
| **ModuleBuilder** | `FrontEnd/js/modules/ModuleBuilder/ModuleBuilder.js` | ✅ Complete | Full layout editor with tenant/department overrides |
| **PageConfigBuilder** | `FrontEnd/js/modules/PageConfigBuilder/PageConfigBuilder.js` | ✅ Complete | Full layout editor; persists to page_configs |
| **ModuleLoader** | `FrontEnd/js/core/ModuleLoader.js` | ✅ Complete | Runtime resolution with `computeEffectiveLayout()` |
| **ModalBuilder** | `FrontEnd/js/core/ModalBuilder.js` | ✅ Complete | Added `buildCard()` and `buildAccordion()` preset-aware renderers |

---

### ✅ High-Priority Migrations (Completed)

| Module/Component | File Path | Status | Notes |
|-----------------|-----------|--------|-------|
| **WorkflowInstances** | `FrontEnd/js/modules/WorkflowInstances.js` | ✅ Complete | Grid layout migrated to `responsiveGrid` preset; supports layout override via mount options |
| **InventoryManagement** | `FrontEnd/js/modules/Inventory/InventoryManagement.js` | ✅ Complete | Tab navigation migrated to `tabs` preset; ARIA attributes added; supports mount options |
| **POS** | `FrontEnd/js/modules/POS/POS.js` | ✅ Phase 1 Complete | Categories grid migrated to `cards` preset; item buttons use preset classes; additional phases deferred |

---

### 📋 Pending Migrations

| Module/Component | File Path | Priority | Estimated Effort | Notes |
|-----------------|-----------|----------|------------------|-------|
| **WorkflowTasks** | `FrontEnd/js/modules/WorkflowTasks.js` | Medium | 2-3h | Queue/task list rendering |
| **WorkflowAdmin** | `FrontEnd/js/modules/WorkflowAdmin.js` | Medium | 2-3h | Admin grid views |
| **WorkflowBuilder** | `FrontEnd/js/modules/WorkflowBuilder/WorkflowBuilder.js` | Low | 3-4h | Designer canvas layout |
| **Calendar** | `FrontEnd/js/modules/Calendar.js` | Medium | 4-5h | Event grid/list views |
| **UserProfile** | `FrontEnd/js/modules/UserProfile.js` | Medium | 3-4h | Profile card layouts |
| **Organisation** | `FrontEnd/js/modules/Organisation.js` | Low | 2-3h | Org hierarchy views |
| **Employees** | `FrontEnd/js/modules/Employees.js` | Medium | 2-3h | Employee list/grid |
| **Payroll** | `FrontEnd/js/modules/Payroll/*.js` | Low | 4-6h | Multiple payroll modules |

---

## Migration Checklist

For each module being migrated, follow these steps:

### 1. **Identify Layout Patterns**
- [ ] Review current hardcoded classes (cards, grids, tables, tabs)
- [ ] Document responsive breakpoints in use
- [ ] Note any custom container/item styling
- [ ] Identify tenant/department-specific overrides

### 2. **Import Layout Preset APIs**
```javascript
import {
  getPreset,
  applyContainerPreset,
  getItemClasses,
  getContainerClasses,
  resolvePreset,
  DEFAULT_PRESET_ID,
} from 'core/layoutpresets';
```

### 3. **Replace Hardcoded Classes**

**Before:**
```javascript
const $card = $('<div class="card bg-base-100 shadow rounded-lg p-4"></div>');
```

**After:**
```javascript
const preset = getPreset('cards');
const itemClasses = getItemClasses('cards');
const $card = $(`<div class="${itemClasses}"></div>`);
```

### 4. **Apply Container Presets**

**Before:**
```javascript
const $grid = $('<div class="grid grid-cols-2 md:grid-cols-3 gap-4"></div>');
```

**After:**
```javascript
const $grid = $('<div></div>');
applyContainerPreset($grid[0], 'cards', {
  preserveExistingAttributes: true,
});
```

### 5. **Support Layout Overrides**

If the module accepts layout configuration:
```javascript
// In mount() or initialization
function mount(target = '#work-area', options = {}) {
  const layoutPreset = options.layoutPreset || DEFAULT_PRESET_ID;
  const overrides = options.layoutOverrides || {};
  
  const resolved = resolvePreset(layoutPreset, overrides);
  // Apply to containers...
}
```

### 6. **Provide Fallback for Legacy Usage**

Maintain backwards compatibility:
```javascript
// Detect legacy usage
const hasLegacyClasses = $element.attr('class')?.includes('legacy-pattern');
if (hasLegacyClasses) {
  console.warn('Module using legacy layout classes; consider migrating');
  // Keep existing classes intact
} else {
  // Apply preset
  applyContainerPreset($element[0], presetId);
}
```

### 7. **Update Tests**

Add Jest tests for preset usage:
```javascript
describe('ModuleName layout presets', () => {
  it('applies container preset correctly', () => {
    const container = document.createElement('div');
    applyContainerPreset(container, 'cards');
    expect(container.classList.contains('dashboard-grid')).toBe(true);
  });
});
```

### 8. **Document Module-Specific Presets**

If creating custom presets:
```javascript
import { registerPreset } from 'core/layoutpresets';

// Register module-specific preset
registerPreset('inventory-grid', {
  container: {
    tag: 'section',
    classes: 'inventory-container grid gap-4 md:grid-cols-3',
    attributes: { 'aria-label': 'Inventory items' },
  },
  item: {
    tag: 'article',
    classes: 'inventory-card card bg-base-100 p-4 shadow',
  },
  breakpoints: {
    sm: 'sm:grid-cols-2',
    md: 'md:grid-cols-3',
    lg: 'lg:grid-cols-4',
  },
});
```

---

## High-Priority Module Migration Results

### 1. InventoryManagement Migration ✅

**File:** `FrontEnd/js/modules/Inventory/InventoryManagement.js`

**Completed Changes:**
- ✅ Imported layout preset APIs (`getPreset`, `applyContainerPreset`)
- ✅ Replaced tab container with `tabs` preset
- ✅ Applied preset classes to tab buttons (including `tab-active` for DaisyUI)
- ✅ Added ARIA attributes (`role="tab"`, `aria-selected`)
- ✅ Applied preset to tabs container after DOM insertion
- ✅ Added module-level `moduleLayoutPreset` configuration
- ✅ Mount function now accepts `options` parameter for layout overrides

**Actual Effort:** ~1 hour

**Breaking Changes:** None - fallback classes preserved

**Testing Notes:** Tab switching tested; ARIA attributes improve accessibility

---

### 2. WorkflowInstances Migration ✅

**File:** `FrontEnd/js/modules/WorkflowInstances.js`

**Completed Changes:**
- ✅ Imported layout preset APIs (`applyContainerPreset`, `getContainerClasses`)
- ✅ Replaced hardcoded grid classes with `responsiveGrid` preset
- ✅ Added `data-layout-container` attribute for preset targeting
- ✅ Applied preset to container after DOM insertion
- ✅ Preserved fallback classes for backwards compatibility
- ✅ Mount function now accepts `options` parameter for layout overrides
- ✅ Module-level `layoutPreset` configuration added

**Actual Effort:** ~30 minutes

**Breaking Changes:** None - fallback classes preserved

**Testing Notes:** Grid responsive behavior maintained; preset override tested

---

### 3. POS Migration (Phase 1) ✅

**File:** `FrontEnd/js/modules/POS/POS.js`

**Completed Changes (Phase 1 - Categories Grid):**
- ✅ Imported layout preset APIs (`getPreset`, `getItemClasses`, `applyContainerPreset`)
- ✅ Replaced hardcoded categories grid classes with `cards` preset
- ✅ Applied preset to categoriesGrid after DOM insertion
- ✅ Category buttons now use preset item classes
- ✅ Added ARIA attributes (`role="button"`, `aria-label`)
- ✅ Added module-level `posLayoutPreset` configuration
- ✅ Mount function now accepts `options` parameter for layout overrides

**Actual Effort:** ~45 minutes

**Breaking Changes:** None - fallback classes preserved

**Deferred Phases:**
- Phase 2: Cart layout table (not critical for MVP)
- Phase 3: Payment forms (uses existing modals)
- Phase 4: Full integration testing (scheduled for QA cycle)

**Testing Notes:** Category grid displays correctly; button interactions preserved; QZ Tray printing unaffected

---

## Best Practices

### DO:
✅ Use `resolvePreset()` when applying overrides  
✅ Always provide fallback classes for legacy compatibility  
✅ Test responsive behavior at multiple breakpoints  
✅ Document custom presets in module comments  
✅ Use `preserveExistingAttributes: true` when applying presets  
✅ Add Jest tests for preset application  

### DON'T:
❌ Remove legacy classes without testing backwards compatibility  
❌ Create duplicate presets for similar layouts (reuse existing)  
❌ Hardcode tenant/department overrides (use preset system)  
❌ Skip accessibility attributes (role, aria-*)  
❌ Forget to handle preset resolution failures gracefully  

---

## Testing Checklist

Before marking a module as migrated:

- [ ] Visual regression test at sm/md/lg/xl breakpoints
- [ ] Test with different layout presets (cards, responsiveGrid, accordion)
- [ ] Verify tenant override application (if applicable)
- [ ] Verify department override application (if applicable)
- [ ] Check ARIA attributes preserved
- [ ] Test keyboard navigation still works
- [ ] Verify no console errors or warnings
- [ ] Test legacy usage paths (if fallback provided)
- [ ] Run Jest suite for module
- [ ] Manual smoke test on staging/test environment

---

## Performance Considerations

### Lazy Loading Presets
Presets are loaded once on initial import via `layoutPresets.js`. No runtime overhead for re-fetching.

### Class Merging
The `joinClassList()` helper deduplicates classes, preventing bloat from overrides.

### Minimal Re-renders
Layout presets are applied once during mount. Dynamic updates only re-apply changed sections.

---

## Rollback Plan

If a migration causes issues:

1. **Immediate:** Add `data-layout-legacy="true"` attribute to affected containers
2. **Detect in code:**
   ```javascript
   if ($element.data('layout-legacy')) {
     // Skip preset application
     return;
   }
   ```
3. **Revert commit:** Each migration should be a separate commit for easy rollback
4. **Document issue:** Add to "Known Issues" section below

---

## Known Issues

*None currently tracked.*

---

## Custom Presets Registry

Document any module-specific presets created during migration:

| Preset ID | Module | Purpose | Container Classes | Item Classes |
|-----------|--------|---------|-------------------|--------------|
| *(none yet)* | - | - | - | - |

---

## Resources

- Layout Preset API: `FrontEnd/js/core/layoutPresets.js`
- PHP Helper: `FrontEnd/helpers/LayoutPresetHelper.php`
- Preset Definitions: `FrontEnd/config/layoutPresets.json`
- ModuleLoader Integration: `FrontEnd/js/core/ModuleLoader.js` (lines 70-180)
- ModuleBuilder Editor: `FrontEnd/js/modules/ModuleBuilder/ModuleBuilder.js` (lines 470-720)
- Jest Tests: `tests/js/layoutPresets.test.js`

---

## Timeline

| Milestone | Target Date | Status |
|-----------|-------------|--------|
| Foundation & Core Modules | 2025-10-04 | ✅ Complete |
| High-Priority Modules (Inventory, Workflow, POS) | 2025-10-11 | 🔄 In Progress |
| Medium-Priority Modules | 2025-10-18 | 📋 Planned |
| Low-Priority Modules | 2025-10-25 | 📋 Planned |
| Documentation & Training | 2025-11-01 | 📋 Planned |

---

## Questions & Support

For migration questions or issues:
- Review this guide and linked resources
- Check Jest test examples in `tests/js/layoutPresets.test.js`
- Consult AGENTS.md for architecture patterns
- Raise issues in project tracker with `layout-preset-migration` tag

---

**Last Updated:** 2025-10-04  
**Maintained By:** TAF Development Team
