|
| 1 | +# Angular 21 Migration Plan |
| 2 | + |
| 3 | +## Overview |
| 4 | +This document outlines the comprehensive migration of RangerTrak from Angular with legacy patterns to Angular 21 with modern features including signals, standalone components, and signal-based forms. |
| 5 | + |
| 6 | +## Migration Phases |
| 7 | + |
| 8 | +### Phase 1: Foundation & Cleanup ✓ IN PROGRESS |
| 9 | +**Goal:** Remove incompatible dependencies and set up modern infrastructure |
| 10 | + |
| 11 | +#### 1.1 Remove Incompatible Packages |
| 12 | +- [x] Remove `@angular-material-components/datetime-picker` (incompatible with Angular 21) |
| 13 | +- [x] Remove `@angular-material-components/color-picker` (incompatible with Angular 21) |
| 14 | +- [ ] Replace with native Angular Material components or custom implementations |
| 15 | + |
| 16 | +#### 1.2 Update Package.json |
| 17 | +- [ ] Clean up overrides section |
| 18 | +- [ ] Add any missing Angular 21 packages |
| 19 | +- [ ] Update tsconfig for Angular 21 features |
| 20 | + |
| 21 | +### Phase 2: Convert to Standalone Components |
| 22 | +**Goal:** Eliminate NgModules and adopt standalone architecture |
| 23 | + |
| 24 | +#### 2.1 Module Analysis |
| 25 | +Current modules to convert: |
| 26 | +- `AppModule` → Standalone bootstrap |
| 27 | +- `MaterialModule` → Direct component imports |
| 28 | +- `LazyModule` → Standalone lazy routes |
| 29 | + |
| 30 | +#### 2.2 Conversion Steps |
| 31 | +1. Convert all components to standalone |
| 32 | +2. Add explicit imports to each component |
| 33 | +3. Update routing to use standalone components |
| 34 | +4. Remove all NgModule declarations |
| 35 | +5. Update main.ts to bootstrap standalone component |
| 36 | + |
| 37 | +### Phase 3: Implement Signals for State Management |
| 38 | +**Goal:** Replace RxJS patterns with signals where appropriate |
| 39 | + |
| 40 | +#### 3.1 Services to Migrate |
| 41 | +- `DataService` - Convert BehaviorSubjects to signals |
| 42 | +- `FieldReportService` - Use signals for report state |
| 43 | +- `RangerService` - Use signals for ranger data |
| 44 | +- `ClockService` - Convert to signal-based time updates |
| 45 | +- `SettingsService` - Migrate settings to signals |
| 46 | +- `InstallableService` - Convert observable patterns |
| 47 | + |
| 48 | +#### 3.2 Signal Patterns |
| 49 | +```typescript |
| 50 | +// Before |
| 51 | +private dataSubject = new BehaviorSubject<Data[]>([]); |
| 52 | +data$ = this.dataSubject.asObservable(); |
| 53 | + |
| 54 | +// After |
| 55 | +readonly data = signal<Data[]>([]); |
| 56 | +readonly dataComputed = computed(() => this.data().filter(...)); |
| 57 | +``` |
| 58 | + |
| 59 | +### Phase 4: Modern Control Flow Syntax |
| 60 | +**Goal:** Replace structural directives with built-in control flow |
| 61 | + |
| 62 | +#### 4.1 Template Updates |
| 63 | +- Replace `*ngIf` with `@if` |
| 64 | +- Replace `*ngFor` with `@for` |
| 65 | +- Replace `*ngSwitch` with `@switch` |
| 66 | +- Use `@empty` for empty state handling |
| 67 | + |
| 68 | +#### 4.2 Components to Update |
| 69 | +- All HTML templates (58+ component templates) |
| 70 | + |
| 71 | +### Phase 5: Modernize Dependency Injection |
| 72 | +**Goal:** Use inject() function instead of constructor injection |
| 73 | + |
| 74 | +#### 5.1 Pattern |
| 75 | +```typescript |
| 76 | +// Before |
| 77 | +constructor( |
| 78 | + private http: HttpClient, |
| 79 | + private router: Router |
| 80 | +) {} |
| 81 | + |
| 82 | +// After |
| 83 | +private http = inject(HttpClient); |
| 84 | +private router = inject(Router); |
| 85 | +``` |
| 86 | + |
| 87 | +### Phase 6: Signal-Based Forms |
| 88 | +**Goal:** Integrate signals with reactive forms |
| 89 | + |
| 90 | +#### 6.1 Forms to Migrate |
| 91 | +- `EntryComponent` - Field report entry form |
| 92 | +- `LocationComponent` - Location input form |
| 93 | +- `SettingsComponent` - Settings editor form |
| 94 | +- `TimePickerComponent` - Time selection form |
| 95 | + |
| 96 | +#### 6.2 Modern Form Patterns |
| 97 | +```typescript |
| 98 | +// Use signal inputs |
| 99 | +readonly initialValue = input<string>(''); |
| 100 | + |
| 101 | +// Use signal outputs |
| 102 | +readonly formSubmit = output<FormData>(); |
| 103 | + |
| 104 | +// Create form with signals |
| 105 | +readonly form = new FormGroup({ |
| 106 | + field: new FormControl(this.initialValue()) |
| 107 | +}); |
| 108 | + |
| 109 | +// React to form changes with effects |
| 110 | +constructor() { |
| 111 | + effect(() => { |
| 112 | + const value = this.initialValue(); |
| 113 | + this.form.patchValue({ field: value }); |
| 114 | + }); |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +### Phase 7: Component Modernization |
| 119 | +**Goal:** Use modern component features |
| 120 | + |
| 121 | +#### 7.1 Signal Inputs/Outputs |
| 122 | +- Convert `@Input()` to `input()` signals |
| 123 | +- Convert `@Output()` to `output()` signals |
| 124 | +- Use `model()` for two-way binding |
| 125 | + |
| 126 | +#### 7.2 Components Priority List |
| 127 | +1. Shared components (Header, Footer, Navbar) |
| 128 | +2. Core components (Entry, FieldReports, Rangers) |
| 129 | +3. Map components (GMap, LMap) |
| 130 | +4. Settings components |
| 131 | +5. Utility components |
| 132 | + |
| 133 | +### Phase 8: Routing & Lazy Loading |
| 134 | +**Goal:** Modern routing with standalone components |
| 135 | + |
| 136 | +#### 8.1 Route Updates |
| 137 | +```typescript |
| 138 | +// Before |
| 139 | +{ |
| 140 | + path: 'about', |
| 141 | + loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) |
| 142 | +} |
| 143 | + |
| 144 | +// After |
| 145 | +{ |
| 146 | + path: 'about', |
| 147 | + loadComponent: () => import('./lazy/about/about.component').then(m => m.AboutComponent) |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +### Phase 9: Testing & Validation |
| 152 | +**Goal:** Ensure all features work correctly |
| 153 | + |
| 154 | +#### 9.1 Test Areas |
| 155 | +- [ ] Form submissions |
| 156 | +- [ ] Data persistence |
| 157 | +- [ ] Map interactions |
| 158 | +- [ ] Service worker functionality |
| 159 | +- [ ] Offline capabilities |
| 160 | +- [ ] Settings management |
| 161 | + |
| 162 | +## Breaking Changes to Address |
| 163 | + |
| 164 | +### Removed Angular Material APIs |
| 165 | +The following APIs used by deprecated packages need alternatives: |
| 166 | + |
| 167 | +1. **DateTime Picker** |
| 168 | + - Use native `MatDatepicker` with time input |
| 169 | + - Create custom time picker component if needed |
| 170 | + |
| 171 | +2. **Color Picker** |
| 172 | + - Use native HTML `<input type="color">` |
| 173 | + - Or use alternative library (ngx-colors) |
| 174 | + - Or create custom color picker |
| 175 | + |
| 176 | +### Template Syntax Changes |
| 177 | +- `[formGroup]` only works on `<form>` elements |
| 178 | +- New control flow syntax is required |
| 179 | +- Router directives need imports |
| 180 | + |
| 181 | +## Implementation Order |
| 182 | + |
| 183 | +1. ✓ **Remove incompatible packages** (Phase 1.1) |
| 184 | +2. **Fix immediate errors** (Add missing imports) |
| 185 | +3. **Convert to standalone** (Phase 2) |
| 186 | +4. **Update control flow** (Phase 4) - Can be done during conversion |
| 187 | +5. **Modernize DI** (Phase 5) - Can be done during conversion |
| 188 | +6. **Implement signals** (Phase 3) - Iterative process |
| 189 | +7. **Update forms** (Phase 6) - After signals are in place |
| 190 | +8. **Update routing** (Phase 8) |
| 191 | +9. **Test thoroughly** (Phase 9) |
| 192 | + |
| 193 | +## Estimated Timeline |
| 194 | +- **Phase 1:** 1-2 hours (removing packages, fixing imports) |
| 195 | +- **Phase 2:** 4-6 hours (standalone conversion) |
| 196 | +- **Phase 3:** 6-8 hours (signal implementation) |
| 197 | +- **Phase 4:** 2-3 hours (control flow updates) |
| 198 | +- **Phase 5:** 3-4 hours (DI modernization) |
| 199 | +- **Phase 6:** 4-5 hours (form updates) |
| 200 | +- **Phase 7:** 3-4 hours (component modernization) |
| 201 | +- **Phase 8:** 2-3 hours (routing updates) |
| 202 | +- **Phase 9:** 3-4 hours (testing) |
| 203 | + |
| 204 | +**Total:** ~30-40 hours of development time |
| 205 | + |
| 206 | +## Notes |
| 207 | +- This is a significant refactoring that touches most files |
| 208 | +- Each phase should be tested before moving to the next |
| 209 | +- Some phases can be done incrementally |
| 210 | +- Git commits should be made after each successful phase |
| 211 | +- Consider feature branches for major changes |
| 212 | + |
| 213 | +## Resources |
| 214 | +- [Angular Signals Guide](https://angular.dev/guide/signals) |
| 215 | +- [Standalone Components](https://angular.dev/guide/components/importing) |
| 216 | +- [Built-in Control Flow](https://angular.dev/guide/templates/control-flow) |
| 217 | +- [Modern Dependency Injection](https://angular.dev/guide/di/dependency-injection) |
0 commit comments