Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8ad46ac
when the footer is not present in the dialog remove empty div
nick-livefront Apr 1, 2026
5c59fe8
add new item type feature flag
nick-livefront Apr 1, 2026
7313d07
add subtitle text to cipher menu items
nick-livefront Apr 1, 2026
75f1c89
add add item dialog and associated components
nick-livefront Apr 1, 2026
c6f2e96
integrate the new item dialog into web and AC vaults
nick-livefront Apr 1, 2026
e029cde
add dialog header start slot for dialog
nick-livefront Apr 2, 2026
ab371dd
fix menu trigger when feature flag is disabled
nick-livefront Apr 2, 2026
a56030c
add back button for cipher dialogs
nick-livefront Apr 2, 2026
116d05a
bind `this` for back action
nick-livefront Apr 2, 2026
eb597c4
only show back button when a new cipher is being created
nick-livefront Apr 2, 2026
7f41b87
fix edit access for new ciphers
nick-livefront Apr 2, 2026
a13ef76
fix logic for adding a cipher and showing the back button
nick-livefront Apr 2, 2026
116a007
add back action to the collection dialog
nick-livefront Apr 2, 2026
009b342
add back action to folder dialog
nick-livefront Apr 2, 2026
0eed040
fix formatting and strict types
nick-livefront Apr 2, 2026
caf356f
update backAction getter for consistency
nick-livefront Apr 2, 2026
c746672
add story without footer
nick-livefront Apr 2, 2026
abd3feb
prettier fixes
nick-livefront Apr 2, 2026
bf5cf60
address local claude feedback
nick-livefront Apr 3, 2026
ced61ee
update icons on dialog
nick-livefront Apr 3, 2026
760d439
adjust spacing and sizes
nick-livefront Apr 3, 2026
c314f78
fix strict typings
nick-livefront Apr 3, 2026
6a7f6b4
add typography import
nick-livefront Apr 3, 2026
ac81e6d
design pass after working on other platforms
nick-livefront Apr 3, 2026
6bbf459
update to use the icon tile component
nick-livefront Apr 6, 2026
6ece4e6
Merge branch 'main' into vault/pm-34119/new-item-type-dialog
nick-livefront Apr 6, 2026
dc66202
address feedback from design
nick-livefront Apr 7, 2026
67a6cab
Merge branch 'main' of github.com:bitwarden/clients into vault/pm-341…
nick-livefront Apr 9, 2026
2a839d2
update grid to use bit item
nick-livefront Apr 9, 2026
73fec8b
remove dialog description
nick-livefront Apr 9, 2026
d3e9fc1
update to single column when less than 6 items
nick-livefront Apr 9, 2026
07b99d2
Revert "add dialog header start slot for dialog"
nick-livefront Apr 9, 2026
7fc9c8a
remove back action for new cipher dialog
nick-livefront Apr 9, 2026
02b85c7
match padding-top of dialog when there is no footer
nick-livefront Apr 9, 2026
7998924
fix alignment of carrot
nick-livefront Apr 9, 2026
7b31605
remove tests associated back action
nick-livefront Apr 9, 2026
960e095
Merge branch 'main' of github.com:bitwarden/clients into vault/pm-341…
nick-livefront Apr 9, 2026
406b199
use default bit-item styles for typography
nick-livefront Apr 10, 2026
4d99067
reduce margin of bit-item
nick-livefront Apr 10, 2026
ea3d9c2
prefer `inject` function
nick-livefront Apr 14, 2026
6383f63
add readonly and protected
nick-livefront Apr 14, 2026
5cb3243
move types into the grid component to streamline the api integration
nick-livefront Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2102,6 +2102,27 @@
"typeNote": {
"message": "Note"
},
"typeLoginSubtitle": {
"message": "Website or app"
},
"typeCardSubtitle": {
"message": "Credit or debit card"
},
"typeIdentitySubtitle": {
"message": "Personal info"
},
"typeNoteSubtitle": {
"message": "Important text"
},
"typeSshKeySubtitle": {
"message": "Server login token"
},
"folderSubtitle": {
"message": "Organize your items"
},
"collectionSubtitle": {
"message": "Organize shared items"
},
"newItemHeaderLogin": {
"message": "New Login",
"description": "Header for new login item type"
Expand Down
21 changes: 21 additions & 0 deletions apps/desktop/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@
"typeSshKey": {
"message": "SSH key"
},
"typeLoginSubtitle": {
"message": "Website or app"
},
"typeCardSubtitle": {
"message": "Credit or debit card"
},
"typeIdentitySubtitle": {
"message": "Personal info"
},
"typeNoteSubtitle": {
"message": "Important text"
},
"typeSshKeySubtitle": {
"message": "Server login token"
},
"folderSubtitle": {
"message": "Organize your items"
},
"collectionSubtitle": {
"message": "Organize shared items"
},
"folders": {
"message": "Folders"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
[canCreateCollection]="canCreateCollection"
(cipherAdded)="addCipher($event)"
(collectionAdded)="addCollection()"
(onAddItemDialog)="openAddItemDialog()"
/>
</div>
</app-header>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// FIXME: rename output bindings and then remove this line
/* eslint-disable @angular-eslint/no-output-on-prefix */
import { CommonModule } from "@angular/common";
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { Component, EventEmitter, Input, output, Output } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom, switchMap } from "rxjs";

Expand Down Expand Up @@ -109,6 +109,9 @@ export class VaultHeaderComponent {
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() searchTextChanged = new EventEmitter<string>();

/** Emits an event when the add item dialog should be opened */
readonly onOpenAddItemDialog = output();

protected CollectionDialogTabType = CollectionDialogTabType;

/** The cipher type enum. */
Expand Down Expand Up @@ -218,6 +221,10 @@ export class VaultHeaderComponent {
this.onAddCipher.emit(cipherType);
}

protected openAddItemDialog(): void {
this.onOpenAddItemDialog.emit();
}

async addCollection() {
if (this.organization.productTierType === ProductTierType.Free) {
const collections = await firstValueFrom(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
(onEditCollection)="editCollection(selectedCollection?.node, $event.tab, $event.readonly)"
(onDeleteCollection)="deleteCollection(selectedCollection?.node)"
(searchTextChanged)="filterSearchText($event)"
(onOpenAddItemDialog)="openAddItemDialog()"
></app-org-vault-header>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ import {
ToastService,
} from "@bitwarden/components";
import {
AddItemDialogCloseResult,
AddItemDialogComponent,
AddItemDialogResult,
AttachmentDialogResult,
AttachmentsV2Component,
CipherFormConfig,
Expand Down Expand Up @@ -838,6 +841,27 @@ export class VaultComponent implements OnInit, OnDestroy {
}
}

/**
* Opens the add-item type selection dialog and handles the result.
*/
protected async openAddItemDialog(): Promise<void> {
const organization = await firstValueFrom(this.organization$);
const ref = AddItemDialogComponent.open(this.dialogService, {
canCreateFolder: false,
canCreateCollection: organization?.canCreateNewCollections ?? false,
canCreateSshKey: true,
});
const result: AddItemDialogCloseResult | undefined = await firstValueFrom(ref.closed);
if (!result) {
return;
}
if (result.result === AddItemDialogResult.Cipher) {
await this.addCipher(result.cipherType);
} else if (result.result === AddItemDialogResult.Collection) {
await this.addCollection();
}
}

/** Opens the Add/Edit Dialog */
async addCipher(cipherType?: CipherType) {
const cipherFormConfig = await this.cipherFormConfigService.buildConfig(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<bit-dialog dialogSize="large" background="alt" [loading]="performingInitialLoad">
<span bitDialogTitle aria-live="polite">
<span bitDialogTitle class="tw-flex tw-items-center tw-gap-1" aria-live="polite">
{{ title }}
</span>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
DIALOG_DATA,
DialogRef,
AsyncActionsModule,
BitIconButtonComponent,
ButtonModule,
DialogModule,
DialogService,
Expand Down Expand Up @@ -133,6 +134,7 @@ export type VaultItemDialogResult = UnionOfValues<typeof VaultItemDialogResult>;
selector: "app-vault-item-dialog",
templateUrl: "vault-item-dialog.component.html",
imports: [
BitIconButtonComponent,
ButtonModule,
CipherViewComponent,
DialogModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
(cipherAdded)="addCipher($event)"
(folderAdded)="addFolder()"
(collectionAdded)="addCollection()"
(onAddItemDialog)="openAddItemDialog()"
/>
<app-coachmark #addItemCoachmark stepId="addItem" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
inject,
Input,
Output,
output,
} from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom, switchMap } from "rxjs";
Expand Down Expand Up @@ -122,6 +123,9 @@ export class VaultHeaderComponent {
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() onDeleteCollection = new EventEmitter<void>();

/** Emits an event when the add item dialog should be opened */
readonly onOpenAddItemDialog = output<void>();

constructor(
private readonly i18nService: I18nService,
private readonly collectionAdminService: CollectionAdminService,
Expand Down Expand Up @@ -257,6 +261,10 @@ export class VaultHeaderComponent {
this.onAddCipher.emit(cipherType);
}

protected openAddItemDialog(): void {
this.onOpenAddItemDialog.emit();
}

async addFolder(): Promise<void> {
this.onAddFolder.emit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
(onAddFolder)="addFolder()"
(onEditCollection)="editCollection(selectedCollection.node, $event.tab)"
(onDeleteCollection)="deleteCollection(selectedCollection.node)"
(onOpenAddItemDialog)="openAddItemDialog()"
></app-vault-header>

<app-vault-onboarding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,13 @@ describe("VaultComponent", () => {
{ provide: OrganizationWarningsService, useValue: mock<OrganizationWarningsService>() },
{ provide: PremiumUpgradePromptService, useValue: mock<PremiumUpgradePromptService>() },
{ provide: SyncService, useValue: mock<SyncService>() },
{ provide: ConfigService, useValue: mock<ConfigService>() },
{
provide: ConfigService,
useValue: {
...mock<ConfigService>(),
getFeatureFlag$: jest.fn().mockReturnValue(of(false)),
},
},
{ provide: DialogService, useValue: mock<DialogService>() },
{ provide: WelcomeDialogService, useValue: mock<WelcomeDialogService>() },
{ provide: OrganizationUserApiService, useValue: mock<OrganizationUserApiService>() },
Expand Down
27 changes: 26 additions & 1 deletion apps/web/src/app/vault/individual-vault/vault.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ import { CipherListView } from "@bitwarden/sdk-internal";
import {
AddEditFolderDialogComponent,
AddEditFolderDialogResult,
AddItemDialogCloseResult,
AddItemDialogComponent,
AddItemDialogResult,
AttachmentDialogResult,
AttachmentsV2Component,
CipherFormConfig,
Expand Down Expand Up @@ -951,6 +954,28 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
);
}

/**
* Opens the add-item type selection dialog and handles the result.
*/
protected async openAddItemDialog(): Promise<void> {
const ref = AddItemDialogComponent.open(this.dialogService, {
canCreateFolder: true,
canCreateCollection: this.canCreateCollections,
canCreateSshKey: true,
});
const result: AddItemDialogCloseResult | undefined = await firstValueFrom(ref.closed);
if (!result) {
return;
}
if (result.result === AddItemDialogResult.Cipher) {
await this.addCipher(result.cipherType);
} else if (result.result === AddItemDialogResult.Folder) {
this.addFolder();
} else {
await this.addCollection();
}
}

/**
* Opens the add cipher dialog.
* @param cipherType The type of cipher to add.
Expand Down Expand Up @@ -1073,7 +1098,7 @@ export class VaultComponent<C extends CipherViewLike> implements OnInit, OnDestr
);
}

async addCollection() {
async addCollection(): Promise<void> {
const dialog = openCollectionDialog(this.dialogService, {
data: {
organizationId: this.allOrganizations
Expand Down
26 changes: 25 additions & 1 deletion apps/web/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,27 @@
"typeSshKey": {
"message": "SSH key"
},
"typeLoginSubtitle": {
"message": "Website or app"
},
"typeCardSubtitle": {
"message": "Credit or debit card"
},
"typeIdentitySubtitle": {
"message": "Personal info"
},
"typeNoteSubtitle": {
"message": "Important text"
},
"typeSshKeySubtitle": {
"message": "Server login token"
},
"folderSubtitle": {
"message": "Organize your items"
},
"collectionSubtitle": {
"message": "Organize shared items"
},
"typeLoginPlural": {
"message": "Logins"
},
Expand Down Expand Up @@ -1057,6 +1078,9 @@
"addItem": {
"message": "Add item"
},
"chooseItemToAdd": {
"message": "Choose item to add"
},
"editItem": {
"message": "Edit item"
},
Expand Down Expand Up @@ -13251,4 +13275,4 @@
}
}
}
}
}
2 changes: 2 additions & 0 deletions libs/common/src/enums/feature-flag.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export enum FeatureFlag {
AccessIntelligenceNewArchitecture = "pm-31936-access-intelligence-new-architecture",

/* Vault */
PM32009NewItemTypes = "pm-32009-new-item-types",
PM19941MigrateCipherDomainToSdk = "pm-19941-migrate-cipher-domain-to-sdk",
PM22134SdkCipherListView = "pm-22134-sdk-cipher-list-view",
PM22136_SdkCipherEncryption = "pm-22136-sdk-cipher-encryption",
Expand Down Expand Up @@ -141,6 +142,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.AccessIntelligenceNewArchitecture]: FALSE,

/* Vault */
[FeatureFlag.PM32009NewItemTypes]: FALSE,
[FeatureFlag.CipherKeyEncryption]: FALSE,
[FeatureFlag.PM19941MigrateCipherDomainToSdk]: FALSE,
[FeatureFlag.PM22134SdkCipherListView]: FALSE,
Expand Down
Loading
Loading