重构: tool_registry拆分及多批改进
This commit is contained in:
@@ -9,6 +9,12 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 错误条:消费 store.error(加载/创建/删除失败对用户可见,对齐 Knowledge error-banner) -->
|
||||
<div v-if="store.error" class="error-banner">
|
||||
<span class="error-text">{{ store.error }}</span>
|
||||
<button class="error-dismiss" @click="store.clearError()">✕</button>
|
||||
</div>
|
||||
|
||||
<!-- 新建项目模态框 -->
|
||||
<div v-if="showCreateModal" class="modal-overlay" @click.self="showCreateModal = false">
|
||||
<div class="modal-box">
|
||||
@@ -42,7 +48,7 @@
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-ghost" @click="showCreateModal = false">{{ $t('common.cancel') }}</button>
|
||||
<button class="btn btn-primary" @click="submitCreate" :disabled="!newName.trim()">{{ $t('projects.confirmCreate') }}</button>
|
||||
<button class="btn btn-primary" @click="submitCreate" :disabled="submitting || !newName.trim()">{{ $t('projects.confirmCreate') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -215,6 +221,8 @@ const pathWarning = ref('')
|
||||
const scanning = ref(false)
|
||||
const scanError = ref('')
|
||||
const scanProjectType = ref('')
|
||||
// 创建提交中(防双击重复提交,对齐 ProviderPanel.saving 模式)
|
||||
const submitting = ref(false)
|
||||
|
||||
// 选择目录 → 探测技术栈 + 查重
|
||||
async function pickDir() {
|
||||
@@ -267,13 +275,19 @@ async function aiScan() {
|
||||
async function submitCreate() {
|
||||
if (!newName.value.trim()) return
|
||||
if (pathWarning.value) return // 目录冲突,禁止创建
|
||||
const stack = detectedStack.value.length ? JSON.stringify(detectedStack.value) : undefined
|
||||
const r = await store.createProject(newName.value.trim(), newDesc.value.trim(), undefined, newPath.value || undefined, stack)
|
||||
if (!r) return // 失败已 toast,保持弹窗不关
|
||||
showCreateModal.value = false
|
||||
newName.value = ''
|
||||
newDesc.value = ''
|
||||
clearDir()
|
||||
if (submitting.value) return // 防双击重复提交
|
||||
submitting.value = true
|
||||
try {
|
||||
const stack = detectedStack.value.length ? JSON.stringify(detectedStack.value) : undefined
|
||||
const r = await store.createProject(newName.value.trim(), newDesc.value.trim(), undefined, newPath.value || undefined, stack)
|
||||
if (!r) return // 失败已 toast,保持弹窗不关
|
||||
showCreateModal.value = false
|
||||
newName.value = ''
|
||||
newDesc.value = ''
|
||||
clearDir()
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ── 删除 / 回收站 ──
|
||||
@@ -603,6 +617,20 @@ async function runImport() {
|
||||
font-size: 14px; color: var(--df-text-dim);
|
||||
}
|
||||
|
||||
/* ===== 错误条(消费 store.error,对齐 Knowledge error-banner) ===== */
|
||||
.error-banner {
|
||||
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
||||
padding: 8px 12px; margin-bottom: var(--df-gap-page);
|
||||
background: rgba(255,107,107,0.12); border: 0.5px solid var(--df-danger);
|
||||
border-radius: var(--df-radius-sm); color: var(--df-danger); font-size: 12px;
|
||||
}
|
||||
.error-text { word-break: break-word; }
|
||||
.error-dismiss {
|
||||
flex-shrink: 0; background: transparent; border: none; color: var(--df-danger);
|
||||
font-size: 14px; cursor: pointer; line-height: 1; padding: 0 2px;
|
||||
}
|
||||
.error-dismiss:hover { opacity: 0.7; }
|
||||
|
||||
/* ===== 卡片删除按钮 + 回收站 ===== */
|
||||
.card-top-actions { display: flex; align-items: center; gap: 8px; }
|
||||
.card-del-btn {
|
||||
|
||||
Reference in New Issue
Block a user