mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
PM-20106 Pass indicator data to notification bar cipher items (#14246)
* PM-20106 initial approach whihc preserves exisiting indicator file style * refactored approach to be able to pass any icon when or if needed in the future * address feedback
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
} from "@bitwarden/common/autofill/constants";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import { UserNotificationSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
||||
import { ProductTierType } from "@bitwarden/common/billing/enums/product-tier-type.enum";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { NeverDomains } from "@bitwarden/common/models/domain/domain-service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
@@ -41,7 +42,11 @@ import { SecurityTask } from "@bitwarden/common/vault/tasks/models/security-task
|
||||
import { openUnlockPopout } from "../../auth/popup/utils/auth-popout-window";
|
||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||
import { openAddEditVaultItemPopout } from "../../vault/popup/utils/vault-popout-window";
|
||||
import { NotificationCipherData } from "../content/components/cipher/types";
|
||||
import {
|
||||
OrganizationCategory,
|
||||
OrganizationCategories,
|
||||
NotificationCipherData,
|
||||
} from "../content/components/cipher/types";
|
||||
import { NotificationQueueMessageType } from "../enums/notification-queue-message-type.enum";
|
||||
import { AutofillService } from "../services/abstractions/autofill.service";
|
||||
|
||||
@@ -174,8 +179,29 @@ export default class NotificationBackground {
|
||||
activeUserId,
|
||||
);
|
||||
|
||||
const organizations = await firstValueFrom(
|
||||
this.organizationService.organizations$(activeUserId),
|
||||
);
|
||||
|
||||
return decryptedCiphers.map((view) => {
|
||||
const { id, name, reprompt, favorite, login } = view;
|
||||
const { id, name, reprompt, favorite, login, organizationId } = view;
|
||||
|
||||
const organizationType = organizationId
|
||||
? organizations.find((org) => org.id === organizationId)?.productTierType
|
||||
: null;
|
||||
|
||||
const organizationCategories: OrganizationCategory[] = [];
|
||||
|
||||
if (
|
||||
[ProductTierType.Teams, ProductTierType.Enterprise, ProductTierType.TeamsStarter].includes(
|
||||
organizationType,
|
||||
)
|
||||
) {
|
||||
organizationCategories.push(OrganizationCategories.business);
|
||||
}
|
||||
if ([ProductTierType.Families, ProductTierType.Free].includes(organizationType)) {
|
||||
organizationCategories.push(OrganizationCategories.family);
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
@@ -183,6 +209,7 @@ export default class NotificationBackground {
|
||||
type: CipherType.Login,
|
||||
reprompt,
|
||||
favorite,
|
||||
...(organizationCategories.length ? { organizationCategories } : {}),
|
||||
icon: buildCipherIcon(iconsServerUrl, view, showFavicons),
|
||||
login: login && {
|
||||
username: login.username,
|
||||
|
||||
@@ -1,30 +1,35 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { html } from "lit";
|
||||
import { html, TemplateResult } from "lit";
|
||||
|
||||
import { Theme } from "@bitwarden/common/platform/enums";
|
||||
|
||||
import { themes } from "../../../content/components/constants/styles";
|
||||
import { Business, Users } from "../../../content/components/icons";
|
||||
|
||||
// @TODO connect data source to icon checks
|
||||
// @TODO support other indicator types (attachments, etc)
|
||||
import { OrganizationCategories, OrganizationCategory } from "./types";
|
||||
|
||||
const cipherIndicatorIconsMap: Record<
|
||||
OrganizationCategory,
|
||||
(args: { color: string; theme: Theme }) => TemplateResult
|
||||
> = {
|
||||
[OrganizationCategories.business]: Business,
|
||||
[OrganizationCategories.family]: Users,
|
||||
};
|
||||
|
||||
export function CipherInfoIndicatorIcons({
|
||||
showBusinessIcon,
|
||||
showFamilyIcon,
|
||||
organizationCategories = [],
|
||||
theme,
|
||||
}: {
|
||||
showBusinessIcon?: boolean;
|
||||
showFamilyIcon?: boolean;
|
||||
organizationCategories?: OrganizationCategory[];
|
||||
theme: Theme;
|
||||
}) {
|
||||
const indicatorIcons = [
|
||||
...(showBusinessIcon ? [Business({ color: themes[theme].text.muted, theme })] : []),
|
||||
...(showFamilyIcon ? [Users({ color: themes[theme].text.muted, theme })] : []),
|
||||
];
|
||||
|
||||
return indicatorIcons.length
|
||||
? html` <span class=${cipherInfoIndicatorIconsStyles}> ${indicatorIcons} </span> `
|
||||
: null; // @TODO null case should be handled by parent
|
||||
return html`
|
||||
<span class=${cipherInfoIndicatorIconsStyles}>
|
||||
${organizationCategories.map((name) =>
|
||||
cipherIndicatorIconsMap[name]?.({ color: themes[theme].text.muted, theme }),
|
||||
)}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
const cipherInfoIndicatorIconsStyles = css`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { html } from "lit";
|
||||
import { html, nothing } from "lit";
|
||||
|
||||
import { Theme } from "@bitwarden/common/platform/enums";
|
||||
|
||||
@@ -8,14 +8,22 @@ import { themes, typography } from "../../../content/components/constants/styles
|
||||
import { CipherInfoIndicatorIcons } from "./cipher-indicator-icons";
|
||||
import { NotificationCipherData } from "./types";
|
||||
|
||||
// @TODO support other cipher types (card, identity, notes, etc)
|
||||
export function CipherInfo({ cipher, theme }: { cipher: NotificationCipherData; theme: Theme }) {
|
||||
const { name, login } = cipher;
|
||||
const { name, login, organizationCategories } = cipher;
|
||||
const hasIndicatorIcons = organizationCategories?.length;
|
||||
|
||||
return html`
|
||||
<div>
|
||||
<span class=${cipherInfoPrimaryTextStyles(theme)}>
|
||||
${[name, CipherInfoIndicatorIcons({ theme })]}
|
||||
${[
|
||||
name,
|
||||
hasIndicatorIcons
|
||||
? CipherInfoIndicatorIcons({
|
||||
theme,
|
||||
organizationCategories,
|
||||
})
|
||||
: nothing,
|
||||
]}
|
||||
</span>
|
||||
|
||||
${login?.username
|
||||
|
||||
@@ -14,6 +14,14 @@ export const CipherRepromptTypes = {
|
||||
|
||||
type CipherRepromptType = (typeof CipherRepromptTypes)[keyof typeof CipherRepromptTypes];
|
||||
|
||||
export type OrganizationCategory =
|
||||
(typeof OrganizationCategories)[keyof typeof OrganizationCategories];
|
||||
|
||||
export const OrganizationCategories = {
|
||||
business: "business",
|
||||
family: "family",
|
||||
} as const;
|
||||
|
||||
export type WebsiteIconData = {
|
||||
imageEnabled: boolean;
|
||||
image: string;
|
||||
@@ -50,4 +58,5 @@ export type NotificationCipherData = BaseCipherData<typeof CipherTypes.Login> &
|
||||
login?: {
|
||||
username: string;
|
||||
};
|
||||
organizationCategories?: OrganizationCategory[];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user