1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 13:53:34 +00:00

Fix flood of Angular warning messages on policies page (#16618)

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
Maciej Zieniuk
2025-09-30 03:52:04 +02:00
committed by GitHub
parent f92eddf7b9
commit cae01c6e0f
2 changed files with 43 additions and 26 deletions

View File

@@ -1,7 +1,6 @@
<app-header></app-header> <app-header></app-header>
<bit-container> <bit-container>
@let organization = organization$ | async;
@if (loading) { @if (loading) {
<i <i
class="bwi bwi-spinner bwi-spin tw-text-muted" class="bwi bwi-spinner bwi-spin tw-text-muted"
@@ -13,18 +12,16 @@
@if (!loading) { @if (!loading) {
<bit-table> <bit-table>
<ng-template body> <ng-template body>
@for (p of policies; track p.name) { @for (p of policies$ | async; track p.type) {
@if (p.display$(organization, configService) | async) { <tr bitRow>
<tr bitRow> <td bitCell ngPreserveWhitespaces>
<td bitCell ngPreserveWhitespaces> <button type="button" bitLink (click)="edit(p)">{{ p.name | i18n }}</button>
<button type="button" bitLink (click)="edit(p)">{{ p.name | i18n }}</button> @if (policiesEnabledMap.get(p.type)) {
@if (policiesEnabledMap.get(p.type)) { <span bitBadge variant="success">{{ "on" | i18n }}</span>
<span bitBadge variant="success">{{ "on" | i18n }}</span> }
} <small class="tw-text-muted tw-block">{{ p.description | i18n }}</small>
<small class="tw-text-muted tw-block">{{ p.description | i18n }}</small> </td>
</td> </tr>
</tr>
}
} }
</ng-template> </ng-template>
</bit-table> </bit-table>

View File

@@ -2,8 +2,17 @@
// @ts-strict-ignore // @ts-strict-ignore
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { firstValueFrom, lastValueFrom, Observable } from "rxjs"; import {
import { first, map } from "rxjs/operators"; combineLatest,
firstValueFrom,
lastValueFrom,
Observable,
of,
switchMap,
first,
map,
withLatestFrom,
} from "rxjs";
import { import {
getOrganizationById, getOrganizationById,
@@ -11,7 +20,6 @@ import {
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response"; import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@@ -39,8 +47,7 @@ import { POLICY_EDIT_REGISTER } from "./policy-register-token";
export class PoliciesComponent implements OnInit { export class PoliciesComponent implements OnInit {
loading = true; loading = true;
organizationId: string; organizationId: string;
policies: readonly BasePolicyEditDefinition[]; policies$: Observable<BasePolicyEditDefinition[]>;
protected organization$: Observable<Organization>;
private orgPolicies: PolicyResponse[]; private orgPolicies: PolicyResponse[];
protected policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>(); protected policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
@@ -63,28 +70,41 @@ export class PoliciesComponent implements OnInit {
this.accountService.activeAccount$.pipe(map((a) => a?.id)), this.accountService.activeAccount$.pipe(map((a) => a?.id)),
); );
this.organization$ = this.organizationService const organization$ = this.organizationService
.organizations$(userId) .organizations$(userId)
.pipe(getOrganizationById(this.organizationId)); .pipe(getOrganizationById(this.organizationId));
this.policies = this.policyListService.getPolicies(); this.policies$ = organization$.pipe(
withLatestFrom(of(this.policyListService.getPolicies())),
switchMap(([organization, policies]) => {
return combineLatest(
policies.map((policy) =>
policy
.display$(organization, this.configService)
.pipe(map((shouldDisplay) => ({ policy, shouldDisplay }))),
),
);
}),
map((results) =>
results.filter((result) => result.shouldDisplay).map((result) => result.policy),
),
);
await this.load(); await this.load();
// Handle policies component launch from Event message // Handle policies component launch from Event message
this.route.queryParams combineLatest([this.route.queryParams.pipe(first()), this.policies$])
.pipe(first())
/* eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe, rxjs/no-nested-subscribe */ /* eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe, rxjs/no-nested-subscribe */
.subscribe(async (qParams) => { .subscribe(async ([qParams, policies]) => {
if (qParams.policyId != null) { if (qParams.policyId != null) {
const policyIdFromEvents: string = qParams.policyId; const policyIdFromEvents: string = qParams.policyId;
for (const orgPolicy of this.orgPolicies) { for (const orgPolicy of this.orgPolicies) {
if (orgPolicy.id === policyIdFromEvents) { if (orgPolicy.id === policyIdFromEvents) {
for (let i = 0; i < this.policies.length; i++) { for (let i = 0; i < policies.length; i++) {
if (this.policies[i].type === orgPolicy.type) { if (policies[i].type === orgPolicy.type) {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises // eslint-disable-next-line @typescript-eslint/no-floating-promises
this.edit(this.policies[i]); this.edit(policies[i]);
break; break;
} }
} }