From 3f3fc6f9849cfd09c0ea2b2ee258bd36e7955e03 Mon Sep 17 00:00:00 2001 From: Jared Date: Wed, 11 Feb 2026 10:52:50 -0500 Subject: [PATCH] [PM-31937] Close drawer on navigation (#18852) * Implement OnDestroy lifecycle hook in PoliciesComponent to close dialog on component destruction. Update dialog reference handling for improved resource management. * Add documentation to dialogs.mdx so others can know how to prevent drawers staying open * Fix for PR action test * Update PoliciesComponent to use optional chaining for myDialogRef --- .../policies/policies.component.ts | 13 ++++++--- libs/components/src/dialog/dialogs.mdx | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/policies/policies.component.ts b/apps/web/src/app/admin-console/organizations/policies/policies.component.ts index d13a2097628..0dd0b67c189 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policies.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policies.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, DestroyRef } from "@angular/core"; +import { ChangeDetectionStrategy, Component, DestroyRef, OnDestroy } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute } from "@angular/router"; import { combineLatest, Observable, of, switchMap, first, map, shareReplay } from "rxjs"; @@ -14,7 +14,7 @@ import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { getById } from "@bitwarden/common/platform/misc"; import { OrganizationId, UserId } from "@bitwarden/common/types/guid"; -import { DialogService } from "@bitwarden/components"; +import { DialogRef, DialogService } from "@bitwarden/components"; import { safeProvider } from "@bitwarden/ui-common"; import { HeaderModule } from "../../../layouts/header/header.module"; @@ -37,7 +37,8 @@ import { POLICY_EDIT_REGISTER } from "./policy-register-token"; ], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class PoliciesComponent { +export class PoliciesComponent implements OnDestroy { + private myDialogRef?: DialogRef; private userId$: Observable = this.accountService.activeAccount$.pipe(getUserId); protected organizationId$: Observable = this.route.params.pipe( @@ -98,6 +99,10 @@ export class PoliciesComponent { this.handleLaunchEvent(); } + ngOnDestroy() { + this.myDialogRef?.close(); + } + // Handle policies component launch from Event message private handleLaunchEvent() { combineLatest([ @@ -131,7 +136,7 @@ export class PoliciesComponent { edit(policy: BasePolicyEditDefinition, organizationId: OrganizationId) { const dialogComponent: PolicyDialogComponent = policy.editDialogComponent ?? PolicyEditDialogComponent; - dialogComponent.open(this.dialogService, { + this.myDialogRef = dialogComponent.open(this.dialogService, { data: { policy: policy, organizationId: organizationId, diff --git a/libs/components/src/dialog/dialogs.mdx b/libs/components/src/dialog/dialogs.mdx index ee03dda6f57..4a49804484b 100644 --- a/libs/components/src/dialog/dialogs.mdx +++ b/libs/components/src/dialog/dialogs.mdx @@ -25,6 +25,35 @@ interruptive if overused. For non-blocking, supplementary content, open dialogs as a [Drawer](?path=/story/component-library-dialogs-service--drawer) (requires `bit-layout`). +### Closing Drawers on Navigation + +When using drawers, you may want to close them automatically when the user navigates to another page +to prevent the drawer from persisting across route changes. To implement this functionality: + +1. Store a reference to the dialog when opening it +2. Implement `OnDestroy` and close the dialog in `ngOnDestroy` + +```ts +import { Component, OnDestroy } from "@angular/core"; +import { DialogRef } from "@bitwarden/components"; + +export class MyComponent implements OnDestroy { + private myDialogRef: DialogRef; + + ngOnDestroy() { + this.myDialogRef?.close(); + } + + openDrawer() { + this.myDialogRef = this.dialogService.open(MyDialogComponent, { + // dialog options + }); + } +} +``` + +This ensures drawers are closed when the component is destroyed during navigation. + ## Placement Dialogs should be centered vertically and horizontally on screen. Dialogs height should expand to