diff --git a/apps/web/src/app/admin-console/common/base.events.component.ts b/apps/web/src/app/admin-console/common/base.events.component.ts index ba315dee7fb..dd1c393bc13 100644 --- a/apps/web/src/app/admin-console/common/base.events.component.ts +++ b/apps/web/src/app/admin-console/common/base.events.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Directive, OnDestroy } from "@angular/core"; +import { Directive, OnDestroy, signal } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { combineLatest, filter, map, Observable, Subject, switchMap, takeUntil } from "rxjs"; @@ -22,9 +22,9 @@ import { EventExportService } from "../../tools/event-export"; @Directive() export abstract class BaseEventsComponent implements OnDestroy { - loading = true; - loaded = false; - events: EventView[]; + readonly loading = signal(true); + readonly loaded = signal(false); + readonly events = signal([]); dirtyDates = true; continuationToken: string; canUseSM = false; @@ -115,7 +115,7 @@ export abstract class BaseEventsComponent implements OnDestroy { return; } - this.loading = true; + this.loading.set(true); const dates = this.parseDates(); if (dates == null) { @@ -131,7 +131,7 @@ export abstract class BaseEventsComponent implements OnDestroy { } promise = null; - this.loading = false; + this.loading.set(false); }; loadEvents = async (clearExisting: boolean) => { @@ -140,7 +140,7 @@ export abstract class BaseEventsComponent implements OnDestroy { return; } - this.loading = true; + this.loading.set(true); let events: EventView[] = []; let promise: Promise; promise = this.loadAndParseEvents( @@ -153,14 +153,16 @@ export abstract class BaseEventsComponent implements OnDestroy { this.continuationToken = result.continuationToken; events = result.events; - if (!clearExisting && this.events != null && this.events.length > 0) { - this.events = this.events.concat(events); + if (!clearExisting && this.events() != null && this.events().length > 0) { + this.events.update((current) => { + return [...current, ...events]; + }); } else { - this.events = events; + this.events.set(events); } this.dirtyDates = false; - this.loading = false; + this.loading.set(false); promise = null; }; @@ -227,7 +229,7 @@ export abstract class BaseEventsComponent implements OnDestroy { private async export(start: string, end: string) { let continuationToken = this.continuationToken; - let events = [].concat(this.events); + let events = [].concat(this.events()); while (continuationToken != null) { const result = await this.loadAndParseEvents(start, end, continuationToken); diff --git a/apps/web/src/app/admin-console/organizations/manage/events.component.html b/apps/web/src/app/admin-console/organizations/manage/events.component.html index 83665a4b99e..3e76c8c879b 100644 --- a/apps/web/src/app/admin-console/organizations/manage/events.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/events.component.html @@ -1,14 +1,16 @@ @let usePlaceHolderEvents = !organization?.useEvents; + - - {{ "upgrade" | i18n }} - + @if (usePlaceHolderEvents) { + + {{ "upgrade" | i18n }} + + }
@@ -61,79 +63,87 @@
- - {{ "upgradeEventLogMessage" | i18n }} - - - - {{ "loading" | i18n }} - - - @let displayedEvents = organization?.useEvents ? events : placeholderEvents; +@if (loaded() && usePlaceHolderEvents) { + + {{ "upgradeEventLogMessage" | i18n }} + +} -

{{ "noEventsInList" | i18n }}

- - - - {{ "timestamp" | i18n }} - {{ "client" | i18n }} - {{ "member" | i18n }} - {{ "event" | i18n }} - - - - - - {{ i > 4 && usePlaceHolderEvents ? "******" : (e.date | date: "medium") }} - - - {{ e.appName }} - - - {{ e.userName }} - - - - - - -
+@if (!loaded()) { + + + {{ "loading" | i18n }} + +} +@if (loaded()) { + + @let displayedEvents = organization?.useEvents ? events() : placeholderEvents; - -
-
- + @if (!displayedEvents || !displayedEvents.length) { +

{{ "noEventsInList" | i18n }}

+ } -

- {{ "upgradeEventLogTitleMessage" | i18n }} -

-

- {{ "upgradeForFullEventsMessage" | i18n }} -

- - + } + +} + +@if (loaded() && usePlaceHolderEvents) { + +
+
+ + +

+ {{ "upgradeEventLogTitleMessage" | i18n }} +

+

+ {{ "upgradeForFullEventsMessage" | i18n }} +

+ + +
-
- + +} diff --git a/apps/web/src/app/admin-console/organizations/manage/events.component.ts b/apps/web/src/app/admin-console/organizations/manage/events.component.ts index fffe1c06ab8..01d6515c486 100644 --- a/apps/web/src/app/admin-console/organizations/manage/events.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/events.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Component, OnDestroy, OnInit, ChangeDetectionStrategy } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { concatMap, firstValueFrom, lastValueFrom, map, of, switchMap, takeUntil, tap } from "rxjs"; @@ -47,9 +47,8 @@ const EVENT_SYSTEM_USER_TO_TRANSLATION: Record = { [EventSystemUser.BitwardenPortal]: "system", }; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: "events.component.html", imports: [SharedModule, HeaderModule], }) @@ -168,7 +167,7 @@ export class EventsComponent extends BaseEventsComponent implements OnInit, OnDe } } await this.refreshEvents(); - this.loaded = true; + this.loaded.set(true); } protected requestEvents(startDate: string, endDate: string, continuationToken: string) { diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.html index 070505a53b2..c79b39a6feb 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.html @@ -50,56 +50,64 @@
- - - {{ "loading" | i18n }} - - -

{{ "noEventsInList" | i18n }}

- - - - {{ "timestamp" | i18n }} - {{ "device" | i18n }} - {{ "user" | i18n }} - {{ "event" | i18n }} - - - - - {{ e.date | date: "medium" }} - - - {{ e.appName }}, {{ e.ip }} - - - {{ e.userName }} - - - - - - -
+ > + {{ "loading" | i18n }} +
+} +@if (loaded()) { + + @if (!events() || !events().length) { +

{{ "noEventsInList" | i18n }}

+ } + + @if (events() && events().length) { + + + + {{ "timestamp" | i18n }} + {{ "device" | i18n }} + {{ "user" | i18n }} + {{ "event" | i18n }} + + + + @for (e of events(); track i; let i = $index) { + + {{ e.date | date: "medium" }} + + + {{ e.appName }}, {{ e.ip }} + + + {{ e.userName }} + + + + } + + + } + @if (continuationToken) { + + } +
+} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.ts index 3d00d897175..fe14e56bbaa 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/events.component.ts @@ -94,7 +94,7 @@ export class EventsComponent extends BaseEventsComponent implements OnInit { this.providerUsersUserIdMap.set(u.userId, { name: name, email: u.email }); }); await this.refreshEvents(); - this.loaded = true; + this.loaded.set(true); } protected requestEvents(startDate: string, endDate: string, continuationToken: string) { diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.html index a895ab058ec..d1f410abc33 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.html @@ -47,41 +47,47 @@ - - - {{ "loading" | i18n }} - - -

{{ "noEventsInList" | i18n }}

- - - - {{ "timestamp" | i18n }} - {{ "client" | i18n }} - {{ "event" | i18n }} - - - - - {{ e.date | date: "medium" }} - - {{ e.appName }} - - - - - - -
+@if (!loaded()) { + + + {{ "loading" | i18n }} + +} +@if (loaded()) { + + @if (!events() || !events().length) { +

{{ "noEventsInList" | i18n }}

+ } + @if (events() && events().length) { + + + + {{ "timestamp" | i18n }} + {{ "client" | i18n }} + {{ "event" | i18n }} + + + + @for (e of events(); track i; let i = $index) { + + {{ e.date | date: "medium" }} + + {{ e.appName }} + + + + } + + + } + @if (continuationToken) { + + } +
+} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.ts index 5968933064d..525d658f233 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/event-logs/service-accounts-events.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { takeUntil } from "rxjs"; @@ -17,9 +17,8 @@ import { EventExportService } from "@bitwarden/web-vault/app/tools/event-export" import { ServiceAccountEventLogApiService } from "./service-account-event-log-api.service"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, selector: "sm-service-accounts-events", templateUrl: "./service-accounts-events.component.html", standalone: false, @@ -69,7 +68,7 @@ export class ServiceAccountEventsComponent async load() { await this.refreshEvents(); - this.loaded = true; + this.loaded.set(true); } protected requestEvents(startDate: string, endDate: string, continuationToken: string) {