Webhook sources are hooked up when selected from the dropdown

This commit is contained in:
Matt Aitken
2022-12-28 12:09:06 +00:00
parent 728ddb0dc2
commit 4ffc94e9ee
4 changed files with 95 additions and 23 deletions
@@ -5,6 +5,7 @@ import {
CheckIcon,
PlusIcon,
} from "@heroicons/react/24/outline";
import { useFetcher } from "@remix-run/react";
import classNames from "classnames";
import { Fragment } from "react";
import type { APIConnection } from "~/models/apiConnection.server";
@@ -12,7 +13,7 @@ import type { Integration } from "./ConnectButton";
import { ConnectButton } from "./ConnectButton";
type Props = {
slotId: string;
sourceId: string;
organizationId: string;
integration: Integration;
connections: Pick<APIConnection, "id" | "title">[];
@@ -20,12 +21,14 @@ type Props = {
};
export function ConnectionSelector({
slotId,
sourceId,
integration,
connections,
selectedConnectionId,
organizationId,
}: Props) {
const fetcher = useFetcher();
if (connections.length === 0) {
return (
<ConnectButton
@@ -95,28 +98,38 @@ export function ConnectionSelector({
<div className="relative grid gap-y-1 py-1 bg-slate-700 grid-cols-1">
{connections.map((connection) => {
return (
<Popover.Button
<fetcher.Form
key={connection.id}
// to={`/orgs/${currentOrganization.slug}/workflows/${connection.slug}`}
className={classNames(
"flex items-center justify-between gap-1.5 mx-1 px-3 py-2 text-white rounded hover:bg-slate-800 transition",
connection.id === selectedConnectionId &&
"!bg-slate-800"
)}
action={`/api/v1/internal/sources/${sourceId}`}
method="put"
>
<div className="flex items-center gap-2">
<ArrowsRightLeftIcon
className="h-5 w-5 z-100"
aria-hidden="true"
/>
<span className="block truncate">
{connection.title}
</span>
</div>
{connection.id === selectedConnectionId && (
<CheckIcon className="h-5 w-5 text-blue-600" />
)}
</Popover.Button>
<input
type="hidden"
name={"connectionId"}
value={connection.id}
/>
<Popover.Button
className={classNames(
"flex items-center justify-between gap-1.5 mx-1 px-3 py-2 text-white rounded hover:bg-slate-800 transition",
connection.id === selectedConnectionId &&
"!bg-slate-800"
)}
type="submit"
>
<div className="flex items-center gap-2">
<ArrowsRightLeftIcon
className="h-5 w-5 z-100"
aria-hidden="true"
/>
<span className="block truncate">
{connection.title}
</span>
</div>
{connection.id === selectedConnectionId && (
<CheckIcon className="h-5 w-5 text-blue-600" />
)}
</Popover.Button>
</fetcher.Form>
);
})}
<ConnectButton
@@ -13,3 +13,20 @@ export async function findExternalSourceById(id: string) {
},
});
}
export async function connectExternalSource({
sourceId,
connectionId,
}: {
sourceId: string;
connectionId: string;
}) {
return await prisma.externalSource.update({
where: {
id: sourceId,
},
data: {
connectionId: connectionId,
},
});
}
@@ -22,7 +22,7 @@ export default function Page() {
{connectionSlots.map((slot) => (
<ConnectionSelector
key={slot.id}
slotId={slot.id}
sourceId={slot.id}
organizationId={organization.id}
integration={integrations[0]}
connections={slot.possibleConnections}
@@ -0,0 +1,42 @@
import type { ActionArgs } from "@remix-run/server-runtime";
import { json } from "@remix-run/server-runtime";
import { typedjson } from "remix-typedjson";
import invariant from "tiny-invariant";
import { z } from "zod";
import { connectExternalSource } from "~/models/externalSource.server";
import { internalPubSub } from "~/services/messageBroker.server";
import { requireUserId } from "~/services/session.server";
const requestSchema = z.object({
connectionId: z.string(),
});
// PUT /api/v1/internal/sources/:sourceId
/** This is used to connect an external source with a connection to an API */
export async function action({ request, params }: ActionArgs) {
await requireUserId(request);
const { sourceId } = params;
invariant(sourceId, "sourceId is required");
// first make sure this is a PUT request
if (request.method.toUpperCase() !== "PUT") {
return json({ error: "Method not allowed" }, { status: 405 });
}
try {
const formData = await request.formData();
const formObject = Object.fromEntries(formData.entries());
const { connectionId } = requestSchema.parse(formObject);
await connectExternalSource({ sourceId, connectionId });
await internalPubSub.publish("EXTERNAL_SOURCE_UPSERTED", {
id: sourceId,
});
return typedjson({ success: true });
} catch (error: any) {
console.error(error);
return typedjson({ error: error.message }, { status: 400 });
}
}