refactor: 将 ExtensionCard 替换为 InfoCard 以统一组件使用

This commit is contained in:
Wenjie Zhang 2026-04-27 10:22:41 +08:00
parent e9678e32d3
commit 417b1de308
7 changed files with 41 additions and 41 deletions

View File

@ -27,7 +27,7 @@
<template v-else>
<div v-if="filteredEnabledServers.length" class="extension-section-header">已添加</div>
<ExtensionCardGrid>
<ExtensionCard
<InfoCard
v-for="server in filteredEnabledServers"
:key="server.name"
:title="server.name"
@ -39,14 +39,14 @@
@click="navigateToDetail(server)"
>
<template #icon>
<span class="extension-card-emoji-icon">{{ server.icon || '🔌' }}</span>
<span class="info-card-emoji-icon">{{ server.icon || '🔌' }}</span>
</template>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
<div v-if="filteredDisabledServers.length" class="extension-section-header">可添加</div>
<ExtensionCardGrid v-if="filteredDisabledServers.length">
<ExtensionCard
<InfoCard
v-for="server in filteredDisabledServers"
:key="server.name"
:title="server.name"
@ -59,9 +59,9 @@
@action-click="handleSetServerEnabled(server, true)"
>
<template #icon>
<span class="extension-card-emoji-icon">{{ server.icon || '🔌' }}</span>
<span class="info-card-emoji-icon">{{ server.icon || '🔌' }}</span>
</template>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
</template>
@ -80,7 +80,7 @@ import { message } from 'ant-design-vue'
import { Plus, RefreshCw, Plug } from 'lucide-vue-next'
import { mcpApi } from '@/apis/mcp_api'
import ExtensionCardGrid from './ExtensionCardGrid.vue'
import ExtensionCard from './ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
import McpFormModal from './McpFormModal.vue'
@ -178,7 +178,7 @@ defineExpose({ fetchServers, loading })
<style lang="less" scoped>
@import '@/assets/css/extensions.less';
.extension-card-emoji-icon {
.info-card-emoji-icon {
font-size: 18px;
line-height: 1;
}

View File

@ -42,7 +42,7 @@
已添加 Skills
</div>
<ExtensionCardGrid>
<ExtensionCard
<InfoCard
v-for="skill in filteredInstalledSkills"
:key="skill.slug"
:title="skill.name"
@ -52,14 +52,14 @@
:status="{ label: '已安装', level: 'success' }"
@click="navigateToDetail(skill)"
>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
<div v-if="filteredUninstalledBuiltinSkills.length" class="extension-section-header">
可添加 Skills
</div>
<ExtensionCardGrid v-if="filteredUninstalledBuiltinSkills.length">
<ExtensionCard
<InfoCard
v-for="skill in filteredUninstalledBuiltinSkills"
:key="skill.slug"
:title="skill.name"
@ -69,7 +69,7 @@
action-label="安装"
@action-click="handleInstallBuiltin(skill)"
>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
</template>
@ -148,7 +148,7 @@ import { message } from 'ant-design-vue'
import { RefreshCw, Upload, Computer, BookMarked } from 'lucide-vue-next'
import { skillApi } from '@/apis/skill_api'
import ExtensionCardGrid from './ExtensionCardGrid.vue'
import ExtensionCard from './ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
const BookMarkedIcon = BookMarked

View File

@ -24,7 +24,7 @@
<template v-else>
<div v-if="filteredEnabledSubAgents.length" class="extension-section-header">已添加</div>
<ExtensionCardGrid>
<ExtensionCard
<InfoCard
v-for="agent in filteredEnabledSubAgents"
:key="agent.name"
:title="agent.name"
@ -34,12 +34,12 @@
:status="{ label: '已添加', level: 'success' }"
@click="navigateToDetail(agent)"
>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
<div v-if="filteredDisabledSubAgents.length" class="extension-section-header">可添加</div>
<ExtensionCardGrid v-if="filteredDisabledSubAgents.length">
<ExtensionCard
<InfoCard
v-for="agent in filteredDisabledSubAgents"
:key="agent.name"
:title="agent.name"
@ -50,7 +50,7 @@
@click="navigateToDetail(agent)"
@action-click="handleSetAgentEnabled(agent, true)"
>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
</template>
@ -109,7 +109,7 @@ import { Plus, RefreshCw, Bot } from 'lucide-vue-next'
import { subagentApi } from '@/apis/subagent_api'
import { toolApi } from '@/apis/tool_api'
import ExtensionCardGrid from './ExtensionCardGrid.vue'
import ExtensionCard from './ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'

View File

@ -34,7 +34,7 @@
</div>
<ExtensionCardGrid v-else>
<ExtensionCard
<InfoCard
v-for="tool in filteredTools"
:key="tool.id"
:title="tool.name"
@ -44,7 +44,7 @@
:tags="toolTags(tool)"
@click="selectTool(tool)"
>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
<a-modal
@ -123,7 +123,7 @@ import { Wrench, RefreshCw, SlidersHorizontal, FileText, Tag, Tags, List } from
import { toolApi } from '@/apis/tool_api'
import { getToolIcon } from '@/components/ToolCallingResult/toolRegistry'
import ExtensionCardGrid from './ExtensionCardGrid.vue'
import ExtensionCard from './ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
const WrenchIcon = Wrench

View File

@ -1,22 +1,22 @@
<template>
<div
class="extension-card"
:class="{ 'extension-card-disabled': disabled }"
class="info-card"
:class="{ 'info-card-disabled': disabled }"
@click="$emit('click')"
>
<div class="extension-card-header">
<div class="extension-card-icon">
<div class="info-card-header">
<div class="info-card-icon">
<slot name="icon">
<component :is="defaultIcon" v-if="defaultIcon" :size="20" />
</slot>
</div>
<div class="extension-card-info">
<span class="extension-card-name" :title="title">{{ title }}</span>
<span v-if="subtitle" class="extension-card-subtitle" :title="subtitle">{{
<div class="info-card-info">
<span class="info-card-name" :title="title">{{ title }}</span>
<span v-if="subtitle" class="info-card-subtitle" :title="subtitle">{{
subtitle
}}</span>
</div>
<div class="extension-card-status">
<div class="info-card-status">
<slot name="status" />
<template v-if="!$slots.status">
<button
@ -41,13 +41,13 @@
</div>
</div>
<div v-if="$slots.info" class="extension-card-body">
<div v-if="$slots.info" class="info-card-body">
<slot name="info" />
</div>
<div v-else-if="description" class="extension-card-desc" :title="description">
<div v-else-if="description" class="info-card-desc" :title="description">
{{ description }}
</div>
<div v-else-if="info && info.length > 0" class="extension-card-info-rows">
<div v-else-if="info && info.length > 0" class="info-card-info-rows">
<div v-for="(row, idx) in info" :key="idx" class="info-row">
<span class="info-label">{{ row.label }}</span>
<span class="info-value">{{ row.value }}</span>
@ -56,7 +56,7 @@
<div
v-if="$slots.tags || (normalizedTags && normalizedTags.length > 0)"
class="extension-card-tags"
class="info-card-tags"
>
<slot name="tags">
<span
@ -70,7 +70,7 @@
</slot>
</div>
<div v-if="$slots.footer" class="extension-card-footer">
<div v-if="$slots.footer" class="info-card-footer">
<slot name="footer" />
</div>
</div>
@ -113,7 +113,7 @@ const normalizedTags = computed(() => {
</script>
<style lang="less" scoped>
.extension-card {
.info-card {
display: flex;
flex-direction: column;
gap: 10px;

View File

@ -205,7 +205,7 @@
<!-- 数据库列表 -->
<ExtensionCardGrid v-else>
<ExtensionCard
<InfoCard
v-for="database in filteredDatabases"
:key="database.db_id"
:title="database.name"
@ -220,7 +220,7 @@
<template #status>
<LockOutlined v-if="database.metadata?.is_private" title="私有知识库" />
</template>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
</div>
</template>
@ -240,7 +240,7 @@ import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'
import EmbeddingModelSelector from '@/components/EmbeddingModelSelector.vue'
import ShareConfigForm from '@/components/ShareConfigForm.vue'
import ExtensionCardGrid from '@/components/extensions/ExtensionCardGrid.vue'
import ExtensionCard from '@/components/extensions/ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import dayjs, { parseToShanghai } from '@/utils/time'
import AiTextarea from '@/components/AiTextarea.vue'
import { getKbTypeLabel, getKbTypeIcon, getKbTypeColor } from '@/utils/kb_utils'

View File

@ -16,7 +16,7 @@ import { modelProviderApi } from '@/apis/system_api'
import { modelIcons } from '@/utils/modelIcon'
import PageHeader from '@/components/shared/PageHeader.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
import ExtensionCard from '@/components/extensions/ExtensionCard.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import ExtensionCardGrid from '@/components/extensions/ExtensionCardGrid.vue'
// ============ State ============
@ -599,7 +599,7 @@ onMounted(loadProviders)
<!-- Provider Card Grid -->
<ExtensionCardGrid :min-width="320">
<ExtensionCard
<InfoCard
v-for="provider in filteredProviders"
:key="provider.provider_id"
:title="provider.display_name"
@ -632,7 +632,7 @@ onMounted(loadProviders)
</a-button>
</a-tooltip>
</template>
</ExtensionCard>
</InfoCard>
</ExtensionCardGrid>
<!-- Provider Edit Modal -->