Ready for 1.1.5-rc.1

This commit is contained in:
charlesgauthereau
2025-12-21 11:25:33 +01:00
parent 82ab2c63d6
commit b8442803d9
10 changed files with 1804 additions and 29 deletions
@@ -18,9 +18,14 @@ export const metadata: Metadata = {
export default async function RoutePage(props: PageParams<{}>) {
const agents = await db.query.agent.findMany({
where: not(eq(drizzleDb.schemas.agent.isArchived, true))
where: not(eq(drizzleDb.schemas.agent.isArchived, true)),
with: {
databases: true
}
});
console.log(agents);
if (!agents) {
notFound();
@@ -1,12 +1,10 @@
import {PageParams} from "@/types/next";
import {notFound, redirect} from "next/navigation";
import {Page, PageActions, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
import {Page, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
import {BackupButton} from "@/components/wrappers/dashboard/backup/backup-button/backup-button";
import {DatabaseTabs} from "@/components/wrappers/dashboard/projects/database/database-tabs";
import {DatabaseKpi} from "@/components/wrappers/dashboard/projects/database/database-kpi";
import {EditButton} from "@/components/wrappers/dashboard/database/edit-button/edit-button";
import {CronButton} from "@/components/wrappers/dashboard/database/cron-button/cron-button";
import {db} from "@/db";
import {eq, and, inArray} from "drizzle-orm";
import * as drizzleDb from "@/db";
@@ -92,22 +90,23 @@ export default async function RoutePage(props: PageParams<{
const isMember = activeMember?.role === "member";
return (
<Page>
<div className="justify-between gap-2 sm:flex">
<PageTitle className="flex flex-col md:flex-row items-center justify-between w-full">
<div className=" w-full md:w-fit">
<PageTitle className="flex flex-col md:flex-row items-center justify-between w-full ">
<div className="min-w-full md:min-w-fit ">
{capitalizeFirstLetter(dbItem.name)}
</div>
{!isMember && (
<div className="flex items-center gap-2 md:justify-between w-full">
<div className="flex items-center gap-2 md:justify-between w-full ">
<div className="flex items-center gap-2">
{/* Do not delete*/}
{/*<EditButton/>*/}
<RetentionPolicySheet database={dbItem}/>
<CronButton database={dbItem}/>
<AlertPolicyModal database={dbItem} notificationChannels={activeOrganizationChannels} organizationId={organization.id} />
<AlertPolicyModal database={dbItem} notificationChannels={activeOrganizationChannels}
organizationId={organization.id}/>
</div>
<div className="flex items-center gap-2">
<BackupButton disable={isAlreadyBackup} databaseId={databaseId}/>
@@ -115,6 +114,8 @@ export default async function RoutePage(props: PageParams<{
</div>
)}
</PageTitle>
</div>
{dbItem.description && (
+7 -2
View File
@@ -7,6 +7,7 @@ import {db} from "@/db";
import {EDbmsSchema} from "@/db/schema/types";
import {eq} from "drizzle-orm";
import {isUuidv4} from "@/utils/verify-uuid";
import {withUpdatedAt} from "@/db/utils";
export type databaseAgent = {
name: string,
@@ -15,12 +16,13 @@ export type databaseAgent = {
}
export type Body = {
version: string,
databases: databaseAgent[]
}
// Function to test the get file url presigned local
export async function GET(request: Request) {
const url = await getFileUrlPresignedLocal({fileName:"d4a7fa35-2506-4d01-a612-a8ef2e2cc1c5.dump"})
const url = await getFileUrlPresignedLocal({fileName: "d4a7fa35-2506-4d01-a612-a8ef2e2cc1c5.dump"})
return Response.json({
message: url
})
@@ -60,7 +62,10 @@ export async function POST(
await db
.update(drizzleDb.schemas.agent)
.set({lastContact: lastContact})
.set(withUpdatedAt({
version: body.version,
lastContact: lastContact
}))
.where(eq(drizzleDb.schemas.agent.id, agentId));
eventEmitter.emit('modification', {update: true});
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "portabase",
"version": "1.1.4",
"version": "1.1.5",
"private": true,
"scripts": {
"dev": "next dev --turbopack -p 8887",
@@ -1,17 +1,18 @@
"use client";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import {Card, CardContent, CardHeader} from "@/components/ui/card";
import Link from "next/link";
import { formatDateLastContact } from "@/utils/date-formatting";
import { ConnectionCircle } from "@/components/wrappers/common/connection-circle";
import {Agent} from "@/db/schema/08_agent";
import {formatDateLastContact} from "@/utils/date-formatting";
import {ConnectionCircle} from "@/components/wrappers/common/connection-circle";
import {Agent, AgentWith} from "@/db/schema/08_agent";
import {Activity, Database, ShieldCheck} from "lucide-react";
export type agentCardProps = {
data: Agent;
data: AgentWith;
};
export const AgentCard = (props: agentCardProps) => {
const { data: agent } = props;
const {data: agent} = props;
return (
<Link href={`/dashboard/agents/${agent.id}`}
@@ -20,10 +21,31 @@ export const AgentCard = (props: agentCardProps) => {
<Card className="flex flex-row justify-between">
<div className="flex-1 text-left">
<CardHeader className="text-2xl font-bold">{agent.name}</CardHeader>
<CardContent>Last contact: {formatDateLastContact(agent.lastContact)}</CardContent>
<CardContent>
<div className="flex flex-wrap items-center gap-x-6 gap-y-2 text-sm text-muted-foreground">
<div className="flex items-center gap-2">
<Activity className="h-4 w-4"/>
<span>{formatDateLastContact(agent.lastContact)}</span>
</div>
<div className="flex items-center gap-2">
<Database className="h-4 w-4"/>
<span>{agent.databases?.length ?? 0} DB</span>
</div>
<div className="flex items-center gap-2">
<ShieldCheck className="h-4 w-4"/>
{agent.version ?
<span>v{agent.version}</span>
:
<span>N/A</span>
}
</div>
</div>
</CardContent>
</div>
<div className="flex items-center px-4">
<ConnectionCircle date={agent.lastContact} />
<ConnectionCircle date={agent.lastContact}/>
</div>
</Card>
</Link>
@@ -0,0 +1 @@
ALTER TABLE "agents" ADD COLUMN "version" text;
File diff suppressed because it is too large Load Diff
+7
View File
@@ -85,6 +85,13 @@
"when": 1765097874110,
"tag": "0011_outgoing_blob",
"breakpoints": true
},
{
"idx": 12,
"version": "7",
"when": 1766308683196,
"tag": "0012_peaceful_leopardon",
"breakpoints": true
}
]
}
-3
View File
@@ -8,9 +8,6 @@ import {member, OrganizationMember} from "@/db/schema/04_member";
import {User} from "@/db/schema/02_user";
import {timestamps} from "@/db/schema/00_common";
import {NotificationChannel, organizationNotificationChannel} from "@/db/schema/09_notification-channel";
import {Agent} from "@/db/schema/08_agent";
import {AlertPolicy} from "@/db/schema/10_alert-policy";
import {Backup, Database, Restoration, RetentionPolicy} from "@/db/schema/07_database";
export const organization = pgTable("organization", {
id: uuid("id").defaultRandom().primaryKey(),
+10 -5
View File
@@ -1,25 +1,30 @@
import {boolean, pgTable, text, timestamp, uuid} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
import { z } from "zod";
import {database} from "@/db/schema/07_database";
import {createSelectSchema} from "drizzle-zod";
import {z} from "zod";
import {Database, database} from "@/db/schema/07_database";
import {relations} from "drizzle-orm";
import {timestamps} from "@/db/schema/00_common";
export const agent = pgTable("agents", {
id: uuid("id").primaryKey().defaultRandom(),
slug: text("slug").notNull().unique(),
version: text("version"),
name: text("name").notNull().notNull(),
description: text("description").notNull(),
isArchived: boolean("is_archived").default(false),
lastContact: timestamp("last_contact"),
...timestamps
});
export const agentSchema = createSelectSchema(agent);
export type Agent = z.infer<typeof agentSchema>;
export const agentRelations = relations(agent, ({ many }) => ({
export const agentRelations = relations(agent, ({many}) => ({
databases: many(database),
}));
export type AgentWith = Agent & {
databases?: Database[] | null;
};