mirror of
https://github.com/bitwarden/browser
synced 2026-01-30 16:23:53 +00:00
approach 1 of handling dialog close from menu item trigger
This commit is contained in:
@@ -49,6 +49,7 @@ import {
|
||||
ItemModule,
|
||||
ToastService,
|
||||
CenterPositionStrategy,
|
||||
DialogConfig,
|
||||
} from "@bitwarden/components";
|
||||
import {
|
||||
AttachmentDialogCloseResult,
|
||||
@@ -667,10 +668,15 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
* @param dialogService
|
||||
* @param params
|
||||
*/
|
||||
static open(dialogService: DialogService, params: VaultItemDialogParams) {
|
||||
static open(
|
||||
dialogService: DialogService,
|
||||
params: VaultItemDialogParams,
|
||||
dialogConfig?: DialogConfig,
|
||||
) {
|
||||
return dialogService.open<VaultItemDialogResult, VaultItemDialogParams>(
|
||||
VaultItemDialogComponent,
|
||||
{
|
||||
...dialogConfig,
|
||||
data: params,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
viewChild,
|
||||
} from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
@@ -56,6 +63,9 @@ export class VaultHeaderComponent {
|
||||
protected CollectionDialogTabType = CollectionDialogTabType;
|
||||
protected CipherType = CipherType;
|
||||
|
||||
/** Query for the NewCipherMenuComponent in the template */
|
||||
readonly newCipherMenu = viewChild(NewCipherMenuComponent);
|
||||
|
||||
/**
|
||||
* Boolean to determine the loading state of the header.
|
||||
* Shows a loading spinner if set to true
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
computed,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
viewChild,
|
||||
ViewChild,
|
||||
} from "@angular/core";
|
||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import {
|
||||
BehaviorSubject,
|
||||
@@ -195,6 +204,12 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@ViewChild("vaultItems", { static: false }) vaultItemsComponent: VaultItemsComponent<C>;
|
||||
|
||||
readonly vaultHeaderComponent = viewChild(VaultHeaderComponent);
|
||||
|
||||
readonly newButtonEl = computed(
|
||||
() => this.vaultHeaderComponent()?.newCipherMenu()?.newCipherButton()?.el.nativeElement,
|
||||
);
|
||||
|
||||
trashCleanupWarning: string = null;
|
||||
kdfIterations: number;
|
||||
activeFilter: VaultFilter = new VaultFilter();
|
||||
@@ -861,7 +876,9 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
}
|
||||
|
||||
addFolder = (): void => {
|
||||
AddEditFolderDialogComponent.open(this.dialogService);
|
||||
AddEditFolderDialogComponent.open(this.dialogService, undefined, {
|
||||
restoreFocus: this.newButtonEl(),
|
||||
});
|
||||
};
|
||||
|
||||
editFolder = async (folder: FolderFilter): Promise<void> => {
|
||||
@@ -947,12 +964,18 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
formConfig: CipherFormConfig,
|
||||
activeCollectionId?: CollectionId,
|
||||
) {
|
||||
this.vaultItemDialogRef = VaultItemDialogComponent.open(this.dialogService, {
|
||||
mode,
|
||||
formConfig,
|
||||
activeCollectionId,
|
||||
restore: this.restore,
|
||||
});
|
||||
this.vaultItemDialogRef = VaultItemDialogComponent.open(
|
||||
this.dialogService,
|
||||
{
|
||||
mode,
|
||||
formConfig,
|
||||
activeCollectionId,
|
||||
restore: this.restore,
|
||||
},
|
||||
{
|
||||
restoreFocus: this.newButtonEl(),
|
||||
},
|
||||
);
|
||||
|
||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||
this.vaultItemDialogRef = undefined;
|
||||
@@ -1098,6 +1121,7 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
showOrgSelector: true,
|
||||
limitNestedCollections: true,
|
||||
},
|
||||
restoreFocus: this.newButtonEl(),
|
||||
});
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
if (result.action === CollectionDialogAction.Saved) {
|
||||
@@ -1121,6 +1145,7 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
|
||||
initialTab: tab,
|
||||
limitNestedCollections: true,
|
||||
},
|
||||
restoreFocus: this.newButtonEl(),
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(dialog.closed);
|
||||
|
||||
@@ -148,7 +148,7 @@ export class ButtonComponent implements ButtonLikeAbstraction {
|
||||
);
|
||||
|
||||
readonly disabled = model<boolean>(false);
|
||||
private el = inject(ElementRef<HTMLButtonElement>);
|
||||
readonly el = inject(ElementRef<HTMLButtonElement>);
|
||||
|
||||
constructor() {
|
||||
ariaDisableElement(this.el.nativeElement, this.disabledAttr);
|
||||
|
||||
@@ -62,7 +62,7 @@ export abstract class DialogRef<R = unknown, C = unknown> implements Pick<
|
||||
|
||||
export type DialogConfig<D = unknown, R = unknown> = Pick<
|
||||
CdkDialogConfig<D, R>,
|
||||
"data" | "disableClose" | "ariaModal" | "positionStrategy" | "height" | "width"
|
||||
"data" | "disableClose" | "ariaModal" | "positionStrategy" | "height" | "width" | "restoreFocus"
|
||||
>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,3 +38,8 @@ prior to being clicked and `aria-expanded="true"` after the user clicks the elem
|
||||
|
||||
User should be able to navigate the opened menu via the up and down arrow keys and close the menu
|
||||
using the escape key or clicking out of the menu.
|
||||
|
||||
Are you using a menu item to open a dialog? Be sure to pass the `restoreFocus` config option to the
|
||||
`dialog.open` method, specifying where the user's focus should return to upon dialog close. (The
|
||||
menu closes when the dialog launches, so the built-in strategy of returning focus to the trigger
|
||||
element is not possible, since the trigger element menu item is gone.)
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
FormFieldModule,
|
||||
IconButtonModule,
|
||||
ToastService,
|
||||
DialogConfig,
|
||||
} from "@bitwarden/components";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
|
||||
@@ -175,10 +176,17 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit {
|
||||
this.dialogRef.close(result);
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService, data?: AddEditFolderDialogData) {
|
||||
static open(
|
||||
dialogService: DialogService,
|
||||
data?: AddEditFolderDialogData,
|
||||
dialogConfig?: DialogConfig,
|
||||
) {
|
||||
return dialogService.open<AddEditFolderDialogResult, AddEditFolderDialogData>(
|
||||
AddEditFolderDialogComponent,
|
||||
{ data },
|
||||
{
|
||||
...dialogConfig,
|
||||
data,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
[bitMenuTriggerFor]="addOptions"
|
||||
id="newItemDropdown"
|
||||
[appA11yTitle]="'new' | i18n"
|
||||
#newItemDropdown
|
||||
>
|
||||
<i class="bwi bwi-plus" aria-hidden="true"></i>
|
||||
{{ "new" | i18n }}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, input, output } from "@angular/core";
|
||||
import { Component, input, output, viewChild } from "@angular/core";
|
||||
import { map, shareReplay } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { RestrictedItemTypesService } from "@bitwarden/common/vault/services/restricted-item-types.service";
|
||||
import { CIPHER_MENU_ITEMS } from "@bitwarden/common/vault/types/cipher-menu-items";
|
||||
import { ButtonModule, MenuModule } from "@bitwarden/components";
|
||||
import { ButtonComponent, ButtonModule, MenuModule } from "@bitwarden/components";
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
@@ -33,6 +33,8 @@ export class NewCipherMenuComponent {
|
||||
collectionAdded = output();
|
||||
cipherAdded = output<CipherType>();
|
||||
|
||||
readonly newCipherButton = viewChild<ButtonComponent>("newItemDropdown");
|
||||
|
||||
constructor(private restrictedItemTypesService: RestrictedItemTypesService) {}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user