Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / containers / members / MemberActions.tsx
blob9595f51949e540067e6bcd4ee298e64c0cfb67eb
1 import { c } from 'ttag';
3 import DropdownActions from '@proton/components/components/dropdown/DropdownActions';
4 import { useLoading } from '@proton/hooks';
5 import type { APP_NAMES } from '@proton/shared/lib/constants';
6 import { APPS, MEMBER_PRIVATE, MEMBER_TYPE, ORGANIZATION_STATE } from '@proton/shared/lib/constants';
7 import { hasOrganizationSetup, hasOrganizationSetupWithKeys } from '@proton/shared/lib/helpers/organization';
8 import type {
9     CachedOrganizationKey,
10     EnhancedMember,
11     Member,
12     Organization,
13     PartialMemberAddress,
14     UserModel,
15 } from '@proton/shared/lib/interfaces';
16 import { MemberUnprivatizationState } from '@proton/shared/lib/interfaces';
17 import { getCanGenerateMemberKeysPermissions, getShouldSetupMemberKeys } from '@proton/shared/lib/keys/memberKeys';
18 import isTruthy from '@proton/utils/isTruthy';
20 export const MagicLinkMemberActions = ({
21     state,
22     onResend,
23     onDelete,
24     onEdit,
25 }: {
26     state?: MemberUnprivatizationState;
27     onResend?: () => void;
28     onDelete?: () => Promise<void>;
29     onEdit?: () => void;
30 }) => {
31     const [loadingDelete, withLoadingDelete] = useLoading();
33     return (
34         <DropdownActions
35             list={[
36                 onEdit && {
37                     text: c('Member action').t`Edit`,
38                     onClick: () => onEdit(),
39                 },
40                 onResend && {
41                     text: c('Member action').t`Resend invite link`,
42                     onClick: () => onResend(),
43                 },
44                 onDelete && {
45                     actionType: 'delete' as const,
46                     text:
47                         state === MemberUnprivatizationState.Pending
48                             ? c('Member action').t`Delete and revoke invite`
49                             : c('Member action').t`Delete`,
50                     loading: loadingDelete,
51                     onClick: () => withLoadingDelete(onDelete()),
52                 },
53             ].filter(isTruthy)}
54             size="small"
55         />
56     );
59 export const getMemberPermissions = ({
60     appName,
61     user,
62     addresses,
63     member,
64     organization,
65     organizationKey,
66     disableMemberSignIn,
67 }: {
68     addresses: PartialMemberAddress[] | undefined;
69     appName: APP_NAMES;
70     user: UserModel;
71     member: Member;
72     organization?: Organization;
73     organizationKey?: CachedOrganizationKey;
74     disableMemberSignIn: boolean;
75 }) => {
76     const hasSetupOrganizationWithKeys = hasOrganizationSetupWithKeys(organization);
77     const hasSetupOrganization = hasOrganizationSetup(organization);
78     const isOrganizationDelinquent = organization?.State === ORGANIZATION_STATE.DELINQUENT;
80     const canDelete = !member.Self;
81     const canEdit = hasSetupOrganization || hasSetupOrganizationWithKeys;
82     const canRevokeSessions = !member.Self && member.Type === MEMBER_TYPE.MANAGED;
84     const hasUnprivatization = Boolean(member.Unprivatization);
86     const canSetupMember =
87         !hasUnprivatization &&
88         getCanGenerateMemberKeysPermissions(user, organizationKey) &&
89         getShouldSetupMemberKeys(member) &&
90         addresses?.length;
92     const canLogin =
93         !disableMemberSignIn &&
94         appName !== APPS.PROTONVPN_SETTINGS &&
95         hasSetupOrganizationWithKeys &&
96         !member.Self &&
97         member.Private === MEMBER_PRIVATE.READABLE &&
98         member.Keys.length > 0 &&
99         !!organizationKey?.privateKey &&
100         addresses &&
101         addresses?.length > 0;
103     const canChangePassword =
104         hasSetupOrganizationWithKeys &&
105         !member.Self &&
106         member.Private === MEMBER_PRIVATE.READABLE &&
107         member.Keys.length > 0 &&
108         !!organizationKey?.privateKey &&
109         addresses &&
110         addresses.length > 0;
112     const canAddAddress = !member.SSO && addresses && addresses.length === 0;
114     return {
115         canAddAddress,
116         canDelete,
117         canEdit,
118         canRevokeSessions,
119         canSetupMember,
120         canLogin,
121         canChangePassword,
122         isOrganizationDelinquent,
123     };
126 interface Props {
127     member: EnhancedMember;
128     onLogin: (member: EnhancedMember) => void;
129     onAddAddress: (member: EnhancedMember) => void;
130     onChangePassword: (member: EnhancedMember) => void;
131     onEdit: (member: EnhancedMember) => void;
132     onDelete: (member: EnhancedMember) => void;
133     onRevoke: (member: EnhancedMember) => Promise<void>;
134     onSetup: (member: EnhancedMember) => void;
135     permissions: ReturnType<typeof getMemberPermissions>;
136     disableEdit: boolean;
139 const MemberActions = ({
140     member,
141     onAddAddress,
142     onEdit,
143     onDelete,
144     onLogin,
145     onSetup,
146     onChangePassword,
147     onRevoke,
148     disableEdit,
149     permissions: {
150         canEdit,
151         canAddAddress,
152         canLogin,
153         canRevokeSessions,
154         canSetupMember,
155         canChangePassword,
156         canDelete,
157         isOrganizationDelinquent,
158     },
159 }: Props) => {
160     const [loading, withLoading] = useLoading();
162     const list = [
163         canEdit && {
164             text: c('Member action').t`Edit`,
165             disabled: isOrganizationDelinquent || disableEdit,
166             onClick: () => {
167                 onEdit(member);
168             },
169         },
170         canLogin && {
171             text: c('Member action').t`Sign in`,
172             disabled: isOrganizationDelinquent,
173             onClick: () => {
174                 onLogin(member);
175             },
176         },
177         canAddAddress && {
178             text: c('Member action').t`Add address`,
179             disabled: isOrganizationDelinquent,
180             onClick: () => {
181                 onAddAddress(member);
182             },
183         },
184         canSetupMember && {
185             text: c('Member action').t`Activate user`,
186             disabled: isOrganizationDelinquent,
187             onClick: () => {
188                 onSetup(member);
189             },
190         },
191         canChangePassword && {
192             text: c('Member action').t`Change password`,
193             disabled: isOrganizationDelinquent,
194             onClick: () => {
195                 onChangePassword(member);
196             },
197         },
198         canRevokeSessions && {
199             text: c('Member action').t`Revoke sessions`,
200             disabled: isOrganizationDelinquent,
201             onClick: () => {
202                 void withLoading(onRevoke(member));
203             },
204         },
205         canDelete &&
206             ({
207                 text: canRevokeSessions ? c('Member action').t`Delete` : c('Member action').t`Remove`,
208                 actionType: 'delete',
209                 onClick: () => {
210                     onDelete(member);
211                 },
212             } as const),
213     ].filter(isTruthy);
215     return <DropdownActions loading={loading} list={list} size="small" />;
218 export default MemberActions;