diff --git a/frontend/src/views/Settings/OrgSettingsPage/OrgSettingsPage.tsx b/frontend/src/views/Settings/OrgSettingsPage/OrgSettingsPage.tsx index 473b6f8c3..f73249196 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/OrgSettingsPage.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/OrgSettingsPage.tsx @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { useState } from 'react'; import { useTranslation } from 'next-i18next'; import { plans } from 'public/data/frequentConstants'; @@ -51,6 +52,8 @@ export const OrgSettingsPage = () => { const addIncidentContact = useAddIncidentContact(); const removeIncidentContact = useDeleteIncidentContact(); + const [completeInviteLink, setcompleteInviteLink] = useState("") + const isMoreUsersNotAllowed = (orgUsers || []).length >= 5 && subscriptionPlan === plans.starter && @@ -96,11 +99,16 @@ export const OrgSettingsPage = () => { if (!currentOrg?._id) return; try { - await addUserToOrg.mutateAsync({ organizationId: currentOrg?._id, inviteeEmail: email }); - createNotification({ - text: 'Successfully invited user to the organization.', - type: 'success' - }); + const {data} = await addUserToOrg.mutateAsync({ organizationId: currentOrg?._id, inviteeEmail: email }); + setcompleteInviteLink(data?.completeInviteLink) + + // only show this notification when email is configured. A [completeInviteLink] will not be sent if smtp is configured + if (!data.completeInviteLink){ + createNotification({ + text: 'Successfully invited user to the organization.', + type: 'success' + }); + } } catch (error) { console.error(error); createNotification({ @@ -247,6 +255,8 @@ export const OrgSettingsPage = () => { onRemoveMember={onRemoveUserOrgMembership} onRoleChange={onUpdateOrgUserRole} onGrantAccess={onGrantUserAccess} + completeInviteLink={completeInviteLink} + setCompleteInviteLink={setcompleteInviteLink} />
diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx index b127abeb9..04ee9da3d 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx @@ -1,7 +1,7 @@ -import { useMemo, useState } from 'react'; +import { Dispatch, SetStateAction, useMemo, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useRouter } from 'next/router'; -import { faMagnifyingGlass, faPlus, faTrash, faUsers } from '@fortawesome/free-solid-svg-icons'; +import { faCheck, faCopy, faMagnifyingGlass, faPlus, faTrash, faUsers } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; @@ -43,6 +43,8 @@ type Props = { onGrantAccess: (userId: string, publicKey: string) => Promise; // the current user id to block remove org button userId: string; + completeInviteLink: string | undefined, + setCompleteInviteLink: Dispatch> }; const addMemberFormSchema = yup.object({ @@ -61,7 +63,9 @@ export const OrgMembersTable = ({ onGrantAccess, onRoleChange, userId, - isLoading + isLoading, + completeInviteLink, + setCompleteInviteLink }: Props) => { const router = useRouter(); const [searchMemberFilter, setSearchMemberFilter] = useState(''); @@ -82,8 +86,11 @@ export const OrgMembersTable = ({ const onAddMember = async ({ email }: TAddMemberForm) => { await onInviteMember(email); - handlePopUpClose('addMember'); - reset(); + if (serverDetails?.emailConfigured){ + handlePopUpClose('addMember'); + } + + reset(); }; const onRemoveOrgMemberApproved = async () => { @@ -109,6 +116,11 @@ export const OrgMembersTable = ({ [members, searchMemberFilter] ); + const copyTokenToClipboard = () => { + navigator.clipboard.writeText(completeInviteLink as string); + // setIsTokenCopied.on(); + }; + return (
@@ -124,15 +136,16 @@ export const OrgMembersTable = ({ @@ -241,20 +254,23 @@ export const OrgMembersTable = ({ isOpen={popUp?.addMember?.isOpen} onOpenChange={(isOpen) => { handlePopUpToggle('addMember', isOpen); - reset(); + setCompleteInviteLink(undefined) }} > - An invite is specific to an email address and expires after 1 day. -
- For security reasons, you will need to separately add members to projects. - +
+ {!completeInviteLink &&
+ An invite is specific to an email address and expires after 1 day. +
+ For security reasons, you will need to separately add members to projects. +
} + {completeInviteLink && "This Infisical instance does not have a email provider setup. Please share this invite link with the invitee manually"} +
} > -
+ {!completeInviteLink &&
- + } + { + completeInviteLink && +
+

{completeInviteLink}

+ + + click to copy + +
+ }