Skip to content

Commit bc177af

Browse files
Merge branch 'main' into billing/pm-26044/update-survey-for-user-and-organization
2 parents 86ed8f2 + a5caa19 commit bc177af

File tree

19 files changed

+361
-42
lines changed

19 files changed

+361
-42
lines changed

apps/browser/src/tools/popup/send-v2/send-v2.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
<app-send-list-items-container [headerText]="title | i18n" [sends]="sends$ | async" />
4848
</ng-container>
4949
@if (showSkeletonsLoaders$ | async) {
50-
<vault-fade-in-skeleton>
50+
<vault-fade-in-out-skeleton>
5151
<vault-loading-skeleton></vault-loading-skeleton>
52-
</vault-fade-in-skeleton>
52+
</vault-fade-in-out-skeleton>
5353
}
5454
</popup-page>

apps/browser/src/tools/popup/send-v2/send-v2.component.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
1515
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
1616
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
1717
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
18+
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
19+
import { skeletonLoadingDelay } from "@bitwarden/common/vault/utils/skeleton-loading.operator";
1820
import {
1921
ButtonModule,
2022
CalloutModule,
@@ -95,8 +97,16 @@ export class SendV2Component implements OnDestroy {
9597
/** Skeleton Loading State */
9698
protected showSkeletonsLoaders$ = combineLatest([
9799
this.sendsLoading$,
100+
this.searchService.isSendSearching$,
98101
this.skeletonFeatureFlag$,
99-
]).pipe(map(([loading, skeletonsEnabled]) => loading && skeletonsEnabled));
102+
]).pipe(
103+
map(
104+
([loading, cipherSearching, skeletonsEnabled]) =>
105+
(loading || cipherSearching) && skeletonsEnabled,
106+
),
107+
distinctUntilChanged(),
108+
skeletonLoadingDelay(),
109+
);
100110

101111
protected title: string = "allSends";
102112
protected noItemIcon = NoSendsIcon;
@@ -110,6 +120,7 @@ export class SendV2Component implements OnDestroy {
110120
private policyService: PolicyService,
111121
private accountService: AccountService,
112122
private configService: ConfigService,
123+
private searchService: SearchService,
113124
) {
114125
combineLatest([
115126
this.sendItemsService.emptyList$,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<ng-content></ng-content>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { animate, style, transition, trigger } from "@angular/animations";
2+
import { ChangeDetectionStrategy, Component, HostBinding } from "@angular/core";
3+
4+
@Component({
5+
selector: "vault-fade-in-out",
6+
templateUrl: "./vault-fade-in-out.component.html",
7+
animations: [
8+
trigger("fadeInOut", [
9+
transition(":enter", [
10+
style({ opacity: 0 }),
11+
animate("100ms ease-in", style({ opacity: 1 })),
12+
]),
13+
transition(":leave", [animate("300ms ease-out", style({ opacity: 0 }))]),
14+
]),
15+
],
16+
changeDetection: ChangeDetectionStrategy.OnPush,
17+
})
18+
export class VaultFadeInOutComponent {
19+
@HostBinding("@fadeInOut") fadeInOut = true;
20+
}

apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,32 @@
88
</ng-container>
99
</popup-header>
1010

11-
<div
12-
*ngIf="vaultState === VaultStateEnum.Empty"
13-
class="tw-flex tw-flex-col tw-h-full tw-justify-center"
14-
>
15-
<bit-no-items [icon]="vaultIcon">
16-
<ng-container slot="title">{{ "yourVaultIsEmpty" | i18n }}</ng-container>
17-
<ng-container slot="description">
18-
<p bitTypography="body2" class="tw-mx-6 tw-mt-2">{{ "emptyVaultDescription" | i18n }}</p>
19-
</ng-container>
20-
<a slot="button" bitButton buttonType="secondary" [routerLink]="['/add-cipher']">
21-
{{ "newLogin" | i18n }}
22-
</a>
23-
</bit-no-items>
24-
</div>
11+
<ng-template #emptyVaultTemplate>
12+
<div
13+
*ngIf="vaultState === VaultStateEnum.Empty"
14+
class="tw-flex tw-flex-col tw-h-full tw-justify-center"
15+
>
16+
<bit-no-items [icon]="vaultIcon">
17+
<ng-container slot="title">{{ "yourVaultIsEmpty" | i18n }}</ng-container>
18+
<ng-container slot="description">
19+
<p bitTypography="body2" class="tw-mx-6 tw-mt-2">
20+
{{ "emptyVaultDescription" | i18n }}
21+
</p>
22+
</ng-container>
23+
<a slot="button" bitButton buttonType="secondary" [routerLink]="['/add-cipher']">
24+
{{ "newLogin" | i18n }}
25+
</a>
26+
</bit-no-items>
27+
</div>
28+
</ng-template>
29+
30+
@if (skeletonFeatureFlag$ | async) {
31+
<vault-fade-in-out *ngIf="vaultState === VaultStateEnum.Empty">
32+
<ng-container *ngTemplateOutlet="emptyVaultTemplate"></ng-container>
33+
</vault-fade-in-out>
34+
} @else {
35+
<ng-container *ngTemplateOutlet="emptyVaultTemplate"></ng-container>
36+
}
2537

2638
<blocked-injection-banner
2739
*ngIf="vaultState !== VaultStateEnum.Empty"
@@ -95,22 +107,32 @@
95107
</div>
96108
</div>
97109

98-
<ng-container *ngIf="vaultState === null">
99-
<app-autofill-vault-list-items></app-autofill-vault-list-items>
100-
<app-vault-list-items-container
101-
[title]="'favorites' | i18n"
102-
[ciphers]="(favoriteCiphers$ | async) || []"
103-
id="favorites"
104-
collapsibleKey="favorites"
105-
></app-vault-list-items-container>
106-
<app-vault-list-items-container
107-
[title]="'allItems' | i18n"
108-
[ciphers]="(remainingCiphers$ | async) || []"
109-
id="allItems"
110-
disableSectionMargin
111-
collapsibleKey="allItems"
112-
></app-vault-list-items-container>
113-
</ng-container>
110+
<ng-template #vaultContentTemplate>
111+
<ng-container *ngIf="vaultState === null">
112+
<app-autofill-vault-list-items></app-autofill-vault-list-items>
113+
<app-vault-list-items-container
114+
[title]="'favorites' | i18n"
115+
[ciphers]="(favoriteCiphers$ | async) || []"
116+
id="favorites"
117+
collapsibleKey="favorites"
118+
></app-vault-list-items-container>
119+
<app-vault-list-items-container
120+
[title]="'allItems' | i18n"
121+
[ciphers]="(remainingCiphers$ | async) || []"
122+
id="allItems"
123+
disableSectionMargin
124+
collapsibleKey="allItems"
125+
></app-vault-list-items-container>
126+
</ng-container>
127+
</ng-template>
128+
129+
@if (skeletonFeatureFlag$ | async) {
130+
<vault-fade-in-out *ngIf="vaultState === null">
131+
<ng-container *ngTemplateOutlet="vaultContentTemplate"></ng-container>
132+
</vault-fade-in-out>
133+
} @else {
134+
<ng-container *ngTemplateOutlet="vaultContentTemplate"></ng-container>
135+
}
114136
</ng-container>
115137

116138
@if (showSkeletonsLoaders$ | async) {

apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
2323
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
2424
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
2525
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
26+
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
2627
import { RestrictedItemTypesService } from "@bitwarden/common/vault/services/restricted-item-types.service";
2728
import { TaskService } from "@bitwarden/common/vault/tasks";
2829
import { DialogService } from "@bitwarden/components";
@@ -259,6 +260,10 @@ describe("VaultV2Component", () => {
259260
getFeatureFlag$: (_: string) => of(false),
260261
},
261262
},
263+
{
264+
provide: SearchService,
265+
useValue: { isCipherSearching$: of(false) },
266+
},
262267
],
263268
schemas: [NO_ERRORS_SCHEMA],
264269
}).compileComponents();

apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
3232
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
3333
import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid";
3434
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
35+
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
3536
import { CipherType } from "@bitwarden/common/vault/enums";
3637
import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values";
38+
import { skeletonLoadingDelay } from "@bitwarden/common/vault/utils/skeleton-loading.operator";
3739
import {
3840
ButtonModule,
3941
DialogService,
@@ -54,6 +56,7 @@ import { VaultPopupListFiltersService } from "../../services/vault-popup-list-fi
5456
import { VaultPopupLoadingService } from "../../services/vault-popup-loading.service";
5557
import { VaultPopupScrollPositionService } from "../../services/vault-popup-scroll-position.service";
5658
import { AtRiskPasswordCalloutComponent } from "../at-risk-callout/at-risk-password-callout.component";
59+
import { VaultFadeInOutComponent } from "../vault-fade-in-out/vault-fade-in-out.component";
5760
import { VaultFadeInOutSkeletonComponent } from "../vault-fade-in-out-skeleton/vault-fade-in-out-skeleton.component";
5861
import { VaultLoadingSkeletonComponent } from "../vault-loading-skeleton/vault-loading-skeleton.component";
5962

@@ -100,6 +103,7 @@ type VaultState = UnionOfValues<typeof VaultState>;
100103
TypographyModule,
101104
VaultLoadingSkeletonComponent,
102105
VaultFadeInOutSkeletonComponent,
106+
VaultFadeInOutComponent,
103107
],
104108
})
105109
export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
@@ -129,7 +133,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
129133
}),
130134
);
131135

132-
private skeletonFeatureFlag$ = this.configService.getFeatureFlag$(
136+
protected skeletonFeatureFlag$ = this.configService.getFeatureFlag$(
133137
FeatureFlag.VaultLoadingSkeletons,
134138
);
135139

@@ -183,9 +187,18 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
183187
map(([loading, skeletonsEnabled]) => loading && !skeletonsEnabled),
184188
);
185189

186-
/** When true, show skeleton loading state */
187-
protected showSkeletonsLoaders$ = combineLatest([this.loading$, this.skeletonFeatureFlag$]).pipe(
188-
map(([loading, skeletonsEnabled]) => loading && skeletonsEnabled),
190+
/** When true, show skeleton loading state with debouncing to prevent flicker */
191+
protected showSkeletonsLoaders$ = combineLatest([
192+
this.loading$,
193+
this.searchService.isCipherSearching$,
194+
this.skeletonFeatureFlag$,
195+
]).pipe(
196+
map(
197+
([loading, cipherSearching, skeletonsEnabled]) =>
198+
(loading || cipherSearching) && skeletonsEnabled,
199+
),
200+
distinctUntilChanged(),
201+
skeletonLoadingDelay(),
189202
);
190203

191204
protected newItemItemValues$: Observable<NewItemInitialValues> =
@@ -228,6 +241,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
228241
private liveAnnouncer: LiveAnnouncer,
229242
private i18nService: I18nService,
230243
private configService: ConfigService,
244+
private searchService: SearchService,
231245
) {
232246
combineLatest([
233247
this.vaultPopupItemsService.emptyVault$,

apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/vnext-organization-data-ownership.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<p>
2-
{{ "organizationDataOwnershipContent" | i18n }}
2+
{{ "organizationDataOwnershipDescContent" | i18n }}
33
<a
44
bitLink
55
href="https://bitwarden.com/resources/credential-lifecycle-management/"

apps/web/src/locales/en/messages.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5813,9 +5813,9 @@
58135813
"message": "Require all items to be owned by an organization, removing the option to store items at the account level.",
58145814
"description": "This is the policy description shown in the policy list."
58155815
},
5816-
"organizationDataOwnershipContent": {
5817-
"message": "All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection be available for each member to store items. Learn more about managing the ",
5818-
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection be available for each member to store items. Learn more about managing the credential lifecycle.'"
5816+
"organizationDataOwnershipDescContent": {
5817+
"message": "All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection will be available for each member to store items. Learn more about managing the ",
5818+
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection will be available for each member to store items. Learn more about managing the credential lifecycle.'"
58195819
},
58205820
"organizationDataOwnershipContentAnchor": {
58215821
"message": "credential lifecycle",
@@ -12130,6 +12130,15 @@
1213012130
"startFreeFamiliesTrial": {
1213112131
"message": "Start free Families trial"
1213212132
},
12133+
"blockClaimedDomainAccountCreation": {
12134+
"message": "Block account creation for claimed domains"
12135+
},
12136+
"blockClaimedDomainAccountCreationDesc": {
12137+
"message": "Prevent users from creating accounts outside of your organization using email addresses from claimed domains."
12138+
},
12139+
"blockClaimedDomainAccountCreationPrerequisite": {
12140+
"message": "A domain must be claimed before activating this policy."
12141+
},
1213312142
"unlockMethodNeededToChangeTimeoutActionDesc": {
1213412143
"message": "Set up an unlock method to change your vault timeout action."
1213512144
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<bit-callout type="info" title="{{ 'prerequisite' | i18n }}">
2+
{{ "blockClaimedDomainAccountCreationPrerequisite" | i18n }}
3+
<a
4+
bitLink
5+
href="https://bitwarden.com/help/domain-verification/"
6+
target="_blank"
7+
rel="noreferrer"
8+
>{{ "learnMore" | i18n }}</a
9+
>
10+
</bit-callout>
11+
12+
<bit-form-control>
13+
<input type="checkbox" id="enabled" bitCheckbox [formControl]="enabled" />
14+
<bit-label>{{ "turnOn" | i18n }}</bit-label>
15+
</bit-form-control>

0 commit comments

Comments
 (0)