mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
[PM-26074] All Activities tab - Updated UI (#16587)
* PM-26074 simplified and update the all-activities tab * PM-26074 removed learn more * PM-26074 fixing missing line
This commit is contained in:
@@ -59,9 +59,28 @@
|
|||||||
"createNewLoginItem": {
|
"createNewLoginItem": {
|
||||||
"message": "Create new login item"
|
"message": "Create new login item"
|
||||||
},
|
},
|
||||||
"criticalApplicationsActivityDescription": {
|
"onceYouMarkCriticalApplicationsActivityDescription": {
|
||||||
"message": "Once you mark applications critical, they will display here."
|
"message": "Once you mark applications critical, they will display here."
|
||||||
},
|
},
|
||||||
|
"viewAtRiskMembers": {
|
||||||
|
"message": "View at-risk members"
|
||||||
|
},
|
||||||
|
"viewAtRiskApplications": {
|
||||||
|
"message": "View at-risk applications"
|
||||||
|
},
|
||||||
|
"criticalApplicationsAreAtRisk": {
|
||||||
|
"message": "$COUNT$ out of $TOTAL$ critical applications are at-risk due to at-risk passwords",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "3"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"content": "$2",
|
||||||
|
"example": "5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"criticalApplicationsWithCount": {
|
"criticalApplicationsWithCount": {
|
||||||
"message": "Critical applications ($COUNT$)",
|
"message": "Critical applications ($COUNT$)",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -80,6 +99,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"countOfApplicationsAtRisk": {
|
||||||
|
"message": "$COUNT$ applications at-risk",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"notifiedMembersWithCount": {
|
"notifiedMembersWithCount": {
|
||||||
"message": "Notified members ($COUNT$)",
|
"message": "Notified members ($COUNT$)",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
|
import { OrganizationReportSummary } from "../models/report-models";
|
||||||
|
|
||||||
|
export class AllActivitiesService {
|
||||||
|
/// This class is used to manage the summary of all applications
|
||||||
|
/// and critical applications.
|
||||||
|
/// Going forward, this class can be simplified by using the RiskInsightsDataService
|
||||||
|
/// as it contains the application summary data.
|
||||||
|
|
||||||
|
private reportSummarySubject$ = new BehaviorSubject<OrganizationReportSummary>({
|
||||||
|
totalMemberCount: 0,
|
||||||
|
totalCriticalMemberCount: 0,
|
||||||
|
totalAtRiskMemberCount: 0,
|
||||||
|
totalCriticalAtRiskMemberCount: 0,
|
||||||
|
totalApplicationCount: 0,
|
||||||
|
totalCriticalApplicationCount: 0,
|
||||||
|
totalAtRiskApplicationCount: 0,
|
||||||
|
totalCriticalAtRiskApplicationCount: 0,
|
||||||
|
newApplications: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
reportSummary$ = this.reportSummarySubject$.asObservable();
|
||||||
|
|
||||||
|
setCriticalAppsReportSummary(summary: OrganizationReportSummary) {
|
||||||
|
this.reportSummarySubject$.next({
|
||||||
|
...this.reportSummarySubject$.getValue(),
|
||||||
|
totalCriticalApplicationCount: summary.totalApplicationCount,
|
||||||
|
totalCriticalAtRiskApplicationCount: summary.totalAtRiskApplicationCount,
|
||||||
|
totalCriticalMemberCount: summary.totalMemberCount,
|
||||||
|
totalCriticalAtRiskMemberCount: summary.totalAtRiskMemberCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setAllAppsReportSummary(summary: OrganizationReportSummary) {
|
||||||
|
this.reportSummarySubject$.next({
|
||||||
|
...this.reportSummarySubject$.getValue(),
|
||||||
|
totalMemberCount: summary.totalMemberCount,
|
||||||
|
totalAtRiskMemberCount: summary.totalAtRiskMemberCount,
|
||||||
|
totalApplicationCount: summary.totalApplicationCount,
|
||||||
|
totalAtRiskApplicationCount: summary.totalAtRiskApplicationCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,3 +5,4 @@ export * from "./critical-apps-api.service";
|
|||||||
export * from "./risk-insights-api.service";
|
export * from "./risk-insights-api.service";
|
||||||
export * from "./risk-insights-report.service";
|
export * from "./risk-insights-report.service";
|
||||||
export * from "./risk-insights-data.service";
|
export * from "./risk-insights-data.service";
|
||||||
|
export * from "./all-activities.service";
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NgModule } from "@angular/core";
|
|||||||
import { safeProvider } from "@bitwarden/angular/platform/utils/safe-provider";
|
import { safeProvider } from "@bitwarden/angular/platform/utils/safe-provider";
|
||||||
import { CriticalAppsService } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
import { CriticalAppsService } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
import {
|
import {
|
||||||
|
AllActivitiesService,
|
||||||
CriticalAppsApiService,
|
CriticalAppsApiService,
|
||||||
MemberCipherDetailsApiService,
|
MemberCipherDetailsApiService,
|
||||||
PasswordHealthService,
|
PasswordHealthService,
|
||||||
@@ -73,6 +74,11 @@ import { RiskInsightsComponent } from "./risk-insights.component";
|
|||||||
useClass: CriticalAppsApiService,
|
useClass: CriticalAppsApiService,
|
||||||
deps: [ApiService],
|
deps: [ApiService],
|
||||||
}),
|
}),
|
||||||
|
safeProvider({
|
||||||
|
provide: AllActivitiesService,
|
||||||
|
useClass: AllActivitiesService,
|
||||||
|
deps: [],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AccessIntelligenceModule {}
|
export class AccessIntelligenceModule {}
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
<div class="tw-flex-col">
|
<div class="tw-flex-col">
|
||||||
<span bitTypography="h6" class="tw-flex tw-text-main">{{ title | i18n }}</span>
|
<span bitTypography="h6" class="tw-flex tw-text-main">{{ title }}</span>
|
||||||
<div class="tw-flex tw-items-baseline tw-gap-2">
|
<div class="tw-flex tw-items-baseline tw-gap-2">
|
||||||
<span bitTypography="h3">{{ cardMetrics | i18n: value }}</span>
|
<span bitTypography="h3">{{ cardMetrics }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-flex tw-items-baseline tw-gap-2">
|
<div class="tw-flex tw-items-baseline tw-mt-4 tw-gap-2">
|
||||||
<span bitTypography="body2">{{ metricDescription | i18n }}</span>
|
<span bitTypography="body2">{{ metricDescription }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@if (showNavigationLink) {
|
||||||
|
<div class="tw-flex tw-items-baseline tw-mt-4 tw-gap-2">
|
||||||
|
<p bitTypography="body1">
|
||||||
|
<a bitLink (click)="navigateToLink(navigationLink)" rel="noreferrer">
|
||||||
|
{{ navigationText }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component, Input } from "@angular/core";
|
import { Component, Input } from "@angular/core";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { TypographyModule } from "@bitwarden/components";
|
import { ButtonModule, LinkModule, TypographyModule } from "@bitwarden/components";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "dirt-activity-card",
|
selector: "dirt-activity-card",
|
||||||
templateUrl: "./activity-card.component.html",
|
templateUrl: "./activity-card.component.html",
|
||||||
imports: [CommonModule, TypographyModule, JslibModule],
|
imports: [CommonModule, TypographyModule, JslibModule, LinkModule, ButtonModule],
|
||||||
host: {
|
host: {
|
||||||
class:
|
class:
|
||||||
"tw-box-border tw-bg-background tw-block tw-text-main tw-border-solid tw-border tw-border-secondary-300 tw-border [&:not(bit-layout_*)]:tw-rounded-lg tw-rounded-lg tw-p-6",
|
"tw-box-border tw-bg-background tw-block tw-text-main tw-border-solid tw-border tw-border-secondary-300 tw-border [&:not(bit-layout_*)]:tw-rounded-lg tw-rounded-lg tw-p-6",
|
||||||
@@ -18,10 +19,6 @@ export class ActivityCardComponent {
|
|||||||
* The title of the card goes here
|
* The title of the card goes here
|
||||||
*/
|
*/
|
||||||
@Input() title: string = "";
|
@Input() title: string = "";
|
||||||
/**
|
|
||||||
* The current value of the card as emphasized text
|
|
||||||
*/
|
|
||||||
@Input() value: number | null = null;
|
|
||||||
/**
|
/**
|
||||||
* The card metrics text to display next to the value
|
* The card metrics text to display next to the value
|
||||||
*/
|
*/
|
||||||
@@ -30,4 +27,25 @@ export class ActivityCardComponent {
|
|||||||
* The description text to display below the value and metrics
|
* The description text to display below the value and metrics
|
||||||
*/
|
*/
|
||||||
@Input() metricDescription: string = "";
|
@Input() metricDescription: string = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The link to navigate to for more information
|
||||||
|
*/
|
||||||
|
@Input() navigationLink: string = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The text to display for the navigation link
|
||||||
|
*/
|
||||||
|
@Input() navigationText: string = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Navigation link
|
||||||
|
*/
|
||||||
|
@Input() showNavigationLink: boolean = false;
|
||||||
|
|
||||||
|
constructor(private router: Router) {}
|
||||||
|
|
||||||
|
navigateToLink = async (navigationLink: string) => {
|
||||||
|
await this.router.navigateByUrl(navigationLink);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,19 +21,33 @@
|
|||||||
<div class="tw-flex tw-gap-4 tw-col-span-6">
|
<div class="tw-flex tw-gap-4 tw-col-span-6">
|
||||||
<dirt-activity-card
|
<dirt-activity-card
|
||||||
class="tw-col-span-2 tw-cursor-pointer"
|
class="tw-col-span-2 tw-cursor-pointer"
|
||||||
[title]="'atRiskMembers'"
|
[title]="'atRiskMembers' | i18n"
|
||||||
[value]="atRiskMemberCount"
|
[cardMetrics]="'membersAtRisk' | i18n: totalCriticalAppsAtRiskMemberCount"
|
||||||
[cardMetrics]="'membersAtRisk'"
|
[metricDescription]="'membersAtRiskActivityDescription' | i18n"
|
||||||
[metricDescription]="'membersAtRiskActivityDescription'"
|
navigationText="{{ 'viewAtRiskMembers' | i18n }}"
|
||||||
|
navigationLink="{{ getLinkForRiskInsightsTab(RiskInsightsTabType.AllApps) }}"
|
||||||
|
[showNavigationLink]="totalCriticalAppsAtRiskMemberCount > 0"
|
||||||
>
|
>
|
||||||
</dirt-activity-card>
|
</dirt-activity-card>
|
||||||
|
|
||||||
<dirt-activity-card
|
<dirt-activity-card
|
||||||
#allAppsOrgAtRiskApplications
|
#allAppsOrgAtRiskApplications
|
||||||
class="tw-col-span-2 tw-cursor-pointer"
|
class="tw-col-span-2 tw-cursor-pointer"
|
||||||
[title]="'criticalApplications'"
|
[title]="'criticalApplications' | i18n"
|
||||||
[value]="criticalApplicationsCount"
|
[cardMetrics]="
|
||||||
[cardMetrics]="'countOfCriticalApplications'"
|
totalCriticalAppsCount === 0
|
||||||
[metricDescription]="'criticalApplicationsActivityDescription'"
|
? ('countOfCriticalApplications' | i18n: totalCriticalAppsCount)
|
||||||
|
: ('countOfApplicationsAtRisk' | i18n: totalCriticalAppsCount)
|
||||||
|
"
|
||||||
|
[metricDescription]="
|
||||||
|
totalCriticalAppsCount === 0
|
||||||
|
? ('onceYouMarkCriticalApplicationsActivityDescription' | i18n)
|
||||||
|
: ('criticalApplicationsAreAtRisk'
|
||||||
|
| i18n: totalCriticalAppsAtRiskCount : totalCriticalAppsCount)
|
||||||
|
"
|
||||||
|
navigationText="{{ 'viewAtRiskApplications' | i18n }}"
|
||||||
|
navigationLink="{{ getLinkForRiskInsightsTab(RiskInsightsTabType.CriticalApps) }}"
|
||||||
|
[showNavigationLink]="totalCriticalAppsAtRiskCount > 0"
|
||||||
>
|
>
|
||||||
</dirt-activity-card>
|
</dirt-activity-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
||||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { BehaviorSubject, combineLatest, firstValueFrom, of, switchMap } from "rxjs";
|
import { BehaviorSubject, firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CriticalAppsService,
|
AllActivitiesService,
|
||||||
RiskInsightsDataService,
|
RiskInsightsDataService,
|
||||||
RiskInsightsReportService,
|
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { getById } from "@bitwarden/common/platform/misc";
|
import { getById } from "@bitwarden/common/platform/misc";
|
||||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
|
||||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||||
|
|
||||||
import { ActivityCardComponent } from "./activity-card.component";
|
import { ActivityCardComponent } from "./activity-card.component";
|
||||||
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
||||||
|
import { RiskInsightsTabType } from "./risk-insights.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "tools-all-activity",
|
selector: "tools-all-activity",
|
||||||
@@ -28,8 +27,9 @@ export class AllActivityComponent implements OnInit {
|
|||||||
protected isLoading$ = this.dataService.isLoading$;
|
protected isLoading$ = this.dataService.isLoading$;
|
||||||
protected noData$ = new BehaviorSubject(true);
|
protected noData$ = new BehaviorSubject(true);
|
||||||
organization: Organization | null = null;
|
organization: Organization | null = null;
|
||||||
atRiskMemberCount = 0;
|
totalCriticalAppsAtRiskMemberCount = 0;
|
||||||
criticalApplicationsCount = 0;
|
totalCriticalAppsCount = 0;
|
||||||
|
totalCriticalAppsAtRiskCount = 0;
|
||||||
|
|
||||||
destroyRef = inject(DestroyRef);
|
destroyRef = inject(DestroyRef);
|
||||||
|
|
||||||
@@ -43,21 +43,13 @@ export class AllActivityComponent implements OnInit {
|
|||||||
this.organizationService.organizations$(userId).pipe(getById(organizationId)),
|
this.organizationService.organizations$(userId).pipe(getById(organizationId)),
|
||||||
)) ?? null;
|
)) ?? null;
|
||||||
|
|
||||||
combineLatest([
|
this.allActivitiesService.reportSummary$
|
||||||
this.dataService.applications$,
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||||
this.criticalAppsService.getAppsListForOrg(organizationId as OrganizationId),
|
.subscribe((summary) => {
|
||||||
])
|
this.noData$.next(summary.totalApplicationCount === 0);
|
||||||
.pipe(
|
this.totalCriticalAppsAtRiskMemberCount = summary.totalCriticalAtRiskMemberCount;
|
||||||
takeUntilDestroyed(this.destroyRef),
|
this.totalCriticalAppsCount = summary.totalCriticalApplicationCount;
|
||||||
switchMap(([apps, criticalApps]) => {
|
this.totalCriticalAppsAtRiskCount = summary.totalCriticalAtRiskApplicationCount;
|
||||||
const atRiskMembers = this.reportService.generateAtRiskMemberList(apps ?? []);
|
|
||||||
return of({ apps, atRiskMembers, criticalApps });
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.subscribe(({ apps, atRiskMembers, criticalApps }) => {
|
|
||||||
this.noData$.next((apps?.length ?? 0) === 0);
|
|
||||||
this.atRiskMemberCount = atRiskMembers?.length ?? 0;
|
|
||||||
this.criticalApplicationsCount = criticalApps?.length ?? 0;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +59,15 @@ export class AllActivityComponent implements OnInit {
|
|||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
protected organizationService: OrganizationService,
|
protected organizationService: OrganizationService,
|
||||||
protected dataService: RiskInsightsDataService,
|
protected dataService: RiskInsightsDataService,
|
||||||
protected reportService: RiskInsightsReportService,
|
protected allActivitiesService: AllActivitiesService,
|
||||||
protected criticalAppsService: CriticalAppsService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
get RiskInsightsTabType() {
|
||||||
|
return RiskInsightsTabType;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLinkForRiskInsightsTab(tabIndex: RiskInsightsTabType): string {
|
||||||
|
const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
|
||||||
|
return `/organizations/${organizationId}/access-intelligence/risk-insights?tabIndex=${tabIndex}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { combineLatest, debounceTime, firstValueFrom, map, Observable, of, switc
|
|||||||
|
|
||||||
import { Security } from "@bitwarden/assets/svg";
|
import { Security } from "@bitwarden/assets/svg";
|
||||||
import {
|
import {
|
||||||
|
AllActivitiesService,
|
||||||
CriticalAppsService,
|
CriticalAppsService,
|
||||||
RiskInsightsDataService,
|
RiskInsightsDataService,
|
||||||
RiskInsightsReportService,
|
RiskInsightsReportService,
|
||||||
@@ -120,6 +121,7 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
if (data) {
|
if (data) {
|
||||||
this.dataSource.data = data;
|
this.dataSource.data = data;
|
||||||
this.applicationSummary = this.reportService.generateApplicationsSummary(data);
|
this.applicationSummary = this.reportService.generateApplicationsSummary(data);
|
||||||
|
this.allActivitiesService.setAllAppsReportSummary(this.applicationSummary);
|
||||||
}
|
}
|
||||||
if (organization) {
|
if (organization) {
|
||||||
this.organization = organization;
|
this.organization = organization;
|
||||||
@@ -142,6 +144,7 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
protected criticalAppsService: CriticalAppsService,
|
protected criticalAppsService: CriticalAppsService,
|
||||||
protected riskInsightsEncryptionService: RiskInsightsEncryptionService,
|
protected riskInsightsEncryptionService: RiskInsightsEncryptionService,
|
||||||
|
protected allActivitiesService: AllActivitiesService,
|
||||||
) {
|
) {
|
||||||
this.searchControl.valueChanges
|
this.searchControl.valueChanges
|
||||||
.pipe(debounceTime(200), takeUntilDestroyed())
|
.pipe(debounceTime(200), takeUntilDestroyed())
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { combineLatest, debounceTime, firstValueFrom, map, switchMap } from "rxj
|
|||||||
|
|
||||||
import { Security } from "@bitwarden/assets/svg";
|
import { Security } from "@bitwarden/assets/svg";
|
||||||
import {
|
import {
|
||||||
|
AllActivitiesService,
|
||||||
CriticalAppsService,
|
CriticalAppsService,
|
||||||
RiskInsightsDataService,
|
RiskInsightsDataService,
|
||||||
RiskInsightsReportService,
|
RiskInsightsReportService,
|
||||||
@@ -99,6 +100,7 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
this.dataSource.data = applications;
|
this.dataSource.data = applications;
|
||||||
this.applicationSummary = this.reportService.generateApplicationsSummary(applications);
|
this.applicationSummary = this.reportService.generateApplicationsSummary(applications);
|
||||||
this.enableRequestPasswordChange = this.applicationSummary.totalAtRiskMemberCount > 0;
|
this.enableRequestPasswordChange = this.applicationSummary.totalAtRiskMemberCount > 0;
|
||||||
|
this.allActivitiesService.setCriticalAppsReportSummary(this.applicationSummary);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -176,6 +178,7 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private adminTaskService: DefaultAdminTaskService,
|
private adminTaskService: DefaultAdminTaskService,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
|
private allActivitiesService: AllActivitiesService,
|
||||||
) {
|
) {
|
||||||
this.searchControl.valueChanges
|
this.searchControl.valueChanges
|
||||||
.pipe(debounceTime(200), takeUntilDestroyed())
|
.pipe(debounceTime(200), takeUntilDestroyed())
|
||||||
|
|||||||
Reference in New Issue
Block a user