mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
feat(insight): refine annual activity overview
This commit is contained in:
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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user