feat(insight): refine annual activity overview

This commit is contained in:
digua committed 2026-07-12 15:29:09 +08:00
1 parent 02e5807ec3
commit 85a447b9af
3 files changed
+19 -33

No files matched your search

@@ -34,8 +34,9 @@ const months = computed<CalendarMonth[]>(() => {
const start = startDate.value
const end = endDate.value
const result: CalendarMonth[] = []
const cursor = new Date(start.getFullYear(), start.getMonth(), 1)
const lastMonth = new Date(end.getFullYear(), end.getMonth(), 1)
const year = props.range.year ?? start.getFullYear()
const cursor = props.range.mode === 'year' ? new Date(year, 0, 1) : new Date(start.getFullYear(), start.getMonth(), 1)
const lastMonth = props.range.mode === 'year' ? new Date(year, 11, 1) : new Date(end.getFullYear(), end.getMonth(), 1)
while (cursor <= lastMonth) {
const year = cursor.getFullYear()
@@ -76,12 +77,12 @@ function startOfDay(date: Date): Date {
</script>
<template>
<div class="grid grid-cols-2 gap-x-4 gap-y-4 sm:grid-cols-3 lg:grid-cols-2 xl:grid-cols-3">
<div class="grid grid-cols-2 gap-x-3 gap-y-4 sm:grid-cols-3 lg:grid-cols-4">
<div v-for="month in months" :key="month.key" class="min-w-0">
<div class="mb-1.5 text-[10px] font-semibold text-gray-500 dark:text-zinc-400">
{{ month.label }}
</div>
<div class="grid grid-cols-7 gap-1" aria-hidden="true">
<div class="grid grid-cols-7 gap-0.5" aria-hidden="true">
<span v-for="index in month.leadingDays" :key="`blank-${index}`" class="aspect-square" />
<span
v-for="day in month.days"
@@ -17,17 +17,12 @@ const props = defineProps<{
range: AnnualSummaryRange
metrics: AnnualSummaryMetrics
coverage: AnnualSummaryCoverage
ownerIssueCount: number
monthlyActivity: Array<{ month: string; messageCount: number }>
dailyActivity: Array<{ date: string; messageCount: number }>
messageTypes: Array<{ type: number; count: number }>
textLength: AnnualSummaryTextLength
}>()
const emit = defineEmits<{
openSessions: []
}>()
const { t } = useI18n()
const title = computed(() =>
@@ -122,14 +117,6 @@ function percentage(value: number, total: number): number {
})
}}
</span>
<button
v-if="ownerIssueCount > 0"
type="button"
class="text-pink-600 hover:underline dark:text-pink-400"
@click="emit('openSessions')"
>
{{ t('insight.status.ownerIssues', { count: ownerIssueCount }) }}
</button>
</div>
</div>
</div>
+14 -16
View File
@@ -110,6 +110,17 @@ function openSessions(): void {
<template>
<main class="min-h-0 flex-1 overflow-y-auto">
<div class="mx-auto w-full max-w-[1120px] space-y-6 px-4 py-5 sm:px-6 sm:py-6">
<button
v-if="ownerIssueCount > 0"
type="button"
class="inline-flex w-fit max-w-full items-center gap-2 rounded-lg bg-amber-50 px-3 py-2 text-left text-xs text-amber-800 transition-colors hover:bg-amber-100 dark:bg-amber-950/20 dark:text-amber-300 dark:hover:bg-amber-950/30"
@click="openSessions"
>
<UIcon name="i-heroicons-user-circle" class="h-4 w-4 shrink-0" />
<span class="min-w-0">{{ t('insight.status.ownerIssues', { count: ownerIssueCount }) }}</span>
<UIcon name="i-heroicons-arrow-right" class="h-3.5 w-3.5 shrink-0 opacity-70" />
</button>
<div
v-if="response?.cache.status === 'stale' || (isUpdating && hasSnapshot)"
class="flex items-center gap-2 rounded-xl border border-amber-100 bg-amber-50/50 px-4 py-2.5 text-xs text-amber-800 backdrop-blur-sm dark:border-amber-950/40 dark:bg-amber-950/20 dark:text-amber-300"
@@ -143,26 +154,15 @@ function openSessions(): void {
<template v-else-if="response?.metrics && response.textLength">
<div
v-if="isZeroData"
v-if="isZeroData && !hasNoAnalyzableOwner"
class="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-gray-150 bg-white p-4 text-xs text-gray-600 dark:border-zinc-850 dark:bg-zinc-900/50 dark:text-zinc-300"
>
<span v-if="hasNoAnalyzableOwner">{{ t('insight.status.noAnalyzableOwner') }}</span>
<span v-else-if="latestYearSuggestion">
<span v-if="latestYearSuggestion">
{{ t('insight.status.noDataWithLatest', latestYearSuggestion) }}
</span>
<span v-else>{{ t('insight.noData') }}</span>
<UButton
v-if="hasNoAnalyzableOwner"
size="xs"
variant="soft"
color="neutral"
icon="i-heroicons-user-circle"
@click="openSessions"
>
{{ t('insight.actions.openSessions') }}
</UButton>
<UButton
v-else-if="latestYearSuggestion"
v-if="latestYearSuggestion"
size="xs"
variant="soft"
color="neutral"
@@ -177,12 +177,10 @@ function openSessions(): void {
:range="response.range"
:metrics="response.metrics"
:coverage="response.coverage"
:owner-issue-count="ownerIssueCount"
:monthly-activity="response.monthlyActivity"
:daily-activity="response.dailyActivity"
:message-types="response.messageTypes"
:text-length="response.textLength"
@open-sessions="openSessions"
/>
</template>
</div>