Layout Migration Guide
Overview
This document details the migration process from the single layout system to the multiple layouts system.
Before vs After
Old System (Before)
interface LayoutFidgetDetails {
fidgetInstanceIds: string[];
// Only desktop configurations
}
Characteristics:
- Single layout for all screens
- Mobile order configuration stored in each individual fidget
- No native support for different devices
- Feed always present in all contexts
New System (After)
interface LayoutFidgetDetails {
fidgetInstanceIds: string[]; // Maintained for compatibility
layouts?: { // New configuration
mobile: {
fidgetOrder: string[];
feedEnabled: boolean;
};
};
}
Characteristics:
- Centralized configuration per device type
- Automatic migration system
- Contextual feed (only in homebase)
- Separation of Concerns implemented
Automatic Migration Process
1. Old Layout Detection
// In Space.tsx
const needsMigration = !config.layoutDetails.layouts;
if (needsMigration) {
// Execute migration
}
2. Existing Data Collection
const collectExistingMobileOrder = (fidgetInstanceDatums) => {
return Object.entries(fidgetInstanceDatums)
.map(([id, datum]) => ({
id,
order: datum.config?.settings?.mobileOrder || 0
}))
.sort((a, b) => a.order - b.order)
.map(item => item.id);
};
3. New Configuration Generation
const generateMobileLayout = (fidgetInstanceDatums, pathname) => {
return {
fidgetOrder: collectExistingMobileOrder(fidgetInstanceDatums),
feedEnabled: pathname === '/homebase'
};
};
4. Update and Save
const migratedLayoutDetails = {
...existingLayoutDetails,
layouts: {
mobile: generateMobileLayout(fidgetInstanceDatums, pathname)
}
};
saveLayoutDetails(migratedLayoutDetails);
Files Modified in PR #1279
Main Modified Files
-
src/app/(spaces)/Space.tsx- Added detection and migration system
- Implemented Separation of Concerns
- Removed
showFeedOnMobileprop - Added sorting by mobile order
-
src/app/(spaces)/MobileViewSimplified.tsx(New)- Replaced complex
MobileView.tsx - Simplified component focused only on rendering
- Uses existing layout system
- Replaced complex
-
src/common/lib/theme/ThemeSettingsEditor.tsx- Implemented contextual feed management
- Removed
NogsGateButton - Updated to use new data structure
-
src/common/utils/layoutUtils.ts- Added support for explicit mobile order
- Implemented feed injection logic
-
src/fidgets/layout/tabFullScreen/index.tsx- Added
isHomebasePathprop - Updated tab ordering logic
- Simplified CSS and containers
- Added
Support Files
-
src/common/components/organisms/MobileNavbar.tsx- Current component for mobile navigation, replaces the old TabNavigation
-
src/common/components/organisms/MobileSettings.tsx- Updated draggable component key
Backward Compatibility
Existing Spaces
- Automatic Detection: System detects old layouts automatically
- Transparent Migration: User doesn't notice the migration
- Data Preservation: All existing configurations are maintained
- No Loss: No functionality is lost in the process
Preserved Data
// Data that is maintained during migration
{
fidgetInstanceIds: [...], // Kept exactly the same
data: {...}, // Preserved
customCSS: "...", // Preserved
// All other existing fields are maintained
// Only added:
layouts: {
mobile: {...} // New, based on existing data
}
}
Migration Detection Flow
During Loading
Data States
- Initial State: Old layout loaded from database
- Transition State: Migration being executed
- Final State: Migrated layout in use
- Persisted State: Data saved in new format
Points of Attention
During Migration
- ⚠️ SSR: Migration may not be complete on server
- ⚠️ Cache: Cached data may be in old format
- ⚠️ Performance: Migration only happens once per space
After Migration
- ✅ Consistency: All data is in new format
- ✅ Performance: No migration overhead
- ✅ Functionality: All features work normally
Testing and Validation
Test Scenarios
- New Space: Created already in current format
- Old Space: Migrated automatically
- Mixed Space: Some data migrated, others not
- Edge Cases: Corrupted or incomplete data
Validation
// Check if migration was successful
const validateMigration = (layoutDetails) => {
return (
layoutDetails.layouts &&
layoutDetails.layouts.mobile &&
Array.isArray(layoutDetails.layouts.mobile.fidgetOrder)
);
};
Rollback (If Necessary)
Rollback Strategy
If it's necessary to revert changes:
- Data: Old layouts are still preserved in
fidgetInstanceIds - Code: Revert to previous components
- Functionality: Old system can be restored
Preservation during Rollback
// Original data is always available
const originalLayout = layoutDetails.fidgetInstanceIds;
const mobileOrders = Object.values(fidgetInstanceDatums)
.map(d => d.config?.settings?.mobileOrder);
Monitoring
Metrics to Track
- Successful migration rate
- Performance during migration
- Migration errors
- Loading time after migration
Important Logs
// Logs for monitoring
console.log('Migration started for space:', spaceId);
console.log('Data before:', oldLayoutDetails);
console.log('Data after:', newLayoutDetails);
console.log('Migration completed in:', migrationTime);