mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat(dashboard): Display system version and Git hash, link to release tag #19
This commit is contained in:
@@ -16,12 +16,12 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
use poem_openapi::Object;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tantivy::{schema::Value, TantivyDocument};
|
||||
|
||||
use crate::{
|
||||
bichon_version,
|
||||
modules::{
|
||||
account::migration::AccountModel,
|
||||
error::{code::ErrorCode, BichonResult},
|
||||
@@ -45,6 +45,8 @@ pub struct DashboardStats {
|
||||
pub with_attachment_count: u64, // Emails with attachments
|
||||
pub without_attachment_count: u64, // Emails without attachments
|
||||
pub top_largest_emails: Vec<LargestEmail>, // Top 10 largest emails
|
||||
pub system_version: String, // The semantic version string of the currently running backend service
|
||||
pub commit_hash: String, // Git commit hash used to build this system version
|
||||
}
|
||||
|
||||
impl DashboardStats {
|
||||
@@ -57,6 +59,8 @@ impl DashboardStats {
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
stat.index_usage_bytes = get_total_size(&DATA_DIR_MANAGER.envelope_dir)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
stat.system_version = bichon_version!().to_string();
|
||||
stat.commit_hash = env!("GIT_HASH").to_string();
|
||||
Ok(stat)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ export interface DashboardStats {
|
||||
with_attachment_count: number; // Emails with attachments
|
||||
without_attachment_count: number; // Emails without attachments
|
||||
top_largest_emails: LargestEmail[]; // Top 10 largest emails
|
||||
system_version: string, //The semantic version string of the currently running backend service
|
||||
commit_hash: string //Git commit hash used to build this system version
|
||||
}
|
||||
|
||||
export interface TimeBucket {
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -22,7 +22,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, BarChart, Bar } from 'recharts';
|
||||
import { Mail, HardDrive, Database, Users, Inbox } from 'lucide-react';
|
||||
import { Mail, HardDrive, Database, Users, Inbox, Info } from 'lucide-react';
|
||||
import { formatBytes, formatNumber } from '@/lib/utils';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { get_dashboard_stats, TimeBucket } from '@/api/system/api';
|
||||
@@ -94,7 +94,7 @@ export default function MailArchiveDashboard() {
|
||||
queryFn: get_dashboard_stats,
|
||||
});
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const totalAttachments = (stats?.with_attachment_count ?? 0) + (stats?.without_attachment_count ?? 0);
|
||||
const attachmentRatio = totalAttachments > 0 ? (stats?.with_attachment_count ?? 0) / totalAttachments : 0;
|
||||
|
||||
@@ -123,8 +123,8 @@ export default function MailArchiveDashboard() {
|
||||
<Skeleton className="h-7 w-28 rounded-full" />
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-6">
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<MetricCardSkeleton key={i} />
|
||||
))}
|
||||
</div>
|
||||
@@ -156,8 +156,8 @@ export default function MailArchiveDashboard() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-6">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">{t('dashboard.mailAccounts')}</CardTitle>
|
||||
@@ -212,6 +212,29 @@ export default function MailArchiveDashboard() {
|
||||
<p className="text-xs text-muted-foreground">{t('dashboard.tantivyIndex')}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">{t('dashboard.systemVersion')}</CardTitle>
|
||||
<Info className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className='text-2xl font-bold'>
|
||||
{stats!.system_version ? (
|
||||
<a
|
||||
href={`https://github.com/rustmailer/bichon/releases/tag/${stats!.system_version}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:underline"
|
||||
>
|
||||
{stats!.system_version}
|
||||
</a>
|
||||
) : 'N/A'}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{stats!.commit_hash ?? 'N/A'}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="trend" className="space-y-4">
|
||||
@@ -406,6 +429,11 @@ export default function MailArchiveDashboard() {
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
{/* Footer / Copyright - New Addition */}
|
||||
<div className="p-6 md:p-8 pt-0 text-center text-xs text-muted-foreground">
|
||||
© 2025 <a href="https://rustmailer.com" target="_blank" rel="noopener noreferrer" className="hover:underline">rustmailer.com</a> - Bichon Email Archiving Project
|
||||
</div>
|
||||
</Main>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "لا يوجد نشاط حديث",
|
||||
"noSendersData": "لا توجد بيانات للمرسلين",
|
||||
"noLargeEmails": "لا توجد رسائل بريد إلكتروني كبيرة",
|
||||
"noAccountData": "لا توجد بيانات للحساب"
|
||||
"noAccountData": "لا توجد بيانات للحساب",
|
||||
"systemVersion": "إصدار النظام"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "حسابات البريد الإلكتروني",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Ingen nylig aktivitet",
|
||||
"noSendersData": "Ingen afsenderdata",
|
||||
"noLargeEmails": "Ingen store e-mails",
|
||||
"noAccountData": "Ingen kontodata"
|
||||
"noAccountData": "Ingen kontodata",
|
||||
"systemVersion": "Systemversion"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "E-mailkonti",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Keine kürzliche Aktivität",
|
||||
"noSendersData": "Keine Absenderdaten",
|
||||
"noLargeEmails": "Keine großen E-Mails",
|
||||
"noAccountData": "Keine Kontodaten"
|
||||
"noAccountData": "Keine Kontodaten",
|
||||
"systemVersion": "Systemversion"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "E-Mail-Konten",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "No recent activity",
|
||||
"noSendersData": "No senders data",
|
||||
"noLargeEmails": "No large emails",
|
||||
"noAccountData": "No account data"
|
||||
"noAccountData": "No account data",
|
||||
"systemVersion": "System Version"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Email Accounts",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Sin actividad reciente",
|
||||
"noSendersData": "Sin datos de remitentes",
|
||||
"noLargeEmails": "Sin correos grandes",
|
||||
"noAccountData": "Sin datos de cuenta"
|
||||
"noAccountData": "Sin datos de cuenta",
|
||||
"systemVersion": "Versión del sistema"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Cuentas de correo",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Ei viimeaikaisia tapahtumia",
|
||||
"noSendersData": "Ei lähettäjätietoja",
|
||||
"noLargeEmails": "Ei suuria sähköposteja",
|
||||
"noAccountData": "Ei tilitietoja"
|
||||
"noAccountData": "Ei tilitietoja",
|
||||
"systemVersion": "Järjestelmäversio"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Sähköpostitilit",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Aucune activité récente",
|
||||
"noSendersData": "Aucune donnée d'expéditeurs",
|
||||
"noLargeEmails": "Aucun gros e-mail",
|
||||
"noAccountData": "Aucune donnée de compte"
|
||||
"noAccountData": "Aucune donnée de compte",
|
||||
"systemVersion": "Version du système"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Comptes de Messagerie",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Nessuna attività recente",
|
||||
"noSendersData": "Nessun dato sui mittenti",
|
||||
"noLargeEmails": "Nessuna email di grandi dimensioni",
|
||||
"noAccountData": "Nessun dato sull'account"
|
||||
"noAccountData": "Nessun dato sull'account",
|
||||
"systemVersion": "Versione del sistema"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Account Email",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "最近のアクティビティなし",
|
||||
"noSendersData": "送信者データなし",
|
||||
"noLargeEmails": "サイズの大きいメールなし",
|
||||
"noAccountData": "アカウントデータなし"
|
||||
"noAccountData": "アカウントデータなし",
|
||||
"systemVersion": "システムバージョン"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "メールアカウント",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "최근 활동 없음",
|
||||
"noSendersData": "발신자 데이터 없음",
|
||||
"noLargeEmails": "크기가 큰 이메일 없음",
|
||||
"noAccountData": "계정 데이터 없음"
|
||||
"noAccountData": "계정 데이터 없음",
|
||||
"systemVersion": "시스템 버전"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "이메일 계정",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Geen recente activiteit",
|
||||
"noSendersData": "Geen afzendersgegevens",
|
||||
"noLargeEmails": "Geen grote e-mails",
|
||||
"noAccountData": "Geen accountgegevens"
|
||||
"noAccountData": "Geen accountgegevens",
|
||||
"systemVersion": "Systeemversie"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "E-mailaccounts",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Ingen nylig aktivitet",
|
||||
"noSendersData": "Ingen avsenderdata",
|
||||
"noLargeEmails": "Ingen store e-poster",
|
||||
"noAccountData": "Ingen kontodata"
|
||||
"noAccountData": "Ingen kontodata",
|
||||
"systemVersion": "Systemversjon"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "E-postkontoer",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Nenhuma Atividade Recente",
|
||||
"noSendersData": "Sem Dados de Remetentes",
|
||||
"noLargeEmails": "Sem Emails Grandes",
|
||||
"noAccountData": "Sem Dados de Contas"
|
||||
"noAccountData": "Sem Dados de Contas",
|
||||
"systemVersion": "Versão do sistema"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Contas de Email",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Нет недавней активности",
|
||||
"noSendersData": "Нет данных об отправителях",
|
||||
"noLargeEmails": "Нет больших писем",
|
||||
"noAccountData": "Нет данных об аккаунте"
|
||||
"noAccountData": "Нет данных об аккаунте",
|
||||
"systemVersion": "Версия системы"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "Почтовые учетные записи",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "Ingen nylig aktivitet",
|
||||
"noSendersData": "Inga avsändardata",
|
||||
"noLargeEmails": "Inga stora e-postmeddelanden",
|
||||
"noAccountData": "Inga kontodata"
|
||||
"noAccountData": "Inga kontodata",
|
||||
"systemVersion": "Systemversion"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "E-postkonton",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "無近期活動",
|
||||
"noSendersData": "無寄件人資料",
|
||||
"noLargeEmails": "無大容量郵件",
|
||||
"noAccountData": "無帳號資料"
|
||||
"noAccountData": "無帳號資料",
|
||||
"systemVersion": "系統版本"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "郵件帳號",
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
"noRecentActivity": "无最近活动",
|
||||
"noSendersData": "无发件人数据",
|
||||
"noLargeEmails": "无大邮件",
|
||||
"noAccountData": "无账户数据"
|
||||
"noAccountData": "无账户数据",
|
||||
"systemVersion": "系统版本"
|
||||
},
|
||||
"accounts": {
|
||||
"title": "邮件账户",
|
||||
|
||||
Reference in New Issue
Block a user