diff --git a/keep-ui/app/ai/ai.tsx b/keep-ui/app/ai/ai.tsx
index 7e9d23aa7..2446337a7 100644
--- a/keep-ui/app/ai/ai.tsx
+++ b/keep-ui/app/ai/ai.tsx
@@ -1,7 +1,7 @@
"use client";
import { Card, List, ListItem, Title, Subtitle } from "@tremor/react";
import { useAIStats, usePollAILogs } from "utils/hooks/useAI";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { toast } from "react-toastify";
import { useEffect, useState, useRef, FormEvent } from "react";
diff --git a/keep-ui/app/alerts/ViewAlertModal.tsx b/keep-ui/app/alerts/ViewAlertModal.tsx
index 6bbeca28f..7bc404172 100644
--- a/keep-ui/app/alerts/ViewAlertModal.tsx
+++ b/keep-ui/app/alerts/ViewAlertModal.tsx
@@ -3,7 +3,7 @@ import Modal from "@/components/ui/Modal"; // Ensure this path matches your proj
import { Button, Icon, Switch, Text } from "@tremor/react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { XMarkIcon } from "@heroicons/react/24/outline";
import "./ViewAlertModal.css";
import React, { useState } from "react";
diff --git a/keep-ui/app/alerts/alert-assign-ticket-modal.tsx b/keep-ui/app/alerts/alert-assign-ticket-modal.tsx
index f3920c764..0ca7bae0a 100644
--- a/keep-ui/app/alerts/alert-assign-ticket-modal.tsx
+++ b/keep-ui/app/alerts/alert-assign-ticket-modal.tsx
@@ -4,7 +4,7 @@ import { Button, TextInput, Text } from "@tremor/react";
import { PlusIcon } from "@heroicons/react/20/solid";
import { useForm, Controller, SubmitHandler } from "react-hook-form";
import { Providers } from "./../providers/providers";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { AlertDto } from "./models";
import Modal from "@/components/ui/Modal";
diff --git a/keep-ui/app/alerts/alert-associate-incident-modal.tsx b/keep-ui/app/alerts/alert-associate-incident-modal.tsx
index 9d59afdbf..923d30cd8 100644
--- a/keep-ui/app/alerts/alert-associate-incident-modal.tsx
+++ b/keep-ui/app/alerts/alert-associate-incident-modal.tsx
@@ -2,7 +2,7 @@ import Modal from "@/components/ui/Modal";
import { Button, Divider, Title } from "@tremor/react";
import Select from "@/components/ui/Select";
import { CreateOrUpdateIncidentForm } from "@/features/create-or-update-incident";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { FormEvent, useCallback, useEffect, useState } from "react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
diff --git a/keep-ui/app/alerts/alert-change-status-modal.tsx b/keep-ui/app/alerts/alert-change-status-modal.tsx
index d090599dc..f68f46e61 100644
--- a/keep-ui/app/alerts/alert-change-status-modal.tsx
+++ b/keep-ui/app/alerts/alert-change-status-modal.tsx
@@ -9,7 +9,7 @@ import Select, {
import { useState } from "react";
import { AlertDto, Status } from "./models";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
import {
CheckCircleIcon,
diff --git a/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx b/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx
index ada499e65..9d077ed66 100644
--- a/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx
+++ b/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx
@@ -1,7 +1,7 @@
import React, { useState } from "react";
import Modal from "@/components/ui/Modal";
import { Callout, Button, Title, Card } from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
import Loading from "../loading";
import { AlertDto } from "./models";
diff --git a/keep-ui/app/alerts/alert-dismiss-modal.tsx b/keep-ui/app/alerts/alert-dismiss-modal.tsx
index 11bf3d63f..93976f22d 100644
--- a/keep-ui/app/alerts/alert-dismiss-modal.tsx
+++ b/keep-ui/app/alerts/alert-dismiss-modal.tsx
@@ -17,7 +17,7 @@ import "react-quill/dist/quill.snow.css";
import { AlertDto } from "./models";
import { format, set, isSameDay, isAfter, addMinutes } from "date-fns";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { usePresets } from "utils/hooks/usePresets";
import { useAlerts } from "utils/hooks/useAlerts";
import { toast } from "react-toastify";
diff --git a/keep-ui/app/alerts/alert-menu.tsx b/keep-ui/app/alerts/alert-menu.tsx
index 997be6959..4784090d2 100644
--- a/keep-ui/app/alerts/alert-menu.tsx
+++ b/keep-ui/app/alerts/alert-menu.tsx
@@ -12,7 +12,7 @@ import {
} from "@heroicons/react/24/outline";
import { IoNotificationsOffOutline } from "react-icons/io5";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import Link from "next/link";
import { ProviderMethod } from "app/providers/providers";
diff --git a/keep-ui/app/alerts/alert-note-modal.tsx b/keep-ui/app/alerts/alert-note-modal.tsx
index a737059a9..fb9f6910b 100644
--- a/keep-ui/app/alerts/alert-note-modal.tsx
+++ b/keep-ui/app/alerts/alert-note-modal.tsx
@@ -7,7 +7,7 @@ const ReactQuill =
import "react-quill/dist/quill.snow.css";
import { Button } from "@tremor/react";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { AlertDto } from "./models";
import Modal from "@/components/ui/Modal";
diff --git a/keep-ui/app/alerts/alert-presets.tsx b/keep-ui/app/alerts/alert-presets.tsx
index 5263b7b1f..217ff5fc2 100644
--- a/keep-ui/app/alerts/alert-presets.tsx
+++ b/keep-ui/app/alerts/alert-presets.tsx
@@ -4,7 +4,7 @@ import Modal from "@/components/ui/Modal";
import { Button, Subtitle, TextInput, Switch, Text } from "@tremor/react";
import { useApiUrl } from "utils/hooks/useConfig";
import { toast } from "react-toastify";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { usePresets } from "utils/hooks/usePresets";
import { useTags } from "utils/hooks/useTags";
import { useRouter } from "next/navigation";
diff --git a/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx b/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx
index 76931c8ed..44576e546 100644
--- a/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx
+++ b/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx
@@ -7,7 +7,7 @@ import {
FieldValues,
} from "react-hook-form";
import Modal from "@/components/ui/Modal";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { useProviders } from "utils/hooks/useProviders";
import ImageWithFallback from "@/components/ImageWithFallback";
diff --git a/keep-ui/app/alerts/alert-run-workflow-modal.tsx b/keep-ui/app/alerts/alert-run-workflow-modal.tsx
index 3ade1e15a..514719fb4 100644
--- a/keep-ui/app/alerts/alert-run-workflow-modal.tsx
+++ b/keep-ui/app/alerts/alert-run-workflow-modal.tsx
@@ -3,7 +3,7 @@ import { AlertDto } from "./models";
import Modal from "@/components/ui/Modal";
import { useWorkflows } from "utils/hooks/useWorkflows";
import { useState } from "react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
diff --git a/keep-ui/app/alerts/alert-tab-modal.tsx b/keep-ui/app/alerts/alert-tab-modal.tsx
index d5a99e7d6..c8a2b232d 100644
--- a/keep-ui/app/alerts/alert-tab-modal.tsx
+++ b/keep-ui/app/alerts/alert-tab-modal.tsx
@@ -2,7 +2,7 @@ import { useState } from "react";
import Modal from "@/components/ui/Modal";
import { Button, TextInput } from "@tremor/react";
import { AlertsRulesBuilder } from "app/alerts/alerts-rules-builder";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
interface AlertTabModalProps {
@@ -114,8 +114,8 @@ const AlertTabModal = ({
!newTabName
? "Tab name is required"
: !newTabFilter
- ? "Tab filter is required (notice you need to click 'enter' to apply the filter)"
- : ""
+ ? "Tab filter is required (notice you need to click 'enter' to apply the filter)"
+ : ""
}
>
Add Tab
diff --git a/keep-ui/app/alerts/alert-tabs.tsx b/keep-ui/app/alerts/alert-tabs.tsx
index 42c8ea938..2413c4076 100644
--- a/keep-ui/app/alerts/alert-tabs.tsx
+++ b/keep-ui/app/alerts/alert-tabs.tsx
@@ -5,7 +5,7 @@ import AlertTabModal from "./alert-tab-modal";
import { evalWithContext } from "./alerts-rules-builder";
import { XMarkIcon } from "@heroicons/react/24/outline";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
interface Tab {
id?: string;
name: string;
diff --git a/keep-ui/app/alerts/alerts.tsx b/keep-ui/app/alerts/alerts.tsx
index 3aa011e64..4d0fe7117 100644
--- a/keep-ui/app/alerts/alerts.tsx
+++ b/keep-ui/app/alerts/alerts.tsx
@@ -18,8 +18,7 @@ import { useRouter, useSearchParams } from "next/navigation";
import AlertChangeStatusModal from "./alert-change-status-modal";
import { useAlertPolling } from "utils/hooks/usePusher";
import NotFound from "@/app/not-found";
-import { useMounted } from "@/shared/lib/hooks/useMounted";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
const defaultPresets: Preset[] = [
{
@@ -111,7 +110,6 @@ export default function Alerts({ presetName }: AlertsProps) {
error: alertsError,
} = usePresetAlerts(selectedPreset ? selectedPreset.name : "");
- // const isMounted = useMounted();
const { status: sessionStatus } = useSession();
const isLoading = isAsyncLoading || sessionStatus === "loading";
diff --git a/keep-ui/app/auth-provider.tsx b/keep-ui/app/auth-provider.tsx
index 21e157dfc..8a3107208 100644
--- a/keep-ui/app/auth-provider.tsx
+++ b/keep-ui/app/auth-provider.tsx
@@ -1,11 +1,24 @@
"use client";
+import { Session } from "next-auth";
import { SessionProvider } from "next-auth/react";
+declare global {
+ interface Window {
+ __NEXT_AUTH_SESSION__?: Session | null;
+ }
+}
+
type Props = {
children?: React.ReactNode;
+ session?: Session | null;
};
-export const NextAuthProvider = ({ children }: Props) => {
- return {children}
+export const NextAuthProvider = ({ children, session }: Props) => {
+ // Hydrate session on mount
+ if (typeof window !== "undefined" && !!session) {
+ window.__NEXT_AUTH_SESSION__ = session;
+ }
+
+ return {children};
};
diff --git a/keep-ui/app/dashboard/[id]/dashboard.tsx b/keep-ui/app/dashboard/[id]/dashboard.tsx
index 77b060624..965f7f5fa 100644
--- a/keep-ui/app/dashboard/[id]/dashboard.tsx
+++ b/keep-ui/app/dashboard/[id]/dashboard.tsx
@@ -1,20 +1,29 @@
"use client";
-import {useParams} from "next/navigation";
-import {ChangeEvent, useEffect, useState} from "react";
+import { useParams } from "next/navigation";
+import { ChangeEvent, useEffect, useState } from "react";
import GridLayout from "../GridLayout";
import WidgetModal from "../WidgetModal";
-import {Button, Card, Icon, Subtitle, TextInput} from "@tremor/react";
-import {GenericsMetrics, LayoutItem, Threshold, WidgetData, WidgetType} from "../types";
-import {Preset} from "app/alerts/models";
-import {FiEdit2, FiSave} from "react-icons/fi";
-import {useSession} from "next-auth/react";
-import {useDashboards} from "utils/hooks/useDashboards";
-import {useApiUrl} from "utils/hooks/useConfig";
+import { Button, Card, Icon, Subtitle, TextInput } from "@tremor/react";
+import {
+ GenericsMetrics,
+ LayoutItem,
+ Threshold,
+ WidgetData,
+ WidgetType,
+} from "../types";
+import { Preset } from "app/alerts/models";
+import { FiEdit2, FiSave } from "react-icons/fi";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
+import { useDashboards } from "utils/hooks/useDashboards";
+import { useApiUrl } from "utils/hooks/useConfig";
import "./../styles.css";
-import {toast} from "react-toastify";
-import {GenericFilters} from "@/components/filters/GenericFilters";
-import {useDashboardPreset} from "utils/hooks/useDashboardPresets";
-import {MetricsWidget, useDashboardMetricWidgets} from '@/utils/hooks/useDashboardMetricWidgets';
+import { toast } from "react-toastify";
+import { GenericFilters } from "@/components/filters/GenericFilters";
+import { useDashboardPreset } from "utils/hooks/useDashboardPresets";
+import {
+ MetricsWidget,
+ useDashboardMetricWidgets,
+} from "@/utils/hooks/useDashboardMetricWidgets";
const DASHBOARD_FILTERS = [
{
@@ -33,7 +42,7 @@ const DashboardPage = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [layout, setLayout] = useState([]);
const [widgetData, setWidgetData] = useState([]);
- const {widgets: allMetricWidgets} = useDashboardMetricWidgets(true);
+ const { widgets: allMetricWidgets } = useDashboardMetricWidgets(true);
const [editingItem, setEditingItem] = useState(null);
const [dashboardName, setDashboardName] = useState(decodeURIComponent(id));
const [isEditingName, setIsEditingName] = useState(false);
@@ -59,7 +68,9 @@ const DashboardPage = () => {
const closeModal = () => setIsModalOpen(false);
const handleAddWidget = (
- name: string, widgetType: WidgetType, preset?: Preset ,
+ name: string,
+ widgetType: WidgetType,
+ preset?: Preset,
thresholds?: Threshold[],
metric?: MetricsWidget,
genericMetrics?: GenericsMetrics
@@ -69,10 +80,25 @@ const DashboardPage = () => {
i: uniqueId,
x: (layout.length % 12) * 2,
y: Math.floor(layout.length / 12) * 2,
- w: widgetType === WidgetType.GENERICS_METRICS ? 12 : widgetType === WidgetType.METRIC ? 6 : 3,
- h: widgetType === WidgetType.GENERICS_METRICS ? 20 : widgetType === WidgetType.METRIC ? 8 : 3,
+ w:
+ widgetType === WidgetType.GENERICS_METRICS
+ ? 12
+ : widgetType === WidgetType.METRIC
+ ? 6
+ : 3,
+ h:
+ widgetType === WidgetType.GENERICS_METRICS
+ ? 20
+ : widgetType === WidgetType.METRIC
+ ? 8
+ : 3,
minW: widgetType === WidgetType.GENERICS_METRICS ? 10 : 2,
- minH: widgetType === WidgetType.GENERICS_METRICS ? 15 : widgetType === WidgetType.METRIC ? 7 : 3,
+ minH:
+ widgetType === WidgetType.GENERICS_METRICS
+ ? 15
+ : widgetType === WidgetType.METRIC
+ ? 7
+ : 3,
static: false,
};
const newWidget: WidgetData = {
@@ -82,7 +108,7 @@ const DashboardPage = () => {
name,
widgetType,
genericMetrics,
- metric
+ metric,
};
setLayout((prevLayout) => [...prevLayout, newItem]);
setWidgetData((prevData) => [...prevData, newWidget]);
@@ -90,7 +116,6 @@ const DashboardPage = () => {
const handleEditWidget = (id: string, update?: WidgetData) => {
let itemToEdit = widgetData.find((d) => d.i === id) || null;
- console.log(itemToEdit, update)
if (itemToEdit && update) {
setEditingItem({ ...itemToEdit, ...update });
} else {
diff --git a/keep-ui/app/deduplication/DeduplicationSidebar.tsx b/keep-ui/app/deduplication/DeduplicationSidebar.tsx
index 0a3bf8943..48a6d808e 100644
--- a/keep-ui/app/deduplication/DeduplicationSidebar.tsx
+++ b/keep-ui/app/deduplication/DeduplicationSidebar.tsx
@@ -24,7 +24,7 @@ import {
InformationCircleIcon,
} from "@heroicons/react/24/outline";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { KeyedMutator } from "swr";
interface ProviderOption {
diff --git a/keep-ui/app/deduplication/DeduplicationTable.tsx b/keep-ui/app/deduplication/DeduplicationTable.tsx
index 05d634451..3951fbaaa 100644
--- a/keep-ui/app/deduplication/DeduplicationTable.tsx
+++ b/keep-ui/app/deduplication/DeduplicationTable.tsx
@@ -25,7 +25,7 @@ import DeduplicationSidebar from "app/deduplication/DeduplicationSidebar";
import { TrashIcon, PauseIcon, PlusIcon } from "@heroicons/react/24/outline";
import Image from "next/image";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
const columnHelper = createColumnHelper();
diff --git a/keep-ui/app/extraction/create-or-update-extraction-rule.tsx b/keep-ui/app/extraction/create-or-update-extraction-rule.tsx
index a770f68c9..11d7c032b 100644
--- a/keep-ui/app/extraction/create-or-update-extraction-rule.tsx
+++ b/keep-ui/app/extraction/create-or-update-extraction-rule.tsx
@@ -13,7 +13,7 @@ import {
Switch,
Badge,
} from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { FormEvent, useEffect, useState } from "react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
diff --git a/keep-ui/app/extraction/extractions-table.tsx b/keep-ui/app/extraction/extractions-table.tsx
index 48fcb7f51..7b621b05b 100644
--- a/keep-ui/app/extraction/extractions-table.tsx
+++ b/keep-ui/app/extraction/extractions-table.tsx
@@ -18,7 +18,7 @@ import {
useReactTable,
} from "@tanstack/react-table";
import { MdRemoveCircle, MdModeEdit } from "react-icons/md";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { useMappings } from "utils/hooks/useMappingRules";
import { toast } from "react-toastify";
diff --git a/keep-ui/app/frigade-provider.tsx b/keep-ui/app/frigade-provider.tsx
index 3d98f4aa3..2ae5b4619 100644
--- a/keep-ui/app/frigade-provider.tsx
+++ b/keep-ui/app/frigade-provider.tsx
@@ -1,7 +1,7 @@
"use client";
import * as Frigade from "@frigade/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
export const FrigadeProvider = ({
children,
}: {
@@ -14,7 +14,7 @@ export const FrigadeProvider = ({
userId={
session?.user.email === "keep"
? undefined
- : session?.user.email ?? session?.user.name
+ : (session?.user.email ?? session?.user.name)
}
theme={{
colors: {
diff --git a/keep-ui/app/incidents/[id]/activity/incident-activity.tsx b/keep-ui/app/incidents/[id]/activity/incident-activity.tsx
index 3b6ea0787..7a62633f6 100644
--- a/keep-ui/app/incidents/[id]/activity/incident-activity.tsx
+++ b/keep-ui/app/incidents/[id]/activity/incident-activity.tsx
@@ -11,7 +11,7 @@ import {
usePollIncidentComments,
} from "@/utils/hooks/useIncidents";
import { useAlerts } from "@/utils/hooks/useAlerts";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { IncidentActivityItem } from "./ui/IncidentActivityItem";
import { IncidentActivityComment } from "./ui/IncidentActivityComment";
import { useMemo } from "react";
diff --git a/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx b/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx
index 2cd8f0b77..d015b02e9 100644
--- a/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx
+++ b/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx
@@ -2,7 +2,7 @@ import { IncidentDto } from "@/entities/incidents/model";
import { AuditEvent } from "@/utils/hooks/useAlerts";
import { useApiUrl } from "@/utils/hooks/useConfig";
import { TextInput, Button } from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useState, useCallback, useEffect } from "react";
import { toast } from "react-toastify";
import { KeyedMutator } from "swr";
diff --git a/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx b/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx
index 03d7c615e..f902df664 100644
--- a/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx
+++ b/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx
@@ -1,6 +1,6 @@
import { Icon } from "@tremor/react";
import { AlertDto } from "app/alerts/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
import { useIncidentAlerts } from "utils/hooks/useIncidents";
diff --git a/keep-ui/app/layout.tsx b/keep-ui/app/layout.tsx
index d7b0f90ab..a8ee5503a 100644
--- a/keep-ui/app/layout.tsx
+++ b/keep-ui/app/layout.tsx
@@ -7,11 +7,13 @@ import { TopologyPollingContextProvider } from "@/app/topology/model/TopologyPol
import { FrigadeProvider } from "./frigade-provider";
import { getConfig } from "@/shared/lib/server/getConfig";
import { ConfigProvider } from "./config-provider";
-import "./globals.css";
-import "react-toastify/dist/ReactToastify.css";
import { PHProvider } from "./posthog-provider";
import dynamic from "next/dynamic";
import ReadOnlyBanner from "./read-only-banner";
+import { getServerSession } from "next-auth";
+import { authOptions } from "@/pages/api/auth/[...nextauth]";
+import "./globals.css";
+import "react-toastify/dist/ReactToastify.css";
const PostHogPageView = dynamic(() => import("@/shared/ui/PostHogPageView"), {
ssr: false,
@@ -29,12 +31,14 @@ type RootLayoutProps = {
export default async function RootLayout({ children }: RootLayoutProps) {
const config = getConfig();
+ const session = await getServerSession(authOptions);
+
return (
-
+
{/* @ts-ignore-error Server Component */}
diff --git a/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx b/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx
index fc50ca66d..9a71bc59f 100644
--- a/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx
+++ b/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx
@@ -10,7 +10,7 @@ import {
Select,
SelectItem,
} from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { FormEvent, useEffect, useState } from "react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
diff --git a/keep-ui/app/maintenance/maintenance-rules-table.tsx b/keep-ui/app/maintenance/maintenance-rules-table.tsx
index 819caa4c6..790082e83 100644
--- a/keep-ui/app/maintenance/maintenance-rules-table.tsx
+++ b/keep-ui/app/maintenance/maintenance-rules-table.tsx
@@ -17,7 +17,7 @@ import {
useReactTable,
} from "@tanstack/react-table";
import { MdRemoveCircle, MdModeEdit } from "react-icons/md";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
import { MaintenanceRule } from "./model";
diff --git a/keep-ui/app/mapping/create-or-edit-mapping.tsx b/keep-ui/app/mapping/create-or-edit-mapping.tsx
index 0145999fa..5c0b61a95 100644
--- a/keep-ui/app/mapping/create-or-edit-mapping.tsx
+++ b/keep-ui/app/mapping/create-or-edit-mapping.tsx
@@ -17,7 +17,7 @@ import {
TabPanels,
TabPanel,
} from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import {
ChangeEvent,
FormEvent,
diff --git a/keep-ui/app/mapping/rules-table.tsx b/keep-ui/app/mapping/rules-table.tsx
index 476ec90f3..dc80a5326 100644
--- a/keep-ui/app/mapping/rules-table.tsx
+++ b/keep-ui/app/mapping/rules-table.tsx
@@ -18,7 +18,7 @@ import {
ExpandedState,
} from "@tanstack/react-table";
import { MdRemoveCircle, MdModeEdit } from "react-icons/md";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { useMappings } from "utils/hooks/useMappingRules";
import { toast } from "react-toastify";
diff --git a/keep-ui/app/providers/page.client.tsx b/keep-ui/app/providers/page.client.tsx
index b44cdf109..aac212780 100644
--- a/keep-ui/app/providers/page.client.tsx
+++ b/keep-ui/app/providers/page.client.tsx
@@ -1,6 +1,6 @@
"use client";
import { defaultProvider, Provider } from "./providers";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { KeepApiError } from "@/shared/lib/KeepApiError";
import { useApiUrl } from "utils/hooks/useConfig";
import ProvidersTiles from "./providers-tiles";
diff --git a/keep-ui/app/providers/provider-form.tsx b/keep-ui/app/providers/provider-form.tsx
index 80e519a7d..5d59cf35a 100644
--- a/keep-ui/app/providers/provider-form.tsx
+++ b/keep-ui/app/providers/provider-form.tsx
@@ -2,7 +2,7 @@
// There's also a lot of s**t in here, but it works for now 🤷♂️
// @ts-nocheck
import React, { useEffect, useState, useRef, useCallback } from "react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { Provider } from "./providers";
import { useApiUrl } from "utils/hooks/useConfig";
import Image from "next/image";
diff --git a/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx b/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx
index ffb225c04..29d5d8fa2 100644
--- a/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx
+++ b/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx
@@ -7,7 +7,7 @@ import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { CorrelationForm } from "./CorrelationForm";
import { CorrelationGroups } from "./CorrelationGroups";
import { CorrelationSubmission } from "./CorrelationSubmission";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useRules } from "utils/hooks/useRules";
import { CorrelationForm as CorrelationFormType } from ".";
import { useRouter, useSearchParams } from "next/navigation";
diff --git a/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx b/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx
index feabbeb1d..992a2151c 100644
--- a/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx
+++ b/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx
@@ -1,6 +1,6 @@
import { TrashIcon } from "@radix-ui/react-icons";
import { Button } from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { MouseEvent } from "react";
import { useApiUrl } from "utils/hooks/useConfig";
import { useRules } from "utils/hooks/useRules";
diff --git a/keep-ui/app/settings/auth/permissions-tab.tsx b/keep-ui/app/settings/auth/permissions-tab.tsx
index 6a98e5445..702b00811 100644
--- a/keep-ui/app/settings/auth/permissions-tab.tsx
+++ b/keep-ui/app/settings/auth/permissions-tab.tsx
@@ -10,7 +10,7 @@ import Loading from "app/loading";
import { PermissionsTable } from "./permissions-table";
import PermissionSidebar from "./permissions-sidebar";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
interface Props {
accessToken: string;
diff --git a/keep-ui/app/settings/auth/users-sidebar.tsx b/keep-ui/app/settings/auth/users-sidebar.tsx
index 7c5752ed5..b485ec6af 100644
--- a/keep-ui/app/settings/auth/users-sidebar.tsx
+++ b/keep-ui/app/settings/auth/users-sidebar.tsx
@@ -5,8 +5,6 @@ import {
Subtitle,
Button,
TextInput,
- SearchSelect,
- SearchSelectItem,
MultiSelect,
MultiSelectItem,
Callout,
@@ -21,7 +19,7 @@ import {
import { useRoles } from "utils/hooks/useRoles";
import { useGroups } from "utils/hooks/useGroups";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { User, Group } from "app/settings/models";
import { AuthenticationType } from "utils/authenticationType";
import { useConfig } from "utils/hooks/useConfig";
@@ -105,7 +103,9 @@ const UsersSidebar = ({
}, [user, setValue, isOpen, reset, clearErrors, identifierType]);
const onSubmit: SubmitHandler = async (data) => {
- if (!userCreationAllowed) return;
+ if (!userCreationAllowed) {
+ return;
+ }
setIsSubmitting(true);
clearErrors("root.serverError");
@@ -385,8 +385,8 @@ const UsersSidebar = ({
{isSubmitting
? "Saving..."
: isNewUser
- ? "Create User"
- : "Save"}
+ ? "Create User"
+ : "Save"}
)}
diff --git a/keep-ui/app/settings/settings.client.tsx b/keep-ui/app/settings/settings.client.tsx
index 0b8c213b2..36d912a69 100644
--- a/keep-ui/app/settings/settings.client.tsx
+++ b/keep-ui/app/settings/settings.client.tsx
@@ -11,7 +11,7 @@ import {
LockClosedIcon,
} from "@heroicons/react/24/outline";
import { MdOutlineSecurity } from "react-icons/md";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useConfig } from "utils/hooks/useConfig";
import { AuthenticationType } from "utils/authenticationType";
@@ -73,24 +73,24 @@ export default function SettingsPage() {
newSelectedTab === "users"
? 0
: newSelectedTab === "webhook"
- ? 1
- : newSelectedTab === "smtp"
- ? 2
- : 0;
+ ? 1
+ : newSelectedTab === "smtp"
+ ? 2
+ : 0;
const userSubTabIndex =
newUserSubTab === "users"
? 0
: newUserSubTab === "groups"
- ? 1
- : newUserSubTab === "roles"
- ? 2
- : newUserSubTab === "permissions"
- ? 3
- : newUserSubTab === "api-keys"
- ? 4
- : newUserSubTab === "sso"
- ? 5
- : 0;
+ ? 1
+ : newUserSubTab === "roles"
+ ? 2
+ : newUserSubTab === "permissions"
+ ? 3
+ : newUserSubTab === "api-keys"
+ ? 4
+ : newUserSubTab === "sso"
+ ? 5
+ : 0;
setTabIndex(tabIndex);
setUserSubTabIndex(userSubTabIndex);
setSelectedTab(newSelectedTab);
diff --git a/keep-ui/app/topology/model/useTopology.ts b/keep-ui/app/topology/model/useTopology.ts
index 41f42354f..b93d42c48 100644
--- a/keep-ui/app/topology/model/useTopology.ts
+++ b/keep-ui/app/topology/model/useTopology.ts
@@ -1,5 +1,5 @@
import { TopologyService } from "@/app/topology/model/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { fetcher } from "@/utils/fetcher";
import { useEffect } from "react";
diff --git a/keep-ui/app/topology/model/useTopologyApplications.ts b/keep-ui/app/topology/model/useTopologyApplications.ts
index eb6c34b61..eb749d254 100644
--- a/keep-ui/app/topology/model/useTopologyApplications.ts
+++ b/keep-ui/app/topology/model/useTopologyApplications.ts
@@ -2,7 +2,7 @@ import { TopologyApplication } from "./models";
import { useApiUrl } from "utils/hooks/useConfig";
import useSWR, { SWRConfiguration } from "swr";
import { fetcher } from "@/utils/fetcher";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useCallback, useMemo } from "react";
import { useTopologyBaseKey, useTopology } from "./useTopology";
import { useRevalidateMultiple } from "@/utils/state";
diff --git a/keep-ui/app/workflows/[workflow_id]/executions.tsx b/keep-ui/app/workflows/[workflow_id]/executions.tsx
index 86df4cd2b..963588fcd 100644
--- a/keep-ui/app/workflows/[workflow_id]/executions.tsx
+++ b/keep-ui/app/workflows/[workflow_id]/executions.tsx
@@ -1,7 +1,7 @@
"use client";
import { Callout, Card } from "@tremor/react";
import React, { useEffect, useState } from "react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
import Loading from "app/loading";
import { useRouter } from "next/navigation";
diff --git a/keep-ui/app/workflows/builder/page.client.tsx b/keep-ui/app/workflows/builder/page.client.tsx
index 73f9223d2..fd418e388 100644
--- a/keep-ui/app/workflows/builder/page.client.tsx
+++ b/keep-ui/app/workflows/builder/page.client.tsx
@@ -9,7 +9,7 @@ import {
ArrowUpOnSquareIcon,
PlayIcon,
} from "@heroicons/react/20/solid";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { BuilderCard } from "./builder-card";
import Loading from "../../loading";
diff --git a/keep-ui/app/workflows/builder/workflow-execution-results.tsx b/keep-ui/app/workflows/builder/workflow-execution-results.tsx
index b468682e2..5983214b7 100644
--- a/keep-ui/app/workflows/builder/workflow-execution-results.tsx
+++ b/keep-ui/app/workflows/builder/workflow-execution-results.tsx
@@ -7,7 +7,7 @@ import {
Card,
Title,
} from "@tremor/react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import Loading from "../../loading";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
@@ -211,8 +211,8 @@ export function ExecutionResults({
log.message?.includes("NOT to run")
? "bg-red-100"
: log.message?.includes("evaluated to run")
- ? "bg-green-100"
- : ""
+ ? "bg-green-100"
+ : ""
}`}
key={index}
>
diff --git a/keep-ui/app/workflows/dragndrop.tsx b/keep-ui/app/workflows/dragndrop.tsx
index cc7c1d80f..2cf06f9e3 100644
--- a/keep-ui/app/workflows/dragndrop.tsx
+++ b/keep-ui/app/workflows/dragndrop.tsx
@@ -1,6 +1,6 @@
import React, { useRef, useState } from "react";
import { useApiUrl } from "utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
const FileUpload: React.FC = () => {
const apiUrl = useApiUrl();
diff --git a/keep-ui/app/workflows/manual-run-workflow-modal.tsx b/keep-ui/app/workflows/manual-run-workflow-modal.tsx
index bd548ae12..825fb9375 100644
--- a/keep-ui/app/workflows/manual-run-workflow-modal.tsx
+++ b/keep-ui/app/workflows/manual-run-workflow-modal.tsx
@@ -3,7 +3,7 @@ import { Button, Select, SelectItem, Title } from "@tremor/react";
import Modal from "@/components/ui/Modal";
import { useWorkflows } from "utils/hooks/useWorkflows";
import { useState } from "react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
diff --git a/keep-ui/app/workflows/workflow-tile.tsx b/keep-ui/app/workflows/workflow-tile.tsx
index ad9a4e636..636ad7e3d 100644
--- a/keep-ui/app/workflows/workflow-tile.tsx
+++ b/keep-ui/app/workflows/workflow-tile.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { Workflow, Filter } from "./models";
import { useApiUrl } from "utils/hooks/useConfig";
import Image from "next/image";
diff --git a/keep-ui/app/workflows/workflows.client.tsx b/keep-ui/app/workflows/workflows.client.tsx
index 8a5d9e34b..58e53fc30 100644
--- a/keep-ui/app/workflows/workflows.client.tsx
+++ b/keep-ui/app/workflows/workflows.client.tsx
@@ -8,7 +8,7 @@ import {
ExclamationCircleIcon,
PlusCircleIcon,
} from "@heroicons/react/24/outline";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { fetcher } from "../../utils/fetcher";
import { Workflow, MockWorkflow } from "./models";
import { useApiUrl } from "utils/hooks/useConfig";
diff --git a/keep-ui/entities/incidents/model/useIncidentActions.tsx b/keep-ui/entities/incidents/model/useIncidentActions.tsx
index 98d676009..76b3074ad 100644
--- a/keep-ui/entities/incidents/model/useIncidentActions.tsx
+++ b/keep-ui/entities/incidents/model/useIncidentActions.tsx
@@ -1,5 +1,5 @@
import { useApiUrl } from "@/utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useCallback } from "react";
import { toast } from "react-toastify";
import { useSWRConfig } from "swr";
diff --git a/keep-ui/shared/lib/hooks/useHydratedSession.tsx b/keep-ui/shared/lib/hooks/useHydratedSession.tsx
new file mode 100644
index 000000000..6fddec50f
--- /dev/null
+++ b/keep-ui/shared/lib/hooks/useHydratedSession.tsx
@@ -0,0 +1,31 @@
+"use client";
+import { useState, useEffect } from "react";
+import { useSession as useNextAuthSession } from "next-auth/react";
+import type { Session } from "next-auth";
+import type { UseSessionOptions, SessionContextValue } from "next-auth/react";
+
+export function useHydratedSession(
+ options?: UseSessionOptions
+): SessionContextValue {
+ const [isHydrated, setIsHydrated] = useState(false);
+ const session = useNextAuthSession(options);
+ useEffect(() => {
+ setIsHydrated(true);
+ }, []);
+ // Ensure we're in browser environment
+ const isBrowser = typeof window !== "undefined";
+ // On first render, return hydrated session if available
+ if (
+ (!isHydrated || session.status === "loading") &&
+ isBrowser &&
+ window.__NEXT_AUTH_SESSION__ !== null &&
+ window.__NEXT_AUTH_SESSION__ !== undefined
+ ) {
+ return {
+ data: window.__NEXT_AUTH_SESSION__,
+ status: "authenticated" as const,
+ update: session.update,
+ } satisfies SessionContextValue;
+ }
+ return session;
+}
diff --git a/keep-ui/shared/ui/PostHogPageView.tsx b/keep-ui/shared/ui/PostHogPageView.tsx
index d267f5968..818737a8d 100644
--- a/keep-ui/shared/ui/PostHogPageView.tsx
+++ b/keep-ui/shared/ui/PostHogPageView.tsx
@@ -5,7 +5,7 @@ import { usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { usePostHog } from "posthog-js/react";
import { useConfig } from "@/utils/hooks/useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "../lib/hooks/useHydratedSession";
import { NoAuthUserEmail } from "@/utils/authenticationType";
export default function PostHogPageView(): null {
diff --git a/keep-ui/utils/hooks/useAI.ts b/keep-ui/utils/hooks/useAI.ts
index 329830b32..80f5f2531 100644
--- a/keep-ui/utils/hooks/useAI.ts
+++ b/keep-ui/utils/hooks/useAI.ts
@@ -1,5 +1,5 @@
import { AILogs, AIStats } from "app/ai/model";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useAlertQuality.ts b/keep-ui/utils/hooks/useAlertQuality.ts
index 9921da550..3445ae923 100644
--- a/keep-ui/utils/hooks/useAlertQuality.ts
+++ b/keep-ui/utils/hooks/useAlertQuality.ts
@@ -1,9 +1,9 @@
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import { fetcher } from "../fetcher";
import useSWRImmutable from "swr/immutable";
import { useSearchParams } from "next/navigation";
-import { useMemo } from "react";
+import { useMemo } from "react";
import { useApiUrl } from "./useConfig";
export const useAlertQualityMetrics = (
@@ -19,7 +19,7 @@ export const useAlertQualityMetrics = (
const fieldArray = Array.isArray(fields) ? fields : [fields];
fieldArray.forEach((field) => params.append("fields", field));
}
-
+
return params.toString();
}, [fields, searchParams]);
// TODO: Proper type needs to be defined.
diff --git a/keep-ui/utils/hooks/useAlerts.ts b/keep-ui/utils/hooks/useAlerts.ts
index 4bbe5fd65..6b8abf516 100644
--- a/keep-ui/utils/hooks/useAlerts.ts
+++ b/keep-ui/utils/hooks/useAlerts.ts
@@ -1,6 +1,6 @@
import { useState, useEffect, useMemo } from "react";
import { AlertDto } from "app/alerts/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useDashboardMetricWidgets.ts b/keep-ui/utils/hooks/useDashboardMetricWidgets.ts
index d7d24ecc8..51ab7ba9c 100644
--- a/keep-ui/utils/hooks/useDashboardMetricWidgets.ts
+++ b/keep-ui/utils/hooks/useDashboardMetricWidgets.ts
@@ -1,7 +1,7 @@
- import {useSession} from "next-auth/react";
- import { useApiUrl } from "./useConfig";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
+import { useApiUrl } from "./useConfig";
import useSWR from "swr";
-import {fetcher} from "@/utils/fetcher";
+import { fetcher } from "@/utils/fetcher";
import { usePathname, useSearchParams } from "next/navigation";
export interface MetricsWidget {
@@ -12,7 +12,7 @@ export interface MetricsWidget {
interface DistributionData {
hour: string;
- number: number
+ number: number;
}
interface DashboardDistributionData {
@@ -20,47 +20,48 @@ interface DashboardDistributionData {
ipd: DistributionData[];
apd: DistributionData[];
wpd: DistributionData[];
-
}
export const useDashboardMetricWidgets = (useFilters?: boolean) => {
- const {data: session} = useSession();
+ const { data: session } = useSession();
const apiUrl = useApiUrl();
const searchParams = useSearchParams();
const filters = searchParams?.toString();
- const {data, error, mutate} = useSWR(
- session ? `${apiUrl}/dashboard/metric-widgets${
- useFilters && filters ? `?${filters}` : ""
- }` : null,
- (url: string) => fetcher(url, session!.accessToken)
- )
- console.log(filters)
+ const { data, error, mutate } = useSWR(
+ session
+ ? `${apiUrl}/dashboard/metric-widgets${
+ useFilters && filters ? `?${filters}` : ""
+ }`
+ : null,
+ (url: string) => fetcher(url, session!.accessToken)
+ );
+ console.log(filters);
- let widgets: MetricsWidget[] = []
+ let widgets: MetricsWidget[] = [];
if (data) {
- widgets = [
+ widgets = [
{
id: "mttr",
name: "MTTR",
- data: data.mttr
+ data: data.mttr,
},
{
id: "apd",
- "name": "Alerts/Day",
- data: data.apd
+ name: "Alerts/Day",
+ data: data.apd,
},
{
id: "ipd",
name: "Incidents/Day",
- data: data.ipd
+ data: data.ipd,
},
{
id: "wpd",
name: "Workflows/Day",
- data: data.wpd
- }
+ data: data.wpd,
+ },
];
}
- return {widgets};
-}
\ No newline at end of file
+ return { widgets };
+};
diff --git a/keep-ui/utils/hooks/useDashboardPresets.ts b/keep-ui/utils/hooks/useDashboardPresets.ts
index 2f5cd0310..807fd7e1d 100644
--- a/keep-ui/utils/hooks/useDashboardPresets.ts
+++ b/keep-ui/utils/hooks/useDashboardPresets.ts
@@ -1,16 +1,18 @@
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { usePresets } from "./usePresets";
import { Preset } from "app/alerts/models";
-import { useMemo } from "react";
+import { useCallback, useMemo } from "react";
import { useSearchParams } from "next/navigation";
export const useDashboardPreset = () => {
const { data: session } = useSession();
- const { useAllPresets, useStaticPresets, presetsOrderFromLS, staticPresetsOrderFromLS } = usePresets(
- "dashboard",
- true
- );
+ const {
+ useAllPresets,
+ useStaticPresets,
+ presetsOrderFromLS,
+ staticPresetsOrderFromLS,
+ } = usePresets("dashboard", true);
const { data: presets = [] } = useAllPresets({
revalidateIfStale: false,
revalidateOnFocus: false,
@@ -20,24 +22,35 @@ export const useDashboardPreset = () => {
});
const searchParams = useSearchParams();
-
- const checkValidPreset = (preset: Preset) => {
- if (!preset.is_private) {
- return true;
- }
- return preset && preset.created_by == session?.user?.email;
- };
+ const checkValidPreset = useCallback(
+ (preset: Preset) => {
+ if (!preset.is_private) {
+ return true;
+ }
+ return preset && preset.created_by == session?.user?.email;
+ },
+ [session]
+ );
let allPreset = useMemo(() => {
/*If any filters are applied on the dashboard, we will fetch live data; otherwise,
we will use data from localStorage to sync values between the navbar and the dashboard.*/
- let combinedPresets = searchParams?.toString() ? [...presets, ...fetchedPresets]: [...presetsOrderFromLS, ...staticPresetsOrderFromLS];
+ let combinedPresets = searchParams?.toString()
+ ? [...presets, ...fetchedPresets]
+ : [...presetsOrderFromLS, ...staticPresetsOrderFromLS];
//private preset checks
combinedPresets = combinedPresets.filter((preset) =>
checkValidPreset(preset)
);
return combinedPresets;
- }, [presets, fetchedPresets, searchParams, presets, fetchedPresets]);
+ }, [
+ searchParams,
+ presets,
+ fetchedPresets,
+ presetsOrderFromLS,
+ staticPresetsOrderFromLS,
+ checkValidPreset,
+ ]);
- return allPreset;
+ return allPreset;
};
diff --git a/keep-ui/utils/hooks/useDashboards.ts b/keep-ui/utils/hooks/useDashboards.ts
index 7f3c81245..e3c9e495c 100644
--- a/keep-ui/utils/hooks/useDashboards.ts
+++ b/keep-ui/utils/hooks/useDashboards.ts
@@ -1,5 +1,5 @@
import useSWR from "swr";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useDeduplicationRules.ts b/keep-ui/utils/hooks/useDeduplicationRules.ts
index 54b68015b..74b13fd82 100644
--- a/keep-ui/utils/hooks/useDeduplicationRules.ts
+++ b/keep-ui/utils/hooks/useDeduplicationRules.ts
@@ -1,5 +1,5 @@
import { DeduplicationRule } from "app/deduplication/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useExtractionRules.ts b/keep-ui/utils/hooks/useExtractionRules.ts
index 0ff32b445..4655326a5 100644
--- a/keep-ui/utils/hooks/useExtractionRules.ts
+++ b/keep-ui/utils/hooks/useExtractionRules.ts
@@ -1,5 +1,5 @@
import { ExtractionRule } from "app/extraction/model";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useGroups.ts b/keep-ui/utils/hooks/useGroups.ts
index 3e1dde9a2..fd3c29dae 100644
--- a/keep-ui/utils/hooks/useGroups.ts
+++ b/keep-ui/utils/hooks/useGroups.ts
@@ -1,5 +1,5 @@
import { Group } from "app/settings/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useIncidents.ts b/keep-ui/utils/hooks/useIncidents.ts
index 59ae7353f..c24bdc298 100644
--- a/keep-ui/utils/hooks/useIncidents.ts
+++ b/keep-ui/utils/hooks/useIncidents.ts
@@ -5,7 +5,7 @@ import {
PaginatedIncidentsDto,
} from "@/entities/incidents/model";
import { PaginatedWorkflowExecutionDto } from "app/workflows/builder/types";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useMaintenanceRules.ts b/keep-ui/utils/hooks/useMaintenanceRules.ts
index b771615b1..f2d3f618b 100644
--- a/keep-ui/utils/hooks/useMaintenanceRules.ts
+++ b/keep-ui/utils/hooks/useMaintenanceRules.ts
@@ -1,5 +1,5 @@
import { MaintenanceRule } from "app/maintenance/model";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useMappingRules.ts b/keep-ui/utils/hooks/useMappingRules.ts
index cf116bc9c..49042ae09 100644
--- a/keep-ui/utils/hooks/useMappingRules.ts
+++ b/keep-ui/utils/hooks/useMappingRules.ts
@@ -1,5 +1,5 @@
import { MappingRule } from "app/mapping/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/usePermissions.ts b/keep-ui/utils/hooks/usePermissions.ts
index b240ec2f6..05307ddc7 100644
--- a/keep-ui/utils/hooks/usePermissions.ts
+++ b/keep-ui/utils/hooks/usePermissions.ts
@@ -1,5 +1,5 @@
import { Permission } from "app/settings/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/usePresets.ts b/keep-ui/utils/hooks/usePresets.ts
index a0a0d76e2..5065c74b9 100644
--- a/keep-ui/utils/hooks/usePresets.ts
+++ b/keep-ui/utils/hooks/usePresets.ts
@@ -1,6 +1,6 @@
import { useState, useEffect, useRef } from "react";
import { Preset } from "app/alerts/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useProviders.ts b/keep-ui/utils/hooks/useProviders.ts
index 668af3a1e..06ad74a4d 100644
--- a/keep-ui/utils/hooks/useProviders.ts
+++ b/keep-ui/utils/hooks/useProviders.ts
@@ -1,4 +1,4 @@
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "./useConfig";
import { SWRConfiguration } from "swr";
import { ProvidersResponse } from "app/providers/providers";
diff --git a/keep-ui/utils/hooks/usePusher.ts b/keep-ui/utils/hooks/usePusher.ts
index f1b0c23ed..c430ef054 100644
--- a/keep-ui/utils/hooks/usePusher.ts
+++ b/keep-ui/utils/hooks/usePusher.ts
@@ -1,6 +1,6 @@
import Pusher, { Options as PusherOptions } from "pusher-js";
import { useConfig } from "./useConfig";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "./useConfig";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
diff --git a/keep-ui/utils/hooks/useRoles.ts b/keep-ui/utils/hooks/useRoles.ts
index dabfc9b58..cf37634fa 100644
--- a/keep-ui/utils/hooks/useRoles.ts
+++ b/keep-ui/utils/hooks/useRoles.ts
@@ -1,5 +1,5 @@
import { Role } from "app/settings/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useRules.ts b/keep-ui/utils/hooks/useRules.ts
index 97976d51e..add981b45 100644
--- a/keep-ui/utils/hooks/useRules.ts
+++ b/keep-ui/utils/hooks/useRules.ts
@@ -1,4 +1,4 @@
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
diff --git a/keep-ui/utils/hooks/useScopes.ts b/keep-ui/utils/hooks/useScopes.ts
index 775d8717a..122a2a289 100644
--- a/keep-ui/utils/hooks/useScopes.ts
+++ b/keep-ui/utils/hooks/useScopes.ts
@@ -1,5 +1,5 @@
import { Scope } from "app/settings/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useSearchAlerts.ts b/keep-ui/utils/hooks/useSearchAlerts.ts
index 01de3fe14..9ef8cb0b0 100644
--- a/keep-ui/utils/hooks/useSearchAlerts.ts
+++ b/keep-ui/utils/hooks/useSearchAlerts.ts
@@ -1,6 +1,6 @@
import useSWR, { SWRConfiguration } from "swr";
import { AlertDto } from "app/alerts/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "./useConfig";
import { fetcher } from "utils/fetcher";
import { useDebouncedValue } from "./useDebouncedValue";
diff --git a/keep-ui/utils/hooks/useTags.ts b/keep-ui/utils/hooks/useTags.ts
index 124da6649..7587c386f 100644
--- a/keep-ui/utils/hooks/useTags.ts
+++ b/keep-ui/utils/hooks/useTags.ts
@@ -1,4 +1,4 @@
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useUsers.ts b/keep-ui/utils/hooks/useUsers.ts
index de254e040..723045071 100644
--- a/keep-ui/utils/hooks/useUsers.ts
+++ b/keep-ui/utils/hooks/useUsers.ts
@@ -1,5 +1,5 @@
import { User } from "app/settings/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import useSWRImmutable from "swr/immutable";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useWorkflowExecutions.ts b/keep-ui/utils/hooks/useWorkflowExecutions.ts
index 8e6fccc27..53fea2d8c 100644
--- a/keep-ui/utils/hooks/useWorkflowExecutions.ts
+++ b/keep-ui/utils/hooks/useWorkflowExecutions.ts
@@ -3,7 +3,7 @@ import {
PaginatedWorkflowExecutionDto,
WorkflowExecution,
} from "app/workflows/builder/types";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useSearchParams } from "next/navigation";
import useSWR, { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
diff --git a/keep-ui/utils/hooks/useWorkflowRun.ts b/keep-ui/utils/hooks/useWorkflowRun.ts
index dbaa98dc8..a645e9f86 100644
--- a/keep-ui/utils/hooks/useWorkflowRun.ts
+++ b/keep-ui/utils/hooks/useWorkflowRun.ts
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "./useConfig";
import { useRouter } from "next/navigation";
import { useProviders } from "./useProviders";
diff --git a/keep-ui/utils/hooks/useWorkflows.ts b/keep-ui/utils/hooks/useWorkflows.ts
index 26859eaf2..1a8eae55c 100644
--- a/keep-ui/utils/hooks/useWorkflows.ts
+++ b/keep-ui/utils/hooks/useWorkflows.ts
@@ -1,5 +1,5 @@
import { Workflow } from "app/workflows/models";
-import { useSession } from "next-auth/react";
+import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { SWRConfiguration } from "swr";
import { useApiUrl } from "./useConfig";
import { fetcher } from "../fetcher";