-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: edit model and extensions of a recipe from GUI #6804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3edd124
76c1a60
f7df78f
db5aa33
581219b
a3b6d5a
9de44a6
2d101a6
345750e
cc5888e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| import { useState } from 'react'; | ||
| import { ExtensionConfig } from '../../../api'; | ||
| import { useConfig } from '../../ConfigContext'; | ||
| import { Input } from '../../ui/input'; | ||
| import { Switch } from '../../ui/switch'; | ||
| import { formatExtensionName } from '../../settings/extensions/subcomponents/ExtensionList'; | ||
|
|
||
| interface RecipeExtensionSelectorProps { | ||
| selectedExtensions: ExtensionConfig[]; | ||
| onExtensionsChange: (extensions: ExtensionConfig[]) => void; | ||
| } | ||
|
|
||
| export const RecipeExtensionSelector = ({ | ||
| selectedExtensions, | ||
| onExtensionsChange, | ||
| }: RecipeExtensionSelectorProps) => { | ||
| const { extensionsList: allExtensions } = useConfig(); | ||
| const [searchQuery, setSearchQuery] = useState(''); | ||
|
|
||
| const selectedExtensionNames = new Set(selectedExtensions.map((ext) => ext.name)); | ||
|
|
||
| const extensionMap = new Map(allExtensions.map((ext) => [ext.name, ext])); | ||
|
|
||
| selectedExtensions.forEach((ext) => { | ||
| if (!extensionMap.has(ext.name)) { | ||
| extensionMap.set(ext.name, { ...ext, enabled: true }); | ||
| } | ||
| }); | ||
|
|
||
| const displayExtensions = Array.from(extensionMap.values()); | ||
|
|
||
| const handleToggle = (extensionConfig: ExtensionConfig) => { | ||
| const isSelected = selectedExtensionNames.has(extensionConfig.name); | ||
|
|
||
| if (isSelected) { | ||
| onExtensionsChange(selectedExtensions.filter((ext) => ext.name !== extensionConfig.name)); | ||
| } else { | ||
| const { enabled: _enabled, ...cleanExtension } = extensionConfig as ExtensionConfig & { | ||
| enabled?: boolean; | ||
| }; | ||
| onExtensionsChange([...selectedExtensions, cleanExtension]); | ||
| } | ||
| }; | ||
|
|
||
| const filteredExtensions = displayExtensions.filter((ext) => { | ||
| const query = searchQuery.toLowerCase(); | ||
| return ( | ||
| ext.name.toLowerCase().includes(query) || | ||
| (ext.description && ext.description.toLowerCase().includes(query)) | ||
| ); | ||
| }); | ||
|
|
||
| const sortedExtensions = [...filteredExtensions].sort((a, b) => { | ||
| const aSelected = selectedExtensionNames.has(a.name); | ||
| const bSelected = selectedExtensionNames.has(b.name); | ||
|
|
||
| if (aSelected !== bSelected) return aSelected ? -1 : 1; | ||
|
|
||
| return a.name.localeCompare(b.name); | ||
| }); | ||
|
|
||
| const activeCount = selectedExtensions.length; | ||
|
|
||
| return ( | ||
| <div className="space-y-4"> | ||
| <div> | ||
| <label className="block text-md text-textProminent mb-2 font-bold"> | ||
| Extensions (Optional) | ||
| </label> | ||
| <p className="text-textSubtle text-sm mb-4"> | ||
| Select which extensions should be available when running this recipe. Leave empty to use | ||
| default extensions. | ||
| </p> | ||
|
|
||
| <Input | ||
| type="text" | ||
| placeholder="Search extensions..." | ||
| value={searchQuery} | ||
| onChange={(e) => setSearchQuery(e.target.value)} | ||
| className="mb-3" | ||
| /> | ||
|
|
||
| <p className="text-xs text-textSubtle mb-3 text-right"> | ||
| {activeCount} extension{activeCount !== 1 ? 's' : ''} selected | ||
| </p> | ||
| </div> | ||
|
|
||
| <div className="max-h-[300px] overflow-y-auto border border-borderSubtle rounded-lg"> | ||
| {sortedExtensions.length === 0 ? ( | ||
| <div className="px-4 py-6 text-center text-sm text-textSubtle"> | ||
| {searchQuery ? 'No extensions found' : 'No extensions available'} | ||
| </div> | ||
| ) : ( | ||
| sortedExtensions.map((ext) => { | ||
| const isSelected = selectedExtensionNames.has(ext.name); | ||
| return ( | ||
| <div | ||
| key={ext.name} | ||
| className="flex items-center justify-between px-4 py-3 hover:bg-bgSubtle transition-colors cursor-pointer border-b border-borderSubtle last:border-b-0" | ||
| role="button" | ||
| tabIndex={0} | ||
| aria-pressed={isSelected} | ||
| onClick={() => handleToggle(ext)} | ||
| onKeyDown={(event) => { | ||
| if (event.key === 'Enter' || event.key === ' ') { | ||
| event.preventDefault(); | ||
| handleToggle(ext); | ||
| } | ||
| }} | ||
| title={ext.description || ext.name} | ||
| > | ||
| <div className="flex-1 min-w-0"> | ||
| <div className="text-sm font-medium text-textStandard"> | ||
| {formatExtensionName(ext.name)} | ||
| </div> | ||
| {ext.description && ( | ||
| <div className="text-xs text-textSubtle truncate mt-1">{ext.description}</div> | ||
| )} | ||
| </div> | ||
| <div onClick={(e) => e.stopPropagation()} className="ml-4"> | ||
| <Switch | ||
| checked={isSelected} | ||
| onCheckedChange={() => handleToggle(ext)} | ||
| variant="mono" | ||
| /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }) | ||
| )} | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import React, { useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Parameter } from '../../../recipe'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ChevronDown } from 'lucide-react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ExtensionConfig } from '../../../api'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ParameterInput from '../../parameter/ParameterInput'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import RecipeActivityEditor from '../RecipeActivityEditor'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -9,6 +10,8 @@ import InstructionsEditor from './InstructionsEditor'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Button } from '../../ui/button'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../../ui/collapsible'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { RecipeFormApi, RecipeFormData } from './recipeFormSchema'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { RecipeModelSelector } from './RecipeModelSelector'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { RecipeExtensionSelector } from './RecipeExtensionSelector'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Type for field API to avoid linting issues - use any to bypass complex type constraints | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -149,7 +152,12 @@ export function RecipeFormFields({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasActivities = Boolean(values.activities && values.activities.length > 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasParameters = Boolean(values.parameters && values.parameters.length > 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasJsonSchema = Boolean(values.jsonSchema && values.jsonSchema.trim()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return hasActivities || hasParameters || hasJsonSchema; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasModel = Boolean(values.model && values.model.trim()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasProvider = Boolean(values.provider && values.provider.trim()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasExtensions = Boolean(values.extensions && values.extensions.length > 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hasActivities || hasParameters || hasJsonSchema || hasModel || hasProvider || hasExtensions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [advancedOpen, setAdvancedOpen] = useState(() => checkHasAdvancedData(form.state.values)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -324,8 +332,10 @@ export function RecipeFormFields({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| advancedOpen ? 'rotate-0' : '-rotate-90' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-sm font-medium text-text-default">Advanced Options</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-xs text-text-muted">Activities, parameters, response schema</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-sm font-medium text-textStandard">Advanced Options</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="text-xs text-textSubtle"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Activities, parameters, model, extensions, response schema | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </CollapsibleTrigger> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <CollapsibleContent className="mt-4 space-y-4 pl-6 border-l-2 border-border-default ml-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -460,6 +470,34 @@ export function RecipeFormFields({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form.Field> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* Model and Provider Fields */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form.Field name="provider"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {(providerField: FormFieldApi<string | undefined>) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form.Field name="model"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {(modelField: FormFieldApi<string | undefined>) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <RecipeModelSelector | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| selectedProvider={providerField.state.value} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| selectedModel={modelField.state.value} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onProviderChange={(provider) => providerField.handleChange(provider)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onModelChange={(model) => modelField.handleChange(model)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form.Field> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form.Field> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* Extensions Field */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form.Field name="extensions"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {(field: FormFieldApi<ExtensionConfig[] | undefined>) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <RecipeExtensionSelector | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| selectedExtensions={field.state.value || []} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onExtensionsChange={(extensions) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| field.handleChange(extensions.length > 0 ? extensions : undefined) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form.Field> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+474
to
+499
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form.Field name="provider"> | |
| {(providerField: FormFieldApi<string | undefined>) => ( | |
| <form.Field name="model"> | |
| {(modelField: FormFieldApi<string | undefined>) => ( | |
| <RecipeModelSelector | |
| selectedProvider={providerField.state.value} | |
| selectedModel={modelField.state.value} | |
| onProviderChange={(provider) => providerField.handleChange(provider)} | |
| onModelChange={(model) => modelField.handleChange(model)} | |
| /> | |
| )} | |
| </form.Field> | |
| )} | |
| </form.Field> | |
| {/* Extensions Field */} | |
| <form.Field name="extensions"> | |
| {(field: FormFieldApi<ExtensionConfig[] | undefined>) => ( | |
| <RecipeExtensionSelector | |
| selectedExtensions={field.state.value || []} | |
| onExtensionsChange={(extensions) => | |
| field.handleChange(extensions.length > 0 ? extensions : undefined) | |
| } | |
| /> | |
| )} | |
| </form.Field> | |
| {(() => { | |
| const values = (form as any)?.state?.values ?? {}; | |
| const showProviderModelFields = 'provider' in values || 'model' in values; | |
| if (!showProviderModelFields) { | |
| return null; | |
| } | |
| return ( | |
| <form.Field name="provider"> | |
| {(providerField: FormFieldApi<string | undefined>) => ( | |
| <form.Field name="model"> | |
| {(modelField: FormFieldApi<string | undefined>) => ( | |
| <RecipeModelSelector | |
| selectedProvider={providerField.state.value} | |
| selectedModel={modelField.state.value} | |
| onProviderChange={(provider) => providerField.handleChange(provider)} | |
| onModelChange={(model) => modelField.handleChange(model)} | |
| /> | |
| )} | |
| </form.Field> | |
| )} | |
| </form.Field> | |
| ); | |
| })()} | |
| {/* Extensions Field */} | |
| {(() => { | |
| const values = (form as any)?.state?.values ?? {}; | |
| const showExtensionsField = 'extensions' in values; | |
| if (!showExtensionsField) { | |
| return null; | |
| } | |
| return ( | |
| <form.Field name="extensions"> | |
| {(field: FormFieldApi<ExtensionConfig[] | undefined>) => ( | |
| <RecipeExtensionSelector | |
| selectedExtensions={field.state.value || []} | |
| onExtensionsChange={(extensions) => | |
| field.handleChange(extensions.length > 0 ? extensions : undefined) | |
| } | |
| /> | |
| )} | |
| </form.Field> | |
| ); | |
| })()} |
Uh oh!
There was an error while loading. Please reload this page.