-
Started at
+
Started at
{format(new Date(incident.start_time), formatString)}
@@ -316,18 +368,20 @@ export default function IncidentInformation({ incident }: Props) {
/>
- {changeSameIncidentInThePast ?
setChangeSameIncidentInThePast(null)}
- title="Link to the same incident in the past"
- className="w-[600px]"
- >
- setChangeSameIncidentInThePast(null)}
- />
- : null}
+ {changeSameIncidentInThePast ? (
+
setChangeSameIncidentInThePast(null)}
+ title="Link to the same incident in the past"
+ className="w-[600px]"
+ >
+ setChangeSameIncidentInThePast(null)}
+ />
+
+ ) : null}
;
if (error) return
Incident does not exist.;
@@ -56,6 +55,15 @@ export default function IncidentView({ incidentId }: Props) {
color="orange"
className="sticky xl:-top-10 -top-4 bg-white z-10"
>
+
+ Activity
+
+ New
+
+
Alerts
Timeline
Topology
@@ -71,13 +79,16 @@ export default function IncidentView({ incidentId }: Props) {
+
+
+
-
+
@@ -41,13 +41,16 @@ export function UsersTable({
{/** Image */}
- {authType === AuthenticationType.AUTH0 || authType === AuthenticationType.KEYCLOAK
+ {authType === AuthenticationType.AUTH0 ||
+ authType === AuthenticationType.KEYCLOAK
? "Email"
: "Username"}
Name
Role
- {groupsAllowed && Groups}
+ {groupsAllowed && (
+ Groups
+ )}
Last Login
@@ -84,9 +87,7 @@ export function UsersTable({
{user.email}
- {user.ldap && (
- LDAP
- )}
+ {user.ldap && LDAP}
@@ -119,7 +120,11 @@ export function UsersTable({
)}
- {user.last_login ? new Date(user.last_login).toLocaleString() : "Never"}
+
+ {user.last_login
+ ? new Date(user.last_login).toLocaleString()
+ : "Never"}
+
{!isDisabled && user.email !== currentUserEmail && !user.ldap && (
diff --git a/keep-ui/app/topology/model/useTopology.ts b/keep-ui/app/topology/model/useTopology.ts
index e31bad4b0..ee57a78ae 100644
--- a/keep-ui/app/topology/model/useTopology.ts
+++ b/keep-ui/app/topology/model/useTopology.ts
@@ -1,6 +1,6 @@
import { TopologyService } from "@/app/topology/model/models";
import { useSession } from "next-auth/react";
-import useSWR from "swr";
+import useSWR, { SWRConfiguration } from "swr";
import { getApiURL } from "@/utils/apiUrl";
import { fetcher } from "@/utils/fetcher";
import { useEffect } from "react";
@@ -14,15 +14,23 @@ type UseTopologyOptions = {
services?: string[];
environment?: string;
initialData?: TopologyService[];
+ options?: SWRConfiguration;
};
// TODO: ensure that hook is memoized so could be used multiple times in the tree without rerenders
-export const useTopology = ({
- providerIds,
- services,
- environment,
- initialData: fallbackData,
-}: UseTopologyOptions = {}) => {
+export const useTopology = (
+ {
+ providerIds,
+ services,
+ environment,
+ initialData: fallbackData,
+ options,
+ }: UseTopologyOptions = {
+ options: {
+ revalidateOnFocus: false,
+ },
+ }
+) => {
const { data: session } = useSession();
const pollTopology = useTopologyPollingContext();
@@ -35,6 +43,7 @@ export const useTopology = ({
(url: string) => fetcher(url, session!.accessToken),
{
fallbackData,
+ ...options,
}
);
diff --git a/keep-ui/app/topology/model/useTopologyApplications.ts b/keep-ui/app/topology/model/useTopologyApplications.ts
index 524a4b79c..93da4e5f8 100644
--- a/keep-ui/app/topology/model/useTopologyApplications.ts
+++ b/keep-ui/app/topology/model/useTopologyApplications.ts
@@ -1,6 +1,6 @@
import { TopologyApplication } from "./models";
import { getApiURL } from "@/utils/apiUrl";
-import useSWR from "swr";
+import useSWR, { SWRConfiguration } from "swr";
import { fetcher } from "@/utils/fetcher";
import { useSession } from "next-auth/react";
import { useCallback, useMemo } from "react";
@@ -9,11 +9,16 @@ import { useRevalidateMultiple } from "@/utils/state";
type UseTopologyApplicationsOptions = {
initialData?: TopologyApplication[];
+ options?: SWRConfiguration;
};
-export function useTopologyApplications({
- initialData,
-}: UseTopologyApplicationsOptions = {}) {
+export function useTopologyApplications(
+ { initialData, options }: UseTopologyApplicationsOptions = {
+ options: {
+ revalidateOnFocus: false,
+ },
+ }
+) {
const apiUrl = getApiURL();
const { data: session } = useSession();
const revalidateMultiple = useRevalidateMultiple();
@@ -24,6 +29,7 @@ export function useTopologyApplications({
(url: string) => fetcher(url, session!.accessToken),
{
fallbackData: initialData,
+ ...options,
}
);
diff --git a/keep-ui/components/navbar/UserAvatar.tsx b/keep-ui/components/navbar/UserAvatar.tsx
new file mode 100644
index 000000000..d90300363
--- /dev/null
+++ b/keep-ui/components/navbar/UserAvatar.tsx
@@ -0,0 +1,29 @@
+import Image from "next/image";
+
+interface Props {
+ image: string | null | undefined;
+ name: string;
+}
+
+export const getInitials = (name: string) =>
+ ((name.match(/(^\S\S?|\b\S)?/g) ?? []).join("").match(/(^\S|\S$)?/g) ?? [])
+ .join("")
+ .toUpperCase();
+
+export default function UserAvatar({ image, name }: Props) {
+ return image ? (
+
+ ) : (
+
+
+ {getInitials(name)}
+
+
+ );
+}
diff --git a/keep-ui/components/navbar/UserInfo.tsx b/keep-ui/components/navbar/UserInfo.tsx
index 0af88c1f2..e848579a3 100644
--- a/keep-ui/components/navbar/UserInfo.tsx
+++ b/keep-ui/components/navbar/UserInfo.tsx
@@ -14,11 +14,7 @@ import { VscDebugDisconnect } from "react-icons/vsc";
import DarkModeToggle from "app/dark-mode-toggle";
import { useFloating } from "@floating-ui/react";
import { Icon, Subtitle } from "@tremor/react";
-
-export const getInitials = (name: string) =>
- ((name.match(/(^\S\S?|\b\S)?/g) ?? []).join("").match(/(^\S|\S$)?/g) ?? [])
- .join("")
- .toUpperCase();
+import UserAvatar from "./UserAvatar";
type UserDropdownProps = {
session: Session;
@@ -38,21 +34,7 @@ const UserDropdown = ({ session }: UserDropdownProps) => {