Reduce page reloads for integrations page

This commit is contained in:
Tuan Dang
2023-01-18 17:38:52 +07:00
parent 3a6b2084bc
commit 06803519e6
6 changed files with 100 additions and 40 deletions
@@ -92,24 +92,24 @@ export const updateIntegration = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const deleteIntegration = async (req: Request, res: Response) => { export const deleteIntegration = async (req: Request, res: Response) => {
let deletedIntegration; let integration;
try { try {
const { integrationId } = req.params; const { integrationId } = req.params;
deletedIntegration = await Integration.findOneAndDelete({ integration = await Integration.findOneAndDelete({
_id: integrationId _id: integrationId
}); });
if (!deletedIntegration) throw new Error('Failed to find integration'); if (!integration) throw new Error('Failed to find integration');
const integrations = await Integration.find({ const integrations = await Integration.find({
workspace: deletedIntegration.workspace workspace: integration.workspace
}); });
if (integrations.length === 0) { if (integrations.length === 0) {
// case: no integrations left, deactivate bot // case: no integrations left, deactivate bot
const bot = await Bot.findOneAndUpdate({ const bot = await Bot.findOneAndUpdate({
workspace: deletedIntegration.workspace workspace: integration.workspace
}, { }, {
isActive: false isActive: false
}, { }, {
@@ -129,8 +129,8 @@ export const deleteIntegration = async (req: Request, res: Response) => {
message: 'Failed to delete integration' message: 'Failed to delete integration'
}); });
} }
return res.status(200).send({ return res.status(200).send({
deletedIntegration integration
}); });
}; };
@@ -32,10 +32,21 @@ interface IntegrationApp {
type Props = { type Props = {
integration: TIntegration; integration: TIntegration;
integrations: TIntegration[];
setIntegrations: any;
bot: any;
setBot: any;
environments: Array<{ name: string; slug: string }>; environments: Array<{ name: string; slug: string }>;
}; };
const Integration = ({ integration, environments = [] }: Props) => { const Integration = ({
integration,
integrations,
bot,
setBot,
setIntegrations,
environments = []
}: Props) => {
// set initial environment. This find will only execute when component is mounting // set initial environment. This find will only execute when component is mounting
const [integrationEnvironment, setIntegrationEnvironment] = useState<Props['environments'][0]>( const [integrationEnvironment, setIntegrationEnvironment] = useState<Props['environments'][0]>(
environments.find(({ slug }) => slug === integration.environment) || { environments.find(({ slug }) => slug === integration.environment) || {
@@ -79,6 +90,56 @@ const Integration = ({ integration, environments = [] }: Props) => {
loadIntegration(); loadIntegration();
}, []); }, []);
const handleStartIntegration = async () => {
try {
const siteApp = apps.find((app) => app.name === integrationApp); // obj or undefined
const siteId = siteApp?.siteId ?? null;
const owner = siteApp?.owner ?? null;
// return updated integration
const updatedIntegration = await updateIntegration({
integrationId: integration._id,
environment: integrationEnvironment.slug,
app: integrationApp,
isActive: true,
target: integrationTarget ? integrationTarget.toLowerCase() : null,
context: integrationContext
? reverseContextNetlifyMapping[integrationContext]
: null,
siteId,
owner
});
setIntegrations(
integrations.map((i) => i._id === updatedIntegration._id ? updatedIntegration : i)
);
} catch (err) {
console.error(err);
}
}
const handleDeleteIntegration = async () => {
try {
const deletedIntegration = await deleteIntegration({
integrationId: integration._id
});
const newIntegrations = integrations.filter((i) => i._id !== deletedIntegration._id);
setIntegrations(newIntegrations);
if (newIntegrations.length < 1) {
// case: no integrations left
setBot({
...bot,
isActive: false
})
}
} catch (err) {
console.error(err);
}
}
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
const renderIntegrationSpecificParams = (integration: TIntegration) => { const renderIntegrationSpecificParams = (integration: TIntegration) => {
@@ -172,38 +233,14 @@ const Integration = ({ integration, environments = [] }: Props) => {
) : ( ) : (
<Button <Button
text="Start Integration" text="Start Integration"
onButtonPressed={async () => { onButtonPressed={() => handleStartIntegration()}
const siteApp = apps.find((app) => app.name === integrationApp); // obj or undefined
const siteId = siteApp?.siteId ?? null;
const owner = siteApp?.owner ?? null;
await updateIntegration({
integrationId: integration._id,
environment: integrationEnvironment.slug,
app: integrationApp,
isActive: true,
target: integrationTarget ? integrationTarget.toLowerCase() : null,
context: integrationContext
? reverseContextNetlifyMapping[integrationContext]
: null,
siteId,
owner
});
router.reload();
}}
color="mineshaft" color="mineshaft"
size="md" size="md"
/> />
)} )}
<div className="opacity-50 hover:opacity-100 duration-200 ml-2"> <div className="opacity-50 hover:opacity-100 duration-200 ml-2">
<Button <Button
onButtonPressed={async () => { onButtonPressed={() => handleDeleteIntegration()}
await deleteIntegration({
integrationId: integration._id
});
router.reload();
}}
color="red" color="red"
size="icon-md" size="icon-md"
icon={faX} icon={faX}
@@ -4,6 +4,9 @@ import Integration from './Integration';
interface Props { interface Props {
integrations: any; integrations: any;
setIntegrations: any;
bot: any;
setBot: any;
environments: Array<{ name: string; slug: string }>; environments: Array<{ name: string; slug: string }>;
} }
@@ -17,17 +20,31 @@ interface IntegrationType {
context: string; context: string;
} }
const ProjectIntegrationSection = ({ integrations, environments = [] }: Props) => const ProjectIntegrationSection = ({
integrations,
setIntegrations,
bot,
setBot,
environments = []
}: Props) =>
integrations.length > 0 ? ( integrations.length > 0 ? (
<div className="mb-12"> <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 Integrations</h1> <h1 className="font-semibold text-3xl">Current 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 integrations with third-party services.
</p> </p>
</div> </div>
{integrations.map((integration: IntegrationType) => ( {integrations.map((integration: IntegrationType) => (
<Integration key={guidGenerator()} integration={integration} environments={environments} /> <Integration
key={guidGenerator()}
integration={integration}
integrations={integrations}
bot={bot}
setBot={setBot}
setIntegrations={setIntegrations}
environments={environments}
/>
))} ))}
</div> </div>
) : ( ) : (
@@ -17,7 +17,7 @@ const deleteIntegration = ({ integrationId }: Props) =>
} }
}).then(async (res) => { }).then(async (res) => {
if (res && res.status === 200) { if (res && res.status === 200) {
return (await res.json()).workspace; return (await res.json()).integration;
} }
console.log('Failed to delete an integration'); console.log('Failed to delete an integration');
return undefined; return undefined;
@@ -50,7 +50,7 @@ const updateIntegration = ({
}) })
}).then(async (res) => { }).then(async (res) => {
if (res && res.status === 200) { if (res && res.status === 200) {
return res; return (await res.json()).integration;
} }
console.log('Failed to start an integration'); console.log('Failed to start an integration');
return undefined; return undefined;
+7 -1
View File
@@ -226,7 +226,13 @@ export default function Integrations() {
handleBotActivate={handleBotActivate} handleBotActivate={handleBotActivate}
handleIntegrationOption={handleIntegrationOption} handleIntegrationOption={handleIntegrationOption}
/> */} /> */}
<IntegrationSection integrations={integrations} environments={environments} /> <IntegrationSection
integrations={integrations}
setIntegrations={setIntegrations}
bot={bot}
setBot={setBot}
environments={environments}
/>
{cloudIntegrationOptions.length > 0 && bot ? ( {cloudIntegrationOptions.length > 0 && bot ? (
<CloudIntegrationSection <CloudIntegrationSection
cloudIntegrationOptions={cloudIntegrationOptions} cloudIntegrationOptions={cloudIntegrationOptions}