+
- Timeline
+
Timeline
- {isLoading ? (
-
- ) : (
-
- ({
- title: formatTimestamp(entry.timestamp),
- })) || []
- }
- hideControls
- disableToolbar
- borderLessCards
- slideShow={false}
- mode="VERTICAL"
- theme={{
- primary: "orange",
- secondary: "rgb(255 247 237)",
- titleColor: "orange",
- titleColorActive: "orange",
- }}
- fontSizes={{
- title: ".75rem",
- }}
- cardWidth={400}
- cardHeight="auto"
- classNames={{
- card: "hidden",
- cardMedia: "hidden",
- cardSubTitle: "hidden",
- cardText: "hidden",
- cardTitle: "hidden",
- title: "mb-3",
- contentDetails: "w-full !m-0",
- }}
- >
- {content}
-
-
- )}
+
+ {isLoading ? (
+
+ ) : (
+
+ ({
+ title: formatTimestamp(entry.timestamp),
+ })) || []
+ }
+ hideControls
+ disableToolbar
+ borderLessCards
+ slideShow={false}
+ mode="VERTICAL"
+ theme={{
+ primary: "orange",
+ secondary: "rgb(255 247 237)",
+ titleColor: "orange",
+ titleColorActive: "orange",
+ }}
+ fontSizes={{
+ title: ".75rem",
+ }}
+ cardWidth={400}
+ cardHeight="auto"
+ classNames={{
+ card: "hidden",
+ cardMedia: "hidden",
+ cardSubTitle: "hidden",
+ cardText: "hidden",
+ cardTitle: "hidden",
+ title: "mb-3",
+ contentDetails: "w-full !m-0",
+ }}
+ >
+ {content}
+
+
+ )}
+
);
};
diff --git a/keep-ui/app/(keep)/incidents/[id]/activity/incident-activity.tsx b/keep-ui/app/(keep)/incidents/[id]/activity/incident-activity.tsx
index 0c803d477..2249e6d1e 100644
--- a/keep-ui/app/(keep)/incidents/[id]/activity/incident-activity.tsx
+++ b/keep-ui/app/(keep)/incidents/[id]/activity/incident-activity.tsx
@@ -2,7 +2,7 @@
import { AlertDto } from "@/app/(keep)/alerts/models";
import { IncidentDto } from "@/entities/incidents/model";
-import { useUsers } from "@/utils/hooks/useUsers";
+import { useUsers } from "@/entities/users/model/useUsers";
import Image from "next/image";
import UserAvatar from "@/components/navbar/UserAvatar";
import "./incident-activity.css";
diff --git a/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-menu.tsx b/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-menu.tsx
index 799afbc28..0da0da3ce 100644
--- a/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-menu.tsx
+++ b/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alert-menu.tsx
@@ -1,4 +1,4 @@
-import { Icon } from "@tremor/react";
+import { Button, Icon } from "@tremor/react";
import { AlertDto } from "@/app/(keep)/alerts/models";
import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
@@ -43,14 +43,18 @@ export default function IncidentAlertMenu({ incidentId, alert }: Props) {
}
return (
-
-
+
+ >
+ Remove correlation
+
);
}
diff --git a/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alerts.tsx b/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alerts.tsx
index 7d3d828e8..7d3f52ef2 100644
--- a/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alerts.tsx
+++ b/keep-ui/app/(keep)/incidents/[id]/alerts/incident-alerts.tsx
@@ -8,6 +8,7 @@ import {
} from "@tanstack/react-table";
import {
Card,
+ Icon,
Table,
TableBody,
TableCell,
@@ -33,6 +34,9 @@ import { getCommonPinningStylesAndClassNames } from "@/components/ui/table/utils
import { EmptyStateCard } from "@/components/ui";
import { useRouter } from "next/navigation";
import { TablePagination } from "@/shared/ui";
+import { AlertSeverityBorder } from "@/app/(keep)/alerts/alert-severity-border";
+import { getStatusIcon } from "@/shared/lib/status-utils";
+import { getStatusColor } from "@/shared/lib/status-utils";
interface Props {
incident: IncidentDto;
@@ -110,15 +114,17 @@ export default function IncidentAlerts({ incident }: Props) {
// />
// ),
// }),
- columnHelper.accessor("severity", {
+ columnHelper.display({
id: "severity",
- header: "Severity",
- minSize: 80,
+ maxSize: 4,
+ header: () => <>>,
cell: (context) => (
-
+
),
+ meta: {
+ tdClassName: "p-0",
+ thClassName: "p-0",
+ },
}),
columnHelper.display({
id: "name",
@@ -144,17 +150,28 @@ export default function IncidentAlerts({ incident }: Props) {
id: "status",
minSize: 100,
header: "Status",
+ cell: (context) => (
+
+
+ {context.getValue()}
+
+ ),
}),
columnHelper.accessor("is_created_by_ai", {
id: "is_created_by_ai",
- header: "🔗",
+ header: "🔗 Correlation type",
minSize: 50,
cell: (context) => (
<>
{context.getValue() ? (
-
🤖
+
🤖 AI
) : (
-
👨💻
+
👨💻 Manually
)}
>
),
@@ -186,7 +203,7 @@ export default function IncidentAlerts({ incident }: Props) {
}),
columnHelper.display({
id: "remove",
- header: "",
+ header: "Correlation",
cell: (context) =>
incident.is_confirmed && (
{
+ const { providersSelectedCategories, setProvidersSelectedCategories } =
+ useFilterContext();
+
+ const categories: TProviderCategory[] = [
+ "Monitoring",
+ "Incident Management",
+ "Cloud Infrastructure",
+ "Ticketing",
+ "Developer Tools",
+ "Database",
+ "Identity and Access Management",
+ "Security",
+ "Collaboration",
+ "CRM",
+ "Queues",
+ "Coming Soon",
+ "Others",
+ ];
+
+ const toggleCategory = (category: TProviderCategory) => {
+ setProvidersSelectedCategories((prev) =>
+ prev.includes(category)
+ ? prev.filter((c) => c !== category)
+ : [...prev, category]
+ );
+ };
+
+ return (
+
+ {categories.map((category) => (
+ toggleCategory(category)}
+ >
+ {category}
+
+ ))}
+
+ );
+};
diff --git a/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx b/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx
index 09f696c8e..669c966f1 100644
--- a/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx
+++ b/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx
@@ -18,8 +18,8 @@ export const ProvidersFilterByLabel: FC = (props) => {
{options.map(([value, label]) => (
diff --git a/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx b/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx
index 5d4965038..604f24bd5 100644
--- a/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx
+++ b/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx
@@ -16,6 +16,7 @@ export const ProvidersSearch: FC = () => {
id="search-providers"
icon={MagnifyingGlassIcon}
placeholder="Filter providers..."
+ className="w-full"
value={providersSearchString}
onChange={handleChange}
/>
diff --git a/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx b/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx
index 1e2866721..e61f91dba 100644
--- a/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx
+++ b/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx
@@ -2,7 +2,7 @@ import { createContext, useState, FC, PropsWithChildren } from "react";
import { IFilterContext } from "./types";
import { useSearchParams } from "next/navigation";
import { PROVIDER_LABELS_KEYS } from "./constants";
-import type { TProviderLabels } from "../providers";
+import type { TProviderCategory, TProviderLabels } from "../providers";
export const FilterContext = createContext(null);
@@ -12,6 +12,9 @@ export const FilerContextProvider: FC = ({ children }) => {
const [providersSearchString, setProvidersSearchString] =
useState("");
+ const [providersSelectedCategories, setProvidersSelectedCategories] =
+ useState([]);
+
const [providersSelectedTags, setProvidersSelectedTags] = useState<
TProviderLabels[]
>(() => {
@@ -26,8 +29,10 @@ export const FilerContextProvider: FC = ({ children }) => {
const contextValue: IFilterContext = {
providersSearchString,
providersSelectedTags,
+ providersSelectedCategories,
setProvidersSelectedTags,
setProvidersSearchString,
+ setProvidersSelectedCategories,
};
return (
diff --git a/keep-ui/app/(keep)/providers/filter-context/types.ts b/keep-ui/app/(keep)/providers/filter-context/types.ts
index c56f163b6..aeb6f0d5c 100644
--- a/keep-ui/app/(keep)/providers/filter-context/types.ts
+++ b/keep-ui/app/(keep)/providers/filter-context/types.ts
@@ -1,9 +1,11 @@
import { Dispatch, SetStateAction } from "react";
-import { TProviderLabels } from "../providers";
+import { TProviderCategory, TProviderLabels } from "../providers";
export interface IFilterContext {
providersSearchString: string;
providersSelectedTags: TProviderLabels[];
+ providersSelectedCategories: TProviderCategory[];
setProvidersSearchString: Dispatch>;
setProvidersSelectedTags: Dispatch>;
+ setProvidersSelectedCategories: Dispatch>;
}
diff --git a/keep-ui/app/(keep)/providers/layout.tsx b/keep-ui/app/(keep)/providers/layout.tsx
index 83d2cc7fc..0c229eef2 100644
--- a/keep-ui/app/(keep)/providers/layout.tsx
+++ b/keep-ui/app/(keep)/providers/layout.tsx
@@ -3,16 +3,18 @@ import { PropsWithChildren } from "react";
import { ProvidersFilterByLabel } from "./components/providers-filter-by-label";
import { ProvidersSearch } from "./components/providers-search";
import { FilerContextProvider } from "./filter-context";
+import { ProvidersCategories } from "./components/providers-categories";
export default function ProvidersLayout({ children }: PropsWithChildren) {
return (
-
-
+
{children}
diff --git a/keep-ui/app/(keep)/providers/page.client.tsx b/keep-ui/app/(keep)/providers/page.client.tsx
index fd49f8ff9..b4e4131ad 100644
--- a/keep-ui/app/(keep)/providers/page.client.tsx
+++ b/keep-ui/app/(keep)/providers/page.client.tsx
@@ -110,7 +110,11 @@ export default function ProvidersPage({
session,
isLocalhost,
} = useFetchProviders();
- const { providersSearchString, providersSelectedTags } = useFilterContext();
+ const {
+ providersSearchString,
+ providersSelectedTags,
+ providersSelectedCategories,
+ } = useFilterContext();
const apiUrl = useApiUrl();
const router = useRouter();
useEffect(() => {
@@ -147,6 +151,21 @@ export default function ProvidersPage({
);
};
+ const searchCategories = (provider: Provider) => {
+ if (providersSelectedCategories.includes("Coming Soon")) {
+ if (provider.coming_soon) {
+ return true;
+ }
+ }
+
+ return (
+ providersSelectedCategories.length === 0 ||
+ provider.categories.some((category) =>
+ providersSelectedCategories.includes(category)
+ )
+ );
+ };
+
const searchTags = (provider: Provider) => {
return (
providersSelectedTags.length === 0 ||
@@ -171,7 +190,10 @@ export default function ProvidersPage({
)}
searchProviders(provider) && searchTags(provider)
+ (provider) =>
+ searchProviders(provider) &&
+ searchTags(provider) &&
+ searchCategories(provider)
)}
isLocalhost={isLocalhost}
/>
diff --git a/keep-ui/app/(keep)/providers/provider-tile.tsx b/keep-ui/app/(keep)/providers/provider-tile.tsx
index 34949538f..2e4ef9c95 100644
--- a/keep-ui/app/(keep)/providers/provider-tile.tsx
+++ b/keep-ui/app/(keep)/providers/provider-tile.tsx
@@ -159,16 +159,17 @@ export default function ProviderTile({ provider, onClick }: Props) {
/>
);
};
-
return (