@@ -29,8 +44,11 @@
+
+ {{ t('dialog.user.activity.no_data_in_period') }}
+
@@ -42,6 +60,7 @@
import { computed, h, nextTick, onBeforeUnmount, ref, watch } from 'vue';
import { Button } from '@/components/ui/button';
import { DataTableEmpty } from '@/components/ui/data-table';
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { RefreshCw, Tractor } from 'lucide-vue-next';
import { Spinner } from '@/components/ui/spinner';
import { storeToRefs } from 'pinia';
@@ -63,6 +82,8 @@
const totalOnlineEvents = ref(0);
const peakDayText = ref('');
const peakTimeText = ref('');
+ const selectedPeriod = ref('all');
+ const filteredEventCount = ref(0);
let echartsInstance = null;
let resizeObserver = null;
@@ -110,6 +131,11 @@
watch(() => isDarkMode.value, rebuildChart);
watch(locale, rebuildChart);
+ watch(selectedPeriod, () => {
+ if (cachedTimestamps.length > 0 && echartsInstance) {
+ initChart();
+ }
+ });
onBeforeUnmount(() => {
disposeChart();
@@ -126,6 +152,14 @@
}
}
+ function getFilteredTimestamps() {
+ if (selectedPeriod.value === 'all') return cachedTimestamps;
+ const days = parseInt(selectedPeriod.value, 10);
+ const cutoff = dayjs().subtract(days, 'day');
+ return cachedTimestamps.filter((ts) => dayjs(ts).isAfter(cutoff));
+ }
+
+
/**
* @param {string[]} timestamps
* @returns {{ data: number[][], maxVal: number, peakText: string }}
@@ -210,7 +244,15 @@
function initChart() {
if (!chartRef.value || !echartsInstance) return;
- const { data, maxVal, peakDayResult, peakTimeResult } = aggregateHeatmapData(cachedTimestamps);
+ const filtered = getFilteredTimestamps();
+ filteredEventCount.value = filtered.length;
+
+ if (filtered.length === 0) {
+ peakDayText.value = '';
+ peakTimeText.value = '';
+ return;
+ }
+ const { data, maxVal, peakDayResult, peakTimeResult } = aggregateHeatmapData(filtered);
peakDayText.value = peakDayResult;
peakTimeText.value = peakTimeResult;
@@ -301,6 +343,10 @@
const userId = userDialog.value.id;
if (!userId) return;
+ if (userId !== lastLoadedUserId) {
+ selectedPeriod.value = 'all';
+ }
+
const requestId = ++activeRequestId;
isLoading.value = true;
try {
@@ -314,6 +360,11 @@
await nextTick();
if (timestamps.length > 0) {
+ const filtered = getFilteredTimestamps();
+ filteredEventCount.value = filtered.length;
+
+ await nextTick();
+
if (!echartsInstance && chartRef.value) {
echartsInstance = echarts.init(
chartRef.value,
@@ -335,6 +386,7 @@
} else {
peakDayText.value = '';
peakTimeText.value = '';
+ filteredEventCount.value = 0;
}
} catch (error) {
console.error('Error loading online frequency data:', error);
diff --git a/src/localization/en.json b/src/localization/en.json
index c0073c9c..3189dea3 100644
--- a/src/localization/en.json
+++ b/src/localization/en.json
@@ -1286,6 +1286,13 @@
"times_online": "times online",
"most_active_day": "Most active day:",
"most_active_time": "Peak hours:",
+ "period": "Period:",
+ "period_all": "All Time",
+ "period_365": "Last Year",
+ "period_180": "Last 6 Months",
+ "period_90": "Last 90 Days",
+ "period_30": "Last 30 Days",
+ "no_data_in_period": "No activity data in selected period",
"days": {
"mon": "Mon",
"tue": "Tue",