fix(frontend): hide redundant card badges when section headers apply
Suppress duplicate origin, builtin, role, and org-name pills on knowledge base, agent, and organization list cards when the visible group header or sidebar filter already conveys the same information.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Helpers to suppress card corner badges that repeat what a visible section
|
||||
* header (Group) already communicates.
|
||||
*/
|
||||
|
||||
export type ListCardSectionKey =
|
||||
| 'pinned'
|
||||
| 'mine'
|
||||
| 'tenantOthers'
|
||||
| 'builtin'
|
||||
| 'sharedByMe'
|
||||
| 'sharedEditable'
|
||||
| 'sharedReadonly'
|
||||
| 'created'
|
||||
| 'joined'
|
||||
|
||||
export type ResourceOriginVariant = 'mine' | 'tenant' | 'creator' | 'space' | 'shared'
|
||||
|
||||
/** ResourceOriginBadge on KB / Agent cards. */
|
||||
export function shouldShowResourceOriginBadge(opts: {
|
||||
section: ListCardSectionKey | null
|
||||
variant: ResourceOriginVariant
|
||||
creatorName?: string
|
||||
showSectionHeaders?: boolean
|
||||
}): boolean {
|
||||
if (!opts.showSectionHeaders) return true
|
||||
|
||||
const { section, variant, creatorName } = opts
|
||||
const hasCreator = Boolean(creatorName?.trim())
|
||||
|
||||
if (section === 'mine' && variant === 'mine') return false
|
||||
if (section === 'builtin') return false
|
||||
if (section === 'tenantOthers' && variant === 'creator' && !hasCreator) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/** Owner / role tag on organization cards. */
|
||||
export function shouldShowOrgRelationTag(opts: {
|
||||
spaceSelection: 'all' | 'created' | 'joined'
|
||||
isOwner: boolean
|
||||
myRole?: string
|
||||
}): boolean {
|
||||
if (opts.spaceSelection === 'created') return false
|
||||
if (opts.spaceSelection === 'joined' && !opts.myRole) return false
|
||||
if (opts.spaceSelection === 'all' && opts.isOwner) return false
|
||||
if (opts.spaceSelection === 'all' && !opts.isOwner && !opts.myRole) return false
|
||||
return true
|
||||
}
|
||||
@@ -296,11 +296,11 @@
|
||||
<img src="@/assets/img/organization-green.svg" class="org-icon" alt="" aria-hidden="true" />
|
||||
<span class="org-source-text">{{ agent.org_name }}</span>
|
||||
</div>
|
||||
<div v-else-if="agent.is_builtin" class="builtin-badge">
|
||||
<div v-else-if="showAgentBuiltinBadge(agent)" class="builtin-badge">
|
||||
<t-icon name="lock-on" size="12px" />
|
||||
<span>{{ $t('agent.builtin') }}</span>
|
||||
</div>
|
||||
<ResourceOriginBadge v-else :variant="agentOriginVariant(agent)"
|
||||
<ResourceOriginBadge v-else-if="showAgentOriginBadge(agent)" :variant="agentOriginVariant(agent)"
|
||||
:creator-name="(agent as any).creator_name" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -483,11 +483,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右下角:内置 / 来源徽章(我创建 / 同租户其他成员) -->
|
||||
<div v-if="agent.is_builtin" class="builtin-badge">
|
||||
<div v-if="showAgentBuiltinBadge(agent)" class="builtin-badge">
|
||||
<t-icon name="lock-on" size="12px" />
|
||||
<span>{{ $t('agent.builtin') }}</span>
|
||||
</div>
|
||||
<ResourceOriginBadge v-else :variant="agentOriginVariant(agent)"
|
||||
<ResourceOriginBadge v-else-if="showAgentOriginBadge(agent)" :variant="agentOriginVariant(agent)"
|
||||
:creator-name="(agent as any).creator_name" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -631,11 +631,6 @@
|
||||
</t-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右下角:空间图标+名称 -->
|
||||
<div class="card-bottom-source">
|
||||
<img src="@/assets/img/organization-green.svg" class="org-icon" alt="" aria-hidden="true" />
|
||||
<span class="org-source-text">{{ shared.org_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -839,6 +834,7 @@ import { useUIStore } from '@/stores/ui'
|
||||
import AgentAvatar from '@/components/AgentAvatar.vue'
|
||||
import ListSpaceSidebar from '@/components/ListSpaceSidebar.vue'
|
||||
import ResourceOriginBadge from '@/components/ResourceOriginBadge.vue'
|
||||
import { shouldShowResourceOriginBadge } from '@/utils/card-list-badge'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useListUrlState } from '@/composables/useListUrlState'
|
||||
import { useResourcePins } from '@/composables/useResourcePins'
|
||||
@@ -1347,6 +1343,24 @@ function agentOriginVariant(agent: { created_by?: string }): 'mine' | 'creator'
|
||||
return isMyAgent(agent) ? 'mine' : 'creator'
|
||||
}
|
||||
|
||||
function showAgentOriginBadge(agent: { created_by?: string; creator_name?: string }): boolean {
|
||||
return shouldShowResourceOriginBadge({
|
||||
section: agentSectionOf(agent),
|
||||
variant: agentOriginVariant(agent),
|
||||
creatorName: (agent as any).creator_name,
|
||||
showSectionHeaders: showShareGroupHeaders.value,
|
||||
})
|
||||
}
|
||||
|
||||
function showAgentBuiltinBadge(agent: { is_builtin?: boolean }): boolean {
|
||||
if (!agent.is_builtin) return false
|
||||
return shouldShowResourceOriginBadge({
|
||||
section: agentSectionOf(agent),
|
||||
variant: 'mine',
|
||||
showSectionHeaders: showShareGroupHeaders.value,
|
||||
})
|
||||
}
|
||||
|
||||
// 共享 agent 的可编辑/只读分组开关,与 KB 列表逻辑保持一致:仅对
|
||||
// contributor / editor 中间档展示分组标题。Viewer / Admin+ 不分组。
|
||||
const AGENT_EDITABLE_PERMS = new Set(['admin', 'editor'])
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
</t-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!authStore.isLiteMode" class="bottom-right">
|
||||
<div v-if="!authStore.isLiteMode && showKbOriginBadge(kb)" class="bottom-right">
|
||||
<ResourceOriginBadge :variant="kbOriginVariant(kb)" :creator-name="kb.creator_name" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -504,7 +504,7 @@
|
||||
</t-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!authStore.isLiteMode" class="bottom-right">
|
||||
<div v-if="!authStore.isLiteMode && showKbOriginBadge(kb)" class="bottom-right">
|
||||
<ResourceOriginBadge :variant="kbOriginVariant(kb)" :creator-name="kb.creator_name" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -604,15 +604,6 @@
|
||||
</t-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-right">
|
||||
<t-tooltip :content="shared.org_name" placement="top">
|
||||
<div class="org-source">
|
||||
<img src="@/assets/img/organization-green.svg" class="org-source-icon" alt=""
|
||||
aria-hidden="true" />
|
||||
<span>{{ shared.org_name }}</span>
|
||||
</div>
|
||||
</t-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -783,6 +774,7 @@ import KnowledgeBaseEditorModal from './KnowledgeBaseEditorModal.vue'
|
||||
import ShareKnowledgeBaseDialog from '@/components/ShareKnowledgeBaseDialog.vue'
|
||||
import ListSpaceSidebar from '@/components/ListSpaceSidebar.vue'
|
||||
import ResourceOriginBadge from '@/components/ResourceOriginBadge.vue'
|
||||
import { shouldShowResourceOriginBadge } from '@/utils/card-list-badge'
|
||||
import ContextualGuide from '@/components/ContextualGuide.vue'
|
||||
import { isContextualGuideDone, markContextualGuideDone } from '@/config/contextualGuides'
|
||||
import { useTenantModelReadiness } from '@/composables/useTenantModelReadiness'
|
||||
@@ -1361,6 +1353,15 @@ function kbOriginVariant(kb: { creator_id?: string }): 'mine' | 'creator' {
|
||||
return isMyKb(kb) ? 'mine' : 'creator'
|
||||
}
|
||||
|
||||
function showKbOriginBadge(kb: { creator_id?: string; creator_name?: string }): boolean {
|
||||
return shouldShowResourceOriginBadge({
|
||||
section: kbSectionOf(kb),
|
||||
variant: kbOriginVariant(kb),
|
||||
creatorName: kb.creator_name,
|
||||
showSectionHeaders: showShareGroupHeaders.value,
|
||||
})
|
||||
}
|
||||
|
||||
// 通过 ID 处理设置(用于全部 Tab 下的知识库)
|
||||
const handleSettingsById = (id: string) => {
|
||||
goSettings(id)
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
$t('organization.settings.pendingReview') }}</span>
|
||||
</t-tooltip>
|
||||
</div>
|
||||
<div class="bottom-right">
|
||||
<div v-if="showOrgRelationTag(org)" class="bottom-right">
|
||||
<div class="relation-role-tag" :class="org.is_owner ? 'owner' : (org.my_role || '')">
|
||||
<t-icon :name="org.is_owner ? 'usergroup-add' : 'usergroup'" size="14px" />
|
||||
<span>{{ org.is_owner ? $t('organization.owner') : (org.my_role ?
|
||||
@@ -557,6 +557,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import OrganizationSettingsModal from './OrganizationSettingsModal.vue'
|
||||
import SpaceAvatar from '@/components/SpaceAvatar.vue'
|
||||
import ListSpaceSidebar from '@/components/ListSpaceSidebar.vue'
|
||||
import { shouldShowOrgRelationTag } from '@/utils/card-list-badge'
|
||||
|
||||
interface OrgWithUI extends Organization {
|
||||
showMore?: boolean
|
||||
@@ -809,6 +810,14 @@ const orgSectionCounts = computed<Record<OrgSectionKey, number>>(() => {
|
||||
return c
|
||||
})
|
||||
|
||||
function showOrgRelationTag(org: { is_owner?: boolean; my_role?: string }): boolean {
|
||||
return shouldShowOrgRelationTag({
|
||||
spaceSelection: spaceSelection.value,
|
||||
isOwner: !!org.is_owner,
|
||||
myRole: org.my_role,
|
||||
})
|
||||
}
|
||||
|
||||
const emptyStateTitle = computed(() => {
|
||||
if (spaceSelection.value === 'created') return t('organization.emptyCreated')
|
||||
if (spaceSelection.value === 'joined') return t('organization.emptyJoined')
|
||||
|
||||
Reference in New Issue
Block a user