mirror of
https://github.com/bitwarden/browser
synced 2026-02-25 09:03:28 +00:00
Merge branch 'main' into auth/pm-26578/http-redirect-cloud
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
></app-org-vault-header>
|
||||
}
|
||||
|
||||
<div class="tw-flex tw-flex-row">
|
||||
<div class="tw-flex tw-flex-row tw-flex-1">
|
||||
@let hideVaultFilters = hideVaultFilter$ | async;
|
||||
@if (!hideVaultFilters) {
|
||||
<div class="tw-w-1/4 tw-mr-5">
|
||||
@@ -43,7 +43,9 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div [class]="hideVaultFilters ? 'tw-w-full' : 'tw-w-3/4'">
|
||||
<div
|
||||
[class]="(hideVaultFilters ? 'tw-w-full' : 'tw-w-3/4') + ' tw-flex tw-flex-col tw-min-h-0'"
|
||||
>
|
||||
@if (showAddAccessToggle && activeFilter.selectedCollectionNode) {
|
||||
<bit-toggle-group
|
||||
[selected]="addAccessStatus$ | async"
|
||||
@@ -68,6 +70,7 @@
|
||||
|
||||
@if (filter) {
|
||||
<app-vault-items
|
||||
class="tw-flex-1 tw-min-h-0"
|
||||
#vaultItems
|
||||
[ciphers]="ciphers$ | async"
|
||||
[collections]="collections$ | async"
|
||||
|
||||
@@ -1318,7 +1318,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
selectedCollection?.node.id === c.id
|
||||
) {
|
||||
void this.router.navigate([], {
|
||||
queryParams: { collectionId: selectedCollection.parent.node.id ?? null },
|
||||
queryParams: { collectionId: selectedCollection.parent?.node.id ?? null },
|
||||
queryParamsHandling: "merge",
|
||||
replaceUrl: true,
|
||||
});
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
*ngIf="showBulkReinviteUsers"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
||||
{{ "reinviteSelected" | i18n }}
|
||||
{{ (isSingleInvite ? "resendInvitation" : "reinviteSelected") | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -597,6 +597,16 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
.every((member) => member.managedByOrganization && validStatuses.includes(member.status));
|
||||
}
|
||||
|
||||
get selectedInvitedCount(): number {
|
||||
return this.dataSource
|
||||
.getCheckedUsers()
|
||||
.filter((member) => member.status === this.userStatusType.Invited).length;
|
||||
}
|
||||
|
||||
get isSingleInvite(): boolean {
|
||||
return this.selectedInvitedCount === 1;
|
||||
}
|
||||
|
||||
exportMembers = () => {
|
||||
const result = this.memberExportService.getMemberExport(this.dataSource.data);
|
||||
if (result.success) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@let bulkActions = bulkMenuOptions$ | async;
|
||||
@let showConfirmBanner = showConfirmBanner$ | async;
|
||||
@let isProcessing = this.isProcessing();
|
||||
@let isSingleInvite = isSingleInvite$ | async;
|
||||
|
||||
@if (organization && dataSource) {
|
||||
<app-organization-free-trial-warning
|
||||
@@ -151,7 +152,7 @@
|
||||
(click)="isProcessing ? null : bulkReinvite(organization)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
||||
{{ "reinviteSelected" | i18n }}
|
||||
{{ (isSingleInvite ? "resendInvitation" : "reinviteSelected") | i18n }}
|
||||
</button>
|
||||
}
|
||||
@if (bulkActions.showBulkConfirmUsers) {
|
||||
|
||||
@@ -125,6 +125,16 @@ export class vNextMembersComponent {
|
||||
.usersUpdated()
|
||||
.pipe(map(() => showConfirmBanner(this.dataSource())));
|
||||
|
||||
protected selectedInvitedCount$ = this.dataSource()
|
||||
.usersUpdated()
|
||||
.pipe(
|
||||
map(
|
||||
(members) => members.filter((m) => m.status === OrganizationUserStatusType.Invited).length,
|
||||
),
|
||||
);
|
||||
|
||||
protected isSingleInvite$ = this.selectedInvitedCount$.pipe(map((count) => count === 1));
|
||||
|
||||
protected isProcessing = this.memberActionsService.isProcessing;
|
||||
|
||||
protected readonly canUseSecretsManager: Signal<boolean> = computed(
|
||||
|
||||
@@ -193,7 +193,7 @@ export abstract class CipherReportComponent implements OnDestroy {
|
||||
formConfig,
|
||||
activeCollectionId,
|
||||
disableForm,
|
||||
isAdminConsoleAction: true,
|
||||
isAdminConsoleAction: this.organization != null,
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
bitTypography="h1"
|
||||
noMargin
|
||||
class="tw-m-0 tw-mr-2 tw-leading-10 tw-flex tw-gap-1"
|
||||
[title]="title || (routeData.titleId | i18n)"
|
||||
[title]="title() || (routeData.titleId | i18n)"
|
||||
>
|
||||
<div class="tw-truncate">
|
||||
<i *ngIf="icon" class="bwi {{ icon }}" aria-hidden="true"></i>
|
||||
{{ title || (routeData.titleId | i18n) }}
|
||||
<i *ngIf="icon" class="bwi {{ icon() }}" aria-hidden="true"></i>
|
||||
{{ title() || (routeData.titleId | i18n) }}
|
||||
</div>
|
||||
<div><ng-content select="[slot=title-suffix]"></ng-content></div>
|
||||
</h1>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { Component, input, InputSignal } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
@@ -25,19 +23,15 @@ export class WebHeaderComponent {
|
||||
/**
|
||||
* Custom title that overrides the route data `titleId`
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() title: string;
|
||||
readonly title: InputSignal<string | undefined> = input();
|
||||
|
||||
/**
|
||||
* Icon to show before the title
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() icon: string;
|
||||
readonly icon: InputSignal<string | undefined> = input();
|
||||
|
||||
protected routeData$: Observable<{ titleId: string }>;
|
||||
protected account$: Observable<User & { id: UserId }>;
|
||||
protected account$: Observable<(User & { id: UserId }) | null>;
|
||||
protected canLock$: Observable<boolean>;
|
||||
protected selfHosted: boolean;
|
||||
protected hostname = location.hostname;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="tw-mt-6 tw-flex tw-h-full tw-flex-col tw-items-center tw-justify-start"
|
||||
class="tw-mt-6 tw-flex tw-h-full tw-flex-col tw-items-center tw-justify-start tw-flex-1"
|
||||
*ngIf="isEmpty && !performingInitialLoad"
|
||||
>
|
||||
<bit-no-items [icon]="(emptyState$ | async)?.icon">
|
||||
|
||||
Reference in New Issue
Block a user