mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 20:57:17 +01:00
Add real-time session updates via Server-Sent Events
Implements push-based real-time updates for the Sessions page. New sessions now appear instantly without manual reload or polling. Changes: - Add SSE event emitter for session creation notifications - Create SSE stream endpoint at /api/websites/[id]/sessions/stream - Emit session events in tracking endpoint when sessions are created - Add useSessionStream hook to connect to SSE and invalidate queries - Fix LoadingPanel to prevent flicker during background refetches
This commit is contained in:
parent
81e27fc18c
commit
ef9a382cdd
7 changed files with 78 additions and 5 deletions
|
|
@ -28,9 +28,11 @@ export function LoadingPanel({
|
|||
...props
|
||||
}: LoadingPanelProps): ReactNode {
|
||||
const empty = isEmpty ?? checkEmpty(data);
|
||||
const hasData = data && !empty;
|
||||
|
||||
// Show loading spinner only if no data exists
|
||||
if (isLoading || isFetching) {
|
||||
// Show loading only on initial load when no data exists yet
|
||||
// Don't show loading during background refetches when we already have data
|
||||
if ((isLoading || isFetching) && !hasData) {
|
||||
return (
|
||||
<Column position="relative" height="100%" width="100%" {...props}>
|
||||
<Loading icon={loadingIcon} placement={loadingPlacement} />
|
||||
|
|
@ -48,8 +50,8 @@ export function LoadingPanel({
|
|||
return renderEmpty();
|
||||
}
|
||||
|
||||
// Show main content when data exists
|
||||
if (!isLoading && !isFetching && !error && !empty) {
|
||||
// Show content when we have data (even during background refetch)
|
||||
if (hasData) {
|
||||
return children;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ export * from './useNavigation';
|
|||
export * from './usePagedQuery';
|
||||
export * from './usePageParameters';
|
||||
export * from './useRegionNames';
|
||||
export * from './useSessionStream';
|
||||
export * from './useSlug';
|
||||
export * from './useSticky';
|
||||
export * from './useTimezone';
|
||||
|
|
|
|||
18
src/components/hooks/useSessionStream.ts
Normal file
18
src/components/hooks/useSessionStream.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
export function useSessionStream(websiteId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
useEffect(() => {
|
||||
if (!websiteId) return;
|
||||
|
||||
const eventSource = new EventSource(`/api/websites/${websiteId}/sessions/stream`);
|
||||
|
||||
eventSource.onmessage = () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['sessions'] });
|
||||
};
|
||||
|
||||
return () => eventSource.close();
|
||||
}, [websiteId, queryClient]);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue