1 import { c, msgid } from 'ttag';
3 import { deleteMembers } from '@proton/account/members/actions';
4 import { selectDisabledMembers } from '@proton/account/members/selectors';
6 selectJoinedUnprivatizationState,
7 unprivatizeApprovalMembers,
8 unprivatizeMembersBackground,
9 } from '@proton/account/members/unprivatizeMembers';
10 import { useOrganizationKey } from '@proton/account/organizationKey/hooks';
11 import { Button } from '@proton/atoms';
12 import useModalState from '@proton/components/components/modalTwo/useModalState';
13 import Prompt, { type PromptProps } from '@proton/components/components/prompt/Prompt';
14 import useVerifyOutboundPublicKeys from '@proton/components/containers/keyTransparency/useVerifyOutboundPublicKeys';
15 import useNotifications from '@proton/components/hooks/useNotifications';
16 import useLoading from '@proton/hooks/useLoading';
17 import { useDispatch, useSelector } from '@proton/redux-shared-store';
18 import type { Member } from '@proton/shared/lib/interfaces';
20 import { MemberListBanner, MembersList } from './MemberListBanner';
22 interface Props extends Omit<PromptProps, 'children' | 'buttons'> {
24 onConfirm: () => void;
27 const ConfirmDeleteMembers = ({ members, onConfirm, ...rest }: Props) => {
28 const n = members.length;
31 title={c('sso').ngettext(msgid`Delete ${n} inactive user?`, `Delete ${n} inactive users?`, n)}
39 >{c('Action').t`Delete`}</Button>,
40 <Button onClick={rest.onClose}>{c('Action').t`Cancel`}</Button>,
45 ? c('Info').t`This will permanently delete the data and all email addresses associated with this user.`
47 .t`This will permanently delete the data and all email addresses associated with these users.`}
52 const useOrganizationUnprivatizationModals = () => {
53 const [organizationKey] = useOrganizationKey();
55 const joinedUnprivatizationState = useSelector(selectJoinedUnprivatizationState);
56 const disabledMembers = useSelector(selectDisabledMembers);
57 const dispatch = useDispatch();
58 const verifyOutboundPublicKeys = useVerifyOutboundPublicKeys();
59 const [loadingDelete, withLoadingDelete] = useLoading();
60 const { createNotification } = useNotifications();
62 const unprivatizationApprovalInfo = (() => {
63 const membersToUnprivatize = joinedUnprivatizationState.approval.map(({ member }) => member);
64 if (!organizationKey?.privateKey || !membersToUnprivatize.length) {
67 const n = membersToUnprivatize.length;
74 msgid`${n} user has joined your organization through your Identity Provider. Review the account now:`,
75 `${n} users have joined your organization through your Identity Provider. Review their accounts now:`,
78 <MembersList members={membersToUnprivatize} />
84 loading={joinedUnprivatizationState.loading.approval}
86 dispatch(unprivatizeApprovalMembers({ membersToUnprivatize }));
89 {c('unprivatization').t`Approve all`}
96 const unprivatizationFailureInfo = (() => {
97 const membersToUnprivatize = joinedUnprivatizationState.failures.map(({ member }) => member);
98 if (!organizationKey?.privateKey || !membersToUnprivatize.length) {
101 const n = membersToUnprivatize.length;
104 icon="exclamation-triangle-filled"
107 {c('unprivatization').ngettext(
108 msgid`Could not automatically enable administrator access for ${n} user, because their encryption keys have been updated in the meanwhile:`,
109 `Could not automatically enable administrator access for ${n} users, because their encryption keys have been updated in the meanwhile:`,
112 <MembersList members={membersToUnprivatize} />
118 loading={joinedUnprivatizationState.loading.automatic}
121 unprivatizeMembersBackground({
122 verifyOutboundPublicKeys,
125 members: membersToUnprivatize,
128 ignoreRevisionCheck: true,
134 {c('unprivatization').t`Enable manually`}
141 const [confirmDeleteProps, setConfirmDelete, renderConfirmDelete] = useModalState();
143 const disabledInfo = (() => {
144 if (!disabledMembers.length) {
147 const n = disabledMembers.length;
154 msgid`${n} user is inactive. You can safely remove this user from your organization.`,
155 `${n} users are inactive. You can safely remove them from your organization.`,
158 <MembersList members={disabledMembers} />
164 loading={loadingDelete}
166 setConfirmDelete(true);
169 {c('sso').ngettext(msgid`Delete ${n} user`, `Delete ${n} users`, n)}
178 {unprivatizationApprovalInfo}
179 {unprivatizationFailureInfo}
182 {renderConfirmDelete && (
183 <ConfirmDeleteMembers
184 members={disabledMembers}
187 dispatch(deleteMembers({ members: disabledMembers })).then((result) => {
188 if (result.success.length && !result.failure.length) {
189 confirmDeleteProps.onClose();
191 text: c('Info').t`All inactive members deleted`,
197 {...confirmDeleteProps}
208 export default useOrganizationUnprivatizationModals;