mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
handle PersonalOwnership policy and vault selector with only one option (#14530)
This commit is contained in:
@@ -24,7 +24,11 @@ function getVaultIconByProductTier(productTierType?: ProductTierType): Option["i
|
||||
}
|
||||
}
|
||||
|
||||
// Value represents default selector state outside of data-driven state
|
||||
const defaultNoneSelectValue = "0";
|
||||
|
||||
export type NotificationButtonRowProps = {
|
||||
collections?: CollectionView[];
|
||||
folders?: FolderView[];
|
||||
i18n: { [key: string]: string };
|
||||
organizations?: OrgView[];
|
||||
@@ -32,40 +36,44 @@ export type NotificationButtonRowProps = {
|
||||
text: string;
|
||||
handlePrimaryButtonClick: (args: any) => void;
|
||||
};
|
||||
collections?: CollectionView[];
|
||||
personalVaultIsAllowed: boolean;
|
||||
theme: Theme;
|
||||
};
|
||||
|
||||
export function NotificationButtonRow({
|
||||
folders,
|
||||
collections,
|
||||
folders,
|
||||
i18n,
|
||||
organizations,
|
||||
primaryButton,
|
||||
personalVaultIsAllowed,
|
||||
theme,
|
||||
}: NotificationButtonRowProps) {
|
||||
const currentUserVaultOption: Option = {
|
||||
icon: User,
|
||||
default: true,
|
||||
text: i18n.myVault,
|
||||
value: "0",
|
||||
value: defaultNoneSelectValue,
|
||||
};
|
||||
const organizationOptions: Option[] = organizations?.length
|
||||
? organizations.reduce(
|
||||
(options, { id, name, productTierType }: OrgView) => {
|
||||
const icon = getVaultIconByProductTier(productTierType);
|
||||
return [
|
||||
...options,
|
||||
{
|
||||
icon,
|
||||
text: name,
|
||||
value: id,
|
||||
},
|
||||
];
|
||||
},
|
||||
[currentUserVaultOption],
|
||||
)
|
||||
: ([] as Option[]);
|
||||
|
||||
// Do not include user vault if disallowed by org policy
|
||||
const initialVaultOptions = [
|
||||
...(personalVaultIsAllowed ? [currentUserVaultOption] : []),
|
||||
] as Option[];
|
||||
|
||||
const vaultOptions: Option[] = organizations?.length
|
||||
? organizations.reduce((options, { id, name, productTierType }: OrgView) => {
|
||||
const icon = getVaultIconByProductTier(productTierType);
|
||||
return [
|
||||
...options,
|
||||
{
|
||||
icon,
|
||||
text: name,
|
||||
value: id,
|
||||
},
|
||||
];
|
||||
}, initialVaultOptions)
|
||||
: initialVaultOptions;
|
||||
|
||||
const folderOptions: Option[] = folders?.length
|
||||
? folders.reduce<Option[]>(
|
||||
@@ -74,7 +82,7 @@ export function NotificationButtonRow({
|
||||
{
|
||||
icon: Folder,
|
||||
text: name,
|
||||
value: id === null ? "0" : id,
|
||||
value: id === null ? defaultNoneSelectValue : id,
|
||||
default: id === null,
|
||||
},
|
||||
],
|
||||
@@ -89,7 +97,7 @@ export function NotificationButtonRow({
|
||||
{
|
||||
icon: CollectionShared,
|
||||
text: name,
|
||||
value: id === null ? "0" : id,
|
||||
value: id === null ? defaultNoneSelectValue : id,
|
||||
default: id === null,
|
||||
},
|
||||
],
|
||||
@@ -97,17 +105,31 @@ export function NotificationButtonRow({
|
||||
)
|
||||
: [];
|
||||
|
||||
if (vaultOptions.length === 1) {
|
||||
selectedVaultSignal?.set(vaultOptions[0].value);
|
||||
|
||||
// If the individual vault is disabled by a vault policy,
|
||||
// a collection selection is required
|
||||
if (
|
||||
!personalVaultIsAllowed &&
|
||||
collections?.length &&
|
||||
selectedCollectionSignal.get() === defaultNoneSelectValue
|
||||
) {
|
||||
selectedCollectionSignal?.set(collections[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
return html`
|
||||
${ButtonRow({
|
||||
theme,
|
||||
primaryButton,
|
||||
selectButtons: [
|
||||
...(organizationOptions.length > 1
|
||||
...(vaultOptions.length > 1
|
||||
? [
|
||||
{
|
||||
id: "organization",
|
||||
label: i18n.vault,
|
||||
options: organizationOptions,
|
||||
options: vaultOptions,
|
||||
selectedSignal: selectedVaultSignal,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -29,6 +29,7 @@ export type NotificationContainerProps = NotificationBarIframeInitData & {
|
||||
folders?: FolderView[];
|
||||
i18n: { [key: string]: string };
|
||||
organizations?: OrgView[];
|
||||
personalVaultIsAllowed?: boolean;
|
||||
type: NotificationType; // @TODO typing override for generic `NotificationBarIframeInitData.type`
|
||||
};
|
||||
|
||||
@@ -41,6 +42,7 @@ export function NotificationContainer({
|
||||
folders,
|
||||
i18n,
|
||||
organizations,
|
||||
personalVaultIsAllowed = true,
|
||||
theme = ThemeTypes.Light,
|
||||
type,
|
||||
}: NotificationContainerProps) {
|
||||
@@ -71,6 +73,7 @@ export function NotificationContainer({
|
||||
i18n,
|
||||
notificationType: type,
|
||||
organizations,
|
||||
personalVaultIsAllowed,
|
||||
theme,
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -18,6 +18,7 @@ export type NotificationFooterProps = {
|
||||
i18n: { [key: string]: string };
|
||||
notificationType?: NotificationType;
|
||||
organizations?: OrgView[];
|
||||
personalVaultIsAllowed: boolean;
|
||||
theme: Theme;
|
||||
handleSaveAction: (e: Event) => void;
|
||||
};
|
||||
@@ -28,6 +29,7 @@ export function NotificationFooter({
|
||||
i18n,
|
||||
notificationType,
|
||||
organizations,
|
||||
personalVaultIsAllowed,
|
||||
theme,
|
||||
handleSaveAction,
|
||||
}: NotificationFooterProps) {
|
||||
@@ -46,6 +48,7 @@ export function NotificationFooter({
|
||||
handlePrimaryButtonClick: handleSaveAction,
|
||||
text: primaryButtonText,
|
||||
},
|
||||
personalVaultIsAllowed,
|
||||
theme,
|
||||
})
|
||||
: nothing}
|
||||
|
||||
@@ -135,7 +135,11 @@ async function initNotificationBar(message: NotificationBarWindowMessage) {
|
||||
}
|
||||
|
||||
notificationBarIframeInitData = initData;
|
||||
const { isVaultLocked, theme } = notificationBarIframeInitData;
|
||||
const {
|
||||
isVaultLocked,
|
||||
removeIndividualVault: personalVaultDisallowed, // renamed to avoid local method collision
|
||||
theme,
|
||||
} = notificationBarIframeInitData;
|
||||
const i18n = getI18n();
|
||||
const resolvedTheme = getResolvedTheme(theme ?? ThemeTypes.Light);
|
||||
|
||||
@@ -172,6 +176,7 @@ async function initNotificationBar(message: NotificationBarWindowMessage) {
|
||||
...notificationBarIframeInitData,
|
||||
type: notificationBarIframeInitData.type as NotificationType,
|
||||
theme: resolvedTheme,
|
||||
personalVaultIsAllowed: !personalVaultDisallowed,
|
||||
handleCloseNotification,
|
||||
handleSaveAction,
|
||||
handleEditOrUpdateAction,
|
||||
@@ -266,7 +271,10 @@ function handleSaveAction(e: Event) {
|
||||
const selectedFolder = selectedFolderSignal.get();
|
||||
|
||||
if (selectedVault.length > 1) {
|
||||
openAddEditVaultItemPopout(e, { organizationId: selectedVault, folder: selectedFolder });
|
||||
openAddEditVaultItemPopout(e, {
|
||||
organizationId: selectedVault,
|
||||
folder: selectedFolder,
|
||||
});
|
||||
handleCloseNotification(e);
|
||||
return;
|
||||
}
|
||||
@@ -370,7 +378,11 @@ function handleSaveCipherAttemptCompletedMessage(message: NotificationBarWindowM
|
||||
|
||||
function openAddEditVaultItemPopout(
|
||||
e: Event,
|
||||
options: { cipherId?: string; organizationId?: string; folder?: string },
|
||||
options: {
|
||||
cipherId?: string;
|
||||
organizationId?: string;
|
||||
folder?: string;
|
||||
},
|
||||
) {
|
||||
e.preventDefault();
|
||||
sendPlatformMessage({
|
||||
|
||||
Reference in New Issue
Block a user