Skip to content

fix(notification-center): errors following a full review of the component - #1943

Merged
lskramarov merged 11 commits into
mainfrom
review/notification-center
Sep 7, 2026
Merged

fix(notification-center): errors following a full review of the component#1943
lskramarov merged 11 commits into
mainfrom
review/notification-center

Conversation

@lskramarov

Copy link
Copy Markdown
Contributor

Summary

The review found one crash-class defect and two release-blocking keyboard failures. A notification
whose date the configured DateAdapter could not parse made format(null) throw inside the
groupedItems map, erroring the observable and permanently blanking the panel — reopening
resubscribed to the same dead pipe. Separately, the per-item delete buttons were display: none until
:hover, while being the only focusable element in their container, so a keyboard user could not
delete anything.

Two ng update migrations ship with this branch.

List of notable changes:

  • fixed the unparsable-date crash that permanently blanked the panel; the neighbouring
    compareByDateDesc already guarded exactly this case
  • fixed keyboard access to the delete controls, and applied the focus trap the panel had been
    computing but never installing — Tab escaped the overlay and host-scoped Escape then went dead
  • added accessible names for the icon-only header buttons, which had neither a label nor a tooltip
  • fixed the destroy-while-open path that left a permanent closingActions() subscription throwing
    a TypeError on every subsequent scroll anywhere in the app
  • fixed the inner-scroll "prevent close" protocol, which mutated shared CdkScrollable instances
    without resetting them and silently broke closeOnScroll for other overlays app-wide
  • added two migration schematics — notification-center-signals and read-state-dwell-handlers
    for the renamed surface and the removed mouseenterHandler/mouseleaveHandler
  • fixed the focus origin on the silent-mode toggle: opening the panel with the mouse painted a
    keyboard focus ring, because the call hardcoded 'keyboard'. It now uses the real input modality
    via InputModalityDetector, the same rule as KbqBasePipe.currentFocusOrigin — not FocusMonitor's
    last origin, which reports program for a click landing outside its detection window

What should reviewers focus on?

  • The two new schematics under packages/schematics/src/migrations/ and their registration in
    collection.json / migrations.json.
  • packages/components/core/common-behaviors/read-state.ts is shared with toast — that consumer suite
    runs green here, but the toast branch touches the same file.
  • Removed public symbols: KBQ_NOTIFICATION_CENTER_DEFAULT_CONFIGURATION,
    KBQ_NOTIFICATION_CENTER_SCROLL_STRATEGY, mouseenterHandler, mouseleaveHandler, timestamp.
  • The screenshot baseline for the panel header has shifted and needs /approve-snapshots here.

One of ten pull requests from a single review pass (review/*). Every branch carries two commits: the
fixes from the component review, and a second pass over the findings an independent verifier could not
confirm outright.

The branches share files, so they have to be merged one at a time with a rebase in between. Overlap:
packages/components/core/locales/* (7 branches), tools/public_api_guard/components/core.api.md (7),
tools/cspell-locales/*.json (6), packages/e2e/routes.ts (4) and
packages/schematics/src/{collection,migrations}.json (3).

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 30156db):

https://koobiq-next--prs-1943-yn91re71.web.app

(expires Thu, 10 Sep 2026 11:28:04 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@github-actions github-actions Bot added the bug Something isn't working label Aug 26, 2026
@lskramarov
lskramarov force-pushed the review/notification-center branch from 9e25e84 to e706cf5 Compare August 26, 2026 17:46
@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov lskramarov self-assigned this Aug 27, 2026
@lskramarov
lskramarov force-pushed the review/notification-center branch 2 times, most recently from 18b5a53 to b6192fb Compare August 28, 2026 08:08
@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov
lskramarov force-pushed the review/notification-center branch from 5168dff to 86bf066 Compare August 28, 2026 09:06
@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov
lskramarov force-pushed the review/notification-center branch from 86bf066 to 92d4c53 Compare September 1, 2026 15:33
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov
lskramarov force-pushed the review/notification-center branch from 92d4c53 to 62938a8 Compare September 4, 2026 07:24
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov
lskramarov force-pushed the review/notification-center branch from e71aed0 to 4c4e385 Compare September 4, 2026 10:32
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov

Copy link
Copy Markdown
Contributor Author

/approve-snapshots

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

🔄 Updating snapshots.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

✅ Snapshots updated!

… the migration guide

Two schematics shipped without a section in the upgrade guide, and the change that hurts
most has no schematic to report it at all: the service stopped being provided by the
module, so its date adapter now has to reach the root injector or the first injection
throws NG0201.
KbqLuxonDateModule imports KbqLocaleServiceModule, so providing it app-wide bound
KBQ_LOCALE_SERVICE for every fixture, not just this one. KbqDataSizePipe injects that
token optionally and falls back to its built-in units without it, so file-upload started
rendering "4 Б" against a baseline holding "4 B". LuxonDateModule provides the
DateAdapter the notification-center service needs and nothing else.
The tooltip and popover reviews landed on main while this branch was open, and both narrowed
`KbqPopUpTrigger.placementChange` from `EventEmitter<string>` to
`EventEmitter<KbqPopUpPlacementValues>`. This branch had typed its own override as `string` —
correct against the old base, and no longer assignable to the new one, which broke the whole
component: `KbqNotificationCenterTrigger` stopped satisfying `KbqPopUpTrigger`, so
`KbqNotificationCenterComponent.trigger` failed too.

main's own version declares a bare `new EventEmitter()`, which type-checks only because it
infers `any`. The union is what the base emits, so that is what the override says now.
lskramarov and others added 2 commits September 4, 2026 14:33
…p root

`KbqNotificationCenterService` left `KbqNotificationCenterModule.providers` in this review, so
the `providedIn: 'root'` singleton is now the only instance and it resolves `DateAdapter` and
`DateFormatter` from the root injector. Neither has a root provider — `DateAdapter` is an
abstract class and `DateFormatter` carries no `providedIn` — and the dev-ssr root supplied
neither, so the first notification-center example rendered in a prerender worker threw NG0201
and took the worker down with it, failing every route batched into that worker: 197 of ~530,
spread across every component, from two dead workers.

Same fix the e2e app already got, and the same reasoning for the module choice:
`KbqLuxonDateModule` would also import `KbqLocaleServiceModule`, which this config already
binds a line above.

Measured: `ssr:build` fails with 197 unrendered routes before, 0 after, matching main.
@lskramarov
lskramarov force-pushed the review/notification-center branch from 3459808 to 117e5be Compare September 4, 2026 11:37
@lskramarov
lskramarov marked this pull request as ready for review September 4, 2026 11:38
Copilot AI lite review requested due to automatic review settings September 4, 2026 11:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new migrations should be adjusted to avoid rewriting/scanning .d.ts and .ngtypecheck.ts files and to correctly scope local receiver renames to block-level to prevent false-positive edits.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens and modernizes notification-center by preventing invalid-date crashes, improving keyboard/focus accessibility in the overlay panel, and introducing two ng update migrations to help consumers adapt to the API surface changes.

Changes:

  • Prevent panel-breaking errors from unparsable notification dates (service-side parsing/cache + UI-side guarding).
  • Fix keyboard/focus behavior in the overlay (focus trap installation, focus restoration after deletes, keyboard-reachable delete controls, added ARIA labeling/live-region text).
  • Add ng update migrations to (a) rename KbqReadStateDirective dwell handlers and (b) report non-mechanical notification-center breaking changes.
File summaries
File Description
tools/public_api_guard/components/notification-center.api.md Updates public API snapshot for notification-center surface changes.
tools/public_api_guard/components/core.api.md Updates core public API snapshot (locale + read-state directive signature changes).
tools/check-public-api-any/baseline.json Updates any/unknown baseline counts for notification-center.
packages/schematics/src/migrations/read-state-dwell-handlers/schema.ts Adds migration options typing.
packages/schematics/src/migrations/read-state-dwell-handlers/schema.json Defines migration schema for CLI usage.
packages/schematics/src/migrations/read-state-dwell-handlers/README.md Documents the dwell-handler rename migration and manual follow-ups.
packages/schematics/src/migrations/read-state-dwell-handlers/index.ts Implements the dwell-handler rename + warnings migration.
packages/schematics/src/migrations/read-state-dwell-handlers/index.spec.ts Adds schematic test coverage for renames and reporting behavior.
packages/schematics/src/migrations/read-state-dwell-handlers/data.ts Centralizes patterns/messages for the dwell-handler migration.
packages/schematics/src/migrations/notification-center-signals/schema.ts Adds migration options typing.
packages/schematics/src/migrations/notification-center-signals/schema.json Defines migration schema for CLI usage.
packages/schematics/src/migrations/notification-center-signals/README.md Documents notification-center breaking changes that require manual decisions.
packages/schematics/src/migrations/notification-center-signals/index.ts Implements report-only migration for notification-center API changes.
packages/schematics/src/migrations/notification-center-signals/index.spec.ts Adds schematic test coverage for report behavior.
packages/schematics/src/migrations/notification-center-signals/data.ts Centralizes patterns/messages for notification-center report migration.
packages/schematics/src/migrations.json Registers both new migrations for ng update.
packages/schematics/src/collection.json Registers both schematics in the schematics collection.
packages/e2e/routes.ts Adds new notification-center e2e routes/fixtures.
packages/e2e/main.ts Ensures DateAdapter/formatters are provided at root for e2e app bootstrapping.
packages/components/notification-center/public-api.ts Adjusts exports (adds tokens export, removes animations export).
packages/components/notification-center/notification-item.ts Guards date formatting, switches to panel token contract, adds focus-safe delete behavior.
packages/components/notification-center/notification-item.scss Makes delete button keyboard-reachable and updates sizing tokens.
packages/components/notification-center/notification-item.html Fixes template context exposure, adds unread SR text, wires focus-safe removal.
packages/components/notification-center/notification-center.ts Focus trap + focus restoration + scroll handling fixes; introduces panel token/provider.
packages/components/notification-center/notification-center.tokens.ts Introduces tokens + locale provider utilities + narrow panel contract.
packages/components/notification-center/notification-center.service.ts Adds parsed-date caching/guarding, Subjects instead of EventEmitters, unread counter sharing.
packages/components/notification-center/notification-center.scss Adds tokens, trap wrapper styling, keyboard-reveal affordances, and z-index fixes.
packages/components/notification-center/notification-center-tokens.scss Defines component CSS tokens for sizing/theme.
packages/components/notification-center/notification-center.ru.md Documents new requirements/behavior (root date adapter, unparsable dates, deletion semantics).
packages/components/notification-center/notification-center.en.md Same documentation updates in English.
packages/components/notification-center/notification-center.module.ts Makes NgModule a compatibility wrapper (drops redundant providers).
packages/components/notification-center/notification-center.html Installs focus trap wrapper + live region, improves tracking keys and delete wiring.
packages/components/notification-center/notification-center-animations.ts Removes unused animations file/export.
packages/components/notification-center/e2e.ts Adds richer notification-center e2e fixtures including overlay-triggered scenario.
packages/components/notification-center/e2e.playwright-spec.ts Adds Playwright assertions for new states + keyboard/focus behaviors.
packages/components/notification-center/_notification-center-theme.scss Switches theme styling to tokenized variables.
packages/components/core/locales/types.ts Adds unread string to notification-center locale configuration type.
packages/components/core/locales/en-US.ts Adds unread locale string.
packages/components/core/locales/es-LA.ts Adds unread locale string.
packages/components/core/locales/pt-BR.ts Adds unread locale string.
packages/components/core/locales/ru-RU.ts Adds unread locale string.
packages/components/core/locales/tk-TM.ts Adds unread locale string.
packages/components/core/common-behaviors/read-state.ts Extends dwell tracking to keyboard focus and refactors handlers/timestamp semantics.
packages/components/core/common-behaviors/read-state.spec.ts Adds unit tests for new dwell behavior across pointer and focus.
packages/components-dev/ssr/config.ts Ensures root-provided DateAdapter/formatters for SSR prerender stability.
docs/guides/migration.ru.md Documents notification-center + read-state migration implications.
docs/guides/migration.en.md Same documentation updates in English.
Review details
  • Files reviewed: 48/50 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…ted TypeScript

`read-state-dwell-handlers` collected a `let`/`const` receiver and gave it the whole enclosing
function as its scope, so a sibling block declaring the same name was rewritten too. Reproduced
through the schematic's own runner: an `if` branch holding a real `KbqReadStateDirective` and an
`else` branch holding `{ mouseenterHandler() {} }` both came back as `startDwell()`, silently
breaking the second. A local is visible in its block, so that is what it is scoped to now —
including case and default clauses and module blocks, which are bindings' scopes too but are not
`Block` nodes.

Both migrations also visited every `.ts`, `.d.ts` and `.ngtypecheck.ts` included. A declaration
file has no call sites for the rewriting one to touch and only restates the API the reporting one
warns about, so the first can gain nothing there and the second can only produce noise about the
consumer's own typings. `deprecated-icons` and `new-icons-pack` already skip both.

Raised by Copilot on #1943; the scoping half is its find, verified before acting on it.
Comment thread docs/guides/migration.en.md
…v app roots

Reported on the deploy preview: the notification-center overview page throws NG0201 on load.
Same defect this branch already fixed for the e2e and dev-ssr apps, in the two roots it missed.

`KbqNotificationCenterService` is `providedIn: 'root'` and injects `DateAdapter` and
`DateFormatter` without `optional`. Neither has a root provider — `DateAdapter` is an abstract
class and `DateFormatter` carries no `providedIn` — and importing the modules into a component,
which is what both the docs example and the dev app did, serves that component's own injections
and never the root singleton's.

Reproduced in the dev app, where the message is not minified: "No provider found for
`DateAdapter`". With the providers at the root the panel renders its 30 notifications with
formatted headings and times.

The docs app already binds the locale service, so it takes the bare `LuxonDateModule`; the dev
app has none, so it keeps `KbqLuxonDateModule` and drops the now-redundant component imports.
@lskramarov
lskramarov merged commit db97cbf into main Sep 7, 2026
14 checks passed
@lskramarov
lskramarov deleted the review/notification-center branch September 7, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants