mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 00:33:44 +00:00
[PM-28451] Fix icons in application review table (#17512)
* Fix icons in application review table * Add default icon if none is found in review applications table. Move function to computed signal * Rename function * Remove redundant if statement
This commit is contained in:
@@ -28,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<dirt-review-applications-view
|
<dirt-review-applications-view
|
||||||
[applications]="getApplications()"
|
[applications]="applicationsWithIcons()"
|
||||||
[selectedApplications]="selectedApplications()"
|
[selectedApplications]="selectedApplications()"
|
||||||
(onToggleSelection)="toggleSelection($event)"
|
(onToggleSelection)="toggleSelection($event)"
|
||||||
(onToggleAll)="toggleAll()"
|
(onToggleAll)="toggleAll()"
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
import { I18nPipe } from "@bitwarden/ui-common";
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
|
import { CipherIcon } from "../../shared/app-table-row-scrollable.component";
|
||||||
import { AccessIntelligenceSecurityTasksService } from "../../shared/security-tasks.service";
|
import { AccessIntelligenceSecurityTasksService } from "../../shared/security-tasks.service";
|
||||||
|
|
||||||
import { AssignTasksViewComponent } from "./assign-tasks-view.component";
|
import { AssignTasksViewComponent } from "./assign-tasks-view.component";
|
||||||
@@ -99,6 +100,16 @@ export class NewApplicationsDialogComponent {
|
|||||||
// Applications selected to save as critical applications
|
// Applications selected to save as critical applications
|
||||||
protected readonly selectedApplications = signal<Set<string>>(new Set());
|
protected readonly selectedApplications = signal<Set<string>>(new Set());
|
||||||
|
|
||||||
|
protected readonly applicationIcons = signal<Map<string, CipherIcon>>(
|
||||||
|
new Map<string, CipherIcon>(),
|
||||||
|
);
|
||||||
|
protected readonly applicationsWithIcons = computed(() => {
|
||||||
|
return this.dialogParams.newApplications.map((app) => {
|
||||||
|
const iconCipher = this.applicationIcons().get(app.applicationName);
|
||||||
|
return { ...app, iconCipher } as ApplicationHealthReportDetail & { iconCipher: CipherIcon };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Used to determine if there are unassigned at-risk cipher IDs
|
// Used to determine if there are unassigned at-risk cipher IDs
|
||||||
private readonly _tasks!: Signal<SecurityTask[]>;
|
private readonly _tasks!: Signal<SecurityTask[]>;
|
||||||
|
|
||||||
@@ -150,6 +161,7 @@ export class NewApplicationsDialogComponent {
|
|||||||
private securityTasksService: AccessIntelligenceSecurityTasksService,
|
private securityTasksService: AccessIntelligenceSecurityTasksService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
|
this.setApplicationIconMap(this.dialogParams.newApplications);
|
||||||
// Setup the _tasks signal by manually passing in the injector
|
// Setup the _tasks signal by manually passing in the injector
|
||||||
this._tasks = toSignal(this.securityTasksService.tasks$, {
|
this._tasks = toSignal(this.securityTasksService.tasks$, {
|
||||||
initialValue: [],
|
initialValue: [],
|
||||||
@@ -172,10 +184,6 @@ export class NewApplicationsDialogComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplications() {
|
|
||||||
return this.dialogParams.newApplications;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the organization has no existing critical applications.
|
* Returns true if the organization has no existing critical applications.
|
||||||
* Used to conditionally show different titles and descriptions.
|
* Used to conditionally show different titles and descriptions.
|
||||||
@@ -184,6 +192,22 @@ export class NewApplicationsDialogComponent {
|
|||||||
return !this.dialogParams.hasExistingCriticalApplications;
|
return !this.dialogParams.hasExistingCriticalApplications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps applications to a corresponding iconCipher
|
||||||
|
*
|
||||||
|
* @param applications
|
||||||
|
*/
|
||||||
|
setApplicationIconMap(applications: ApplicationHealthReportDetail[]) {
|
||||||
|
// Map the report data to include the iconCipher for each application
|
||||||
|
const iconCiphers = new Map<string, CipherIcon>();
|
||||||
|
applications.forEach((app) => {
|
||||||
|
const iconCipher =
|
||||||
|
app.cipherIds.length > 0 ? this.dataService.getCipherIcon(app.cipherIds[0]) : undefined;
|
||||||
|
iconCiphers.set(app.applicationName, iconCipher);
|
||||||
|
});
|
||||||
|
this.applicationIcons.set(iconCiphers);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the selection state of an application.
|
* Toggles the selection state of an application.
|
||||||
* @param applicationName The application to toggle
|
* @param applicationName The application to toggle
|
||||||
|
|||||||
@@ -62,7 +62,11 @@
|
|||||||
</td>
|
</td>
|
||||||
<td bitTypography="body1" class="tw-py-3 tw-px-2">
|
<td bitTypography="body1" class="tw-py-3 tw-px-2">
|
||||||
<div class="tw-flex tw-items-center tw-gap-2">
|
<div class="tw-flex tw-items-center tw-gap-2">
|
||||||
|
@if (app.iconCipher) {
|
||||||
|
<app-vault-icon [cipher]="app.iconCipher"></app-vault-icon>
|
||||||
|
} @else {
|
||||||
<i class="bwi bwi-globe tw-text-muted" aria-hidden="true"></i>
|
<i class="bwi bwi-globe tw-text-muted" aria-hidden="true"></i>
|
||||||
|
}
|
||||||
<span>{{ app.applicationName }}</span>
|
<span>{{ app.applicationName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { FormsModule } from "@angular/forms";
|
|||||||
import { ApplicationHealthReportDetail } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
import { ApplicationHealthReportDetail } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
import { ButtonModule, DialogModule, SearchModule, TypographyModule } from "@bitwarden/components";
|
import { ButtonModule, DialogModule, SearchModule, TypographyModule } from "@bitwarden/components";
|
||||||
import { I18nPipe } from "@bitwarden/ui-common";
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||||
|
|
||||||
|
import { CipherIcon } from "../../shared/app-table-row-scrollable.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
@@ -18,10 +21,12 @@ import { I18nPipe } from "@bitwarden/ui-common";
|
|||||||
SearchModule,
|
SearchModule,
|
||||||
TypographyModule,
|
TypographyModule,
|
||||||
I18nPipe,
|
I18nPipe,
|
||||||
|
SharedModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ReviewApplicationsViewComponent {
|
export class ReviewApplicationsViewComponent {
|
||||||
readonly applications = input.required<ApplicationHealthReportDetail[]>();
|
readonly applications =
|
||||||
|
input.required<Array<ApplicationHealthReportDetail & { iconCipher: CipherIcon }>>();
|
||||||
readonly selectedApplications = input.required<Set<string>>();
|
readonly selectedApplications = input.required<Set<string>>();
|
||||||
|
|
||||||
protected readonly searchText = signal<string>("");
|
protected readonly searchText = signal<string>("");
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
[attr.aria-label]="'viewItem' | i18n"
|
[attr.aria-label]="'viewItem' | i18n"
|
||||||
>
|
>
|
||||||
<!-- Passing the first cipher of the application for app-vault-icon cipher input requirement -->
|
|
||||||
<app-vault-icon *ngIf="row.iconCipher" [cipher]="row.iconCipher"></app-vault-icon>
|
<app-vault-icon *ngIf="row.iconCipher" [cipher]="row.iconCipher"></app-vault-icon>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import { MenuModule, TableDataSource, TableModule } from "@bitwarden/components"
|
|||||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||||
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
||||||
|
|
||||||
|
export type CipherIcon = CipherViewLike | undefined;
|
||||||
|
|
||||||
export type ApplicationTableDataSource = ApplicationHealthReportDetailEnriched & {
|
export type ApplicationTableDataSource = ApplicationHealthReportDetailEnriched & {
|
||||||
iconCipher: CipherViewLike | undefined;
|
iconCipher: CipherIcon;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||||
|
|||||||
Reference in New Issue
Block a user