You've already forked agentic-coding-workflow
feat(web): AgentKindForm component (Naive UI form with env editor)
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { NInput, NButton, NCheckbox } from 'naive-ui'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: {
|
||||
name: string
|
||||
display_name: string
|
||||
description: string
|
||||
binary_path: string
|
||||
args: string[]
|
||||
env: Record<string, string>
|
||||
enabled: boolean
|
||||
}
|
||||
isEdit: boolean
|
||||
existingEnvKeys?: string[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: typeof props.modelValue): void
|
||||
(e: 'submit'): void
|
||||
(e: 'cancel'): void
|
||||
}>()
|
||||
|
||||
const local = ref({ ...props.modelValue })
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
local.value = { ...v }
|
||||
},
|
||||
)
|
||||
watch(local, (v) => emit('update:modelValue', v), { deep: true })
|
||||
|
||||
const argsText = computed({
|
||||
get: () => local.value.args.join('\n'),
|
||||
set: (v: string) => {
|
||||
local.value.args = v.split('\n').filter((x) => x.trim() !== '')
|
||||
},
|
||||
})
|
||||
|
||||
interface EnvRow {
|
||||
k: string
|
||||
v: string
|
||||
}
|
||||
const envEntries = ref<EnvRow[]>(
|
||||
Object.entries(local.value.env).map(([k, v]) => ({ k, v })),
|
||||
)
|
||||
|
||||
watch(
|
||||
envEntries,
|
||||
(entries) => {
|
||||
const m: Record<string, string> = {}
|
||||
for (const { k, v } of entries) {
|
||||
if (k.trim()) m[k] = v
|
||||
}
|
||||
local.value.env = m
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
function addEnv() {
|
||||
envEntries.value.push({ k: '', v: '' })
|
||||
}
|
||||
function removeEnv(idx: number) {
|
||||
envEntries.value.splice(idx, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form
|
||||
class="space-y-4"
|
||||
@submit.prevent="emit('submit')"
|
||||
>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Name</label>
|
||||
<NInput
|
||||
v-model:value="local.name"
|
||||
:readonly="isEdit"
|
||||
placeholder="claude_code"
|
||||
/>
|
||||
<p
|
||||
v-if="isEdit"
|
||||
class="text-xs text-gray-500 mt-1"
|
||||
>
|
||||
Name cannot be changed after creation
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Display Name</label>
|
||||
<NInput
|
||||
v-model:value="local.display_name"
|
||||
placeholder="Claude Code"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Description</label>
|
||||
<NInput
|
||||
v-model:value="local.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Binary Path</label>
|
||||
<NInput
|
||||
v-model:value="local.binary_path"
|
||||
placeholder="claude-code or /usr/local/bin/claude-code"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Args (one per line)</label>
|
||||
<NInput
|
||||
v-model:value="argsText"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 8 }"
|
||||
placeholder="--acp"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Env</label>
|
||||
<p
|
||||
v-if="isEdit && existingEnvKeys?.length"
|
||||
class="text-xs text-gray-500 mb-2"
|
||||
>
|
||||
Existing keys (values hidden): {{ existingEnvKeys.join(', ') }}.
|
||||
Edit below to replace entirely.
|
||||
</p>
|
||||
<div
|
||||
v-for="(e, idx) in envEntries"
|
||||
:key="idx"
|
||||
class="flex gap-2 mb-2"
|
||||
>
|
||||
<NInput
|
||||
v-model:value="e.k"
|
||||
placeholder="KEY"
|
||||
class="flex-1"
|
||||
/>
|
||||
<NInput
|
||||
v-model:value="e.v"
|
||||
type="password"
|
||||
show-password-on="click"
|
||||
placeholder="value"
|
||||
class="flex-1"
|
||||
/>
|
||||
<NButton
|
||||
quaternary
|
||||
@click="removeEnv(idx)"
|
||||
>
|
||||
×
|
||||
</NButton>
|
||||
</div>
|
||||
<NButton
|
||||
size="small"
|
||||
dashed
|
||||
@click="addEnv"
|
||||
>
|
||||
+ Add
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<NCheckbox v-model:checked="local.enabled">
|
||||
Enabled
|
||||
</NCheckbox>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<NButton
|
||||
type="primary"
|
||||
attr-type="submit"
|
||||
>
|
||||
Save
|
||||
</NButton>
|
||||
<NButton @click="emit('cancel')">
|
||||
Cancel
|
||||
</NButton>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
Reference in New Issue
Block a user