feat: 完善 UI 交互和 mock 数据

- 修复 tab/modal/toolbar CSS class 不匹配问题
- 新增 Modal 弹窗组件替代原生 prompt()
- 补全所有页面的 mock 数据(日志/记忆/MCP)
- 添加 loading 骨架屏动画、按钮 disabled 状态
- 添加搜索高亮 mark 样式
- 修复记忆页面 memory-sidebar/memory-editor 样式
This commit is contained in:
晴天
2026-02-26 22:55:56 +08:00
parent e26c4d9307
commit d32ce81547
6 changed files with 277 additions and 28 deletions

View File

@@ -3,6 +3,7 @@
*/
import { api } from '../lib/tauri-api.js'
import { toast } from '../components/toast.js'
import { showModal } from '../components/modal.js'
export async function render() {
const page = document.createElement('div')
@@ -122,12 +123,20 @@ function editServer(page, state, key) {
}
function addServer(page, state) {
const name = prompt('输入 MCP Server 名称:')
if (!name) return
const target = state.config?.mcpServers || state.config
target[name] = { command: '', args: [], env: {} }
renderServers(page, state)
toast(`已添加 ${name}`, 'success')
showModal({
title: '添加 MCP Server',
fields: [
{ name: 'name', label: 'Server 名称', placeholder: '如 exa, web-reader' },
{ name: 'command', label: '启动命令', placeholder: '如 npx, node' },
],
onConfirm: ({ name, command }) => {
if (!name) return
const target = state.config?.mcpServers || state.config
target[name] = { command: command || '', args: [], env: {} }
renderServers(page, state)
toast(`已添加 ${name}`, 'success')
},
})
}
async function saveConfig(state) {

View File

@@ -3,6 +3,7 @@
*/
import { api } from '../lib/tauri-api.js'
import { toast } from '../components/toast.js'
import { showModal } from '../components/modal.js'
export async function render() {
const page = document.createElement('div')
@@ -109,11 +110,16 @@ function renderProviders(page, state) {
state.config.models.providers[providerKey].models.splice(idx, 1)
renderProviders(page, state)
} else if (action === 'add-model') {
const id = prompt('输入模型 ID:')
if (id) {
state.config.models.providers[providerKey].models.push({ id })
renderProviders(page, state)
}
showModal({
title: '添加模型',
fields: [{ name: 'id', label: '模型 ID', placeholder: '如 claude-opus-4-6' }],
onConfirm: ({ id }) => {
if (id) {
state.config.models.providers[providerKey].models.push({ id })
renderProviders(page, state)
}
},
})
}
}
})
@@ -128,13 +134,29 @@ function renderProviders(page, state) {
}
function addProvider(page, state) {
const key = prompt('输入 Provider 名称 (如 openai, newapi):')
if (!key) return
if (!state.config.models) state.config.models = { mode: 'replace', providers: {} }
if (!state.config.models.providers) state.config.models.providers = {}
state.config.models.providers[key] = { baseUrl: '', apiType: 'openai', models: [] }
renderProviders(page, state)
toast(`已添加 ${key}`, 'success')
showModal({
title: '添加 Provider',
fields: [
{ name: 'key', label: 'Provider 名称', placeholder: '如 openai, newapi' },
{ name: 'baseUrl', label: 'Base URL', placeholder: 'https://api.openai.com/v1' },
{
name: 'apiType', label: 'API 类型', type: 'select',
options: [
{ value: 'openai', label: 'OpenAI' },
{ value: 'anthropic', label: 'Anthropic' },
{ value: 'google', label: 'Google' },
],
},
],
onConfirm: ({ key, baseUrl, apiType }) => {
if (!key) return
if (!state.config.models) state.config.models = { mode: 'replace', providers: {} }
if (!state.config.models.providers) state.config.models.providers = {}
state.config.models.providers[key] = { baseUrl, apiType, models: [] }
renderProviders(page, state)
toast(`已添加 ${key}`, 'success')
},
})
}
async function saveConfig(state) {