1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-07 11:03:30 +00:00

Merge branch 'main' into PM-26250-Explore-options-to-enable-direct-importer-for-mac-app-store-build

This commit is contained in:
John Harrington
2025-12-09 09:10:08 -07:00
committed by GitHub
16 changed files with 61 additions and 19 deletions

View File

@@ -14,10 +14,11 @@ import { BadgeModule } from "@bitwarden/components";
type="button"
*appNotPremium
bitBadge
variant="success"
[variant]="'primary'"
class="!tw-text-primary-600 !tw-border-primary-600"
(click)="promptForPremium($event)"
>
{{ "premium" | i18n }}
<i class="bwi bwi-premium tw-pe-1"></i>{{ "upgrade" | i18n }}
</button>
`,
imports: [BadgeModule, JslibModule],

View File

@@ -29,7 +29,7 @@ export default {
provide: I18nService,
useFactory: () => {
return new I18nMockService({
premium: "Premium",
upgrade: "Upgrade",
});
},
},

View File

@@ -451,6 +451,24 @@ describe("ChipSelectComponent", () => {
expect(disabledMenuItem?.disabled).toBe(true);
});
it("should handle writeValue called before options are initialized", async () => {
const testApp = fixture.componentInstance;
component["rootTree"] = null;
component.writeValue("opt1");
expect(component["pendingValue"]).toBe("opt1");
expect(component["selectedOption"]).toBeUndefined();
testApp.options.set(testOptions);
fixture.detectChanges();
await fixture.whenStable();
expect(component["selectedOption"]?.value).toBe("opt1");
expect(component["pendingValue"]).toBeUndefined();
});
});
});

View File

@@ -100,10 +100,21 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
/** Tree constructed from `this.options` */
private rootTree?: ChipSelectOption<T> | null;
/** Store the pending value when writeValue is called before options are initialized */
private pendingValue?: T;
constructor() {
// Initialize the root tree whenever options change
effect(() => {
this.initializeRootTree(this.options());
// If there's a pending value, apply it now that options are available
if (this.pendingValue !== undefined) {
this.selectedOption = this.findOption(this.rootTree, this.pendingValue);
this.setOrResetRenderedOptions();
this.pendingValue = undefined;
this.cdr.markForCheck();
}
});
// Focus the first menu item when menuItems change (e.g., navigating submenus)
@@ -255,6 +266,12 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
/** Implemented as part of NG_VALUE_ACCESSOR */
writeValue(obj: T): void {
// If rootTree is not yet initialized, store the value to apply it later
if (!this.rootTree) {
this.pendingValue = obj;
return;
}
this.selectedOption = this.findOption(this.rootTree, obj);
this.setOrResetRenderedOptions();
// OnPush components require manual change detection when writeValue() is called

View File

@@ -1,5 +1,5 @@
<button bitButton [bitMenuTriggerFor]="itemOptions" [buttonType]="buttonType" type="button">
<i *ngIf="!hideIcon" class="bwi bwi-plus" aria-hidden="true"></i>
<i *ngIf="!hideIcon" class="bwi bwi-plus tw-me-2" aria-hidden="true"></i>
{{ (hideIcon ? "createSend" : "new") | i18n }}
</button>
<bit-menu #itemOptions>

View File

@@ -122,7 +122,7 @@
</bit-form-field>
<bit-form-field *ngIf="cipher.login.totp">
<bit-label [appTextDrag]="totpCodeCopyObj?.totpCode">
<div class="tw-flex tw-items-center tw-gap-3">
<div class="tw-flex tw-items-center tw-gap-2">
{{ "verificationCodeTotp" | i18n }}
<app-premium-badge [organizationId]="cipher.organizationId"></app-premium-badge>
</div>