Continue trimming frontend integration page and renaming variables

This commit is contained in:
Tuan Dang
2022-12-12 10:36:13 -05:00
parent 397c15d61e
commit c6c2cfaaa5
6 changed files with 94 additions and 94 deletions
+1 -2
View File
@@ -84,7 +84,6 @@ const handleOAuthExchangeHelper = async ({
}).save(); }).save();
} catch (err) { } catch (err) {
console.error('in', err);
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to handle OAuth2 code-token exchange') throw new Error('Failed to handle OAuth2 code-token exchange')
@@ -184,7 +183,7 @@ const getIntegrationAuthAccessHelper = async ({ integrationAuthId }: { integrati
try { try {
const integrationAuth = await IntegrationAuth const integrationAuth = await IntegrationAuth
.findById(integrationAuthId) .findById(integrationAuthId)
.select('+accessCiphertext +accessIV +accessTag'); .select('workspace integration +accessCiphertext +accessIV +accessTag +accessExpiresAt + refreshCiphertext');
if (!integrationAuth) throw new Error('Failed to find integration auth'); if (!integrationAuth) throw new Error('Failed to find integration auth');
@@ -5,77 +5,76 @@ import {
faCheck, faCheck,
faX, faX,
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import deleteIntegrationAuth from "../../pages/api/integrations/DeleteIntegrationAuth";
interface Props { interface CloudIntegrationOption {
integration: IntegrationOption;
setSelectedIntegrationOption: () => void;
integrationOptionPress: () => void;
deleteIntegrationAuth: () => void;
authorizations: any;
}
interface IntegrationOption {
name: string; name: string;
type: string; type: string;
clientId: string; clientId: string;
docsLink: string; docsLink: string;
} }
interface Props {
cloudIntegrationOption: CloudIntegrationOption;
setSelectedIntegrationOption: () => void;
integrationOptionPress: () => void;
integrationAuths: any;
}
const CloudIntegration = ({ const CloudIntegration = ({
integration, cloudIntegrationOption,
setSelectedIntegrationOption, setSelectedIntegrationOption,
integrationOptionPress, integrationOptionPress,
deleteIntegrationAuth, integrationAuths
authorizations
}: Props) => { }: Props) => {
return authorizations ? ( return integrationAuths ? (
<div <div
className={`relative ${ className={`relative ${
["Heroku"].includes(integration.name) ["Heroku"].includes(cloudIntegrationOption.name)
? "hover:bg-white/10 duration-200 cursor-pointer" ? "hover:bg-white/10 duration-200 cursor-pointer"
: "opacity-50" : "opacity-50"
} flex flex-row bg-white/5 h-32 rounded-md p-4 items-center`} } flex flex-row bg-white/5 h-32 rounded-md p-4 items-center`}
onClick={() => { onClick={() => {
if (!["Heroku"].includes(integration.name)) return; if (!["Heroku"].includes(cloudIntegrationOption.name)) return;
setSelectedIntegrationOption(integration); setSelectedIntegrationOption(cloudIntegrationOption);
integrationOptionPress({ integrationOptionPress({
integrationOption: integration integrationOption: cloudIntegrationOption
}); });
}} }}
key={integration.name} key={cloudIntegrationOption.name}
> >
<Image <Image
src={`/images/integrations/${integration.name}.png`} src={`/images/integrations/${cloudIntegrationOption.name}.png`}
height={70} height={70}
width={70} width={70}
alt="integration logo" alt="integration logo"
/> />
{integration.name.split(" ").length > 2 ? ( {cloudIntegrationOption.name.split(" ").length > 2 ? (
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-3xl ml-4 max-w-xs"> <div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-3xl ml-4 max-w-xs">
<div>{integration.name.split(" ")[0]}</div> <div>{cloudIntegrationOption.name.split(" ")[0]}</div>
<div className="text-base"> <div className="text-base">
{integration.name.split(" ")[1]}{" "} {cloudIntegrationOption.name.split(" ")[1]}{" "}
{integration.name.split(" ")[2]} {cloudIntegrationOption.name.split(" ")[2]}
</div> </div>
</div> </div>
) : ( ) : (
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-xl ml-4 max-w-xs"> <div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-xl ml-4 max-w-xs">
{integration.name} {cloudIntegrationOption.name}
</div> </div>
)} )}
{["Heroku"].includes(integration.name) && {["Heroku"].includes(cloudIntegrationOption.name) &&
authorizations integrationAuths
.map((authorization) => authorization.integration) .map((authorization) => authorization.integration)
.includes(integration.name.toLowerCase()) && ( .includes(cloudIntegrationOption.name.toLowerCase()) && (
<div className="absolute group z-50 top-0 right-0 flex flex-row"> <div className="absolute group z-50 top-0 right-0 flex flex-row">
<div <div
onClick={() => { onClick={() => {
deleteIntegrationAuth({ deleteIntegrationAuth({
integrationAuthId: authorizations integrationAuthId: integrationAuths
.filter( .filter(
(authorization) => (authorization) =>
authorization.integration == authorization.integration ==
integration.name.toLowerCase() cloudIntegrationOption.name.toLowerCase()
) )
.map((authorization) => authorization._id)[0], .map((authorization) => authorization._id)[0],
}); });
@@ -98,7 +97,7 @@ const CloudIntegration = ({
</div> </div>
</div> </div>
)} )}
{!["Heroku"].includes(integration.name) && ( {!["Heroku"].includes(cloudIntegrationOption.name) && (
<div className="absolute group z-50 top-0 right-0 flex flex-row"> <div className="absolute group z-50 top-0 right-0 flex flex-row">
<div className="w-max bg-yellow py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90"> <div className="w-max bg-yellow py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90">
Coming Soon Coming Soon
@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import CloudIntegration from "./CloudIntegration"; import CloudIntegration from "./CloudIntegration";
interface IntegrationOption { interface CloudIntegrationOption {
name: string; name: string;
type: string; type: string;
clientId: string; clientId: string;
@@ -9,39 +9,34 @@ interface IntegrationOption {
} }
interface Props { interface Props {
projectIntegrations: any; cloudIntegrationOptions: CloudIntegrationOption[];
integrations: IntegrationOption[];
setSelectedIntegrationOption: () => void; setSelectedIntegrationOption: () => void;
integrationOptionPress: () => void; integrationOptionPress: () => void;
deleteIntegrationAuth: () => void; integrationAuths: any;
authorizations: any;
} }
const CloudIntegrationSection = ({ const CloudIntegrationSection = ({
projectIntegrations, cloudIntegrationOptions,
integrations,
setSelectedIntegrationOption, setSelectedIntegrationOption,
integrationOptionPress, integrationOptionPress,
deleteIntegrationAuth, integrationAuths
authorizations
}: Props) => { }: Props) => {
return ( return (
<> <>
<div className={`flex flex-col justify-between items-start m-4 ${projectIntegrations.length > 0 ? 'mt-12' : 'mt-6'} text-xl max-w-5xl px-2`}> <div className={`flex flex-col justify-between items-start m-4 mt-7 text-xl max-w-5xl px-2`}>
<h1 className="font-semibold text-3xl">Cloud Integrations</h1> <h1 className="font-semibold text-3xl">Cloud Integrations</h1>
<p className="text-base text-gray-400"> <p className="text-base text-gray-400">
Click on an integration to begin syncing secrets to it. Click on an integration to begin syncing secrets to it.
</p> </p>
</div> </div>
<div className="grid gap-4 grid-cols-4 grid-rows-2 mx-6 max-w-5xl"> <div className="grid gap-4 grid-cols-4 grid-rows-2 mx-6 max-w-5xl">
{integrations.map((integration) => ( {cloudIntegrationOptions.map((cloudIntegrationOption) => (
<CloudIntegration <CloudIntegration
integration={integration} cloudIntegrationOption={cloudIntegrationOption}
setSelectedIntegrationOption={setSelectedIntegrationOption} setSelectedIntegrationOption={setSelectedIntegrationOption}
integrationOptionPress={integrationOptionPress} integrationOptionPress={integrationOptionPress}
deleteIntegrationAuth={deleteIntegrationAuth} integrationAuths={integrationAuths}
authorizations={authorizations} key={`cloud-integration-${cloudIntegrationOption.slug}`}
key={`cloud-integration-${integration.slug}`}
/> />
))} ))}
</div> </div>
@@ -15,7 +15,7 @@ import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps"
import Button from "~/components/basic/buttons/Button"; import Button from "~/components/basic/buttons/Button";
import ListBox from "~/components/basic/Listbox"; import ListBox from "~/components/basic/Listbox";
interface ProjectIntegration { interface Integration {
app?: string; app?: string;
environment: string; environment: string;
integration: string; integration: string;
@@ -24,28 +24,29 @@ interface ProjectIntegration {
} }
const Integration = ({ const Integration = ({
projectIntegration integration
}: { }: {
projectIntegration: ProjectIntegration; integration: Integration;
}) => { }) => {
const [integrationEnvironment, setIntegrationEnvironment] = useState( const [integrationEnvironment, setIntegrationEnvironment] = useState(
reverseEnvMapping[projectIntegration.environment] reverseEnvMapping[integration.environment]
); );
const [fileState, setFileState] = useState([]); const [fileState, setFileState] = useState([]);
const router = useRouter(); const router = useRouter();
const [apps, setApps] = useState([]); const [apps, setApps] = useState([]);
const [integrationApp, setIntegrationApp] = useState( const [integrationApp, setIntegrationApp] = useState(
projectIntegration.app ? projectIntegration.app : apps[0] integration.app ? integration.app : apps[0]
); );
useEffect(async () => { useEffect(async () => {
const tempHerokuApps = await getIntegrationApps({ const tempHerokuApps = await getIntegrationApps({
integrationAuthId: projectIntegration.integrationAuth, integrationAuthId: integration.integrationAuth,
}); });
const tempHerokuAppNames = tempHerokuApps.map((app) => app.name); const tempHerokuAppNames = tempHerokuApps.map((app) => app.name);
setApps(tempHerokuAppNames); setApps(tempHerokuAppNames);
setIntegrationApp( setIntegrationApp(
projectIntegration.app ? projectIntegration.app : tempHerokuAppNames[0] integration.app ? integration.app : tempHerokuAppNames[0]
); );
}, []); }, []);
@@ -59,7 +60,7 @@ const Integration = ({
</div> </div>
<ListBox <ListBox
data={ data={
!projectIntegration.isActive && [ !integration.isActive && [
"Development", "Development",
"Staging", "Staging",
"Production", "Production",
@@ -78,8 +79,8 @@ const Integration = ({
INTEGRATION INTEGRATION
</div> </div>
<div className="py-2.5 bg-white/[.07] rounded-md pl-4 pr-20 text-sm font-semibold text-gray-300"> <div className="py-2.5 bg-white/[.07] rounded-md pl-4 pr-20 text-sm font-semibold text-gray-300">
{projectIntegration.integration.charAt(0).toUpperCase() + {integration.integration.charAt(0).toUpperCase() +
projectIntegration.integration.slice(1)} integration.integration.slice(1)}
</div> </div>
</div> </div>
<div> <div>
@@ -87,14 +88,14 @@ const Integration = ({
HEROKU APP HEROKU APP
</div> </div>
<ListBox <ListBox
data={!projectIntegration.isActive && apps} data={!integration.isActive && apps}
selected={integrationApp} selected={integrationApp}
onChange={setIntegrationApp} onChange={setIntegrationApp}
/> />
</div> </div>
</div> </div>
<div className="flex flex-row mt-6"> <div className="flex flex-row mt-6">
{projectIntegration.isActive ? ( {integration.isActive ? (
<div className="max-w-5xl flex flex-row items-center bg-white/5 p-2 rounded-md px-4"> <div className="max-w-5xl flex flex-row items-center bg-white/5 p-2 rounded-md px-4">
<FontAwesomeIcon <FontAwesomeIcon
icon={faRotate} icon={faRotate}
@@ -107,7 +108,7 @@ const Integration = ({
text="Start Integration" text="Start Integration"
onButtonPressed={async () => { onButtonPressed={async () => {
const result = await updateIntegration({ const result = await updateIntegration({
integrationId: projectIntegration._id, integrationId: integration._id,
environment: envMapping[integrationEnvironment], environment: envMapping[integrationEnvironment],
app: integrationApp, app: integrationApp,
isActive: true isActive: true
@@ -122,7 +123,7 @@ const Integration = ({
<Button <Button
onButtonPressed={async () => { onButtonPressed={async () => {
await deleteIntegration({ await deleteIntegration({
integrationId: projectIntegration._id, integrationId: integration._id,
}); });
router.reload(); router.reload();
}} }}
@@ -2,29 +2,33 @@ import React from "react";
import Integration from "./Integration"; import Integration from "./Integration";
import guidGenerator from "~/utilities/randomId"; import guidGenerator from "~/utilities/randomId";
interface Integration {
}
interface Props { interface Props {
projectIntegrations: any integrations: any
} }
const ProjectIntegrationSection = ({ const ProjectIntegrationSection = ({
projectIntegrations integrations
}: Props) => { }: Props) => {
return ( return integrations.length > 0 ? (
<> <div className="mb-12">
<div className="flex flex-col justify-between items-start mx-4 mb-4 mt-6 text-xl max-w-5xl px-2"> <div className="flex flex-col justify-between items-start mx-4 mb-4 mt-6 text-xl max-w-5xl px-2">
<h1 className="font-semibold text-3xl">Current Project Integrations</h1> <h1 className="font-semibold text-3xl">Current Project Integrations</h1>
<p className="text-base text-gray-400"> <p className="text-base text-gray-400">
Manage your integrations of Infisical with third-party services. Manage your integrations of Infisical with third-party services.
</p> </p>
</div> </div>
{projectIntegrations.map((projectIntegration) => ( {integrations.map((integration => (
<Integration <Integration
key={guidGenerator()} key={guidGenerator()}
projectIntegration={projectIntegration} integration={integration}
/> />
))} )))}
</> </div>
); ) : <div></div>
} }
export default ProjectIntegrationSection; export default ProjectIntegrationSection;
+26 -24
View File
@@ -6,10 +6,9 @@ import NavHeader from "~/components/navigation/NavHeader";
import Integration from "~/components/integrations/Integration"; import Integration from "~/components/integrations/Integration";
import FrameworkIntegrationSection from "~/components/integrations/FrameworkIntegrationSection"; import FrameworkIntegrationSection from "~/components/integrations/FrameworkIntegrationSection";
import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection"; import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection";
import ProjectIntegrationSection from "~/components/integrations/ProjectIntegrationSection"; import IntegrationSection from "~/components/integrations/IntegrationSection";
import frameworkIntegrations from "../../public/json/frameworkIntegrations.json"; import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json";
import cloudIntegrations from "../../public/json/cloudIntegrations.json"; import cloudIntegrationOptions from "../../public/json/cloudIntegrations.json";
import deleteIntegrationAuth from "../api/integrations/DeleteIntegrationAuth";
import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations"; import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations";
import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations"; import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations";
import getBot from "../api/bot/getBot"; import getBot from "../api/bot/getBot";
@@ -34,19 +33,25 @@ export default function Integrations() {
useEffect(async () => { useEffect(async () => {
try { try {
// get project integration authorizations // get project integration authorizations
setIntegrationAuths(await getWorkspaceAuthorizations({ setIntegrationAuths(
workspaceId: router.query.id, await getWorkspaceAuthorizations({
})); workspaceId: router.query.id,
})
);
// get project integrations // get project integrations
setIntegrations(await getWorkspaceIntegrations({ setIntegrations(
workspaceId: router.query.id, await getWorkspaceIntegrations({
})); workspaceId: router.query.id,
})
);
// get project bot // get project bot
setBot(await getBot({ setBot(
workspaceId: router.query.id await getBot({
})); workspaceId: router.query.id
}
));
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@@ -159,7 +164,10 @@ export default function Integrations() {
/> />
</Head> </Head>
<div className="w-full max-h-96 pb-2 h-screen max-h-[calc(100vh-10px)] overflow-y-scroll no-scrollbar no-scrollbar::-webkit-scrollbar"> <div className="w-full max-h-96 pb-2 h-screen max-h-[calc(100vh-10px)] overflow-y-scroll no-scrollbar no-scrollbar::-webkit-scrollbar">
<NavHeader pageName="Project Integrations" isProjectRelated={true} /> <NavHeader
pageName="Project Integrations"
isProjectRelated={true}
/>
<ActivateBotDialog <ActivateBotDialog
isOpen={isActivateBotOpen} isOpen={isActivateBotOpen}
closeModal={() => setIsActivateBotOpen(false)} closeModal={() => setIsActivateBotOpen(false)}
@@ -167,21 +175,15 @@ export default function Integrations() {
handleBotActivate={handleBotActivate} handleBotActivate={handleBotActivate}
handleIntegrationOption={handleIntegrationOption} handleIntegrationOption={handleIntegrationOption}
/> />
{integrations.length > 0 && ( // shouldn't need to check for length <IntegrationSection integrations={integrations} />
<ProjectIntegrationSection
projectIntegrations={integrations}
/>
)}
<CloudIntegrationSection <CloudIntegrationSection
projectIntegrations={integrations} cloudIntegrationOptions={cloudIntegrationOptions}
integrations={cloudIntegrations}
setSelectedIntegrationOption={setSelectedIntegrationOption} setSelectedIntegrationOption={setSelectedIntegrationOption}
integrationOptionPress={integrationOptionPress} integrationOptionPress={integrationOptionPress}
deleteIntegrationAuth={deleteIntegrationAuth} integrationAuths={integrationAuths}
authorizations={integrationAuths}
/> />
<FrameworkIntegrationSection <FrameworkIntegrationSection
frameworks={frameworkIntegrations} frameworks={frameworkIntegrationOptions}
/> />
</div> </div>
</div> </div>