[ZEPPELIN-6424] Upgrade zeppelin-web-angular from Angular 13 to Angular 21#5260
Merged
Conversation
Bumps zeppelin-web-angular from Angular 13.4 to 14.3 in a single lock-step: - @angular/* 13.4 -> 14.3 - @angular/cdk 13.3 -> 14.2 - @angular/cli 13.3 -> 14.2 - @angular-eslint/* 13.5 -> 14.4 - @angular-architects/module-federation 13.0 -> 14.3 - @angular-builders/custom-webpack 13.1 -> 14.1 - ngx-build-plus 13 -> 14 - ng-packagr 13.3 -> 14.2 - ng-zorro-antd 13.4 -> 14.3 - typescript 4.6 -> 4.7 (Angular 14 minimum) - rxjs 6.5 -> 6.6 (module-federation 14 peer) - zone.js 0.11.4 -> 0.11.5 The original spec aimed to leave monaco-editor untouched, but Angular 14's stricter build pipeline forced compatible bumps for: - monaco-editor 0.30.1 -> 0.31.1 - monaco-editor-webpack-plugin 6.0.0 -> 7.0.1 - @babel/runtime via overrides to ^7.27 (transitive dep missing regeneratorValues helper required by Angular 14 babel pipeline) angular.json adjustments are mechanical (whitespace, lintFilePatterns formatting) applied by Angular's update schematics, plus prettier normalization. Angular 14's new features (Strict typed forms, Standalone components) are NOT adopted in this change; only version-level upgrade.
…ms opt-out Auto-applied by 'ng update @angular/core --from=13 --to=14'. In Angular 14, FormControl/FormGroup/FormBuilder/FormArray accept a type parameter for the new strict typed forms. To preserve the existing untyped behavior without changes to form logic, the migration switches references to UntypedFormControl, UntypedFormGroup, UntypedFormBuilder, and UntypedFormArray. This is a backwards-compatible rename only. No runtime behavior change. Adopting strict typed forms is intentionally deferred to a separate future change.
…naco CSS
Angular 14's @angular-devkit/build-angular tightened its CSS pipeline
so that CSS files imported via JS from inside node_modules (as
monaco-editor does) no longer match the default css rule, breaking
the build with "no loaders are configured to process this file".
Adding a plain style-loader+css-loader rule on top of the object-form
config also failed because Angular's existing postcss+mini-css-extract
rule still matched and chained on the JS output, producing a postcss
SyntaxError.
Switch to the function form supported by @angular-builders/custom-webpack:
module.exports = (config, options, targetOptions) => { ... };
This lets us walk Angular's existing module.rules, exclude
monaco-editor from any rule that handles .css, then append our own
dedicated style-loader+css-loader rule scoped to /monaco-editor/.
Existing Module Federation and MonacoWebpackPlugin setup is preserved
unchanged.
prettier --check picked up two existing classic-visualization HTML templates that drift from the project's prettier config. Applying prettier --write is a no-op for runtime behavior; this just makes lint green on the upgrade branch.
Bumps zeppelin-web-angular from Angular 14.3 to 15.2: - @angular/* 14.3 -> 15.2 - @angular/cdk 14.2 -> 15.2 - @angular/cli 14.2 -> 15.2 - @angular-eslint/* 14.4 -> 15.2 - @angular-architects/module-federation 14.3 -> 15.0 - @angular-builders/custom-webpack 14.1 -> 15.0 - @angular-devkit/build-angular 14.2 -> 15.2 - ngx-build-plus 14 -> 15 - ng-packagr 14.2 -> 15.2 - ng-zorro-antd 14.3 -> 15.1 - typescript 4.7 -> 4.8 (Angular 15 minimum) monaco-editor (0.31.1) and monaco-editor-webpack-plugin (7.0.1) stay unchanged; Angular 15's build pipeline accepts them without the webpack rule changes that 13 -> 14 required. Angular 15 schematic migrations applied: - Router: relativeLinkResolution removed (no code changes needed) - RouterLinkWithHref unified into RouterLink (no code changes needed) - ng-zorro v15 migration completed (no code changes needed) No source code changes from migration; this is a pure version bump on top of the 14 work in the same branch.
Required to fix a runtime "Class constructor Message cannot be
invoked without 'new'" error in MessageService.
@zeppelin/sdk and @zeppelin/visualization sub-projects build to
FESM2020 (ES2015+ classes). The main app's tsconfig kept target=es5,
so its ES5-transpiled MessageService — which extends Message from
@zeppelin/sdk — emitted a downleveled `Message.call(this)` against
a real ES2015 class. That fails at runtime: ES2015 classes refuse to
be invoked without `new`.
The matching schematic ('Update TypeScript compilation target to
ES2020') was queued by `ng update @angular/cli --from=13 --to=14`
but bailed out with "Path /tsconfig.json does not exist" because
this workspace puts tsconfigs under src/ and projects/ instead of
the root. Applying the change manually.
es2020 is the minimum recommended target for Angular 14+ and is
already supported by the project's browserslist.
Earlier ng update runs handled @angular/core, @angular/cli, @angular/cdk, and ng-zorro-antd migrations directly, but the @angular-eslint package has its own migration schematics that were never explicitly invoked. Running 'ng update @angular-eslint/schematics --migrate-only' for both 13->14 and 14->15 produced: - @typescript-eslint/eslint-plugin ^5.36.2 -> ^5.43.0 - @typescript-eslint/parser ^5.36.2 -> ^5.43.0 - eslint ^8.23.0 -> ^8.28.0 - angular.json: cli.analytics=false (suppresses CLI's telemetry prompt during the first ng command) - angular.json: schematics block with setParserOptionsProject=true for @angular-eslint/schematics:{application,library} so future generated apps/libraries get type-aware lint by default Build and lint pass with the same 0 errors / 249 warnings baseline.
Bumps zeppelin-web-angular from Angular 15.2 to 16.2: - @angular/* 15.2 -> 16.2 - @angular/cdk 15.2 -> 16.2 - @angular/cli 15.2 -> 16.2 - @angular-eslint/* 15.2 -> 16.3 - @angular-architects/module-federation 15.0 -> 16.0 - @angular-builders/custom-webpack 15.0 -> 16.0 - @angular-devkit/build-angular 15.2 -> 16.2 - ngx-build-plus 15 -> 16 - ng-packagr 15.2 -> 16.2 - ng-zorro-antd 15.1 -> 16.2 - typescript 4.8 -> 5.1 (Angular 16 requires >=4.9.3 <5.2) - zone.js 0.11.5 -> 0.13.3 (Angular 16 default) - @typescript-eslint/* 5.43 -> 5.62 Adds @ctrl/tinycolor ^3.6.0 as a direct dependency: ng-zorro-antd 16's core color module imports it but does not declare it as a dependency, so it must be provided explicitly to resolve at build time.
Auto-applied by 'ng update @angular/core --from=15 --to=16'. Angular 15.2 deprecated the class-based guard interfaces (CanActivate, Resolve, etc.). The migration removes 'implements CanActivate' and the corresponding import from LoginGuard and WorkspaceGuard. The canActivate methods themselves are unchanged and still wired through the route config, so runtime guard behavior is identical.
ng-zorro-antd 16 removed the deprecated `nzComponentParams` option from `NzModalService.create` / `ModalOptions`. Component data is now passed via `nzData` and delivered to the opened component through the `NZ_MODAL_DATA` injection token instead of being set as @input properties. Migrated all four modal call sites and the three opened components: - action-bar.component.ts -> NoteCreateComponent (cloneNote) - note-action.service.ts -> NoteRenameComponent (id, newName) - note-action.service.ts -> FolderRenameComponent (folderId, newFolderPath) - note-action.service.ts -> NoteCreateComponent (path) Each component now injects NZ_MODAL_DATA in its constructor and assigns the values to the same fields it used before, so all internal logic and templates are untouched. The former @input decorators (no longer fed by ng-zorro) are dropped; the properties remain. Behavior of the Clone Note, Rename Note, and Rename Folder dialogs is preserved.
@angular-eslint 16 removed the legacy TSLint-compatibility presets '@angular-eslint/ng-cli-compat' and 'ng-cli-compat--formatting-add-on' that this project's .eslintrc.json extended (a leftover from the original TSLint -> ESLint conversion). Without them ng lint failed to load. Changes: - Replace the two ng-cli-compat extends with the standard 'plugin:@angular-eslint/recommended'. - Declare the plugins whose rules the config references but that ng-cli-compat used to load implicitly: @typescript-eslint, import, jsdoc, prefer-arrow. - Disable @angular-eslint/no-empty-lifecycle-method (newly enforced as error by 'recommended'). 17 pre-existing empty lifecycle methods tripped it; turning it off keeps the lint baseline at 0 errors rather than churning 17 unrelated components in a dependency-upgrade PR. ng lint passes with the same 0 errors / 248 warnings baseline as before.
Bumps zeppelin-web-angular from Angular 16.2 to 17.3: - @angular/* 16.2 -> 17.3 - @angular/cdk 16.2 -> 17.3 - @angular/cli 16.2 -> 17.3 - @angular-eslint/* 16.3 -> 17.5 - @angular-architects/module-federation 16.0 -> 17.0 - @angular-builders/custom-webpack 16.0 -> 17.0 - @angular-devkit/build-angular 16.2 -> 17.3 - ngx-build-plus 16 -> 17 - ng-packagr 16.2 -> 17.3 - ng-zorro-antd 16.2 -> 17.4 - typescript 5.1 -> 5.4 (Angular 17 requires >=5.2 <5.5) - zone.js 0.13 -> 0.14 (Angular 17 default) - @typescript-eslint/* 5.x -> 7.x (required by @angular-eslint 17) - eslint 8.39 -> 8.57 The project keeps the webpack-based browser builder via @angular-builders/custom-webpack; Angular 17's new esbuild/vite application builder is not adopted (it would not support the existing custom webpack config / Module Federation setup).
Auto-applied by 'ng update @angular/core --from=16 --to=17' (the migration left a dangling comma due to a partial edit, fixed here). Under Ivy, CompilerOptions.useJit (and missingTranslation) have no effect and were removed from the type in Angular 17. The runtime compiler providers still create the JIT compiler via JitCompilerFactory; dropping the no-op useJit flag changes nothing at runtime.
After the ng-zorro upgrade, clicking the header user menu items (Interpreter, Notebook Repos, Credential, Configuration) only navigated when the click landed on the link text. Clicking the row padding closed the dropdown without navigating. Root cause: ng-zorro renders nz-menu-item content inside <span class="ant-menu-title-content"> even inside a dropdown, but the upstream rule that stretches the inner <a> across the whole item targets `.ant-dropdown-menu-title-content > a::after`. The class mismatch (ant-menu-* vs ant-dropdown-menu-*) left the <a> covering only its text, so clicking the padding hit the <li>, which closes the dropdown via descendantMenuItemClick without firing routerLink. ng-zorro 13 had no title-content span wrapper, so the link filled the row; the wrapper introduced in later versions is what regressed it. Fix, scoped to this one dropdown so nothing else is affected: - Tag the dropdown overlay with nzOverlayClassName="zeppelin-user-menu". - In header.component.less, an absolutely-filled <a>::after reclaims the whole row as the link hit area. The dropdown renders in a body-level CDK overlay, so the rule uses ::ng-deep to escape view encapsulation, but the .zeppelin-user-menu scope keeps it from leaking to any other dropdown or component. The rule is colocated with the component that owns the dropdown instead of living in global styles. Regression test: e2e/tests/workspace/user-menu-navigation.spec.ts opens the dropdown and clicks the empty row padding (not the text) for each item, asserting navigation. A future ng-zorro/Angular upgrade that reintroduces the dead zone fails here. Verified with a headless elementFromPoint probe: before the fix, clicks on the row padding resolve to the <li>; after, every point resolves to the <a>.
Bumps zeppelin-web-angular from Angular 17.3 to 18.2: - @angular/* 17.3 -> 18.2 - @angular/cdk 17.3 -> 18.2 - @angular/cli 17.3 -> 18.2 - @angular-eslint/* 17.5 -> 18.4 - @angular-architects/module-federation 17.0 -> 18.0 - @angular-builders/custom-webpack 17.0 -> 18.0 - @angular-devkit/build-angular 17.3 -> 18.2 - ngx-build-plus 17 -> 18 - ng-packagr 17.3 -> 18.2 - ng-zorro-antd 17.4 -> 18.2 - typescript 5.4 -> 5.5 (Angular 18 requires >=5.4 <5.6) - zone.js stays ~0.14.10 @typescript-eslint stays on ^7.x: @angular-eslint 18 accepts @typescript-eslint/utils ^7.11.0 || ^8.0.0, and its migration schematic pins 7.x, which is compatible with TypeScript 5.5. The bump to @typescript-eslint 8 is deferred to the Angular 19 step that requires it.
…ngular 18 Auto-applied by 'ng update @angular/core --from=17 --to=18'. Angular 18 deprecates the module-based HTTP setup. The migration swaps HttpClientModule for provideHttpClient(withInterceptorsFromDi()) in both AppModule and WorkspaceModule. withInterceptorsFromDi() preserves the existing class-based HTTP_INTERCEPTORS registrations (the app's request/ message interceptors), so HTTP behavior is unchanged. Both modules already imported HttpClientModule before, so the provider placement mirrors the previous structure exactly.
Angular 18's build pipeline (newer less) broke the dark/light theme build with "ReferenceError: colorPalette is not defined". The theme files computed the antd color ramp via inline JavaScript: @primary-1: color(~`colorPalette('@{primary-color}', 1) `); ng-zorro registers colorPalette as a Less function via `@plugin "./colorPalette"` (node_modules/ng-zorro-antd/src/style/color/ colorPalette.less), not as a JavaScript global, so the inline-JS form can no longer resolve it. ng-zorro's own colors.less calls it as a Less function: `color(colorPalette('@{blue-6}', 1))`. Switch all 38 usages (primary ramp, link colors, alert colors) in theme-dark.less and theme-light.less from the inline-JS backtick form to the plain Less-function form. The colorPalette function is registered by the colors.less import that theme-mixin.less already pulls in, so it is in scope. Computed colors are unchanged.
Bump @angular/* 18.2.14 -> 19.2.24, @angular/cdk -> 19.2.19, @angular/cli and @angular-devkit/build-angular -> 19.2.26, ng-zorro-antd 18.2.1 -> 19.3.1, ng-packagr -> 19.2.2, @angular-architects/module-federation -> 19.0.3, @angular-builders/custom-webpack -> 19.0.1, ngx-build-plus -> 19.0.0, @angular-eslint/* 18.4.3 -> 19.8.1, @typescript-eslint/* 7.x -> 8.x, typescript 5.5.4 -> 5.7.3, zone.js 0.14.10 -> 0.15.1. Versions hand-picked to satisfy peer ranges (Angular 19 compiler-cli allows TypeScript >=5.5 <5.9; ng-zorro 19 requires Angular ^19). ESLint stays on 8.57 -- the angular-eslint 19 migration's bump to ESLint 9 / flat config is deferred to a dedicated step. RxJS remains on 6. Schematic migrations and the resulting code changes follow in subsequent commits.
…for Angular 19 Auto-applied by 'ng update @angular/core --from=18 --to=19'. Angular 19 flips the Component/Directive/Pipe `standalone` default from false to true. This app is NgModule-based -- every declarable is listed in an NgModule -- so the migration adds explicit `standalone: false` to each of them to preserve module compilation. No behavior change. The dynamic-forms and note-import components receive the same standalone: false addition in their respective fix commits (the ng-zorro checkbox migration and the lint adaptation), where they are also touched.
Auto-applied by 'ng update ng-zorro-antd --from=18 --to=19'. ng-zorro 19 ships a redesigned nz-input-number and moves the previous implementation to ng-zorro-antd/input-number-legacy. The migration swaps NzInputNumberModule for NzInputNumberLegacyModule in the runtime dynamic module, which keeps the same nz-input-number selector and rendered control. (No template in the app currently uses nz-input-number, so this only preserves the existing import behavior.)
…ng-zorro 19
ng-zorro 19 splits nz-checkbox-group's old dual-purpose model. Before, a
single [(ngModel)] array of {label, value, checked} objects both rendered
the options and carried the checked state. Now the choices are passed via
[nzOptions] ({label, value} only) and the ngModel holds the array of
selected values directly -- NzCheckboxOption no longer has a `checked`
field (NzCheckBoxOptionInterface is now a deprecated alias of it).
dynamic-forms.component built the old shape and read e.checked in the
change handler, which no longer compiles under v19 (TS2339 'checked' does
not exist on NzCheckboxOption; TS2322 (string|number)[] not assignable to
string|string[]). Migrate it while preserving behavior:
- checkboxGroups[name] now holds NzCheckboxOption[] ({label, value}) for
[nzOptions].
- new checkboxValues[name] holds the selected values, seeded from
paramDefs so the initial checked state is unchanged.
- template binds [nzOptions]=options and one-way [ngModel]=selected
values, with (ngModelChange) writing the selected values back to
paramDefs (one-way + write-back avoids the string|string[] vs
(string|number)[] two-way type mismatch).
This component also carries the Angular 19 `standalone: false` addition
from the core schematic.
…script-eslint 8
angular-eslint 19 adds @angular-eslint/prefer-standalone to the
recommended set, which errors on the `standalone: false` the Angular 19
migration just added to every NgModule declarable. This app is
intentionally NgModule-based, so the rule is turned off.
typescript-eslint 8 removes the `ban-types` rule (split into
no-wrapper-object-types / no-unsafe-function-type / no-empty-object-type)
and tightens no-unused-vars (caughtErrors now defaults to 'all', and vars
used only in a type position are reported):
- .eslintrc.json: replace the ban-types config with no-wrapper-object-
types + no-unsafe-function-type, preserving the ban on Object/String/
Number/Boolean/Function while still allowing {} (which ban-types had
recommended as the alternative).
- shortcut.service.ts: retarget the inline disable at the new rule name
(no-unsafe-function-type) for the deliberate `Function` type.
- copy-text-to-clipboard / note-import / spell-result: use optional catch
binding (`catch {`) for the three intentionally-ignored errors.
- notebook-paragraph-keyboard-event-handler: disable no-unused-vars on
the const array referenced only via `typeof` to derive a type.
note-import.component also carries its `standalone: false` addition from
the core schematic. ng build, ng build --configuration production and ng
lint are all green (0 errors).
…rver `ng serve` failed with "Schema validation failed ... must have required property 'buildTarget'". Angular renamed the dev-server / extract-i18n `browserTarget` option to `buildTarget` in v17 and removed the old name in v19. `ng build` never touches these targets, so the gap only surfaced at serve time (not in the build/prod-build/lint gate run during the upgrade). The 18->19 `ng update @angular/cli` migration didn't catch it: the rename shipped as a v16->17 migration (not re-run on an 18->19 step) and it skips custom builder targets anyway -- serve uses @angular-builders/custom-webpack:dev-server. v18 still accepted browserTarget as a deprecated alias, so it slipped through until v19 dropped it. Rename all four occurrences (serve options + production/development configurations + extract-i18n) to buildTarget. `ng serve` now boots and compiles successfully; `ng build` and build:angular are unaffected (they use the build target, untouched).
Angular 20 drops Node 18 support (requires ^20.19 || ^22.12 || >=24), so the frontend build must move off the pinned Node 18.20.8 before the 19->20 upgrade. Pin Node 22.21.1 (current active LTS) with its bundled npm 10.9.4 in pom.xml's frontend-maven-plugin, and widen package.json engines to >=22.12.0. Done as an isolated step ahead of the Angular 20 dep bump: the existing Angular 19 app reinstalls from the unchanged lockfile (npm ci) and builds (dev + production), lints (0 errors) and `ng serve` boots cleanly under Node 22 / npm 10. No lockfile churn. Local dev builds now run on Node 22 (e.g. via mise); the vendored ./node binary is gitignored and is refreshed to 22.21.1 on the next Maven frontend build.
Bump @angular/* 19.2.24 -> 20.3.23, @angular/cdk -> 20.2.14, @angular/cli and @angular-devkit/build-angular -> 20.3.26, ng-zorro-antd 19.3.1 -> 20.4.4, ng-packagr -> 20.3.2, @angular-architects/module-federation, @angular-builders/custom-webpack and ngx-build-plus -> 20.0.0, @angular-eslint/* 19.8.1 -> 20.7.0, @typescript-eslint/* -> ^8.33.1, typescript 5.7.3 -> 5.9.3. rxjs ~6.6.7 -> ~7.8.2 is forced: ng-zorro 20's compiled code imports operators (debounceTime, finalize, filter) from the 'rxjs' root, which only resolves under RxJS 7. Angular 20 supports both 6 and 7; ng-zorro 20 needs 7. ESLint stays on ^8.57.0: the @angular-eslint 20 migration bumps it to 9, but ESLint 9 defaults to flat config and the lint-staged pre-commit hook runs eslint directly (not via the angular-eslint builder), so under 9 it can't resolve .eslintrc.json. angular-eslint 20 still supports eslint 8 + eslintrc; the ESLint 9 + flat-config migration is deferred to its own step. zone.js stays ~0.15.1; Node was bumped to 22 separately. Schematic migrations and code adaptations follow in subsequent commits.
Auto-applied by 'ng update @angular/core --from=19 --to=20'. Angular 20 deprecates re-exporting DOCUMENT from @angular/common and exports it from @angular/core instead. The migration moves the import in the two services that inject it (shortcut.service, code-editor.service). Same token, no behavior change.
Covers ng-zorro 19 -> 20 breaking changes (schematic + manual): - nz-tabset -> nz-tabs: the `ng update ng-zorro-antd` schematic renamed the component (note-import template + the NzTabsModule imports). - NzMessageModule / NzNotificationModule removed: ng-zorro 20 drops these modules; NzMessageService / NzNotificationService are providedIn 'root' and create their (standalone) containers on demand, so the modules are just deleted from the five modules that imported them. Service usage is unchanged. - nz-button-group removed (Ant Design 5 dropped Button.Group): replace with nz-space-compact, which propagates nzSize to child buttons the same way. Updates action-bar and result templates, the colocated button-group LESS selectors, and adds NzSpaceModule to the two declaring modules.
…create
Angular CDK 20 removed the long-deprecated PortalInjector, and
ComponentPortal dropped its componentFactoryResolver constructor argument
(its 4th parameter is now projectableNodes).
Build the portal injector with Injector.create({ providers, parent })
instead -- same semantics: the VISUALIZATION token resolves to the
visualization instance and falls back to the view-container injector.
Drop the now-unused componentFactoryResolver constructor parameter (all
six call sites already omit it) and the matching ComponentPortal
argument. The WeakMap + eslint-disable the old PortalInjector required
are no longer needed.
RxJS 7 tightens types that RxJS 6 left loose: - Subject.next() now requires an argument. Type the nine signal subjects used purely for teardown as Subject<void> so next() stays valid; the SDK's close$ (a WebSocket closeObserver of CloseEvent) gets a real normal-closure CloseEvent in close() instead of an undefined push (the old no-arg next() would have made the event.code subscriber throw). - interpreter's search$.next() on destroy dropped: it only needs complete(), and Subject<string>.next() can no longer be called bare. - KeyBinder's destroySubject is only read via takeUntil, so type it Observable<unknown> (Subject<void> is assignable to it; Subject<void> is not assignable to the old Subject<unknown>). - toPromise() now resolves T | undefined and is deprecated; switch the two typed call sites (configuration, classic-visualization) to lastValueFrom, which keeps the non-undefined result type. No observable behavior change.
…ngular-eslint 20) angular-eslint 20 adds @angular-eslint/prefer-inject to the recommended set, which errors on every constructor-parameter injection (226 across the app). This codebase uses constructor DI throughout; migrating to the inject() function is a large, separate refactor, so the rule is turned off -- same call made for prefer-standalone at Angular 19. ng lint runs clean (0 errors) under angular-eslint 20, which still supports the existing .eslintrc.json on ESLint 8.
angular-eslint 20's `ng lint` bridges ESLint 9 to the legacy .eslintrc.json, but the lint-staged pre-commit hook runs `eslint` directly, where ESLint 9 defaults to flat config and can't load eslintrc. Rather than pin the hook to ESLINT_USE_FLAT_CONFIG=false, move to flat config so every path (ng lint, raw eslint, pre-commit) shares one modern config and we are off EOL ESLint 8. - eslint ^8.57.0 -> ^9.28.0; swap the individual @angular-eslint and @typescript-eslint plugin/parser packages for the `angular-eslint` and `typescript-eslint` meta-packages (which ship the flat presets). Keep @angular-eslint/builder and @angular-eslint/schematics (angular.json refs). - Add eslint.config.js as a 1:1 port of the three .eslintrc.json files: the root TS rules + inline-template processor + prettier, the `zeppelin` selector prefixes, and the `lib` prefix override for the two library projects. dist/, target/, .angular/ and the React sub-app are ignored. - Drop the four @typescript-eslint formatting rules (member-delimiter-style, semi, type-annotation-spacing, quotes) that v8 removed; they were already `off` and Prettier owns formatting. Flat config validates configured rules, so dead entries can't remain. - Comment, in the config, why every rule the 13->20 upgrade turned off is off (no-empty-lifecycle-method @16, prefer-standalone @19, prefer-inject @20) and why ban-types became no-wrapper-object-types + no-unsafe-function-type. ng lint, raw `eslint` and `npm run lint` all run clean (0 errors). The member-ordering / prefer-arrow warning counts shift slightly (250 -> 265) from ESLint 9 / flat-config processing -- same two rules, no new rules, no errors.
Bump @angular/* 20.3.23 -> 21.2.15, @angular/cdk -> 21.2.13, @angular/cli and @angular-devkit/build-angular -> 21.2.13, ng-zorro-antd 20.4.4 -> 21.3.0, ng-packagr -> 21.2.3, @angular-architects/module-federation -> 21.2.2, @angular-builders/custom-webpack -> 21.0.3, angular-eslint / @angular-eslint/* 20.7.0 -> 21.4.0. Node 22.21.1 and TypeScript 5.9.3 already satisfy Angular 21's requirements (node ^20.19 || ^22.12 || >=24; typescript >=5.9 <6.1, and ng-packagr caps it at <6.0). rxjs 7.8, zone.js 0.15, eslint 9 and typescript-eslint 8 are all still in range, so they stay put. ngx-build-plus stays at ^20.0.0: it has no 21 release, but it is unused (no angular.json builder references it) and its peers are satisfied by Angular 21 (>=20). Schematic migrations and code adaptations follow.
…exports Angular 21 (and ng-zorro 21, @ant-design/icons-angular) drop their per-secondary-entry-point directories and expose entry points only through the package `exports` map. The classic `moduleResolution: node` can't read exports maps, so imports like @angular/common/http, @angular/platform-browser/animations and @ant-design/icons-angular/icons stopped resolving during type-checking (the webpack bundle resolved them, but tsc did not). Switch tsconfig.base.json to `moduleResolution: bundler`, the modern default for a bundled Angular app, which reads exports maps. `module` stays es2020 (bundler allows es2015+). The `ng update @angular/cli` migration also dropped the redundant `lib: ["dom", "es2018"]` override from the two library tsconfigs (they inherit it from the base), included here.
Auto-applied by 'ng update @angular/core --from=20 --to=21', which runs the built-in control-flow migration by default in v21: *ngIf / *ngFor / *ngSwitch become @if / @for / @switch across 37 templates. Behavior is unchanged; the new block syntax is Angular's recommended, more performant form and needs no CommonModule structural directives. One hand-fix on top of the migration output: for the two paragraph templates it emitted `track trackByIndexFn(i, result)`, but trackByIndexFn takes a single `index` parameter, so the explicit two-arg call failed type-checking (TS2554). Dropped the extra argument to `track trackByIndexFn(i)` (the function only ever used the index).
…ular 21 Auto-applied by the Angular 21 migration. bootstrapModule now takes an options bag with applicationProviders, and the migration makes the (previously implicit) zone-based change detection explicit via provideZoneChangeDetection(). Behavior is unchanged -- the app still runs with Zone.js change detection.
ng-zorro 21 restructured several secondary entry points (its own migration schematic crashed under Node 22 with "exports is not defined in ES module scope", so these are applied by hand): - ng-zorro-antd/core/no-animation is gone; NzNoAnimationModule now lives in ng-zorro-antd/core/animation (runtime-dynamic-module + notebook module). - ng-zorro-antd/input-number-legacy is gone (the v19 migration window closed); switch the aggregator back to NzInputNumberModule from ng-zorro-antd/input-number. nz-input-number is not used in any template, so this only keeps the runtime module list valid. - ng-zorro-antd/back-top (NzBackTopModule) was removed; drop it from the aggregator -- nz-back-top is unused. - job-manager: NzHighlightModule was removed in favour of the standalone NzHighlightPipe; import the pipe directly (the nzHighlight pipe is still used in the job template).
…lar/animations ng-zorro 21 removed its @angular/animations-based motion. The collapseMotion trigger no longer exists, and overlays (dropdown/select/tooltip/popover) now animate through Angular's native CSS animate.enter/animate.leave instead of the JS animation engine, so neither the @angular/animations package nor a BrowserAnimations provider is required anymore. - Migrate the credential and interpreter collapse panels from the removed collapseMotion trigger to NzAnimationCollapseDirective (ng-zorro-antd/core/animation). - Wrap each panel body in a flow-root BFC so the directive's sum-of-children-offsetHeight open measurement matches the panel's final auto height; without it the animation stops short and the layout jumps. - Remove BrowserAnimationsModule from AppModule. Native animate.enter/leave needs no provider: ng-zorro enables animations unless ANIMATION_MODULE_TYPE resolves to 'NoopAnimations'. - Drop the now-unused @angular/animations dependency.
…1 overlays dark-theme-overrides.css reset both `transition: none !important` and `animation: none !important` on a broad antd selector list (.ant-dropdown, .ant-select, .ant-tooltip, .ant-popover, .ant-menu, ...) plus the header .search, to make dark/light theme switching instant (no color-transition flicker). Under ng-zorro <= 20 the overlay open/close motion was driven by @angular/animations (JS), so the CSS `animation: none` was a harmless no-op. ng-zorro 21 moved overlays to native CSS animations: animate.enter applies ant-slide-up-enter / ant-zoom-big-* classes that run @Keyframes. The `animation: none !important` reset therefore silently killed every dropdown/select/tooltip/popover open and close animation, in both themes and regardless of the animation provider. Drop the five `animation: none !important` declarations and keep `transition: none !important`, which is what actually prevents the theme-switch flicker. Overlay animations are restored, and .ant-spin keyframes animate again.
6b91106 to
ae392ef
Compare
The Node 18 -> 22 bump updated pom.xml (<node.version>) and package.json `engines`, but missed `.nvmrc`. `.nvmrc` is read by the frontend workflow's npm-audit job (actions/setup-node `node-version-file`) and by local `nvm use`, so it has to match. With the stale 18.20.8, running `nvm use` and then `npm install` fails the `engines: >=22.12.0` check locally. Align it with pom.xml's v22.21.1 and engines >=22.12.0.
jongyoul
approved these changes
Jun 1, 2026
Contributor
Author
|
Merged into master |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR for?
zeppelin-web-angularwas on Angular 13 (end-of-life). This upgrades it to Angular 21 (latest), one major version at a time so each step stays small and reviewable. The production build, lint, and dev-server are green at every bump.Included:
engines@if/@for/@switch),provideHttpClient, explicit zone change detection,standalone: falseon NgModule declarations, RxJS 7 typingNo intended functional or UI changes. This is a framework and tooling upgrade only. Commits are grouped per major version (and per concern within a version) so the PR can be reviewed commit by commit.
What type of PR is it?
Improvement
Todos
What is the Jira issue?
How should this be tested?
cd zeppelin-web-angular && npm cinpm run build:angular(passes)npm run lint(passes)npm start, then click through the main screens to confirm they still work: open and run notebook paragraphs (all result types), the interpreter page, job manager, credentials, header dropdowns, and the dark/light theme toggle.Screenshots (if appropriate)
N/A (no intended UI changes).
Questions: