diff --git a/apps/webapp/app/components/jobs/JobsTable.tsx b/apps/webapp/app/components/jobs/JobsTable.tsx index a7d3ffc44..954eb017f 100644 --- a/apps/webapp/app/components/jobs/JobsTable.tsx +++ b/apps/webapp/app/components/jobs/JobsTable.tsx @@ -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 ( - + @@ -79,12 +85,30 @@ export function JobsTable({ +
+ + {integration.setupStatus === "MISSING_FIELDS" && ( + + )} +
+ } + content={ +
+

+ {integration.setupStatus === "MISSING_FIELDS" && + "This integration requires configuration"} +

+

+ {integration.title}: {integration.key} +

+
} - content={`${integration.title}: ${integration.key}`} /> ))}
diff --git a/apps/webapp/app/presenters/ProjectPresenter.server.ts b/apps/webapp/app/presenters/ProjectPresenter.server.ts index 8bb5eda5f..851898525 100644 --- a/apps/webapp/app/presenters/ProjectPresenter.server.ts +++ b/apps/webapp/app/presenters/ProjectPresenter.server.ts @@ -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, }; diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx index 704123e50..4aa81622b 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx @@ -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() { )} >
+ {project.jobs.length > 0 && + project.jobs.some( + (j) => j.hasIntegrationsRequiringAction + ) && ( + + Some of your Jobs have Integrations that have not been + configured. + + )}
{project.jobs.length === 0 ? ( Jobs diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx index ec0a351ce..d6b9a2f9e 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx @@ -390,7 +390,7 @@ function IntegrationsWithMissingFields({
- Integrations with missing details + Integrations requiring configuration diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route.tsx index b9c66ca3a..44267481a 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route.tsx @@ -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(); const navigation = useNavigation(); const isLoading = navigation.state !== "idle"; + const organization = useOrganization(); + const project = useProject(); + const job = useJob(); return ( - - {(open) => ( -
+ {job.hasIntegrationsRequiringAction && ( + -
-
- - -
- - -
- - - -
+ {simplur`This Job has ${ + job.integrations.filter((j) => j.setupStatus === "MISSING_FIELDS") + .length + } Integration[|s] that [has|have] not been configured.`} + )} -
+ + {(open) => ( +
+
+
+ + +
+ + +
+ + + +
+ )} +
+ ); }