feat(web): align Web WASM session insight navigation

This commit is contained in:
digua committed 2026-07-22 19:00:39 +08:00
1 parent 53bd6750af
commit 69ee6716b1
3 files changed
+56 -45

No files matched your search

@@ -8,23 +8,34 @@ import TypeAnalysisView from '@/components/analysis/message/TypeAnalysisView.vue
import TimeAnalysisView from '@/components/analysis/message/TimeAnalysisView.vue'
import { LanguagePreferenceTab, WordcloudTab } from '@/components/analysis/quotes'
import type { TimeFilter } from '@openchatlab/shared-types'
import type { AnalysisSession, MessageType } from '@/types/base'
import type { DailyActivity, HourlyActivity, MemberActivity } from '@/types/analysis'
import GroupRelationshipInsights from './GroupRelationshipInsights.vue'
import GroupOverview from './GroupOverview.vue'
import PrivateOverview from './PrivateOverview.vue'
const props = defineProps<{
sessionId: string
sessionName?: string
sessionType: string
session: AnalysisSession
memberActivity: MemberActivity[]
messageTypes: Array<{ type: MessageType; count: number }>
hourlyActivity: HourlyActivity[]
dailyActivity: DailyActivity[]
timeRange: { start: number; end: number } | null
filteredMessageCount: number
filteredMemberCount: number
timeFilter?: TimeFilter
}>()
const { t } = useI18n()
const isPrivateChat = computed(() => props.sessionType === 'private')
const activeSubTab = ref(isPrivateChat.value ? 'relationship' : 'type-analysis')
const isPrivateChat = computed(() => props.session.type === 'private')
const activeSubTab = ref('overview')
const selectedMemberId = ref<number | null>(null)
const persistKey = computed(() => (isPrivateChat.value ? 'webWasmPrivateInsightsTab' : 'webWasmGroupInsightsTab'))
const subTabs = computed(() =>
isPrivateChat.value
? [
{ id: 'overview', label: t('analysis.tabs.overview'), icon: 'i-heroicons-squares-2x2' },
{ id: 'relationship', label: t('analysis.subTabs.insights.relationship'), icon: 'i-heroicons-heart' },
{ id: 'type-analysis', label: t('analysis.subTabs.insights.typeAnalysis'), icon: 'i-heroicons-chart-pie' },
{ id: 'time-analysis', label: t('analysis.subTabs.insights.timeAnalysis'), icon: 'i-heroicons-clock' },
@@ -36,6 +47,7 @@ const subTabs = computed(() =>
},
]
: [
{ id: 'overview', label: t('analysis.tabs.overview'), icon: 'i-heroicons-squares-2x2' },
{ id: 'type-analysis', label: t('analysis.subTabs.insights.typeAnalysis'), icon: 'i-heroicons-chart-pie' },
{ id: 'time-analysis', label: t('analysis.subTabs.insights.timeAnalysis'), icon: 'i-heroicons-clock' },
{ id: 'topic', label: t('analysis.subTabs.insights.topic'), icon: 'i-heroicons-cloud' },
@@ -67,8 +79,32 @@ const viewTimeFilter = computed(() => ({ ...props.timeFilter, memberId: selected
<div class="min-h-0 flex-1 overflow-auto">
<Transition name="fade" mode="out-in">
<PrivateOverview
v-if="activeSubTab === 'overview' && isPrivateChat"
:session="props.session"
:member-activity="props.memberActivity"
:message-types="props.messageTypes"
:hourly-activity="props.hourlyActivity"
:daily-activity="props.dailyActivity"
:time-range="props.timeRange"
:filtered-message-count="props.filteredMessageCount"
:filtered-member-count="props.filteredMemberCount"
:time-filter="props.timeFilter"
/>
<GroupOverview
v-else-if="activeSubTab === 'overview'"
:session="props.session"
:member-activity="props.memberActivity"
:message-types="props.messageTypes"
:hourly-activity="props.hourlyActivity"
:daily-activity="props.dailyActivity"
:time-range="props.timeRange"
:filtered-message-count="props.filteredMessageCount"
:filtered-member-count="props.filteredMemberCount"
:time-filter="props.timeFilter"
/>
<PrivateRelationshipView
v-if="activeSubTab === 'relationship'"
v-else-if="activeSubTab === 'relationship'"
:session-id="props.sessionId"
:time-filter="props.timeFilter"
/>
@@ -76,14 +112,14 @@ const viewTimeFilter = computed(() => ({ ...props.timeFilter, memberId: selected
v-else-if="activeSubTab === 'type-analysis'"
:key="selectedMemberId ?? 'all'"
:session-id="props.sessionId"
:session-name="props.sessionName"
:session-name="props.session.name"
:time-filter="viewTimeFilter"
/>
<TimeAnalysisView
v-else-if="activeSubTab === 'time-analysis'"
:key="selectedMemberId ?? 'all'"
:session-id="props.sessionId"
:session-name="props.sessionName"
:session-name="props.session.name"
:time-filter="viewTimeFilter"
/>
<WordcloudTab
+11 -36
View File
@@ -7,8 +7,6 @@ import LoadingState from '@/components/UI/LoadingState.vue'
import SessionAnalysisHeader from '@/components/layout/session/SessionAnalysisHeader.vue'
import { useSessionAnalysisPageBase } from '@/composables'
import { useSessionStore } from '@/stores/session'
import GroupOverview from '../components/session/insights/GroupOverview.vue'
import PrivateOverview from '../components/session/insights/PrivateOverview.vue'
import SessionInsights from '../components/session/insights/SessionInsights.vue'
const { t } = useI18n()
@@ -17,10 +15,7 @@ const router = useRouter()
const sessionStore = useSessionStore()
const { currentSessionId } = storeToRefs(sessionStore)
const tabs = [
{ id: 'overview', labelKey: 'analysis.tabs.overview', icon: 'i-heroicons-chart-pie' },
{ id: 'view', labelKey: 'analysis.tabs.insights', icon: 'i-heroicons-presentation-chart-bar' },
]
const tabs = [{ id: 'insights', labelKey: 'analysis.tabs.insights', icon: 'i-heroicons-presentation-chart-bar' }]
const {
activeTab,
@@ -40,7 +35,7 @@ const {
router,
currentSessionId,
selectSession: sessionStore.selectSession,
defaultTab: 'overview',
defaultTab: 'insights',
validTabIds: tabs.map((tab) => tab.id),
})
@@ -94,38 +89,18 @@ const loadErrorText = computed(() =>
<div class="relative flex-1 overflow-y-auto">
<LoadingState v-if="isLoading" variant="overlay" :text="t('common.loading')" />
<PrivateOverview
v-if="activeTab === 'overview' && isPrivateChat"
:key="'private-overview-' + currentSessionId"
:session="session"
:member-activity="memberActivity"
:message-types="messageTypes"
:hourly-activity="hourlyActivity"
:daily-activity="dailyActivity"
:time-range="fullTimeRange"
:filtered-message-count="filteredMessageCount"
:filtered-member-count="filteredMemberCount"
:time-filter="timeFilter"
/>
<GroupOverview
v-else-if="activeTab === 'overview'"
:key="'group-overview-' + currentSessionId"
:session="session"
:member-activity="memberActivity"
:message-types="messageTypes"
:hourly-activity="hourlyActivity"
:daily-activity="dailyActivity"
:time-range="fullTimeRange"
:filtered-message-count="filteredMessageCount"
:filtered-member-count="filteredMemberCount"
:time-filter="timeFilter"
/>
<SessionInsights
v-else-if="activeTab === 'view'"
v-if="activeTab === 'insights'"
:key="'insights-' + currentSessionId"
:session-id="currentSessionId!"
:session-name="session.name"
:session-type="session.type"
:session="session"
:member-activity="memberActivity"
:message-types="messageTypes"
:hourly-activity="hourlyActivity"
:daily-activity="dailyActivity"
:time-range="fullTimeRange"
:filtered-message-count="filteredMessageCount"
:filtered-member-count="filteredMemberCount"
:time-filter="timeFilter"
/>
</div>
@@ -67,8 +67,8 @@ test('only the latest analysis load may update results and loading state', async
router,
currentSessionId,
selectSession: () => undefined,
defaultTab: 'overview',
validTabIds: ['overview'],
defaultTab: 'insights',
validTabIds: ['insights'],
})
)!