diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx
index c3bd55f51..e118e455b 100644
--- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx
+++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsTable/OrgIncidentContactsTable.tsx
@@ -13,6 +13,7 @@ import * as yup from 'yup';
import {
Button,
DeleteActionModal,
+ EmailServiceSetupModal,
EmptyState,
FormControl,
IconButton,
@@ -28,6 +29,7 @@ import {
THead,
Tr} from '@app/components/v2';
import { usePopUp } from '@app/hooks';
+import { useFetchServerStatus } from '@app/hooks/api/serverDetails';
import { IncidentContact } from '@app/hooks/api/types';
type Props = {
@@ -50,9 +52,11 @@ export const OrgIncidentContactsTable = ({
isLoading
}: Props) => {
const [searchContact, setSearchContact] = useState('');
+ const {data: serverDetails } = useFetchServerStatus()
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
'addContact',
- 'removeContact'
+ 'removeContact',
+ 'setUpEmail'
] as const);
const {
@@ -92,7 +96,13 @@ export const OrgIncidentContactsTable = ({
}
- onClick={() => handlePopUpOpen('addContact')}
+ onClick={() => {
+ if (serverDetails?.emailConfigured){
+ handlePopUpOpen('addContact');
+ } else {
+ handlePopUpOpen('setUpEmail');
+ }
+ }}
>
Add Contact
@@ -180,6 +190,10 @@ export const OrgIncidentContactsTable = ({
onChange={(isOpen) => handlePopUpToggle('removeContact', isOpen)}
onDeleteApproved={onRemoveIncidentContact}
/>
+ handlePopUpToggle('setUpEmail', isOpen)}
+ />
);
};
diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgMembersTable/OrgMembersTable.tsx
index 9bed5954b..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';
@@ -9,7 +9,7 @@ import * as yup from 'yup';
import {
Button,
DeleteActionModal,
- EmptyState,
+ EmailServiceSetupModal, EmptyState,
FormControl,
IconButton,
Input,
@@ -28,6 +28,7 @@ import {
Tr,
UpgradePlanModal} from '@app/components/v2';
import { usePopUp } from '@app/hooks';
+import { useFetchServerStatus } from '@app/hooks/api/serverDetails';
import { OrgUser, Workspace } from '@app/hooks/api/types';
type Props = {
@@ -42,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({
@@ -60,14 +63,18 @@ export const OrgMembersTable = ({
onGrantAccess,
onRoleChange,
userId,
- isLoading
+ isLoading,
+ completeInviteLink,
+ setCompleteInviteLink
}: Props) => {
const router = useRouter();
const [searchMemberFilter, setSearchMemberFilter] = useState('');
+ const {data: serverDetails } = useFetchServerStatus()
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
'addMember',
'removeMember',
- 'upgradePlan'
+ 'upgradePlan',
+ 'setUpEmail'
] as const);
const {
@@ -79,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 () => {
@@ -106,6 +116,11 @@ export const OrgMembersTable = ({
[members, searchMemberFilter]
);
+ const copyTokenToClipboard = () => {
+ navigator.clipboard.writeText(completeInviteLink as string);
+ // setIsTokenCopied.on();
+ };
+
return (
@@ -121,11 +136,16 @@ export const OrgMembersTable = ({
}
onClick={() => {
- if (isMoreUserNotAllowed) {
- handlePopUpOpen('upgradePlan');
- } else {
- handlePopUpOpen('addMember');
- }
+ // if (serverDetails?.emailConfigured){
+ if (isMoreUserNotAllowed) {
+ handlePopUpOpen('upgradePlan');
+ } else {
+ reset();
+ handlePopUpOpen('addMember');
+ }
+ // } else {
+ // handlePopUpOpen('setUpEmail');
+ // }
}}
>
Add Member
@@ -173,7 +193,7 @@ export const OrgMembersTable = ({
member
)}
- {(status === 'invited' || status === 'verified') && (
+ {((status === 'invited' || status === 'verified') && serverDetails?.emailConfigured) && (
@@ -234,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}
+
+
+ click to copy
+
+
+ }
handlePopUpToggle('upgradePlan', isOpen)}
text="You can add custom environments if you switch to Infisical's Team plan."
/>
+ handlePopUpToggle('setUpEmail', isOpen)}
+ />
);
};
diff --git a/frontend/src/views/Settings/PersonalSettingsPage/SecuritySection/SecuritySection.tsx b/frontend/src/views/Settings/PersonalSettingsPage/SecuritySection/SecuritySection.tsx
index 0d7902c60..0c64c41e7 100644
--- a/frontend/src/views/Settings/PersonalSettingsPage/SecuritySection/SecuritySection.tsx
+++ b/frontend/src/views/Settings/PersonalSettingsPage/SecuritySection/SecuritySection.tsx
@@ -1,7 +1,9 @@
import { useEffect, useState } from 'react';
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
-import { Checkbox } from '@app/components/v2';
+import { Checkbox, EmailServiceSetupModal } from '@app/components/v2';
+import { useFetchServerStatus } from '@app/hooks/api/serverDetails';
+import { usePopUp } from '@app/hooks/usePopUp';
import { useGetUser } from '../../../../hooks/api';
import { User } from '../../../../hooks/api/types';
@@ -11,6 +13,11 @@ export const SecuritySection = () => {
const [isMfaEnabled, setIsMfaEnabled] = useState(false);
const { data: user } = useGetUser();
const { createNotification } = useNotificationContext();
+ const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp([
+ 'setUpEmail'
+ ] as const);
+
+ const {data: serverDetails } = useFetchServerStatus()
useEffect(() => {
if (user && typeof user.isMfaEnabled !== 'undefined') {
@@ -42,6 +49,7 @@ export const SecuritySection = () => {
}
return (
+ <>
+ handlePopUpToggle('setUpEmail', isOpen)}
+ />
+ >
);
};