|
| 1 | + |
1 | 2 | # Migration Log: DSOMM Modernization |
2 | 3 |
|
| 4 | + |
| 5 | + |
3 | 6 | This log tracks the progress of the Angular modernization project from version 13 towards version 21. |
4 | 7 |
|
| 8 | + |
| 9 | + |
5 | 10 | <details> |
| 11 | + |
6 | 12 | <summary><strong>Angular 13 → 14</strong></summary> |
7 | 13 |
|
| 14 | + |
| 15 | + |
8 | 16 | ### Summary |
| 17 | + |
9 | 18 | The initial upgrade from Angular 13 to 14 was performed using `ng update`. This phase focused on establishing a stable v14 base, resolving immediate template warnings, and adopting the new Typed Forms feature. |
10 | 19 |
|
| 20 | + |
| 21 | + |
11 | 22 | ### Commit History |
12 | 23 |
|
| 24 | + |
| 25 | + |
13 | 26 | #### 1. Chore: Upgrade Angular 13 to 14 ([c68f708b](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/c68f708b)) |
| 27 | + |
14 | 28 | - Executed `npx ng update @angular/core@14 @angular/cli@14 @angular-eslint/schematics@14`. [[logs](logs/angular-core-14.txt)] |
| 29 | + |
15 | 30 | - This was followed by a `npx ng update @angular/cdk@14 @angular/material@14` [[logs](logs/angular-cdk-14.txt)] |
16 | 31 |
|
| 32 | + |
| 33 | + |
17 | 34 |
|
18 | 35 | #### 2. Fix: Remove Unnecessary Optional Chaining ([387be213](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/387be213)) |
19 | | -- **Action:** Cleaned up template code to resolve `NG8107` warnings. |
20 | | -- **Reason:** Angular 14's improved template type checking flagged optional chaining (`?.`) on properties that are guaranteed to be defined (or where the parent is not null/undefined). This "chore" was necessary to clear the console of noise and ensure clean build outputs. |
21 | | -- **Log Reference:** [`npx ng serve` Warnings logs after prev commit - c68f708b](logs/13-14_warnings.txt) |
| 36 | + |
| 37 | +- **Action:** Cleaned up template code to resolve `NG8107` warnings. |
| 38 | + |
| 39 | +- **Reason:** Angular 14's improved template type checking flagged optional chaining (`?.`) on properties that are guaranteed to be defined (or where the parent is not null/undefined). This "chore" was necessary to clear the console of noise and ensure clean build outputs. |
| 40 | + |
| 41 | +- **Log Reference:** [`npx ng serve` Warnings logs after prev commit - c68f708b](logs/13-14_warnings.txt) |
| 42 | + |
| 43 | + |
22 | 44 |
|
23 | 45 | #### 3. Refactor: Migrate to Typed Reactive Forms ([3d36885e](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/3d36885e)) |
24 | | -- **Action:** Converted `UntypedFormControl`, `UntypedFormGroup`, etc., to their typed counterparts. |
25 | | -- **Reason:** One of the major benefits of Angular 14. This improves type safety across the application and catches potential form-related errors at compile time. |
| 46 | + |
| 47 | +- **Action:** Converted `UntypedFormControl`, `UntypedFormGroup`, etc., to their typed counterparts. |
| 48 | + |
| 49 | +- **Reason:** One of the major benefits of Angular 14. This improves type safety across the application and catches potential form-related errors at compile time. |
| 50 | + |
| 51 | + |
26 | 52 |
|
27 | 53 | #### 4. Fix: Update SettingsComponent Spec to Resolve Test Failures ([31aef4ab](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/31aef4ab)) |
28 | | -- **Action:** Fixed 3 failing tests in `settings.component.spec.ts` by providing missing mock data. |
29 | | -- **Reason:** Removing `?.` in commit `031ef6a1` exposed that the test environment never provided a `meta` object to the component. Since `MockLoaderService` returns no `meta`, `this.meta` stayed `undefined` at render time, causing Angular's template engine to crash with `Cannot read properties of undefined (reading 'activityMeta')`. Added a `meta` stub on the component instance before `detectChanges()`, and provided a `GithubService` spy which was also missing from the test providers. |
30 | | -- **Log Reference** [Test failures logs before this commit](logs/13-14_regression_test_failures.txt) |
| 54 | + |
| 55 | +- **Action:** Fixed 3 failing tests in `settings.component.spec.ts` by providing missing mock data. |
| 56 | + |
| 57 | +- **Reason:** Removing `?.` in commit `031ef6a1` exposed that the test environment never provided a `meta` object to the component. Since `MockLoaderService` returns no `meta`, `this.meta` stayed `undefined` at render time, causing Angular's template engine to crash with `Cannot read properties of undefined (reading 'activityMeta')`. Added a `meta` stub on the component instance before `detectChanges()`, and provided a `GithubService` spy which was also missing from the test providers. |
| 58 | + |
| 59 | +- **Log Reference** [Test failures logs before this commit](logs/13-14_regression_test_failures.txt) |
| 60 | + |
| 61 | + |
31 | 62 |
|
32 | 63 | --- |
33 | 64 |
|
| 65 | + |
| 66 | + |
34 | 67 | #### N. Fix: Correct Typography Configuration in Custom Theme ([commit_hash]) |
35 | | -- **Action:** Replaced `mat.define-typography-level()` with `mat.define-legacy-typography-config()` |
36 | | - and set the font-family to `Roboto, "Helvetica Neue", sans-serif`. |
37 | | -- **Reason:** The original code used `mat.define-typography-level()`, which creates a *single* |
38 | | - typography level (one set of font properties). However, `mat.core()` (and its v15 successor |
39 | | - `mat.all-legacy-component-typographies()`) expects a *full typography config* — a map containing |
40 | | - styles for every text category (headline, body, caption, etc.). Because of this type mismatch, |
41 | | - Angular Material silently ignored the custom config and fell back to its default font stack |
42 | | - (`Roboto, "Helvetica Neue", sans-serif`). The `Montserrat` font declared in the original code |
43 | | - was never actually rendered in production. Switching to `mat.define-legacy-typography-config()` |
44 | | - fixes the function signature, and using Roboto preserves visual parity with the live site. |
45 | | -- **Additional Change:** Reordered `@include` statements so `mat.legacy-core()` runs before |
46 | | - `mat.all-legacy-component-typographies()`, which is the documented correct order in v15 |
47 | | - (foundation before typography). |
| 68 | + |
| 69 | +- **Action:** Replaced `mat.define-typography-level()` with `mat.define-legacy-typography-config()` |
| 70 | + |
| 71 | +and set the font-family to `Roboto, "Helvetica Neue", sans-serif`. |
| 72 | + |
| 73 | +- **Reason:** The original code used `mat.define-typography-level()`, which creates a *single* |
| 74 | + |
| 75 | +typography level (one set of font properties). However, `mat.core()` (and its v15 successor |
| 76 | + |
| 77 | +`mat.all-legacy-component-typographies()`) expects a *full typography config* — a map containing |
| 78 | + |
| 79 | +styles for every text category (headline, body, caption, etc.). Because of this type mismatch, |
| 80 | + |
| 81 | +Angular Material silently ignored the custom config and fell back to its default font stack |
| 82 | + |
| 83 | +(`Roboto, "Helvetica Neue", sans-serif`). The `Montserrat` font declared in the original code |
| 84 | + |
| 85 | +was never actually rendered in production. Switching to `mat.define-legacy-typography-config()` |
| 86 | + |
| 87 | +fixes the function signature, and using Roboto preserves visual parity with the live site. |
| 88 | + |
| 89 | +- **Additional Change:** Reordered `@include` statements so `mat.legacy-core()` runs before |
| 90 | + |
| 91 | +`mat.all-legacy-component-typographies()`, which is the documented correct order in v15 |
| 92 | + |
| 93 | +(foundation before typography). |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +</details> |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +<details> |
| 102 | + |
| 103 | +<summary><strong>Angular 14 → 15</strong></summary> |
| 104 | + |
| 105 | + |
| 106 | + |
| 107 | +### Summary |
| 108 | + |
| 109 | +The upgrade from Angular 14 to 15 involved multiple phases: a TypeScript prerequisite upgrade, the Angular core/CLI `ng update`, the Angular Material/CDK `ng update` (which auto-aliases all components to `mat-legacy-*`), a typography configuration fix, the full MDC migration using Angular's CLI schematics, manual resolution of all `TODO(mdc-migration)` comments, several rounds of CSS/template/component fixes for chips, sliders, form-fields, buttons, and dark-mode styling, test suite updates, and finally a full migration to standalone components (removing `AppModule` and `MaterialModule` entirely). |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +### Commit History |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | +#### 1. Chore: Upgrade TypeScript to 4.8 ([24645b16](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/24645b16)) |
| 118 | + |
| 119 | +- **Action:** Bumped `typescript` from `^4.6.4` to `^4.8.0` in `package.json`. |
| 120 | + |
| 121 | + |
| 122 | + |
| 123 | +#### 2. Chore: Upgrade Angular Core & CLI to v15 ([6a433bbb](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/6a433bbb)) |
| 124 | + |
| 125 | +- **Action:** Executed `npx ng update @angular/core@15 @angular/cli@15 @angular-eslint/schematics@15`. |
| 126 | + |
| 127 | +- **Key Changes:** |
| 128 | + |
| 129 | +- All `@angular/*` core packages bumped from `^14.3.0` to `^15.2.10`. |
| 130 | + |
| 131 | +- `@angular-devkit/build-angular` bumped from `^14.2.13` to `^15.2.11`. |
| 132 | + |
| 133 | +- `@angular-eslint/*` packages bumped from `^14.4.0` to `^15.2.1`. |
| 134 | + |
| 135 | +- `@typescript-eslint/*` bumped from `^5.36.2` to `^5.43.0`. |
| 136 | + |
| 137 | +- `tsconfig.json`: `target` changed from `es2020` to `ES2022`, added `"useDefineForClassFields": false` (required by Angular 15's class field semantics). |
| 138 | + |
| 139 | +- `src/test.ts`: Removed deprecated `require.context()` bootstrapping; Angular 15's test builder auto-discovers spec files. |
| 140 | + |
| 141 | +- `angular.json`: Added `schematics` configuration for `@angular-eslint`. |
| 142 | + |
| 143 | +- **Files:** `angular.json`, `package.json`, `package-lock.json`, `src/test.ts`, `tsconfig.json` |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | +#### 3. Chore: Upgrade Angular Material & CDK to v15 ([a9999c51](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/a9999c51)) |
| 148 | + |
| 149 | +- **Action:** Executed `npx ng update @angular/cdk@15 @angular/material@15`. |
| 150 | + |
| 151 | +- **Key Changes:** |
| 152 | + |
| 153 | +- `@angular/cdk` bumped from `^14.2.7` to `^15.2.9`. |
| 154 | + |
| 155 | +- `@angular/material` bumped from `^14.2.7` to `^15.2.9`. |
| 156 | + |
| 157 | +- **Auto-aliasing to `mat-legacy-*`:** The `ng update` schematic automatically rewrote all Material imports across the entire codebase to use legacy aliases (e.g., `MatButtonModule` → `MatLegacyButtonModule as MatButtonModule`). This is Angular Material 15's strategy for maintaining backward compatibility while introducing new MDC-based components. |
| 158 | + |
| 159 | +- **`material.module.ts`:** All 14 Material module imports were aliased (Button, List, Table, Chips, ProgressSpinner, Autocomplete, Input, Select, FormField, Card, Checkbox, Slider, etc.). |
| 160 | + |
| 161 | +- **Component files:** Dialog, Tooltip, Menu imports were aliased across `app.module.ts`, all modal components, all page components, all spec files, and the notification service. |
| 162 | + |
| 163 | +- **`custom-theme.scss`:** |
| 164 | + |
| 165 | +- `mat.core()` → `mat.legacy-core()` |
| 166 | + |
| 167 | +- `mat.all-component-themes()` → `mat.all-legacy-component-themes()` |
| 168 | + |
| 169 | +- Added auto-generated `TODO(v15)` comment about typography migration |
| 170 | + |
| 171 | +- Added `mat.all-legacy-component-typographies($custom-typography)` |
| 172 | + |
| 173 | +- **Files:** 24 files changed across `package.json`, `app.module.ts`, all component `.ts`/`.spec.ts` files, `material.module.ts`, `notification.service.ts`, `custom-theme.scss` |
| 174 | + |
| 175 | + |
| 176 | + |
| 177 | +#### 4. Fix: Correct Typography Configuration & Theme Structure ([d354b9f5](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/d354b9f5)) |
| 178 | + |
| 179 | +- **Action:** |
| 180 | + |
| 181 | +- Replaced `mat.define-typography-level()` with `mat.define-legacy-typography-config($font-family: 'Roboto, Helvetica Neue, sans-serif')`. |
| 182 | + |
| 183 | +- Reordered SCSS `@include` statements: `mat.legacy-core()` before `mat.all-legacy-component-typographies()`. |
| 184 | + |
| 185 | +- Changed `mat.all-legacy-component-themes()` → `mat.all-legacy-component-colors()` (avoids re-emitting typography/density styles). |
| 186 | + |
| 187 | + |
| 188 | +- **Reason:** The original code used `mat.define-typography-level()` which produces a single level, not a full config map. Material silently ignored it and fell back to defaults. `Montserrat` was never rendered in production. Using `mat.define-legacy-typography-config()` fixes the signature, and Roboto preserves visual parity with the live site. The `all-legacy-component-colors()` mixin avoids duplicate typography emission when theme colors differ between light/dark modes. |
| 189 | + |
| 190 | +- **Files:** `custom-theme.scss`, `docs/migration-doc.md`, `teams.component.html`, `teams.component.ts` |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | +#### 5. Refactor: Run MDC Migration Schematics ([66c409cd](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/66c409cd)) |
| 195 | + |
| 196 | +- **Action:** Executed `ng generate @angular/material:mdc-migration` to migrate all legacy components to MDC. |
| 197 | + |
| 198 | +- **Key Changes (38 files):** |
| 199 | + |
| 200 | +- **CSS:** Auto-generated `TODO(mdc-migration)` comments on rules targeting legacy internal classes (`.mat-slider-horizontal`, `.mat-chip-list`, `.mat-form-field-wrapper`, `.mat-card-header`, etc.) |
| 201 | + |
| 202 | +- **`custom-theme.scss`:** |
| 203 | + |
| 204 | +- `mat.legacy-core()` → `mat.core()` |
| 205 | + |
| 206 | +- `mat.all-legacy-component-typographies()` → `mat.all-component-typographies()` |
| 207 | + |
| 208 | +- `mat.all-legacy-component-colors()` → `mat.all-component-colors()` |
| 209 | + |
| 210 | +- CSS selectors updated: `.mat-table` → `.mat-mdc-table`, `.mat-header-row` → `.mat-mdc-header-row`, `.mat-row` → `.mat-mdc-row`, etc. |
| 211 | + |
| 212 | +- **`styles.css`:** Slider rules updated with `TODO(mdc-migration)` comments. |
| 213 | + |
| 214 | +- **Note:** The CLI migration produced some duplicate `@include` calls and leftover `TODO` comments that were cleaned up in the next commit. |
| 215 | + |
| 216 | +- **Files:** 38 files across all components, specs, modules, theme, and global styles |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | +#### 6. Fix: Resolve All MDC Migration TODOs ([d414cb90](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/d414cb90)) |
| 221 | + |
| 222 | +- **Action:** Manually resolved every `TODO(mdc-migration)` comment generated by the CLI schematics, replacing legacy CSS selectors with their MDC-compliant equivalents. |
| 223 | + |
| 224 | +- **Files:** 15 files across `progress-slider`, `report-config-modal`, `circular-heatmap`, `mapping`, `matrix`, `settings` components + `custom-theme.scss` + `styles.css` |
| 225 | + |
| 226 | + |
| 227 | + |
| 228 | +#### 7. Fix: Migrate Sidenav List Directives to MDC ([b8b39d4c](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/b8b39d4c)) |
| 229 | + |
| 230 | +- **Action:** Updated `sidenav-buttons.component.html` to use MDC list directives. |
| 231 | + |
| 232 | +- **Key Changes:** |
| 233 | + |
| 234 | +- `mat-list-icon` → `matListItemIcon`, `mat-line` → `matListItemTitle` |
| 235 | + |
| 236 | +- Added component CSS for `[matListItemIcon]` with spacing overrides (`margin-right: 18px`, `margin-left: 22px`) to restore icon alignment matching the legacy layout. |
| 237 | + |
| 238 | +- **Reason:** The MDC `mat-list` uses structural directives (`matListItemIcon`, `matListItemTitle`, `matListItemLine`) instead of legacy attribute selectors (`mat-list-icon`, `mat-line`). The CLI migration schematic did not catch these in the sidenav component. |
| 239 | + |
| 240 | +- **Files:** `sidenav-buttons.component.html`, `sidenav-buttons.component.css` |
| 241 | + |
| 242 | + |
| 243 | + |
| 244 | +#### 8. Fix: Resolve Heatmap Chip Selection and Styling Issues ([769b63af](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/769b63af)) |
| 245 | + |
| 246 | +- **Action:** Rewrote the circular heatmap's team filter chip logic and template to work correctly with MDC chips. |
| 247 | + |
| 248 | +- **Key Changes:** |
| 249 | + |
| 250 | +- **Template:** Removed wrapping `<mat-form-field>` from chip listboxes (MDC chips should not be inside form fields for selection-only use). Replaced with plain `<label>` + `<mat-chip-listbox>` structure. Added `<mat-divider>` separators. Changed filter toggle button from `mat-button` to `mat-icon-button`. |
| 251 | + |
| 252 | +- **TypeScript:** Completely rewrote `toggleTeamGroupFilter()` and `toggleTeamFilter()`: |
| 253 | + |
| 254 | +- **Reason:** The initial MDC migration (commits 5-6) broke chip filtering because the MDC `MatChipOption` API differs fundamentally from legacy `MatChip`. The old imperative `chip.toggleSelected()` + `(click)` pattern doesn't work with MDC's `(selectionChange)` event model, which fires *after* internal state is already updated. The form field wrapper also caused rendering issues because MDC chips render their own outline. |
| 255 | + |
| 256 | +- **Files:** `circular-heatmap.component.html`, `circular-heatmap.component.ts`, `custom-theme.scss` |
| 257 | + |
| 258 | + |
| 259 | + |
| 260 | +#### 9. Fix: Resolve Button, Input, and Panel CSS Issues ([8582349b](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/8582349b)) |
| 261 | + |
| 262 | +- **Action:** Fixed broken styling across multiple components after the MDC migration. |
| 263 | + |
| 264 | + |
| 265 | + |
| 266 | +- **Reason:** MDC components use different DOM structures and default spacing than legacy components. The migration schematics update import paths and top-level selectors but cannot account for deep CSS customizations or layout assumptions built around legacy internal structures. |
| 267 | + |
| 268 | +- **Files:** 7 files across `add-evidence-modal`, `report-config-modal`, `team-selector`, `circular-heatmap`, `settings`, `custom-theme.scss` |
| 269 | + |
| 270 | + |
| 271 | +### NOTE |
| 272 | + |
| 273 | +- ⚠️ A few minor visual regressions were flagged after this manual UI change (see [Backlog](#backlog) below). |
| 274 | + |
| 275 | +- Decision: **move ahead with the next upgrade cycle (Angular 15 → 16 → ... → 21)** and track the remaining visual polish items as backlog. |
| 276 | + |
| 277 | + |
| 278 | + |
| 279 | +#### 10. Fix: Resolve Matrix Chip Selection and Rendering Issues ([30aa3ee1](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/30aa3ee1)) |
| 280 | + |
| 281 | +- **Action:** Fixed the Matrix page's chip filters and table rendering. |
| 282 | + |
| 283 | + |
| 284 | +- **Reason:** The Matrix page had the same chip API incompatibility as the heatmap. Additionally, the `<div>` inside `<table>` rendered silently under legacy Material but broke under MDC's stricter DOM expectations. |
| 285 | + |
| 286 | +- **Files:** `matrix.component.css`, `matrix.component.html`, `matrix.component.ts` |
| 287 | + |
| 288 | + |
| 289 | + |
| 290 | +#### 11. Fix: Update Matrix Spec to Use MatChipSelectionChange API ([9970e77e](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/9970e77e)) |
| 291 | + |
| 292 | +- **Action:** Updated `matrix.component.spec.ts` to match the new `MatChipSelectionChange` event-based API. |
| 293 | + |
| 294 | + |
| 295 | +- **Reason:** The component's filter functions now accept `MatChipSelectionChange` events instead of `MatChip` instances, and use `setTimeout()` internally. Tests needed `fakeAsync`/`tick` to properly exercise the async filter logic. |
| 296 | + |
| 297 | +- **Files:** `matrix.component.spec.ts` |
| 298 | + |
| 299 | + |
| 300 | + |
| 301 | +#### 12. Refactor: Migrate All Components to Standalone ([9ec0c58f](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/9ec0c58f)) |
| 302 | + |
| 303 | +- **Action:** Converted every component, directive, and pipe in the application to `standalone: true`, then deleted `AppModule` and `MaterialModule`. |
| 304 | + |
| 305 | + |
| 306 | +- **Reason:** Angular 15 is the first version to support standalone components as stable. Migrating removes the centralized `AppModule` / `MaterialModule` barrel pattern, enabling: |
| 307 | + |
| 308 | +- **Files:** 52 files — all components, directives, pipes, specs, `main.ts` |
| 309 | + |
| 310 | + |
| 311 | + |
| 312 | +</details> |
| 313 | + |
| 314 | + |
| 315 | + |
| 316 | + |
| 317 | +--- |
| 318 | + |
| 319 | + |
| 320 | + |
| 321 | + |
| 322 | + |
| 323 | +--- |
| 324 | + |
| 325 | + |
| 326 | + |
| 327 | +## Backlog |
| 328 | + |
| 329 | + |
| 330 | + |
| 331 | +Known issues deferred from the Angular 14 → 15 migration. These should be addressed alongside or after the upgrade to Angular 21. |
| 332 | + |
| 333 | +| # | Component | Issue | Priority | Notes | |
| 334 | +|---|-----------|-------|----------|-------| |
| 335 | +| 1 | `ProgressSliderComponent` | Slider styling doesn't fully match the pre-migration look. The main issue is in the progress slider's background color in light mode: contrast is lesser. Also the discrete tick marks for completion levels were removed during the MDC migration. The legacy slider supported `[tickInterval]="1"` to render visible notch lines at each step, helping users distinguish between progress levels.. | Medium | The MDC `<mat-slider>` uses a nested `<input matSliderThumb>` pattern with different internal CSS classes (`.mdc-slider__track--active_fill`, `.mdc-slider__thumb-knob`). Current overrides work functionally but the visual fidelity can be improved. | |
| 336 | + |
| 337 | + |
| 338 | + |
| 339 | +> [!NOTE] |
| 340 | +
|
| 341 | +> Add new backlog items here as they are discovered during future upgrades. Remove items once resolved. |
0 commit comments