import { useState } from "react"; import { useAtomValue, useAtomSet, Result } from "@effect-atom/atom-react"; import { graphqlSourceAtom, updateGraphqlSource } from "./atoms"; import { useScope } from "@executor/react/api/scope-context"; import { sourceWriteKeys } from "@executor/react/api/reactivity-keys"; import { useSecretPickerSecrets } from "@executor/react/plugins/use-secret-picker-secrets"; import { headerValueToState, headersFromState, type HeaderState, } from "@executor/react/plugins/secret-header-auth"; import { HeadersList } from "@executor/react/plugins/headers-list"; import { SourceIdentityFields, useSourceIdentity, } from "@executor/react/plugins/source-identity"; import { Button } from "@executor/react/components/button"; import { CardStack, CardStackContent, CardStackEntryField, } from "@executor/react/components/card-stack"; import { FieldLabel } from "@executor/react/components/field"; import { Input } from "@executor/react/components/input"; import { Badge } from "@executor/react/components/badge"; import type { StoredGraphqlSource } from "../sdk/store"; // --------------------------------------------------------------------------- // Edit form // --------------------------------------------------------------------------- function EditForm(props: { sourceId: string; initial: StoredGraphqlSource; onSave: () => void; }) { const scopeId = useScope(); const doUpdate = useAtomSet(updateGraphqlSource, { mode: "promise" }); const secretList = useSecretPickerSecrets(); const identity = useSourceIdentity({ fallbackName: props.initial.name, fallbackNamespace: props.initial.namespace, }); const [endpoint, setEndpoint] = useState(props.initial.endpoint); const [headers, setHeaders] = useState(() => Object.entries(props.initial.headers ?? {}).map(([name, value]) => headerValueToState(name, value), ), ); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [dirty, setDirty] = useState(false); const identityDirty = identity.name.trim() !== props.initial.name.trim(); const handleHeadersChange = (next: HeaderState[]) => { setHeaders(next); setDirty(true); }; const handleSave = async () => { setSaving(true); setError(null); try { await doUpdate({ path: { scopeId, namespace: props.sourceId }, payload: { name: identity.name.trim() || undefined, endpoint: endpoint.trim() || undefined, headers: headersFromState(headers), }, reactivityKeys: sourceWriteKeys, }); setDirty(false); props.onSave(); } catch (e) { setError(e instanceof Error ? e.message : "Failed to update source"); } finally { setSaving(false); } }; return (

Edit GraphQL Source

Update the endpoint and authentication headers for this source.

{props.sourceId}

GraphQL
{ setEndpoint((e.target as HTMLInputElement).value); setDirty(true); }} placeholder="https://api.example.com/graphql" className="font-mono text-sm" />
Headers
{error && (

{error}

)}
); } // --------------------------------------------------------------------------- // Main component // --------------------------------------------------------------------------- export default function EditGraphqlSource(props: { sourceId: string; onSave: () => void }) { const scopeId = useScope(); const sourceResult = useAtomValue(graphqlSourceAtom(scopeId, props.sourceId)); if (!Result.isSuccess(sourceResult) || !sourceResult.value) { return (

Edit GraphQL Source

Loading configuration…

); } return ; }