diff --git a/.eslintrc.json b/.eslintrc.json index ebab12145..542ae520a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -49,14 +49,23 @@ "rules": {} }, { - "files": ["*.html"], - "excludedFiles": ["*inline-template-*.component.html"], - "extends": ["plugin:prettier/recommended"], + "files": [ + "*.html" + ], + "excludedFiles": [ + "*inline-template-*.component.html" + ], + "extends": [ + "plugin:prettier/recommended" + ], "rules": { - // NOTE: WE ARE OVERRIDING THE DEFAULT CONFIG TO ALWAYS SET THE PARSER TO ANGULAR (SEE BELOW) - "prettier/prettier": ["error", { "parser": "angular" }] + "prettier/prettier": [ + "error", + { + "parser": "angular" + } + ] } } - ] } diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9d09dd6f9..815ac831d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,11 +7,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Use Node.js 16.16.0 - uses: actions/setup-node@v1 + - uses: actions/checkout@v4 + - name: Use Node.js 20.19.6 + uses: actions/setup-node@v4 with: - node-version: 16.0 + node-version: 20.19.6 - name: Install dependencies run: npm install --legacy-peer-deps - name: Test diff --git a/angular.json b/angular.json index 2b3baa67e..1bb8d0b27 100644 --- a/angular.json +++ b/angular.json @@ -15,14 +15,22 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-angular:application", "options": { - "outputPath": "dist/dsomm", + "outputPath": { + "base": "dist/dsomm", + "browser": "" + }, "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", + "browser": "src/main.ts", + "polyfills": [ + "@angular/localize/init", + "zone.js" + ], "tsConfig": "tsconfig.app.json", - "allowedCommonJsDependencies": ["yamljs"], + "allowedCommonJsDependencies": [ + "yamljs" + ], "assets": [ "src/favicon.ico", "src/assets" @@ -56,9 +64,7 @@ "outputHashing": "all" }, "development": { - "buildOptimizer": false, "optimization": false, - "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -70,10 +76,10 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "DSOMM:build:production" + "buildTarget": "DSOMM:build:production" }, "development": { - "browserTarget": "DSOMM:build:development" + "buildTarget": "DSOMM:build:development" } }, "defaultConfiguration": "development" @@ -81,14 +87,14 @@ "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "DSOMM:build" + "buildTarget": "DSOMM:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", - "polyfills": "src/polyfills.ts", + "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", "assets": [ @@ -114,9 +120,42 @@ } } }, - "defaultProject": "DSOMM", "cli": { - "defaultCollection": "@angular-eslint/schematics", - "analytics": false + "analytics": false, + "schematicCollections": [ + "@angular-eslint/schematics" + ] + }, + "schematics": { + "@angular-eslint/schematics:application": { + "setParserOptionsProject": true + }, + "@angular-eslint/schematics:library": { + "setParserOptionsProject": true + }, + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } } } diff --git a/docs/migration-doc.md b/docs/migration-doc.md new file mode 100644 index 000000000..c918283f9 --- /dev/null +++ b/docs/migration-doc.md @@ -0,0 +1,641 @@ + +# Migration Log: DSOMM Modernization + + + +This log tracks the progress of the Angular modernization project from version 13 towards version 21. + + + +
+ +Angular 13 → 14 + + + +### Summary + +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. + + + +### Commit History + + + +#### 1. Chore: Upgrade Angular 13 to 14 ([c68f708b](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/c68f708b)) + +- Executed `npx ng update @angular/core@14 @angular/cli@14 @angular-eslint/schematics@14`. + +- This was followed by a `npx ng update @angular/cdk@14 @angular/material@14`. + + + + +#### 2. Fix: Remove Unnecessary Optional Chaining ([387be213](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/387be213)) + +- **Action:** Cleaned up template code to resolve `NG8107` warnings. + +- **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. + + + + +#### 3. Refactor: Migrate to Typed Reactive Forms ([3d36885e](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/3d36885e)) + +- **Action:** Converted `UntypedFormControl`, `UntypedFormGroup`, etc., to their typed counterparts. + +- **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. + + + +#### 4. Fix: Update SettingsComponent Spec to Resolve Test Failures ([31aef4ab](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/31aef4ab)) + +- **Action:** Fixed 3 failing tests in `settings.component.spec.ts` by providing missing mock data. + +- **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. + + +--- + + + + +
+ + + +
+ +Angular 14 → 15 + + + +### Summary + +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). + + + +### Commit History + + + +#### 1. Chore: Upgrade TypeScript to 4.8 ([24645b16](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/24645b16)) + +- **Action:** Bumped `typescript` from `^4.6.4` to `^4.8.0` in `package.json`. + + + +#### 2. Chore: Upgrade Angular Core & CLI to v15 ([6a433bbb](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/6a433bbb)) + +- **Action:** Executed `npx ng update @angular/core@15 @angular/cli@15 @angular-eslint/schematics@15`. + +- **Key Changes:** + +- All `@angular/*` core packages bumped from `^14.3.0` to `^15.2.10`. + +- `@angular-devkit/build-angular` bumped from `^14.2.13` to `^15.2.11`. + +- `@angular-eslint/*` packages bumped from `^14.4.0` to `^15.2.1`. + +- `@typescript-eslint/*` bumped from `^5.36.2` to `^5.43.0`. + +- `tsconfig.json`: `target` changed from `es2020` to `ES2022`, added `"useDefineForClassFields": false` (required by Angular 15's class field semantics). + +- `src/test.ts`: Removed deprecated `require.context()` bootstrapping; Angular 15's test builder auto-discovers spec files. + +- `angular.json`: Added `schematics` configuration for `@angular-eslint`. + +- **Files:** `angular.json`, `package.json`, `package-lock.json`, `src/test.ts`, `tsconfig.json` + + + +#### 3. Chore: Upgrade Angular Material & CDK to v15 ([a9999c51](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/a9999c51)) + +- **Action:** Executed `npx ng update @angular/cdk@15 @angular/material@15`. + +- **Key Changes:** + +- `@angular/cdk` bumped from `^14.2.7` to `^15.2.9`. + +- `@angular/material` bumped from `^14.2.7` to `^15.2.9`. + +- **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. + +- **`material.module.ts`:** All 14 Material module imports were aliased (Button, List, Table, Chips, ProgressSpinner, Autocomplete, Input, Select, FormField, Card, Checkbox, Slider, etc.). + +- **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. + +- **`custom-theme.scss`:** + +- `mat.core()` → `mat.legacy-core()` + +- `mat.all-component-themes()` → `mat.all-legacy-component-themes()` + +- Added auto-generated `TODO(v15)` comment about typography migration + +- Added `mat.all-legacy-component-typographies($custom-typography)` + +- **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` + + + +#### 4. Fix: Correct Typography Configuration & Theme Structure ([d354b9f5](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/d354b9f5)) + +- **Action:** + +- Replaced `mat.define-typography-level()` with `mat.define-legacy-typography-config($font-family: 'Roboto, Helvetica Neue, sans-serif')`. + +- Reordered SCSS `@include` statements: `mat.legacy-core()` before `mat.all-legacy-component-typographies()`. + +- Changed `mat.all-legacy-component-themes()` → `mat.all-legacy-component-colors()` (avoids re-emitting typography/density styles). + + +- **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. + +- **Files:** `custom-theme.scss`, `docs/migration-doc.md`, `teams.component.html`, `teams.component.ts` + + + +#### 5. Refactor: Run MDC Migration Schematics ([66c409cd](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/66c409cd)) + +- **Action:** Executed `ng generate @angular/material:mdc-migration` to migrate all legacy components to MDC. + +- **Key Changes (38 files):** + +- **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.) + +- **`custom-theme.scss`:** + +- `mat.legacy-core()` → `mat.core()` + +- `mat.all-legacy-component-typographies()` → `mat.all-component-typographies()` + +- `mat.all-legacy-component-colors()` → `mat.all-component-colors()` + +- CSS selectors updated: `.mat-table` → `.mat-mdc-table`, `.mat-header-row` → `.mat-mdc-header-row`, `.mat-row` → `.mat-mdc-row`, etc. + +- **`styles.css`:** Slider rules updated with `TODO(mdc-migration)` comments. + +- **Note:** The CLI migration produced some duplicate `@include` calls and leftover `TODO` comments that were cleaned up in the next commit. + +- **Files:** 38 files across all components, specs, modules, theme, and global styles + + + +#### 6. Fix: Resolve All MDC Migration TODOs ([d414cb90](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/d414cb90)) + +- **Action:** Manually resolved every `TODO(mdc-migration)` comment generated by the CLI schematics, replacing legacy CSS selectors with their MDC-compliant equivalents. + +- **Files:** 15 files across `progress-slider`, `report-config-modal`, `circular-heatmap`, `mapping`, `matrix`, `settings` components + `custom-theme.scss` + `styles.css` + + + +#### 7. Fix: Migrate Sidenav List Directives to MDC ([b8b39d4c](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/b8b39d4c)) + +- **Action:** Updated `sidenav-buttons.component.html` to use MDC list directives. + +- **Key Changes:** + +- `mat-list-icon` → `matListItemIcon`, `mat-line` → `matListItemTitle` + +- Added component CSS for `[matListItemIcon]` with spacing overrides (`margin-right: 18px`, `margin-left: 22px`) to restore icon alignment matching the legacy layout. + +- **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. + +- **Files:** `sidenav-buttons.component.html`, `sidenav-buttons.component.css` + + + +#### 8. Fix: Resolve Heatmap Chip Selection and Styling Issues ([769b63af](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel/commit/769b63af)) + +- **Action:** Rewrote the circular heatmap's team filter chip logic and template to work correctly with MDC chips. + +- **Key Changes:** + +- **Template:** Removed wrapping `` from chip listboxes (MDC chips should not be inside form fields for selection-only use). Replaced with plain `