Files
portabase/src/features/database/components/database-content.tsx
T

176 lines
7.4 KiB
TypeScript
Raw Normal View History

2026-03-02 11:21:20 +01:00
"use client";
2026-06-27 17:08:38 +02:00
import {DatabaseBackupActionsModal} from "@/features/database/components/backup-actions-modal";
import {DatabaseTabs} from "@/features/database/components/database-tabs";
2026-04-24 21:42:20 +02:00
import {Setting} from "@/db/schema/01_setting";
2026-06-07 11:15:21 +02:00
import {BackupWith, DatabaseWith, RestorationWith} from "@/db/schema/07_database";
2026-04-24 21:42:20 +02:00
import {MemberWithUser} from "@/db/schema/03_organization";
2026-06-27 17:08:38 +02:00
import {useBackupModal} from "@/features/database/components/backup-modal-context";
import {DatabaseKpi} from "@/features/database/components/database-kpi";
2026-04-24 21:42:20 +02:00
import {useQuery} from "@tanstack/react-query";
2026-06-27 17:08:38 +02:00
import {getDatabaseDataAction} from "@/features/database/actions/backup-get-data.action";
2026-03-02 11:21:20 +01:00
import {
2026-04-24 21:42:20 +02:00
PageContent,
PageDescription,
PageTitle,
2026-06-27 17:08:38 +02:00
} from "@/features/layout/components/page";
2026-04-24 21:42:20 +02:00
import {capitalizeFirstLetter} from "@/utils/text";
2026-06-27 17:08:38 +02:00
import {RetentionPolicySheet} from "@/features/database/components/retention-policy-sheet";
import {CronButton} from "@/features/database/components/cron-button";
import {ChannelPoliciesModal} from "@/features/database/components/channels-policy-modal";
2026-04-24 21:42:20 +02:00
import {HardDrive, Megaphone} from "lucide-react";
2026-06-27 17:08:38 +02:00
import {ImportModal} from "@/features/database/components/import-modal";
import {BackupButton} from "@/features/database/components/backup-button";
import {HealthModal} from "@/features/database/components/health-modal";
2026-03-28 16:35:02 +01:00
import {HealthcheckLog} from "@/db/schema/15_healthcheck-log";
2026-04-29 22:39:37 +02:00
import {Badge} from "@/components/ui/badge";
2026-06-27 17:08:38 +02:00
import {LogsModal} from "@/features/logs/components/logs-modal";
export type DatabaseContentProps = {
2026-04-24 21:42:20 +02:00
settings: Setting;
backups: BackupWith[];
2026-06-07 11:15:21 +02:00
restorations: RestorationWith[];
2026-04-24 21:42:20 +02:00
isAlreadyRestore: boolean;
database: DatabaseWith;
activeMember: MemberWithUser;
totalBackups: number;
availableBackups: number;
successRate: number | null;
organizationId: string;
activeOrganizationChannels: any[];
activeOrganizationStorageChannels: any[];
databaseHealthLogs: HealthcheckLog[]
2026-03-02 11:21:20 +01:00
};
2026-02-10 11:44:45 +01:00
export const DatabaseContent = (props: DatabaseContentProps) => {
2026-04-24 21:42:20 +02:00
const {} = useBackupModal();
2026-04-24 21:42:20 +02:00
const {data} = useQuery({
queryKey: ["database-data", props.database.id],
queryFn: async () => {
const result = await getDatabaseDataAction({
databaseId: props.database.id,
});
return result?.data;
},
initialData: {
// TODO : to be patched
// @ts-ignore
database: {
...props.database,
project: props.database.project ?? null,
},
backups: props.backups,
restorations: props.restorations,
activeOrganizationChannels: props.activeOrganizationChannels,
activeOrganizationStorageChannels:
props.activeOrganizationStorageChannels,
stats: {
totalBackups: props.totalBackups,
availableBackups: props.availableBackups,
successRate: props.successRate,
},
health: props.databaseHealthLogs
},
staleTime: 0,
gcTime: 0,
refetchInterval: 1000,
});
const database = data?.database ?? props.database;
const backups = data?.backups ?? props.backups;
const restorations = data?.restorations ?? props.restorations;
const activeOrganizationChannels =
data?.activeOrganizationChannels ?? props.activeOrganizationChannels;
const activeOrganizationStorageChannels =
data?.activeOrganizationStorageChannels ??
props.activeOrganizationStorageChannels;
const stats = data?.stats ?? {
2026-02-10 11:44:45 +01:00
totalBackups: props.totalBackups,
availableBackups: props.availableBackups,
2026-03-02 11:21:20 +01:00
successRate: props.successRate,
2026-04-24 21:42:20 +02:00
};
2026-02-10 11:44:45 +01:00
2026-04-24 21:42:20 +02:00
const isAlreadyRestore = restorations.some((r) => r.status === "waiting");
const isAlreadyBackup = backups.some(
(b) => b.status === "waiting" || b.status === "ongoing",
);
2026-02-10 11:44:45 +01:00
2026-04-24 21:42:20 +02:00
const isMember = props.activeMember.role === "member";
2026-02-10 11:44:45 +01:00
2026-04-24 21:42:20 +02:00
return (
<>
<div className="justify-between gap-2 sm:flex">
<PageTitle className="flex flex-col md:flex-row items-center justify-between w-full ">
2026-04-29 22:39:37 +02:00
<div className="flex min-w-full md:min-w-fit justify-between gap-2 items-center ">
2026-04-24 21:42:20 +02:00
{capitalizeFirstLetter(database.name)}
2026-04-29 22:39:37 +02:00
<div className=" flex items-center justify-center">
<Badge variant="outline" className="bg-orange-400/10 border-orange-600/50 text-orange-600">
{database.dbms}
</Badge>
</div>
2026-04-24 21:42:20 +02:00
</div>
{!isMember && (
<div className="flex items-center gap-2 md:justify-between w-full ">
<div className="flex items-center gap-2">
<RetentionPolicySheet database={database}/>
<CronButton database={database}/>
<ChannelPoliciesModal
database={database}
kind={"notification"}
icon={<Megaphone/>}
channels={activeOrganizationChannels}
organizationId={props.organizationId}
/>
<ChannelPoliciesModal
database={database}
icon={<HardDrive/>}
kind={"storage"}
channels={activeOrganizationStorageChannels}
organizationId={props.organizationId}
/>
2026-07-05 16:33:28 +02:00
{database.dbms != "docker-volume" && (
<ImportModal database={database}/>
)}
2026-04-24 21:42:20 +02:00
<HealthModal database={database} healthLogs={data?.health ?? []}/>
</div>
2026-03-28 16:35:02 +01:00
2026-04-24 21:42:20 +02:00
<div className="flex items-center gap-2">
<BackupButton
disable={isAlreadyBackup || !database.lastContact}
databaseId={database.id}
/>
</div>
</div>
)}
</PageTitle>
2026-02-10 11:44:45 +01:00
</div>
2026-04-24 21:42:20 +02:00
{database.description && (
<PageDescription className="mt-5 sm:mt-0">
{database.description}
</PageDescription>
)}
2026-02-10 11:44:45 +01:00
2026-04-24 21:42:20 +02:00
<PageContent className="flex flex-col w-full h-full">
<DatabaseKpi
successRate={stats.successRate}
database={database}
availableBackups={stats.availableBackups}
totalBackups={stats.totalBackups}
/>
2026-06-06 22:46:36 +02:00
<LogsModal/>
2026-04-24 21:42:20 +02:00
<DatabaseBackupActionsModal/>
<DatabaseTabs
activeMember={props.activeMember}
settings={props.settings}
database={database}
isAlreadyRestore={isAlreadyRestore}
backups={backups}
restorations={restorations}
/>
</PageContent>
</>
);
2026-03-02 11:21:20 +01:00
};