@@ -54,7 +54,7 @@ const interactiveValue = ref(false)
id="sizes"
title="Different Contexts"
>
-
+
diff --git a/packages/stage-ui/src/components/Form/Field/FieldCheckbox.story.vue b/packages/stage-ui/src/components/Form/Field/FieldCheckbox.story.vue
index 7b72c13ac..ca62fe907 100644
--- a/packages/stage-ui/src/components/Form/Field/FieldCheckbox.story.vue
+++ b/packages/stage-ui/src/components/Form/Field/FieldCheckbox.story.vue
@@ -21,7 +21,7 @@ const uncheckedValue = ref(false)
id="checked"
title="Checked"
>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+import { reactive, watch } from 'vue'
+
+import FieldKeyValues from './FieldKeyValues.vue'
+
+const emptyHeaders = reactive<{ key: string, value: string }[]>([
+ { key: '', value: '' },
+])
+const singleHeader = reactive<{ key: string, value: string }[]>([
+ { key: 'Content-Type', value: 'application/json' },
+])
+const multipleHeaders = reactive<{ key: string, value: string }[]>([
+ { key: 'Authorization', value: 'Bearer token123' },
+ { key: 'Accept', value: 'application/json' },
+ { key: 'X-API-Key', value: 'abc123xyz456' },
+])
+
+function addKeyValue(headers: { key: string, value: string }[], key: string, value: string) {
+ if (!headers)
+ return
+
+ headers.push({ key, value })
+}
+
+function removeKeyValue(index: number, headers: { key: string, value: string }[]) {
+ if (!headers)
+ return
+
+ if (headers.length === 1) {
+ headers[0].key = ''
+ headers[0].value = ''
+ }
+ else {
+ headers.splice(index, 1)
+ }
+}
+
+watch(emptyHeaders, (headers) => {
+ if (headers.length > 0 && (headers[headers.length - 1].key !== '' || headers[headers.length - 1].value !== '')) {
+ emptyHeaders.push({ key: '', value: '' })
+ }
+}, {
+ deep: true,
+ immediate: true,
+})
+
+watch(singleHeader, (headers) => {
+ if (headers.length > 0 && (headers[headers.length - 1].key !== '' || headers[headers.length - 1].value !== '')) {
+ singleHeader.push({ key: '', value: '' })
+ }
+}, {
+ deep: true,
+ immediate: true,
+})
+
+watch(multipleHeaders, (headers) => {
+ if (headers.length > 0 && (headers[headers.length - 1].key !== '' || headers[headers.length - 1].value !== '')) {
+ multipleHeaders.push({ key: '', value: '' })
+ }
+}, {
+ deep: true,
+ immediate: true,
+})
+
+
+
+
+
+
+
+
+
+
+ addKeyValue(emptyHeaders, key, value)"
+ @remove="(index) => removeKeyValue(index, emptyHeaders)"
+ />
+
+
+
+
+
+
+
+
+
+ addKeyValue(emptyHeaders, key, value)"
+ @remove="(index) => removeKeyValue(index, emptyHeaders)"
+ />
+
+
+
+
+
+ addKeyValue(emptyHeaders, key, value)"
+ @remove="(index) => removeKeyValue(index, emptyHeaders)"
+ />
+
+
+
+
+
+ addKeyValue(emptyHeaders, key, value)"
+ @remove="(index) => removeKeyValue(index, emptyHeaders)"
+ />
+
+
+
+
diff --git a/packages/stage-ui/src/components/Form/Field/FieldKeyValues.vue b/packages/stage-ui/src/components/Form/Field/FieldKeyValues.vue
new file mode 100644
index 000000000..65b4cb350
--- /dev/null
+++ b/packages/stage-ui/src/components/Form/Field/FieldKeyValues.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
diff --git a/packages/stage-ui/src/components/Form/Field/FieldRange.story.vue b/packages/stage-ui/src/components/Form/Field/FieldRange.story.vue
index 27071e629..a337618e2 100644
--- a/packages/stage-ui/src/components/Form/Field/FieldRange.story.vue
+++ b/packages/stage-ui/src/components/Form/Field/FieldRange.story.vue
@@ -27,7 +27,7 @@ function formatPercentage(value: number): string {
id="default-min"
title="Default (min)"
>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+import Input from './Input.vue'
+
+const props = defineProps<{
+ name?: string
+ keyPlaceholder?: string
+ valuePlaceholder?: string
+}>()
+
+const key = defineModel
('propertyKey', { required: true })
+const value = defineModel('propertyValue', { required: true })
+
+
+
+
+
+
+
+
diff --git a/packages/stage-ui/src/components/Form/Input/index.ts b/packages/stage-ui/src/components/Form/Input/index.ts
index a691dd6c1..30da630e1 100644
--- a/packages/stage-ui/src/components/Form/Input/index.ts
+++ b/packages/stage-ui/src/components/Form/Input/index.ts
@@ -1 +1,2 @@
export { default as Input } from './Input.vue'
+export { default as InputKeyValue } from './InputKeyValue.vue'
diff --git a/packages/stage-ui/src/components/Providers/ProviderAccountIdInput.story.vue b/packages/stage-ui/src/components/Providers/ProviderAccountIdInput.story.vue
index 059111e3b..d9e5d9c20 100644
--- a/packages/stage-ui/src/components/Providers/ProviderAccountIdInput.story.vue
+++ b/packages/stage-ui/src/components/Providers/ProviderAccountIdInput.story.vue
@@ -21,7 +21,7 @@ const filledAccountId = ref('1234567890abcdef1234567890abcdef')
id="empty"
title="Empty"
>
-
+
-
+
-
+
-
+
-
+
Advanced settings content (initially hidden)
@@ -29,7 +29,7 @@ import ProviderAdvancedSettings from './ProviderAdvancedSettings.vue'
id="expanded"
title="Expanded"
>
-
+
Advanced settings content (initially visible)
@@ -42,7 +42,7 @@ import ProviderAdvancedSettings from './ProviderAdvancedSettings.vue'
id="custom-title"
title="Custom Title"
>
-
+
Expert settings content
diff --git a/packages/stage-ui/src/components/Providers/ProviderApiKeyInput.story.vue b/packages/stage-ui/src/components/Providers/ProviderApiKeyInput.story.vue
index 16b3669fd..b2b216904 100644
--- a/packages/stage-ui/src/components/Providers/ProviderApiKeyInput.story.vue
+++ b/packages/stage-ui/src/components/Providers/ProviderApiKeyInput.story.vue
@@ -21,7 +21,7 @@ const filledApiKey = ref('sk-1234567890abcdefghijklmnopqrstuvwxyz')
id="empty"
title="Empty"
>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
Settings content goes here
@@ -29,7 +29,7 @@ import ProviderBasicSettings from './ProviderBasicSettings.vue'
id="with-title-description"
title="With Title & Description"
>
-
+
-
+
-
+
Container content goes here
@@ -31,7 +31,7 @@ import ProviderSettingsContainer from './ProviderSettingsContainer.vue'
id="with-sections"
title="With Sections"
>
-
+
-
+
Provider settings content goes here
@@ -29,7 +29,7 @@ import ProviderSettingsLayout from './ProviderSettingsLayout.vue'
id="with-icon"
title="With Icon"
>
-
+
@@ -44,7 +44,7 @@ import ProviderSettingsLayout from './ProviderSettingsLayout.vue'
id="with-icon-color"
title="With Icon Color"
>
-
+
diff --git a/packages/stage-ui/src/stores/providers.ts b/packages/stage-ui/src/stores/providers.ts
index 339a0c957..14f048d06 100644
--- a/packages/stage-ui/src/stores/providers.ts
+++ b/packages/stage-ui/src/stores/providers.ts
@@ -161,8 +161,8 @@ export const useProvidersStore = defineStore('providers', () => {
},
},
},
- 'ollama-ai': {
- id: 'ollama-ai',
+ 'ollama': {
+ id: 'ollama',
nameKey: 'providers.ollama.name',
name: 'Ollama',
descriptionKey: 'providers.ollama.description',
@@ -180,7 +180,7 @@ export const useProvidersStore = defineStore('providers', () => {
return {
id: model.id,
name: model.id,
- provider: 'ollama-ai',
+ provider: 'ollama',
description: '',
contextLength: 0,
deprecated: false,
@@ -538,7 +538,7 @@ export const useProvidersStore = defineStore('providers', () => {
return !!config.apiKey && !!config.baseUrl
case 'openai':
return !!config.apiKey
- case 'ollama-ai':
+ case 'ollama':
return !!config.baseUrl
case 'vllm':
return !!config.baseUrl
diff --git a/packages/stage-ui/stories/setup.ts b/packages/stage-ui/stories/setup.ts
index c08a5fa03..95c04c0f4 100644
--- a/packages/stage-ui/stories/setup.ts
+++ b/packages/stage-ui/stories/setup.ts
@@ -1,4 +1,6 @@
+import { autoAnimatePlugin } from '@formkit/auto-animate/vue'
import { defineSetupVue3 } from '@histoire/plugin-vue'
+import { MotionPlugin } from '@vueuse/motion'
import ThemeColorsHueControl from './ThemeColorsHueControl.vue'
@@ -7,5 +9,8 @@ import '@unocss/reset/tailwind.css'
import './main.css'
export const setupVue3 = defineSetupVue3(({ app }) => {
+ app.use(MotionPlugin)
+ app.use(autoAnimatePlugin)
+
app.component('ThemeColorsHueControl', ThemeColorsHueControl)
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e664b8c10..f02df8bfc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1053,9 +1053,15 @@ importers:
packages/stage-ui:
dependencies:
+ '@vueuse/motion':
+ specifier: ^3.0.3
+ version: 3.0.3(magicast@0.3.5)(rollup@4.35.0)(vue@3.5.13(typescript@5.8.2))
reka-ui:
specifier: ^2.1.0
version: 2.1.0(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))
+ vue:
+ specifier: link:@formkit/auto-animate/vue
+ version: 3.5.13(typescript@5.8.2)
devDependencies:
'@electron-toolkit/preload':
specifier: ^3.0.1