Added UI to guide you to fixing unconfigured integrations
This commit is contained in:
@@ -18,6 +18,7 @@ import { runStatusTitle } from "../runs/RunStatuses";
|
||||
import { ProjectJob, useProject } from "~/hooks/useProject";
|
||||
import { useOrganization } from "~/hooks/useOrganizations";
|
||||
import { JobRunStatus } from "~/models/job.server";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
export function JobsTable({
|
||||
jobs,
|
||||
@@ -46,7 +47,12 @@ export function JobsTable({
|
||||
jobs.map((job) => {
|
||||
const path = jobPath(organization, project, job);
|
||||
return (
|
||||
<TableRow key={job.id}>
|
||||
<TableRow
|
||||
key={job.id}
|
||||
className={cn(
|
||||
job.hasIntegrationsRequiringAction && "bg-rose-500/30"
|
||||
)}
|
||||
>
|
||||
<TableCell to={path}>
|
||||
<span className="flex items-center gap-2">
|
||||
<NamedIcon name={job.event.icon} className="h-8 w-8" />
|
||||
@@ -79,12 +85,30 @@ export function JobsTable({
|
||||
<SimpleTooltip
|
||||
key={integration.key}
|
||||
button={
|
||||
<NamedIcon
|
||||
name={integration.icon}
|
||||
className="h-6 w-6"
|
||||
/>
|
||||
<div className="relative">
|
||||
<NamedIcon
|
||||
name={integration.icon}
|
||||
className="h-6 w-6"
|
||||
/>
|
||||
{integration.setupStatus === "MISSING_FIELDS" && (
|
||||
<NamedIcon
|
||||
name="error"
|
||||
className="absolute -left-1 -top-1 h-4 w-4"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
content={
|
||||
<div>
|
||||
<p className="mb-1 text-rose-400">
|
||||
{integration.setupStatus === "MISSING_FIELDS" &&
|
||||
"This integration requires configuration"}
|
||||
</p>
|
||||
<p>
|
||||
{integration.title}: {integration.key}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
content={`${integration.title}: ${integration.key}`}
|
||||
/>
|
||||
))}
|
||||
</TableCell>
|
||||
|
||||
@@ -57,6 +57,7 @@ export class ProjectPresenter {
|
||||
select: {
|
||||
slug: true,
|
||||
definition: true,
|
||||
setupStatus: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -169,6 +170,7 @@ export class ProjectPresenter {
|
||||
key: integration.key,
|
||||
title: integration.integration.slug,
|
||||
icon: integration.integration.definition.id,
|
||||
setupStatus: integration.integration.setupStatus,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -197,6 +199,9 @@ export class ProjectPresenter {
|
||||
source: eventSpecification.source,
|
||||
},
|
||||
integrations,
|
||||
hasIntegrationsRequiringAction: integrations.some(
|
||||
(i) => i.setupStatus === "MISSING_FIELDS"
|
||||
),
|
||||
lastRun,
|
||||
properties,
|
||||
};
|
||||
|
||||
+14
-1
@@ -21,7 +21,7 @@ import { useProject } from "~/hooks/useProject";
|
||||
import { cn } from "~/utils/cn";
|
||||
import { Handle } from "~/utils/handle";
|
||||
import useWindowSize from "react-use/lib/useWindowSize";
|
||||
import { docsPath } from "~/utils/pathBuilder";
|
||||
import { docsPath, projectIntegrationsPath } from "~/utils/pathBuilder";
|
||||
|
||||
export const handle: Handle = {
|
||||
breadcrumb: {
|
||||
@@ -83,6 +83,19 @@ export default function Page() {
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
{project.jobs.length > 0 &&
|
||||
project.jobs.some(
|
||||
(j) => j.hasIntegrationsRequiringAction
|
||||
) && (
|
||||
<Callout
|
||||
variant="error"
|
||||
to={projectIntegrationsPath(organization, project)}
|
||||
className="mb-2"
|
||||
>
|
||||
Some of your Jobs have Integrations that have not been
|
||||
configured.
|
||||
</Callout>
|
||||
)}
|
||||
<div className="mb-2 flex items-center justify-between gap-x-2">
|
||||
{project.jobs.length === 0 ? (
|
||||
<Header2>Jobs</Header2>
|
||||
|
||||
+1
-1
@@ -390,7 +390,7 @@ function IntegrationsWithMissingFields({
|
||||
<div className="mb-6">
|
||||
<Header2 className="mb-2 flex items-center gap-1">
|
||||
<NamedIcon name="error" className="h-5 w-5" />
|
||||
Integrations with missing details
|
||||
Integrations requiring configuration
|
||||
</Header2>
|
||||
|
||||
<Table>
|
||||
|
||||
+48
-26
@@ -9,8 +9,13 @@ import { RunListPresenter } from "~/presenters/RunListPresenter.server";
|
||||
import { requireUserId } from "~/services/session.server";
|
||||
import { cn } from "~/utils/cn";
|
||||
import { Handle } from "~/utils/handle";
|
||||
import { JobParamsSchema } from "~/utils/pathBuilder";
|
||||
import { JobParamsSchema, projectIntegrationsPath } from "~/utils/pathBuilder";
|
||||
import { ListPagination } from "./ListPagination";
|
||||
import { Callout } from "~/components/primitives/Callout";
|
||||
import { useOrganization } from "~/hooks/useOrganizations";
|
||||
import { useProject } from "~/hooks/useProject";
|
||||
import { useJob } from "~/hooks/useJob";
|
||||
import simplur from "simplur";
|
||||
|
||||
export const DirectionSchema = z.union([
|
||||
z.literal("forward"),
|
||||
@@ -56,34 +61,51 @@ export default function Page() {
|
||||
const { list } = useTypedLoaderData<typeof loader>();
|
||||
const navigation = useNavigation();
|
||||
const isLoading = navigation.state !== "idle";
|
||||
const organization = useOrganization();
|
||||
const project = useProject();
|
||||
const job = useJob();
|
||||
|
||||
return (
|
||||
<Help defaultOpen={list.runs.length === 0}>
|
||||
{(open) => (
|
||||
<div
|
||||
className={cn(
|
||||
"grid h-fit gap-4",
|
||||
open ? "grid-cols-2" : "grid-cols-1"
|
||||
)}
|
||||
<>
|
||||
{job.hasIntegrationsRequiringAction && (
|
||||
<Callout
|
||||
variant="error"
|
||||
to={projectIntegrationsPath(organization, project)}
|
||||
className="mb-2"
|
||||
>
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-end gap-x-2">
|
||||
<ListPagination list={list} />
|
||||
<HelpTrigger title="How do I run my Job?" />
|
||||
</div>
|
||||
<RunsTable
|
||||
total={list.runs.length}
|
||||
hasFilters={false}
|
||||
runs={list.runs}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ListPagination list={list} className="mt-2 justify-end" />
|
||||
</div>
|
||||
<HelpContent title="How to run your Job">
|
||||
<HowToRunYourJob />
|
||||
</HelpContent>
|
||||
</div>
|
||||
{simplur`This Job has ${
|
||||
job.integrations.filter((j) => j.setupStatus === "MISSING_FIELDS")
|
||||
.length
|
||||
} Integration[|s] that [has|have] not been configured.`}
|
||||
</Callout>
|
||||
)}
|
||||
</Help>
|
||||
<Help defaultOpen={list.runs.length === 0}>
|
||||
{(open) => (
|
||||
<div
|
||||
className={cn(
|
||||
"grid h-fit gap-4",
|
||||
open ? "grid-cols-2" : "grid-cols-1"
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-end gap-x-2">
|
||||
<ListPagination list={list} />
|
||||
<HelpTrigger title="How do I run my Job?" />
|
||||
</div>
|
||||
<RunsTable
|
||||
total={list.runs.length}
|
||||
hasFilters={false}
|
||||
runs={list.runs}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ListPagination list={list} className="mt-2 justify-end" />
|
||||
</div>
|
||||
<HelpContent title="How to run your Job">
|
||||
<HowToRunYourJob />
|
||||
</HelpContent>
|
||||
</div>
|
||||
)}
|
||||
</Help>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user