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

View File

@@ -92,24 +92,24 @@ export const updateIntegration = async (req: Request, res: Response) => {
* @returns
*/
export const deleteIntegration = async (req: Request, res: Response) => {
let deletedIntegration;
let integration;
try {
const { integrationId } = req.params;
deletedIntegration = await Integration.findOneAndDelete({
integration = await Integration.findOneAndDelete({
_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({
workspace: deletedIntegration.workspace
workspace: integration.workspace
});
if (integrations.length === 0) {
// case: no integrations left, deactivate bot
const bot = await Bot.findOneAndUpdate({
workspace: deletedIntegration.workspace
workspace: integration.workspace
}, {
isActive: false
}, {
@@ -129,8 +129,8 @@ export const deleteIntegration = async (req: Request, res: Response) => {
message: 'Failed to delete integration'
});
}
return res.status(200).send({
deletedIntegration
integration
});
};

View File

@@ -32,10 +32,21 @@ interface IntegrationApp {
type Props = {
integration: TIntegration;
integrations: TIntegration[];
setIntegrations: any;
bot: any;
setBot: any;
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
const [integrationEnvironment, setIntegrationEnvironment] = useState<Props['environments'][0]>(
environments.find(({ slug }) => slug === integration.environment) || {
@@ -79,6 +90,56 @@ const Integration = ({ integration, environments = [] }: Props) => {
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
const renderIntegrationSpecificParams = (integration: TIntegration) => {
@@ -172,38 +233,14 @@ const Integration = ({ integration, environments = [] }: Props) => {
) : (
<Button
text="Start Integration"
onButtonPressed={async () => {
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();
}}
onButtonPressed={() => handleStartIntegration()}
color="mineshaft"
size="md"
/>
)}
<div className="opacity-50 hover:opacity-100 duration-200 ml-2">
<Button
onButtonPressed={async () => {
await deleteIntegration({
integrationId: integration._id
});
router.reload();
}}
onButtonPressed={() => handleDeleteIntegration()}
color="red"
size="icon-md"
icon={faX}

View File

@@ -4,6 +4,9 @@ import Integration from './Integration';
interface Props {
integrations: any;
setIntegrations: any;
bot: any;
setBot: any;
environments: Array<{ name: string; slug: string }>;
}
@@ -17,17 +20,31 @@ interface IntegrationType {
context: string;
}
const ProjectIntegrationSection = ({ integrations, environments = [] }: Props) =>
const ProjectIntegrationSection = ({
integrations,
setIntegrations,
bot,
setBot,
environments = []
}: Props) =>
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">
<h1 className="font-semibold text-3xl">Current Integrations</h1>
<p className="text-base text-gray-400">
Manage your integrations of Infisical with third-party services.
Manage integrations with third-party services.
</p>
</div>
{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>
) : (

View File

@@ -17,7 +17,7 @@ const deleteIntegration = ({ integrationId }: Props) =>
}
}).then(async (res) => {
if (res && res.status === 200) {
return (await res.json()).workspace;
return (await res.json()).integration;
}
console.log('Failed to delete an integration');
return undefined;

View File

@@ -50,7 +50,7 @@ const updateIntegration = ({
})
}).then(async (res) => {
if (res && res.status === 200) {
return res;
return (await res.json()).integration;
}
console.log('Failed to start an integration');
return undefined;

View File

@@ -226,7 +226,13 @@ export default function Integrations() {
handleBotActivate={handleBotActivate}
handleIntegrationOption={handleIntegrationOption}
/> */}
<IntegrationSection integrations={integrations} environments={environments} />
<IntegrationSection
integrations={integrations}
setIntegrations={setIntegrations}
bot={bot}
setBot={setBot}
environments={environments}
/>
{cloudIntegrationOptions.length > 0 && bot ? (
<CloudIntegrationSection
cloudIntegrationOptions={cloudIntegrationOptions}