mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 22:03:36 +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 = {
|
export type NotificationButtonRowProps = {
|
||||||
|
collections?: CollectionView[];
|
||||||
folders?: FolderView[];
|
folders?: FolderView[];
|
||||||
i18n: { [key: string]: string };
|
i18n: { [key: string]: string };
|
||||||
organizations?: OrgView[];
|
organizations?: OrgView[];
|
||||||
@@ -32,27 +36,33 @@ export type NotificationButtonRowProps = {
|
|||||||
text: string;
|
text: string;
|
||||||
handlePrimaryButtonClick: (args: any) => void;
|
handlePrimaryButtonClick: (args: any) => void;
|
||||||
};
|
};
|
||||||
collections?: CollectionView[];
|
personalVaultIsAllowed: boolean;
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function NotificationButtonRow({
|
export function NotificationButtonRow({
|
||||||
folders,
|
|
||||||
collections,
|
collections,
|
||||||
|
folders,
|
||||||
i18n,
|
i18n,
|
||||||
organizations,
|
organizations,
|
||||||
primaryButton,
|
primaryButton,
|
||||||
|
personalVaultIsAllowed,
|
||||||
theme,
|
theme,
|
||||||
}: NotificationButtonRowProps) {
|
}: NotificationButtonRowProps) {
|
||||||
const currentUserVaultOption: Option = {
|
const currentUserVaultOption: Option = {
|
||||||
icon: User,
|
icon: User,
|
||||||
default: true,
|
default: true,
|
||||||
text: i18n.myVault,
|
text: i18n.myVault,
|
||||||
value: "0",
|
value: defaultNoneSelectValue,
|
||||||
};
|
};
|
||||||
const organizationOptions: Option[] = organizations?.length
|
|
||||||
? organizations.reduce(
|
// Do not include user vault if disallowed by org policy
|
||||||
(options, { id, name, productTierType }: OrgView) => {
|
const initialVaultOptions = [
|
||||||
|
...(personalVaultIsAllowed ? [currentUserVaultOption] : []),
|
||||||
|
] as Option[];
|
||||||
|
|
||||||
|
const vaultOptions: Option[] = organizations?.length
|
||||||
|
? organizations.reduce((options, { id, name, productTierType }: OrgView) => {
|
||||||
const icon = getVaultIconByProductTier(productTierType);
|
const icon = getVaultIconByProductTier(productTierType);
|
||||||
return [
|
return [
|
||||||
...options,
|
...options,
|
||||||
@@ -62,10 +72,8 @@ export function NotificationButtonRow({
|
|||||||
value: id,
|
value: id,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
}, initialVaultOptions)
|
||||||
[currentUserVaultOption],
|
: initialVaultOptions;
|
||||||
)
|
|
||||||
: ([] as Option[]);
|
|
||||||
|
|
||||||
const folderOptions: Option[] = folders?.length
|
const folderOptions: Option[] = folders?.length
|
||||||
? folders.reduce<Option[]>(
|
? folders.reduce<Option[]>(
|
||||||
@@ -74,7 +82,7 @@ export function NotificationButtonRow({
|
|||||||
{
|
{
|
||||||
icon: Folder,
|
icon: Folder,
|
||||||
text: name,
|
text: name,
|
||||||
value: id === null ? "0" : id,
|
value: id === null ? defaultNoneSelectValue : id,
|
||||||
default: id === null,
|
default: id === null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -89,7 +97,7 @@ export function NotificationButtonRow({
|
|||||||
{
|
{
|
||||||
icon: CollectionShared,
|
icon: CollectionShared,
|
||||||
text: name,
|
text: name,
|
||||||
value: id === null ? "0" : id,
|
value: id === null ? defaultNoneSelectValue : id,
|
||||||
default: id === null,
|
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`
|
return html`
|
||||||
${ButtonRow({
|
${ButtonRow({
|
||||||
theme,
|
theme,
|
||||||
primaryButton,
|
primaryButton,
|
||||||
selectButtons: [
|
selectButtons: [
|
||||||
...(organizationOptions.length > 1
|
...(vaultOptions.length > 1
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
id: "organization",
|
id: "organization",
|
||||||
label: i18n.vault,
|
label: i18n.vault,
|
||||||
options: organizationOptions,
|
options: vaultOptions,
|
||||||
selectedSignal: selectedVaultSignal,
|
selectedSignal: selectedVaultSignal,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export type NotificationContainerProps = NotificationBarIframeInitData & {
|
|||||||
folders?: FolderView[];
|
folders?: FolderView[];
|
||||||
i18n: { [key: string]: string };
|
i18n: { [key: string]: string };
|
||||||
organizations?: OrgView[];
|
organizations?: OrgView[];
|
||||||
|
personalVaultIsAllowed?: boolean;
|
||||||
type: NotificationType; // @TODO typing override for generic `NotificationBarIframeInitData.type`
|
type: NotificationType; // @TODO typing override for generic `NotificationBarIframeInitData.type`
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ export function NotificationContainer({
|
|||||||
folders,
|
folders,
|
||||||
i18n,
|
i18n,
|
||||||
organizations,
|
organizations,
|
||||||
|
personalVaultIsAllowed = true,
|
||||||
theme = ThemeTypes.Light,
|
theme = ThemeTypes.Light,
|
||||||
type,
|
type,
|
||||||
}: NotificationContainerProps) {
|
}: NotificationContainerProps) {
|
||||||
@@ -71,6 +73,7 @@ export function NotificationContainer({
|
|||||||
i18n,
|
i18n,
|
||||||
notificationType: type,
|
notificationType: type,
|
||||||
organizations,
|
organizations,
|
||||||
|
personalVaultIsAllowed,
|
||||||
theme,
|
theme,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export type NotificationFooterProps = {
|
|||||||
i18n: { [key: string]: string };
|
i18n: { [key: string]: string };
|
||||||
notificationType?: NotificationType;
|
notificationType?: NotificationType;
|
||||||
organizations?: OrgView[];
|
organizations?: OrgView[];
|
||||||
|
personalVaultIsAllowed: boolean;
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
handleSaveAction: (e: Event) => void;
|
handleSaveAction: (e: Event) => void;
|
||||||
};
|
};
|
||||||
@@ -28,6 +29,7 @@ export function NotificationFooter({
|
|||||||
i18n,
|
i18n,
|
||||||
notificationType,
|
notificationType,
|
||||||
organizations,
|
organizations,
|
||||||
|
personalVaultIsAllowed,
|
||||||
theme,
|
theme,
|
||||||
handleSaveAction,
|
handleSaveAction,
|
||||||
}: NotificationFooterProps) {
|
}: NotificationFooterProps) {
|
||||||
@@ -46,6 +48,7 @@ export function NotificationFooter({
|
|||||||
handlePrimaryButtonClick: handleSaveAction,
|
handlePrimaryButtonClick: handleSaveAction,
|
||||||
text: primaryButtonText,
|
text: primaryButtonText,
|
||||||
},
|
},
|
||||||
|
personalVaultIsAllowed,
|
||||||
theme,
|
theme,
|
||||||
})
|
})
|
||||||
: nothing}
|
: nothing}
|
||||||
|
|||||||
@@ -135,7 +135,11 @@ async function initNotificationBar(message: NotificationBarWindowMessage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
notificationBarIframeInitData = initData;
|
notificationBarIframeInitData = initData;
|
||||||
const { isVaultLocked, theme } = notificationBarIframeInitData;
|
const {
|
||||||
|
isVaultLocked,
|
||||||
|
removeIndividualVault: personalVaultDisallowed, // renamed to avoid local method collision
|
||||||
|
theme,
|
||||||
|
} = notificationBarIframeInitData;
|
||||||
const i18n = getI18n();
|
const i18n = getI18n();
|
||||||
const resolvedTheme = getResolvedTheme(theme ?? ThemeTypes.Light);
|
const resolvedTheme = getResolvedTheme(theme ?? ThemeTypes.Light);
|
||||||
|
|
||||||
@@ -172,6 +176,7 @@ async function initNotificationBar(message: NotificationBarWindowMessage) {
|
|||||||
...notificationBarIframeInitData,
|
...notificationBarIframeInitData,
|
||||||
type: notificationBarIframeInitData.type as NotificationType,
|
type: notificationBarIframeInitData.type as NotificationType,
|
||||||
theme: resolvedTheme,
|
theme: resolvedTheme,
|
||||||
|
personalVaultIsAllowed: !personalVaultDisallowed,
|
||||||
handleCloseNotification,
|
handleCloseNotification,
|
||||||
handleSaveAction,
|
handleSaveAction,
|
||||||
handleEditOrUpdateAction,
|
handleEditOrUpdateAction,
|
||||||
@@ -266,7 +271,10 @@ function handleSaveAction(e: Event) {
|
|||||||
const selectedFolder = selectedFolderSignal.get();
|
const selectedFolder = selectedFolderSignal.get();
|
||||||
|
|
||||||
if (selectedVault.length > 1) {
|
if (selectedVault.length > 1) {
|
||||||
openAddEditVaultItemPopout(e, { organizationId: selectedVault, folder: selectedFolder });
|
openAddEditVaultItemPopout(e, {
|
||||||
|
organizationId: selectedVault,
|
||||||
|
folder: selectedFolder,
|
||||||
|
});
|
||||||
handleCloseNotification(e);
|
handleCloseNotification(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -370,7 +378,11 @@ function handleSaveCipherAttemptCompletedMessage(message: NotificationBarWindowM
|
|||||||
|
|
||||||
function openAddEditVaultItemPopout(
|
function openAddEditVaultItemPopout(
|
||||||
e: Event,
|
e: Event,
|
||||||
options: { cipherId?: string; organizationId?: string; folder?: string },
|
options: {
|
||||||
|
cipherId?: string;
|
||||||
|
organizationId?: string;
|
||||||
|
folder?: string;
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
sendPlatformMessage({
|
sendPlatformMessage({
|
||||||
|
|||||||
Reference in New Issue
Block a user