mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Adding events for auto reload on data updating.
This commit is contained in:
@@ -77,6 +77,7 @@ export default async function RoutePage(props: PageParams<{ databaseId: string }
|
|||||||
totalBackups={totalBackups}
|
totalBackups={totalBackups}
|
||||||
/>
|
/>
|
||||||
<DatabaseTabs
|
<DatabaseTabs
|
||||||
|
database={database}
|
||||||
isAlreadyRestore={isAlreadyRestore}
|
isAlreadyRestore={isAlreadyRestore}
|
||||||
backups={backups}
|
backups={backups}
|
||||||
restaurations={restaurations}
|
restaurations={restaurations}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {isUuidv4} from "@/utils/verify-uuid";
|
|||||||
import {uploadLocalPrivate} from "@/features/upload/private/upload.action";
|
import {uploadLocalPrivate} from "@/features/upload/private/upload.action";
|
||||||
import {v4 as uuidv4} from "uuid";
|
import {v4 as uuidv4} from "uuid";
|
||||||
import {Backup, Database} from "@prisma/client";
|
import {Backup, Database} from "@prisma/client";
|
||||||
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -118,6 +119,7 @@ export async function POST(
|
|||||||
status: "success",
|
status: "success",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventEmitter.emit('modification', { update: true });
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
@@ -130,6 +132,7 @@ export async function POST(
|
|||||||
where: { id: backup.id },
|
where: { id: backup.id },
|
||||||
data: { status: "failed" },
|
data: { status: "failed" },
|
||||||
});
|
});
|
||||||
|
eventEmitter.emit('modification', { update: true });
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {NextResponse} from "next/server";
|
import {NextResponse} from "next/server";
|
||||||
import {isUuidv4} from "@/utils/verify-uuid";
|
import {isUuidv4} from "@/utils/verify-uuid";
|
||||||
import {prisma} from "@/prisma";
|
import {prisma} from "@/prisma";
|
||||||
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +73,10 @@ export async function POST(
|
|||||||
message: true,
|
message: true,
|
||||||
details: "Restoration successfully updated"
|
details: "Restoration successfully updated"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventEmitter.emit('modification', { update: true });
|
||||||
|
|
||||||
|
|
||||||
return Response.json(response , {status: 200})
|
return Response.json(response , {status: 200})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {NextResponse} from "next/server";
|
|||||||
import {Dbms} from "@prisma/client";
|
import {Dbms} from "@prisma/client";
|
||||||
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
||||||
import {handleDatabases} from "./helpers";
|
import {handleDatabases} from "./helpers";
|
||||||
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
|
||||||
|
|
||||||
export type databaseAgent = {
|
export type databaseAgent = {
|
||||||
@@ -50,6 +51,8 @@ export async function POST(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
eventEmitter.emit('modification', { update: true });
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
agent: {
|
agent: {
|
||||||
id: agentId,
|
id: agentId,
|
||||||
@@ -58,7 +61,6 @@ export async function POST(
|
|||||||
databases: databasesResponse
|
databases: databasesResponse
|
||||||
}
|
}
|
||||||
console.log(response)
|
console.log(response)
|
||||||
|
|
||||||
return Response.json(response)
|
return Response.json(response)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in POST handler:', error);
|
console.error('Error in POST handler:', error);
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
// import { EventEmitter } from 'events';
|
||||||
|
|
||||||
|
//
|
||||||
|
// const eventEmitter = new EventEmitter();
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// export async function GET(request: Request) {
|
||||||
|
// return new Response(new ReadableStream({
|
||||||
|
// async pull(controller) {
|
||||||
|
// eventEmitter.on('modification', (data) => {
|
||||||
|
// controller.enqueue(`event: modification\n`);
|
||||||
|
// controller.enqueue(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
|
// controller.close();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// }), {
|
||||||
|
// status: 200,
|
||||||
|
// headers: {
|
||||||
|
// 'Content-Type': 'text/event-stream',
|
||||||
|
// 'Cache-Control': 'no-cache',
|
||||||
|
// Connection: 'keep-alive',
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// export async function POST(request: Request) {
|
||||||
|
// const data = await request.json();
|
||||||
|
// eventEmitter.emit('modification', data);
|
||||||
|
// return new Response('Event sent', { status: 200 });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const eventEmitter = new EventEmitter();
|
||||||
|
//
|
||||||
|
// export async function GET(request: Request) {
|
||||||
|
// return new Response(new ReadableStream({
|
||||||
|
// async pull(controller) {
|
||||||
|
// eventEmitter.on('modification', (data) => {
|
||||||
|
// console.log('Modification event triggered:', data);
|
||||||
|
// controller.enqueue(`event: modification\n`);
|
||||||
|
// controller.enqueue(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // Close the controller when the client closes the connection
|
||||||
|
// request.signal.addEventListener('abort', () => {
|
||||||
|
// controller.close();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// }), {
|
||||||
|
// status: 200,
|
||||||
|
// headers: {
|
||||||
|
// 'Content-Type': 'text/event-stream',
|
||||||
|
// 'Cache-Control': 'no-cache',
|
||||||
|
// Connection: 'keep-alive',
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// export async function POST(request: Request) {
|
||||||
|
// const data = await request.json();
|
||||||
|
// console.log(data);
|
||||||
|
// eventEmitter.emit('modification', data);
|
||||||
|
// return new Response('Event sent', { status: 200 });
|
||||||
|
// }
|
||||||
|
// const eventEmitter = new EventEmitter();
|
||||||
|
//
|
||||||
|
// export async function GET(request: Request) {
|
||||||
|
// console.log('GET request received');
|
||||||
|
// return new Response(new ReadableStream({
|
||||||
|
// async pull(controller) {
|
||||||
|
// console.log('Controller created:', controller);
|
||||||
|
// eventEmitter.on('modification', (data) => {
|
||||||
|
// console.log('Modification event triggered:', data);
|
||||||
|
// controller.enqueue(`event: modification\n`);
|
||||||
|
// controller.enqueue(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
|
// });
|
||||||
|
// // Close the controller when the client closes the connection
|
||||||
|
// request.signal.addEventListener('abort', () => {
|
||||||
|
// controller.close();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// }), {
|
||||||
|
// status: 200,
|
||||||
|
// headers: {
|
||||||
|
// 'Content-Type': 'text/event-stream',
|
||||||
|
// 'Cache-Control': 'no-cache',
|
||||||
|
// Connection: 'keep-alive',
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// export async function POST(request: Request) {
|
||||||
|
// console.log('POST request received');
|
||||||
|
// const data = await request.json();
|
||||||
|
// console.log('Data received:', data);
|
||||||
|
// eventEmitter.emit('modification', data);
|
||||||
|
// return new Response('Event sent', { status: 200 });
|
||||||
|
// }
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
|
export const eventEmitter = new EventEmitter();
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
console.log('GET request received');
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
new ReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
console.log('Stream started');
|
||||||
|
|
||||||
|
const handleModification = (data: any) => {
|
||||||
|
console.log('Modification event triggered:', data);
|
||||||
|
controller.enqueue(`event: modification\n`);
|
||||||
|
controller.enqueue(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
|
};
|
||||||
|
|
||||||
|
eventEmitter.on('modification', handleModification);
|
||||||
|
|
||||||
|
// Handle client disconnect
|
||||||
|
request.signal.addEventListener('abort', () => {
|
||||||
|
console.log('Client disconnected');
|
||||||
|
controller.close();
|
||||||
|
eventEmitter.off('modification', handleModification);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
Connection: 'keep-alive',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
console.log('POST request received');
|
||||||
|
const data = await request.json();
|
||||||
|
console.log('Data received:', data);
|
||||||
|
|
||||||
|
// Emit the event to all connected clients
|
||||||
|
eventEmitter.emit('modification', data);
|
||||||
|
|
||||||
|
return new Response('Event sent', { status: 200 });
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ function checkRouteExists(pathname) {
|
|||||||
/^\/api\/agent\/[^/]+\/backup\/?$/,
|
/^\/api\/agent\/[^/]+\/backup\/?$/,
|
||||||
/^\/api\/agent\/[^/]+\/restore\/?$/,
|
/^\/api\/agent\/[^/]+\/restore\/?$/,
|
||||||
/^\/api\/files\/[^/]+\/?$/,
|
/^\/api\/files\/[^/]+\/?$/,
|
||||||
|
/^\/api\/events\/?$/,
|
||||||
];
|
];
|
||||||
return routePatterns.some(pattern => pattern.test(pathname));
|
return routePatterns.some(pattern => pattern.test(pathname));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,39 @@
|
|||||||
|
"use client"
|
||||||
import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs";
|
import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs";
|
||||||
import {DataTableWithPagination} from "@/components/wrappers/table/data-table-with-pagination";
|
import {DataTableWithPagination} from "@/components/wrappers/table/data-table-with-pagination";
|
||||||
import {backupColumns} from "@/features/backup/columns";
|
import {backupColumns} from "@/features/backup/columns";
|
||||||
import {restoreColumns} from "@/features/restore/columns";
|
import {restoreColumns} from "@/features/restore/columns";
|
||||||
import {Backup, Restauration} from "@prisma/client";
|
import {Backup, Database, Restauration} from "@prisma/client";
|
||||||
|
import {useEffect} from "react";
|
||||||
|
import {useRouter} from "next/navigation";
|
||||||
|
import {eventUpdate} from "@/types/events";
|
||||||
|
|
||||||
export type DatabaseTabsProps = {
|
export type DatabaseTabsProps = {
|
||||||
backups: Backup[]
|
backups: Backup[]
|
||||||
restaurations: Restauration[]
|
restaurations: Restauration[]
|
||||||
isAlreadyRestore: boolean
|
isAlreadyRestore: boolean
|
||||||
|
database: Database
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DatabaseTabs = (props: DatabaseTabsProps) => {
|
export const DatabaseTabs = (props: DatabaseTabsProps) => {
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
useEffect(() => {
|
||||||
|
const eventSource = new EventSource('/api/events');
|
||||||
|
|
||||||
|
eventSource.addEventListener('modification', (event) => {
|
||||||
|
const data:eventUpdate = JSON.parse(event.data)
|
||||||
|
if(data.update){
|
||||||
|
console.log("update", data.update)
|
||||||
|
router.refresh()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
eventSource.close();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs className="flex flex-col flex-1" defaultValue="backup">
|
<Tabs className="flex flex-col flex-1" defaultValue="backup">
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export type eventUpdate = {
|
||||||
|
update : boolean
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user