Skip to content

Commit

Permalink
feat: merge incidents (#2274)
Browse files Browse the repository at this point in the history
Signed-off-by: Kirill Chernakov <[email protected]>
  • Loading branch information
Kiryous authored Oct 29, 2024
1 parent ab8c6ff commit f549b05
Show file tree
Hide file tree
Showing 55 changed files with 2,514 additions and 765 deletions.
3 changes: 3 additions & 0 deletions docs/api-ref/alerts/get-alert-quality.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /alerts/quality/metrics
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/add-comment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: post /incidents/{incident_id}/comment
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/{incident_id}/future_incidents
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/get-incident-workflows.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/{incident_id}/workflows
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/get-incidents-meta.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/meta
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/merge-incidents.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: post /incidents/merge
---
10 changes: 8 additions & 2 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@
"api-ref/alerts/unenrich-alert",
"api-ref/alerts/search-alerts",
"api-ref/alerts/get-alert-audit",
"api-ref/alerts/get-alerts"
"api-ref/alerts/get-alerts",
"api-ref/alerts/get-alert-quality"
]
},
{
Expand Down Expand Up @@ -366,7 +367,12 @@
"api-ref/incidents/get-incident-alerts",
"api-ref/incidents/add-alerts-to-incident",
"api-ref/incidents/delete-alerts-from-incident",
"api-ref/incidents/confirm-incident"
"api-ref/incidents/confirm-incident",
"api-ref/incidents/add-comment",
"api-ref/incidents/get-future-incidents-for-an-incident",
"api-ref/incidents/get-incident-workflows",
"api-ref/incidents/get-incidents-meta",
"api-ref/incidents/merge-incidents"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi.json

Large diffs are not rendered by default.

121 changes: 71 additions & 50 deletions keep-ui/app/alerts/alert-pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
TableCellsIcon,
} from "@heroicons/react/24/outline";
} from "@heroicons/react/16/solid";
import { Button, Text } from "@tremor/react";
import { StylesConfig, SingleValueProps, components, GroupBase } from 'react-select';
import Select from 'react-select';
import {
StylesConfig,
SingleValueProps,
components,
GroupBase,
} from "react-select";
import Select from "react-select";
import { AlertDto } from "./models";
import { Table } from "@tanstack/react-table";
import { useAlerts } from "utils/hooks/useAlerts";
Expand All @@ -24,39 +29,46 @@ interface OptionType {
label: string;
}

const customStyles: StylesConfig<OptionType, false, GroupBase<OptionType>> = {
control: (provided, state) => ({
...provided,
borderColor: state.isFocused ? 'orange' : provided.borderColor,
'&:hover': { borderColor: 'orange' },
boxShadow: state.isFocused ? '0 0 0 1px orange' : provided.boxShadow,
}),
singleValue: (provided) => ({
...provided,
display: 'flex',
alignItems: 'center',
}),
menu: (provided) => ({
...provided,
color: 'orange',
}),
option: (provided, state) => ({
...provided,
backgroundColor: state.isSelected ? 'orange' : provided.backgroundColor,
'&:hover': { backgroundColor: state.isSelected ? 'orange' : '#f5f5f5' },
color: state.isSelected ? 'white' : provided.color,
}),
};

const SingleValue = ({ children, ...props }: SingleValueProps<OptionType, false, GroupBase<OptionType>>) => (
<components.SingleValue {...props}>
{children}
<TableCellsIcon className="w-4 h-4 ml-2" />
</components.SingleValue>
);
const customStyles: StylesConfig<OptionType, false, GroupBase<OptionType>> = {
control: (provided, state) => ({
...provided,
borderColor: state.isFocused ? "orange" : "rgb(229 231 235)",
borderRadius: "0.5rem",
"&:hover": { borderColor: "orange" },
boxShadow: state.isFocused ? "0 0 0 1px orange" : provided.boxShadow,
}),
singleValue: (provided) => ({
...provided,
display: "flex",
alignItems: "center",
}),
menu: (provided) => ({
...provided,
color: "orange",
}),
option: (provided, state) => ({
...provided,
backgroundColor: state.isSelected ? "orange" : provided.backgroundColor,
"&:hover": { backgroundColor: state.isSelected ? "orange" : "#f5f5f5" },
color: state.isSelected ? "white" : provided.color,
}),
};

const SingleValue = ({
children,
...props
}: SingleValueProps<OptionType, false, GroupBase<OptionType>>) => (
<components.SingleValue {...props}>
{children}
<TableCellsIcon className="w-4 h-4 ml-2" />
</components.SingleValue>
);

export default function AlertPagination({ presetName, table, isRefreshAllowed }: Props) {
export default function AlertPagination({
presetName,
table,
isRefreshAllowed,
}: Props) {
const { usePresetAlerts } = useAlerts();
const { mutate, isLoading: isValidating } = usePresetAlerts(presetName);

Expand All @@ -69,50 +81,59 @@ export default function AlertPagination({ presetName, table, isRefreshAllowed }:
Showing {pageCount === 0 ? 0 : pageIndex + 1} of {pageCount}
</Text>
<div className="flex gap-1">
<Select
styles={customStyles}
components={{ SingleValue }}
value={{ value: table.getState().pagination.pageSize.toString(), label: table.getState().pagination.pageSize.toString() }}
onChange={(selectedOption) => table.setPageSize(Number(selectedOption!.value))}
options={[
{ value: "10", label: "10" },
{ value: "20", label: "20" },
{ value: "50", label: "50" },
{ value: "100", label: "100" },
]}
menuPlacement="top"
<Select
styles={customStyles}
components={{ SingleValue }}
value={{
value: table.getState().pagination.pageSize.toString(),
label: table.getState().pagination.pageSize.toString(),
}}
onChange={(selectedOption) =>
table.setPageSize(Number(selectedOption!.value))
}
options={[
{ value: "10", label: "10" },
{ value: "20", label: "20" },
{ value: "50", label: "50" },
{ value: "100", label: "100" },
]}
menuPlacement="top"
/>
<div className="flex">
<Button
className="pagination-button"
icon={ChevronDoubleLeftIcon}
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronLeftIcon}
onClick={table.previousPage}
disabled={!table.getCanPreviousPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronRightIcon}
onClick={table.nextPage}
disabled={!table.getCanNextPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronDoubleRightIcon}
onClick={() => table.setPageIndex(pageCount - 1)}
disabled={!table.getCanNextPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
</div>
Expand Down
42 changes: 42 additions & 0 deletions keep-ui/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,45 @@
/* original value is ridiculous 15.000, overflowing toasts*/
@apply z-[1000] !important;
}

@keyframes scroll-shadow-left {
0% {
filter: none
}
25%, 100% {
filter: drop-shadow(rgba(0, 0, 0, 0.07) -2px 9px 5px)
}
}

@keyframes scroll-shadow-right {
0%, 75% {
filter: drop-shadow(rgba(0, 0, 0, 0.07) 2px 9px 5px)
}
99% {
filter: none
}
}

.pagination-button {
@apply shadow-tremor-input border-tremor-border bg-tremor-background ;

&:not(:first-child) {
@apply -ml-px;
}

&:first-child:not(:last-child) {
@apply rounded-r-none;
}

&:last-child:not(:first-child) {
@apply rounded-l-none;
}

&:not(:first-child):not(:last-child) {
@apply rounded-l-none rounded-r-none;
}

&:not(:disabled):hover {
@apply bg-slate-100;
}
}
16 changes: 9 additions & 7 deletions keep-ui/app/incidents/[id]/incident-activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ export function IncidentActivityChronoItem({ activity }: { activity: any }) {
". ";
return (
<div className="relative h-full w-full flex items-center">
{activity.type === "alert" && (
<AlertSeverity
severity={(activity.initiator as AlertDto).severity}
marginLeft={false}
/>
)}
{activity.type === "alert" &&
(activity.initiator as AlertDto)?.severity && (
<AlertSeverity
severity={(activity.initiator as AlertDto).severity}
marginLeft={false}
/>
)}
<span className="font-semibold mr-2.5">{title}</span>
<span className="text-gray-300">
{subTitle} <TimeAgo date={activity.timestamp + "Z"} />
Expand Down Expand Up @@ -214,6 +215,7 @@ export default function IncidentActivity({
)
);
const chronoIcons = activities?.map((activity, index) => {
console.log("activity", activity);
if (activity.type === "comment" || activity.type === "newcomment") {
const user = users?.find((user) => user.email === activity.initiator);
return (
Expand All @@ -224,7 +226,7 @@ export default function IncidentActivity({
/>
);
} else {
const source = (activity.initiator as AlertDto).source[0];
const source = (activity.initiator as AlertDto)?.source?.[0];
const imagePath = `/icons/${source}-icon.png`;
return (
<Image
Expand Down
6 changes: 3 additions & 3 deletions keep-ui/app/incidents/[id]/incident-alert-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { TrashIcon } from "@radix-ui/react-icons";
import { Icon } from "@tremor/react";
import { AlertDto } from "app/alerts/models";
import { useSession } from "next-auth/react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
import { useIncidentAlerts } from "utils/hooks/useIncidents";
import { LinkSlashIcon } from "@heroicons/react/24/outline";

interface Props {
incidentId: string;
Expand Down Expand Up @@ -45,9 +45,9 @@ export default function IncidentAlertMenu({ incidentId, alert }: Props) {
return (
<div className="flex flex-col">
<Icon
icon={TrashIcon}
icon={LinkSlashIcon}
color="red"
tooltip="Remove"
tooltip="Remove correlation"
className="cursor-pointer"
onClick={onRemove}
/>
Expand Down
Loading

0 comments on commit f549b05

Please sign in to comment.