Integrations in the web app now use the yml file

This commit is contained in:
Matt Aitken
2022-12-29 15:36:25 +00:00
parent cb2e1b7775
commit 61f7dfc4da
15 changed files with 43 additions and 44 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

@@ -1,4 +1,3 @@
import githubLogo from "~/assets/images/integrations/logo-github.png";
import { useCallback, useEffect } from "react";
import Pizzly from "@nangohq/pizzly-frontend";
import { useFetcher } from "@remix-run/react";
@@ -7,20 +6,7 @@ import type {
Update,
UpdateResponse,
} from "~/routes/resources/connection";
export type Integration = {
key: string;
name: string;
logo: string;
};
export const integrations: Integration[] = [
{
key: "github",
name: "GitHub",
logo: githubLogo,
},
];
import type { CatalogIntegration } from "internal-catalog";
const actionPath = "/resources/connection";
@@ -31,7 +17,7 @@ export function ConnectButton({
className,
children,
}: {
integration: Integration;
integration: CatalogIntegration;
organizationId: string;
sourceId?: string;
className?: string;
@@ -43,7 +29,7 @@ export function ConnectButton({
<createFetcher.Form method="post" action={actionPath}>
<input type="hidden" name="type" value="create" />
<input type="hidden" name="organizationId" value={organizationId} />
<input type="hidden" name="key" value={integration.key} />
<input type="hidden" name="key" value={integration.slug} />
<button
type="submit"
disabled={status === "loading"}
@@ -2,15 +2,15 @@ import { Popover, Transition } from "@headlessui/react";
import { ChevronUpDownIcon, CheckIcon } from "@heroicons/react/24/outline";
import { useFetcher } from "@remix-run/react";
import classNames from "classnames";
import type { CatalogIntegration } from "internal-catalog";
import { Fragment } from "react";
import type { APIConnection } from "~/models/apiConnection.server";
import type { Integration } from "./ConnectButton";
import { ConnectButton } from "./ConnectButton";
type Props = {
sourceId: string;
organizationId: string;
integration: Integration;
integration: CatalogIntegration;
connections: Pick<APIConnection, "id" | "title">[];
selectedConnectionId?: string;
};
@@ -27,7 +27,7 @@ export function ConnectionSelector({
if (connections.length === 0) {
return (
<ConnectButton
key={integration.key}
key={integration.slug}
integration={integration}
organizationId={organizationId}
sourceId={sourceId}
@@ -135,12 +135,12 @@ export function ConnectionSelector({
);
}
function IntegrationIcon({ integration }: { integration: Integration }) {
function IntegrationIcon({ integration }: { integration: CatalogIntegration }) {
return (
<img
src={integration.logo}
src={integration.icon}
alt={integration.name}
className="h-8 w-8 shadow-lg group-hover:opacity-80 transition"
className="h-5 w-5 shadow-lg group-hover:opacity-80 transition"
/>
);
}
@@ -2,7 +2,6 @@ import invariant from "tiny-invariant";
import { useConnectionSlots } from "~/hooks/useConnectionSlots";
import { useCurrentOrganization } from "~/hooks/useOrganizations";
import { Body } from "../primitives/text/Body";
import { integrations } from "./ConnectButton";
import { ConnectionSelector } from "./ConnectionSelector";
export function WorkflowConnections() {
@@ -19,7 +18,7 @@ export function WorkflowConnections() {
<ConnectionSelector
sourceId={slot.id}
organizationId={organization.id}
integration={integrations[0]}
integration={slot.integration}
connections={slot.possibleConnections}
selectedConnectionId={slot.connection?.id}
/>
@@ -0,0 +1,7 @@
import * as fs from "node:fs";
import { getCatalog } from "internal-catalog";
export function getIntegrations() {
const file = fs.readFileSync("./integrations.yml", "utf8");
return getCatalog(file);
}
@@ -1,8 +1,10 @@
import { PlusCircleIcon } from "@heroicons/react/24/solid";
import type { LoaderArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import invariant from "tiny-invariant";
import { ConnectButton } from "~/components/integrations/ConnectButton";
import { Container } from "~/components/layout/Container";
import { Body } from "~/components/primitives/text/Body";
import { List } from "~/components/layout/List";
import {
Header1,
Header2,
@@ -10,15 +12,8 @@ import {
} from "~/components/primitives/text/Headers";
import { useCurrentOrganization } from "~/hooks/useOrganizations";
import { getConnectedApiConnectionsForOrganizationSlug } from "~/models/apiConnection.server";
import {
ConnectButton,
integrations,
} from "~/components/integrations/ConnectButton";
import { getIntegrations } from "~/models/integrations.server";
import { requireUserId } from "~/services/session.server";
import logoGithub from "~/assets/images/integrations/logo-github.png";
import { ArrowsRightLeftIcon } from "@heroicons/react/24/outline";
import { List } from "~/components/layout/List";
import { PlusCircleIcon } from "@heroicons/react/24/solid";
export const loader = async ({ request, params }: LoaderArgs) => {
await requireUserId(request);
@@ -29,11 +24,11 @@ export const loader = async ({ request, params }: LoaderArgs) => {
slug: organizationSlug,
});
return typedjson({ connections });
return typedjson({ connections, integrations: getIntegrations() });
};
export default function Integrations() {
const { connections } = useTypedLoaderData<typeof loader>();
const { connections, integrations } = useTypedLoaderData<typeof loader>();
const organization = useCurrentOrganization();
invariant(organization, "Organization not found");
@@ -55,7 +50,11 @@ export default function Integrations() {
<div className="flex gap-4 items-center px-4 py-4">
<img
className="h-14 w-14 shadow-md"
src={logoGithub}
src={
integrations.find(
(i) => i.slug === connection.apiIdentifier
)?.icon
}
alt="Github integration logo"
/>
<div className="flex flex-col gap-2">
@@ -87,7 +86,7 @@ export default function Integrations() {
<div className="flex flex-wrap gap-2 w-full">
{integrations.map((integration) => (
<ConnectButton
key={integration.key}
key={integration.slug}
integration={integration}
organizationId={organization.id}
className="flex flex-col group max-w-[160px] rounded-md bg-slate-800 border border-slate-800 gap-4 text-sm text-slate-200 items-center overflow-hidden hover:bg-slate-800/30 transition shadow-md disabled:opacity-50"
@@ -97,7 +96,7 @@ export default function Integrations() {
<div className="relative flex items-center justify-center w-full py-6 bg-black/20 border-b border-slate-800">
<PlusCircleIcon className="absolute h-7 w-7 top-[16px] right-[28px] z-10 text-slate-200 shadow-md" />
<img
src={integration.logo}
src={integration.icon}
alt={integration.name}
className="h-20 shadow-lg group-hover:opacity-80 transition"
/>
@@ -3,13 +3,13 @@ import type { LoaderArgs } from "@remix-run/server-runtime";
import { TriggerMetadataSchema } from "@trigger.dev/common-schemas";
import { typedjson } from "remix-typedjson";
import invariant from "tiny-invariant";
import { integrations } from "~/components/integrations/ConnectButton";
import { Container } from "~/components/layout/Container";
import {
SideMenuContainer,
WorkflowsSideMenu,
} from "~/components/navigation/SideMenu";
import { getConnectedApiConnectionsForOrganizationSlug } from "~/models/apiConnection.server";
import { getIntegrations } from "~/models/integrations.server";
import { getRuntimeEnvironmentFromRequest } from "~/models/runtimeEnvironment.server";
import { getWorkflowFromSlugs } from "~/models/workflow.server";
import { requireUserId } from "~/services/session.server";
@@ -50,7 +50,7 @@ export const loader = async ({ request, params }: LoaderArgs) => {
possibleConnections: allConnections.filter(
(a) => a.apiIdentifier === c.service
),
integration: integrations.find((i) => i.key === c.service),
integration: getIntegrations().find((i) => i.slug === c.service),
}));
return typedjson({
@@ -6,12 +6,12 @@ import {
createAPIConnection,
setConnectedAPIConnection,
} from "~/models/apiConnection.server";
import { integrations } from "~/components/integrations/ConnectButton";
import { requireUserId } from "~/services/session.server";
import { APIConnectionType } from ".prisma/client";
import { env } from "~/env.server";
import { connectExternalSource } from "~/models/externalSource.server";
import { internalPubSub } from "~/services/messageBroker.server";
import { getIntegrations } from "~/models/integrations.server";
const updateSchema = z.object({
type: z.literal("update"),
@@ -59,7 +59,7 @@ export const action = async ({ request, params }: ActionArgs) => {
case "create": {
const { organizationId, key } = parsed;
const integrationInfo = integrations.find((i) => i.key === key);
const integrationInfo = getIntegrations().find((i) => i.slug === key);
if (!integrationInfo) {
throw new Error("Integration not found");
}
+1
View File
@@ -78,6 +78,7 @@
"humanize-duration": "^3.27.3",
"internal-integrations": "workspace:*",
"internal-platform": "workspace:*",
"internal-catalog": "workspace:*",
"javascript-time-ago": "^2.5.7",
"json-query": "^2.2.2",
"jsonata": "^1.8.6",
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

+2
View File
@@ -12,6 +12,7 @@ module.exports = {
"axios",
"internal-platform",
"internal-integrations",
"internal-catalog",
"@trigger.dev/common-schemas",
],
watchPaths: async () => {
@@ -19,6 +20,7 @@ module.exports = {
"../../packages/internal-platform/src/**/*",
"../../packages/common-schemas/src/**/*",
"../../packages/internal-integrations/src/**/*",
"../../packages/internal-catalog/src/**/*",
];
},
};
+1
View File
@@ -1,6 +1,7 @@
{
"private": true,
"name": "internal-catalog",
"type": "module",
"version": "0.0.1",
"description": "Get the API integration catalog",
"main": "./src/index.ts",
+3
View File
@@ -12,6 +12,9 @@ const schema = z.array(
})
);
type Catalog = z.infer<typeof schema>;
export type CatalogIntegration = Catalog[number];
export function getCatalog(raw: string) {
const doc = parseDocument(raw);
const jsObject = doc.toJS();
-1
View File
@@ -15,7 +15,6 @@ async function run() {
const file = fs.readFileSync(integrationFilePath, "utf8");
const catalog = getCatalog(file);
console.log(catalog);
}
run();
+2
View File
@@ -149,6 +149,7 @@ importers:
glob: ^8.0.3
happy-dom: ^6.0.4
humanize-duration: ^3.27.3
internal-catalog: workspace:*
internal-integrations: workspace:*
internal-platform: workspace:*
javascript-time-ago: ^2.5.7
@@ -245,6 +246,7 @@ importers:
date-fns: 2.29.3
express: 4.18.2
humanize-duration: 3.27.3
internal-catalog: link:../../packages/internal-catalog
internal-integrations: link:../../packages/internal-integrations
internal-platform: link:../../packages/internal-platform
javascript-time-ago: 2.5.9