Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9e64f9d
Copy changes to titles
samejr Feb 20, 2023
a117a3b
APIs not connected get a red border treatment to make them stand out
samejr Feb 20, 2023
c9bd181
Swapped over the workflow panel with the API panel
samejr Feb 20, 2023
ad8a2f1
Improved the border style of the disconnected apis
samejr Feb 20, 2023
350a605
WIP adding a concertina menu to the main workflow panel
samejr Feb 20, 2023
3c27b3c
Passed classnames props
samejr Feb 21, 2023
cd8e85f
Show hide the concertina panel for connecting the source
samejr Feb 21, 2023
f969f03
Now exporting the connection data for useConnectionSlots
samejr Feb 21, 2023
0c6d98d
Added margin between the sections
samejr Feb 21, 2023
a63ebd7
Added a connection icon and fixed some concertina behaviour issues
samejr Feb 21, 2023
ed1c2da
Added a permenant message about api connectiions
samejr Feb 21, 2023
8862b56
Added a “How to run your workflow” concertina
samejr Feb 21, 2023
d744efd
Added a generic webhook example workflow
samejr Feb 21, 2023
547aab6
Added a custom plug icon
samejr Feb 21, 2023
0d72b8e
Added a custom webhook connection concertina
samejr Feb 21, 2023
28fb5d0
Updated the integrations link
samejr Feb 21, 2023
841421b
Made the concertina panels open when relevant
samejr Feb 21, 2023
cc6adec
Only show the Create workflow run panel if a workflow or non-test run…
samejr Feb 21, 2023
db9b03c
Link to the org integrations page
samejr Feb 21, 2023
3e384ff
Show better copy in the How to trigger your workflow panel
samejr Feb 21, 2023
f80253e
typography improvements
samejr Feb 21, 2023
058afb4
Copy improvement
samejr Feb 21, 2023
8587841
Made the test button less prominent
samejr Feb 21, 2023
96c4f31
Label positioned better
samejr Feb 21, 2023
75589d3
Reduced prominence of connect api message
samejr Feb 21, 2023
2337645
Merge remote-tracking branch 'origin/dev' into features/new-overview-…
matt-aitken Feb 21, 2023
8de37d4
Renamed new example package to @examples/generic-webhook
matt-aitken Feb 21, 2023
f0378fa
Fix for incorrect types (after merge)
matt-aitken Feb 21, 2023
352b7f7
Installed packages
matt-aitken Feb 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 32 additions & 50 deletions apps/webapp/app/components/integrations/WorkflowConnections.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,40 @@
import { Link } from "@remix-run/react";
import classNames from "classnames";
import invariant from "tiny-invariant";
import { useConnectionSlots } from "~/hooks/useConnectionSlots";
import type { ConnectionSlot } from "~/hooks/useConnectionSlots";
import { useCurrentOrganization } from "~/hooks/useOrganizations";
import { ApiLogoIcon } from "../code/ApiLogoIcon";
import { List } from "../layout/List";
import { Body } from "../primitives/text/Body";
import { Header3 } from "../primitives/text/Headers";
import { SubTitle } from "../primitives/text/SubTitle";
import { ConnectionSelector } from "./ConnectionSelector";

export function WorkflowConnections() {
export function WorkflowConnections({
className,
connectionSlots,
}: {
className?: string;
connectionSlots: ConnectionSlot[];
}) {
const organization = useCurrentOrganization();
invariant(organization, "Organization not found");
const connectionSlots = useConnectionSlots();
invariant(connectionSlots, "Connection slots not found");
const allApisCount =
connectionSlots.services.length + (connectionSlots.source ? 1 : 0);
const connectedApisCount =
connectionSlots.services.filter((c) => c.connection).length +
(connectionSlots.source?.connection ? 1 : 0);
const unconnectedApisCount = allApisCount - connectedApisCount ? 1 : 0;
const unconnectedApisCountCopy = `, ${unconnectedApisCount} to connect`;

return (
<>
<SubTitle>
<>
{connectedApisCount} API
{connectedApisCount > 1
? "s"
: connectedApisCount === 0
? "s"
: ""}{" "}
connected
{unconnectedApisCount === 0 ? "" : unconnectedApisCountCopy}
</>
</SubTitle>
<div className={classNames(className)}>
<SubTitle>API Connections</SubTitle>
<List>
{connectionSlots.source && (
<li className="flex gap-4 w-full px-4 py-4">
<ApiLogoIcon
integration={connectionSlots.source.integration}
size="regular"
/>
<div className="flex items-center justify-between gap-1 w-full">
<Body>{connectionSlots.source.integration.name}</Body>
<ConnectionSelector
type="source"
sourceServiceId={connectionSlots.source.id}
organizationId={organization.id}
integration={connectionSlots.source.integration}
connections={connectionSlots.source.possibleConnections}
selectedConnectionId={connectionSlots.source.connection?.id}
className="mr-1"
popoverAlign="right"
/>
</div>
</li>
)}
{connectionSlots.services.map((slot) => (
{connectionSlots.map((slot) => (
<li
key={slot.id}
className="flex gap-4 items-center w-full px-4 py-4"
className={classNames(
slot.connection === null
? "!border !border-rose-600 bg-rose-500/10"
: "",
"flex w-full items-center gap-4 px-4 py-4 first:rounded-t-md last:rounded-b-md"
)}
>
<ApiLogoIcon integration={slot.integration} size="regular" />
<div className="flex items-center justify-between w-full">
<div className="flex w-full items-center justify-between">
<Header3 size="small" className="truncate text-slate-300">
{slot.integration?.name}
</Header3>
Expand All @@ -80,7 +51,18 @@ export function WorkflowConnections() {
</div>
</li>
))}
<li className="font-sm p-4 pl-5 text-slate-500">
You will be able to authenticate APIs on demand when your workflow
runs. You can also{" "}
<Link
to="../integrations"
className="text-slate-500 underline decoration-slate-500 underline-offset-4 transition hover:text-slate-400"
>
connect them now
</Link>
.
</li>
</List>
</>
</div>
);
}
25 changes: 25 additions & 0 deletions apps/webapp/app/components/primitives/IconPlug.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export function PlugIcon({
className,
fill,
}: {
className?: string;
fill?: string;
}) {
return (
<svg
width="418"
height="418"
viewBox="0 0 418 418"
xmlns="http://www.w3.org/2000/svg"
className={className}
fill={fill}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M411.662 6.12075C419.821 14.2794 419.821 27.5054 411.662 35.6637L390.942 56.3841C422.842 102.22 418.355 165.702 377.482 206.57L357.947 226.104C341.701 242.351 315.354 242.351 299.106 226.104L191.677 118.675C175.43 102.428 175.43 76.0848 191.677 59.8335L211.211 40.3029C252.084 -0.570291 315.56 -5.05725 361.397 26.8393L382.117 6.11896C390.276 -2.03965 403.502 -2.03965 411.66 6.11896L411.662 6.12075ZM347.939 69.8441C318.34 40.2456 270.35 40.2456 240.751 69.8441L221.342 89.2565L328.53 196.444L347.942 177.031C377.541 147.433 377.541 99.4426 347.942 69.8441H347.939ZM172.391 142.848C180.549 151.007 180.549 164.233 172.391 172.391L135.889 208.893L208.893 281.897L245.395 245.396C253.553 237.237 266.78 237.237 274.938 245.396C283.093 253.554 283.093 266.78 274.938 274.939L235.736 314.14C241.164 328.891 237.953 346.103 226.105 357.952L206.575 377.482C165.701 418.356 102.216 422.846 56.3797 390.946L35.6593 411.666C27.5007 419.821 14.2747 419.821 6.11634 411.666C-2.03878 403.508 -2.03878 390.282 6.11634 382.123L26.8367 361.403C-5.05987 315.567 -0.57291 252.085 40.3003 211.217L59.8309 191.683C71.6785 179.835 88.8913 176.629 103.642 182.056L142.848 142.85C151.003 134.695 164.229 134.695 172.387 142.85L172.391 142.848ZM89.2557 221.343L69.8468 240.756C40.2483 270.354 40.2483 318.345 69.8468 347.943C99.4426 377.545 147.432 377.545 177.034 347.943L196.447 328.534L89.2557 221.343Z"
fill={fill}
/>
</svg>
);
}
9 changes: 9 additions & 0 deletions apps/webapp/app/hooks/useConnectionSlots.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import type { APIConnection } from ".prisma/client";
import type { ServiceMetadata } from "@trigger.dev/integration-sdk";
import type { UseDataFunctionReturn } from "remix-typedjson/dist/remix";
import type { loader } from "~/routes/__app/orgs/$organizationSlug/workflows/$workflowSlug";
import { hydrateObject, useMatchesData } from "~/utils";

export type ConnectionSlot = {
id: string;
connection: APIConnection | null;
integration: ServiceMetadata;
possibleConnections: APIConnection[];
};

export function useConnectionSlots() {
const routeMatch = useMatchesData(
"routes/__app/orgs/$organizationSlug/workflows/$workflowSlug"
Expand Down
24 changes: 24 additions & 0 deletions apps/webapp/app/presenters/workflowRunListPresenter.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ export class WorkflowRunListPresenter {
},
});

const totalRealRuns = await this.#prismaClient.workflowRun.count({
where: {
isTest: false,
workflow: {
slug: workflowSlug,
organization: {
slug: organizationSlug,
users: {
some: {
id: userId,
},
},
},
},
environment: {
slug: environmentSlug,
},
status: {
in: statuses,
},
},
});

const runs = await this.#prismaClient.workflowRun.findMany({
select: {
id: true,
Expand Down Expand Up @@ -111,6 +134,7 @@ export class WorkflowRunListPresenter {
page,
pageCount: Math.ceil(total / pageSize),
total,
totalRealRuns,
filters: {
statuses,
},
Expand Down
Loading