From e11c3d1c065b6214cad9bf285b258de4af44ad3d Mon Sep 17 00:00:00 2001 From: RemiBonnet Date: Wed, 5 Aug 2026 10:20:00 +0200 Subject: [PATCH] fix(agentic-workflow): use semantic layout components --- .../agentic-workflow-configuration.tsx | 630 +++++++++--------- 1 file changed, 319 insertions(+), 311 deletions(-) diff --git a/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx b/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx index fa4db11099b..2494f20cf56 100644 --- a/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx +++ b/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx @@ -1,7 +1,17 @@ import { type IconName } from '@fortawesome/fontawesome-common-types' import { useNavigate } from '@tanstack/react-router' import { type ReactNode, useEffect, useRef } from 'react' -import { Button, CodeEditor, FunnelFlowBody, Icon, InputText, InputTextArea, InputToggle } from '@qovery/shared/ui' +import { + Button, + CodeEditor, + FunnelFlowBody, + Heading, + Icon, + InputText, + InputTextArea, + InputToggle, + Section, +} from '@qovery/shared/ui' import { type AgenticWorkflowConfigurationSection, type AgenticWorkflowGitRepository, @@ -89,11 +99,7 @@ function AgenticWorkflowSection({ <>
-

- {title} -

+ {title}
{showStatus && @@ -107,7 +113,7 @@ function AgenticWorkflowSection({ ) return ( -
+
{active ? (
{headerContent} @@ -124,7 +130,7 @@ function AgenticWorkflowSection({ )} {active &&
{children}
} -
+
) } @@ -281,327 +287,329 @@ export function AgenticWorkflowConfiguration() { return ( -
-

Create agentic workflow

-

- Configure the inputs, tools, model, governance, and outputs used by your workflow. -

-
+
+
+ Create agentic workflow +

+ Configure the inputs, tools, model, governance, and outputs used by your workflow. +

+
-
- - form.setValue('name', event.currentTarget.value, { shouldDirty: true })} - /> - form.setValue('description', event.currentTarget.value, { shouldDirty: true })} - /> -
+
+ form.setValue('cpu', event.currentTarget.value, { shouldDirty: true })} + name="name" + label="Name" + value={values.name} + autoFocus + error={showNameError ? 'Please enter a workflow name.' : undefined} + onChange={(event) => form.setValue('name', event.currentTarget.value, { shouldDirty: true })} /> - form.setValue('memory', event.currentTarget.value, { shouldDirty: true })} + form.setValue('description', event.currentTarget.value, { shouldDirty: true })} /> +
+ form.setValue('cpu', event.currentTarget.value, { shouldDirty: true })} + /> + form.setValue('memory', event.currentTarget.value, { shouldDirty: true })} + /> + form.setValue('storage', event.currentTarget.value, { shouldDirty: true })} + /> +
+ form.setValue('workflowEnabled', value, { shouldDirty: true })} + /> + +
+ + + form.setValue('storage', event.currentTarget.value, { shouldDirty: true })} + ref={modelApiKeyInputRef} + name="model-api-key" + label="API key" + type="password" + value={values.modelApiKey} + hint="API key used to call the selected cloud model." + error={showModelApiKeyError ? 'Please enter an API key.' : undefined} + onChange={(event) => form.setValue('modelApiKey', event.currentTarget.value, { shouldDirty: true })} /> -
- form.setValue('workflowEnabled', value, { shouldDirty: true })} - /> - - + + Need help configuring Claude Code settings? Read the{' '} + + Claude Code settings documentation + + . + + } + onChange={(value) => form.setValue('modelSettingsJson', value, { shouldDirty: true })} + /> + + - - - form.setValue('modelApiKey', event.currentTarget.value, { shouldDirty: true })} - /> - - Need help configuring Claude Code settings? Read the{' '} - - Claude Code settings documentation - - . - - } - onChange={(value) => form.setValue('modelSettingsJson', value, { shouldDirty: true })} - /> - - + + + See Claude Code docs for{' '} + + remote HTTP + {' '} + and{' '} + + local stdio + {' '} + servers. + + } + onChange={(value) => form.setValue('mcpJson', value, { shouldDirty: true })} + /> + + - - - See Claude Code docs for{' '} - - remote HTTP - {' '} - and{' '} - - local stdio - {' '} - servers. - + + + Add repository + } - onChange={(value) => form.setValue('mcpJson', value, { shouldDirty: true })} - /> - - + > + {values.gitRepositories.map((repository, index) => ( + { + const gitRepositories = [...values.gitRepositories] + gitRepositories[index] = nextRepository + form.setValue('gitRepositories', gitRepositories, { shouldDirty: true }) + }} + onRemove={() => + form.setValue( + 'gitRepositories', + values.gitRepositories.filter((_, repositoryIndex) => repositoryIndex !== index), + { shouldDirty: true } + ) + } + /> + ))} + {!gitRepositoriesValid && ( +

+ Select a Git account, repository, and branch for each repository. +

+ )} + +
- - - Add repository - - } - > - {values.gitRepositories.map((repository, index) => ( - { - const gitRepositories = [...values.gitRepositories] - gitRepositories[index] = nextRepository - form.setValue('gitRepositories', gitRepositories, { shouldDirty: true }) - }} - onRemove={() => - form.setValue( - 'gitRepositories', - values.gitRepositories.filter((_, repositoryIndex) => repositoryIndex !== index), - { shouldDirty: true } - ) - } + + form.setValue('whitelistHosts', event.currentTarget.value, { shouldDirty: true })} /> - ))} - {!gitRepositoriesValid && ( -

- Select a Git account, repository, and branch for each repository. -

- )} - -
+ +
- - form.setValue('whitelistHosts', event.currentTarget.value, { shouldDirty: true })} - /> - - + + form.setValue('dockerFragment', value, { shouldDirty: true })} + /> + + - - form.setValue('dockerFragment', value, { shouldDirty: true })} - /> - - + + + Add webhook + + } + > + {values.outputs.map((output, index) => ( +
+
+ Webhook {index + 1} + +
+
+ { + const outputs = [...values.outputs] + outputs[index] = { ...output, url: event.currentTarget.value } + form.setValue('outputs', outputs, { shouldDirty: true }) + }} + /> + { + const outputs = [...values.outputs] + outputs[index] = { ...output, headersJson: value } + form.setValue('outputs', outputs, { shouldDirty: true }) + }} + /> + { + const outputs = [...values.outputs] + outputs[index] = { ...output, prompt: event.currentTarget.value } + form.setValue('outputs', outputs, { shouldDirty: true }) + }} + /> +
+
+ ))} + {!outputsValid && ( +

+ Enter a webhook URL for each configured output webhook. +

+ )} + +
- + form.setValue('agentPrompt', event.currentTarget.value, { shouldDirty: true })} + /> + + +
+ +
+ +
) }