+
{{ title() }}
- @if (iconClass) {
-
+ @if (iconClass()) {
+
}
- {{ cardMetrics }}
+ {{ cardMetrics() }}
- {{ metricDescription }}
+ {{ metricDescription() }}
- @if (buttonClick.observed && buttonText) {
+ @if (buttonText()) {
}
- @if (showActionLink && !buttonText) {
+ @if (showActionLink() && !buttonText()) {
diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-card.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-card.component.ts
index f98ce397ee9..415338b5715 100644
--- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-card.component.ts
+++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-card.component.ts
@@ -1,15 +1,12 @@
-import { Component, EventEmitter, Input, Output } from "@angular/core";
-import { Router } from "@angular/router";
+import { ChangeDetectionStrategy, Component, input, output } from "@angular/core";
-import { JslibModule } from "@bitwarden/angular/jslib.module";
import { ButtonModule, ButtonType, LinkModule, TypographyModule } from "@bitwarden/components";
-// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
-// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "dirt-activity-card",
+ changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: "./activity-card.component.html",
- imports: [TypographyModule, JslibModule, LinkModule, ButtonModule],
+ imports: [TypographyModule, LinkModule, ButtonModule],
host: {
class:
"tw-box-border tw-bg-background tw-block tw-text-main tw-border-solid tw-border-secondary-100 tw-border [&:not(bit-layout_*)]:tw-rounded-lg tw-rounded-lg tw-p-6 tw-min-h-56 tw-overflow-hidden",
@@ -19,87 +16,72 @@ export class ActivityCardComponent {
/**
* The title of the card goes here
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() title: string = "";
+ readonly title = input.required
();
/**
* The card metrics text to display next to the value
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() cardMetrics: string = "";
+ readonly cardMetrics = input.required();
/**
* The description text to display below the value and metrics
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() metricDescription: string = "";
+ readonly metricDescription = input.required();
/**
* The text to display for the action link
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() actionText: string = "";
+ readonly actionText = input("");
/**
* Show action link
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() showActionLink: boolean = false;
+ readonly showActionLink = input(false);
/**
* Icon class to display next to metrics (e.g., "bwi-exclamation-triangle").
* If null, no icon is displayed.
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() iconClass: string | null = null;
+ readonly iconClass = input(null);
/**
* CSS class for icon color (e.g., "tw-text-success", "tw-text-muted").
* Defaults to "tw-text-muted" if not provided.
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() iconColorClass: string = "tw-text-muted";
+ readonly iconColorClass = input("tw-text-muted");
/**
* Button text. If provided, a button will be displayed instead of a navigation link.
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() buttonText: string = "";
+ readonly buttonText = input("");
/**
* Button type (e.g., "primary", "secondary")
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-signals
- @Input() buttonType: ButtonType = "primary";
+ readonly buttonType = input("primary");
/**
* Event emitted when button is clicked
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
- @Output() buttonClick = new EventEmitter();
+ readonly buttonClick = output();
+
+ /*
+ * To facilitate automated testing, provide a testId that will be
+ * added as a data attribute to the root element of the card
+ * (e.g., ).
+ * This allows tests to easily select the card using
+ * the data attribute (e.g., [data-test-id="my-card"].
+ */
+ readonly testId = input.required();
/**
* Event emitted when action link is clicked
*/
- // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
- // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
- @Output() actionClick = new EventEmitter();
+ readonly actionClick = output();
- constructor(private router: Router) {}
-
- onButtonClick = () => {
+ readonly onButtonClick = () => {
this.buttonClick.emit();
};
- onActionClick = () => {
+ readonly onActionClick = () => {
this.actionClick.emit();
};
}
diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-cards/password-change-metric.component.html b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-cards/password-change-metric.component.html
index ac17a25ff20..9ae479f0344 100644
--- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-cards/password-change-metric.component.html
+++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/activity-cards/password-change-metric.component.html
@@ -1,5 +1,6 @@
{{ "passwordChangeProgress" | i18n }}
@@ -7,7 +8,7 @@
@switch (currentView()) {
@case (PasswordChangeViewEnum.EMPTY) {
-
+
{{ "assignMembersTasksToMonitorProgress" | i18n }}
@@ -17,7 +18,7 @@
}
@case (PasswordChangeViewEnum.NO_TASKS_ASSIGNED) {
-
+
{{ "assignMembersTasksToMonitorProgress" | i18n }}
@@ -38,7 +39,7 @@
}
@case (PasswordChangeViewEnum.NEW_TASKS_AVAILABLE) {
-
+
{{ "assignMembersTasksToMonitorProgress" | i18n }}
@@ -55,7 +56,7 @@
}
@case (PasswordChangeViewEnum.PROGRESS) {
-
+
{{ "percentageCompleted" | i18n: completedTasksPercent() }}
@@ -66,12 +67,13 @@
-
+
{{ completedTasksCount() }}
{{ tasksCount() }}
0"
(actionClick)="onViewAtRiskMembers()"
+ [testId]="'at-risk-members-card'"
>
0"
(actionClick)="onViewAtRiskMembers()"
+ [testId]="'at-risk-members-card'"
>
@@ -70,6 +72,7 @@
actionText="{{ 'viewAtRiskApplications' | i18n }}"
[showActionLink]="totalCriticalAppsAtRiskCount > 0"
(actionClick)="onViewAtRiskApplications()"
+ [testId]="'critical-applications-card'"
>
@@ -86,6 +89,7 @@
[buttonText]="''"
[buttonType]="'primary'"
(buttonClick)="onReviewNewApplications()"
+ [testId]="'allCaughtUp'"
>
@@ -102,6 +106,7 @@
[buttonText]="'reviewApplications' | i18n"
[buttonType]="'primary'"
(buttonClick)="onReviewNewApplications()"
+ [testId]="'needs-review-card'"
>
@@ -118,6 +123,7 @@
[buttonText]="'reviewNow' | i18n"
[buttonType]="'primary'"
(buttonClick)="onReviewNewApplications()"
+ [testId]="'review-new-applications-card'"
>
diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/application-review-dialog/assign-tasks-view.component.html b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/application-review-dialog/assign-tasks-view.component.html
index 889563055a2..2110c8f38e1 100644
--- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/application-review-dialog/assign-tasks-view.component.html
+++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/activity/application-review-dialog/assign-tasks-view.component.html
@@ -1,4 +1,4 @@
-
+
@@ -13,7 +13,7 @@
-
+
-
+
-
+
@if (currentView() === DialogView.SelectApplications) {
-
+