diff --git a/orchestrator/src/client/pages/SettingsPage.tsx b/orchestrator/src/client/pages/SettingsPage.tsx index cae31d2..075286a 100644 --- a/orchestrator/src/client/pages/SettingsPage.tsx +++ b/orchestrator/src/client/pages/SettingsPage.tsx @@ -16,10 +16,9 @@ import { DangerZoneSection } from "@client/pages/settings/components/DangerZoneS import { DisplaySettingsSection } from "@client/pages/settings/components/DisplaySettingsSection" import { EnvironmentSettingsSection } from "@client/pages/settings/components/EnvironmentSettingsSection" import { GradcrackerSection } from "@client/pages/settings/components/GradcrackerSection" -import { JobCompleteWebhookSection } from "@client/pages/settings/components/JobCompleteWebhookSection" import { JobspySection } from "@client/pages/settings/components/JobspySection" import { ModelSettingsSection } from "@client/pages/settings/components/ModelSettingsSection" -import { PipelineWebhookSection } from "@client/pages/settings/components/PipelineWebhookSection" +import { WebhooksSection } from "@client/pages/settings/components/WebhooksSection" import { ResumeProjectsSection } from "@client/pages/settings/components/ResumeProjectsSection" import { SearchTermsSection } from "@client/pages/settings/components/SearchTermsSection" import { UkvisajobsSection } from "@client/pages/settings/components/UkvisajobsSection" @@ -452,13 +451,10 @@ export const SettingsPage: React.FC = () => { isLoading={isLoading} isSaving={isSaving} /> - - diff --git a/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.test.tsx b/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.test.tsx index ef117d6..8801d2e 100644 --- a/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.test.tsx +++ b/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.test.tsx @@ -56,7 +56,6 @@ describe("EnvironmentSettingsSection", () => { expect(screen.getByText("sk-1********")).toBeInTheDocument() expect(screen.getByText("pass********")).toBeInTheDocument() expect(screen.getByText("abcd********")).toBeInTheDocument() - expect(screen.getByText("sec-********")).toBeInTheDocument() expect(screen.getByText("Not set")).toBeInTheDocument() // Basic Auth diff --git a/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.tsx b/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.tsx index 583c3a8..c7511d5 100644 --- a/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.tsx +++ b/orchestrator/src/client/pages/settings/components/EnvironmentSettingsSection.tsx @@ -50,16 +50,6 @@ export const EnvironmentSettingsSection: React.FC - - diff --git a/orchestrator/src/client/pages/settings/components/JobCompleteWebhookSection.tsx b/orchestrator/src/client/pages/settings/components/JobCompleteWebhookSection.tsx deleted file mode 100644 index fa0c2c3..0000000 --- a/orchestrator/src/client/pages/settings/components/JobCompleteWebhookSection.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from "react" -import { useFormContext } from "react-hook-form" - -import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" -import { UpdateSettingsInput } from "@shared/settings-schema" -import type { WebhookValues } from "@client/pages/settings/types" -import { SettingsInput } from "@client/pages/settings/components/SettingsInput" - -type JobCompleteWebhookSectionProps = { - values: WebhookValues - isLoading: boolean - isSaving: boolean -} - -export const JobCompleteWebhookSection: React.FC = ({ - values, - isLoading, - isSaving, -}) => { - const { default: defaultJobCompleteWebhookUrl, effective: effectiveJobCompleteWebhookUrl } = values - const { register, formState: { errors } } = useFormContext() - - return ( - - - Job Complete Webhook - - -
- -
-
-
- ) -} diff --git a/orchestrator/src/client/pages/settings/components/PipelineWebhookSection.tsx b/orchestrator/src/client/pages/settings/components/PipelineWebhookSection.tsx deleted file mode 100644 index 7339866..0000000 --- a/orchestrator/src/client/pages/settings/components/PipelineWebhookSection.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from "react" -import { useFormContext } from "react-hook-form" - -import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" -import { UpdateSettingsInput } from "@shared/settings-schema" -import type { WebhookValues } from "@client/pages/settings/types" -import { SettingsInput } from "@client/pages/settings/components/SettingsInput" - -type PipelineWebhookSectionProps = { - values: WebhookValues - isLoading: boolean - isSaving: boolean -} - -export const PipelineWebhookSection: React.FC = ({ - values, - isLoading, - isSaving, -}) => { - const { default: defaultPipelineWebhookUrl, effective: effectivePipelineWebhookUrl } = values - const { register, formState: { errors } } = useFormContext() - - return ( - - - Pipeline Webhook - - -
- -
-
-
- ) -} diff --git a/orchestrator/src/client/pages/settings/components/WebhooksSection.test.tsx b/orchestrator/src/client/pages/settings/components/WebhooksSection.test.tsx new file mode 100644 index 0000000..1547fa2 --- /dev/null +++ b/orchestrator/src/client/pages/settings/components/WebhooksSection.test.tsx @@ -0,0 +1,50 @@ +import { render, screen } from "@testing-library/react" +import { useForm, FormProvider } from "react-hook-form" + +import { Accordion } from "@/components/ui/accordion" +import { WebhooksSection } from "./WebhooksSection" +import { UpdateSettingsInput } from "@shared/settings-schema" + +const WebhooksHarness = () => { + const methods = useForm({ + defaultValues: { + pipelineWebhookUrl: "https://pipeline.com", + jobCompleteWebhookUrl: "https://job.com", + webhookSecret: "", + } + }) + + return ( + + + + + + ) +} + +describe("WebhooksSection", () => { + it("renders both webhook sections and the secret", () => { + render() + + expect(screen.getByText("Pipeline Status")).toBeInTheDocument() + expect(screen.getByText("Job Completion")).toBeInTheDocument() + + expect(screen.getByDisplayValue("https://pipeline.com")).toBeInTheDocument() + expect(screen.getByDisplayValue("https://job.com")).toBeInTheDocument() + + expect(screen.getByText("sec-********")).toBeInTheDocument() + }) +}) diff --git a/orchestrator/src/client/pages/settings/components/WebhooksSection.tsx b/orchestrator/src/client/pages/settings/components/WebhooksSection.tsx new file mode 100644 index 0000000..5c21850 --- /dev/null +++ b/orchestrator/src/client/pages/settings/components/WebhooksSection.tsx @@ -0,0 +1,80 @@ +import React from "react" +import { useFormContext } from "react-hook-form" + +import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" +import { Separator } from "@/components/ui/separator" +import { UpdateSettingsInput } from "@shared/settings-schema" +import type { WebhookValues } from "@client/pages/settings/types" +import { SettingsInput } from "@client/pages/settings/components/SettingsInput" + +type WebhooksSectionProps = { + pipelineWebhook: WebhookValues + jobCompleteWebhook: WebhookValues + webhookSecretHint: string | null + isLoading: boolean + isSaving: boolean +} + +export const WebhooksSection: React.FC = ({ + pipelineWebhook, + jobCompleteWebhook, + webhookSecretHint, + isLoading, + isSaving, +}) => { + const { register, formState: { errors } } = useFormContext() + + const formatSecretHint = (hint: string | null) => (hint ? `${hint}********` : "Not set") + + return ( + + + Webhooks + + +
+
+
Pipeline Status
+ +
+ + + +
+
Job Completion
+
+ + + +
+
+
+
+
+ ) +}