Skip to content

Commit a6cbaa1

Browse files
skynetigorshahargl
andauthored
feat: Multiple sorting columns choice based on priority (#4311)
Co-authored-by: Shahar Glazner <[email protected]>
1 parent 9746f45 commit a6cbaa1

File tree

19 files changed

+420
-208
lines changed

19 files changed

+420
-208
lines changed

keep-ui/app/(keep)/alerts/alert-table-headers.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,19 @@ const DraggableHeaderCell = ({
154154
column.id === "checkbox"
155155
? "32px !important"
156156
: column.id === "source"
157-
? "40px !important"
158-
: column.id === "status"
159-
? "24px !important"
160-
: column.getSize(),
157+
? "40px !important"
158+
: column.id === "status"
159+
? "24px !important"
160+
: column.getSize(),
161161
opacity: isDragging ? 0.5 : 1,
162162
transform: CSS.Translate.toString(transform),
163163
transition,
164164
cursor:
165165
column.getIsPinned() !== false
166166
? "default"
167167
: isDragging
168-
? "grabbing"
169-
: "grab",
168+
? "grabbing"
169+
: "grab",
170170
};
171171

172172
// Hide menu for checkbox, source, severity and alertMenu columns
@@ -263,8 +263,8 @@ const DraggableHeaderCell = ({
263263
column.getNextSortingOrder() === "asc"
264264
? "Sort ascending"
265265
: column.getNextSortingOrder() === "desc"
266-
? "Sort descending"
267-
: "Clear sort"
266+
? "Sort descending"
267+
: "Clear sort"
268268
}
269269
>
270270
{column.getIsSorted() === "asc" ? (
@@ -273,6 +273,9 @@ const DraggableHeaderCell = ({
273273
<ArrowUpIcon className="w-4 h-4" />
274274
)}
275275
</span>
276+
{table.getState().sorting.length > 1 && (
277+
<span className="text-sm">{column.getSortIndex() + 1}</span>
278+
)}
276279
</>
277280
)}
278281
</button>

keep-ui/app/(keep)/alerts/alert-table-server-side.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { GrTest } from "react-icons/gr";
5858
import { PlusIcon } from "@heroicons/react/20/solid";
5959
import { DynamicImageProviderIcon } from "@/components/ui";
6060
import { useAlertRowStyle } from "@/entities/alerts/model/useAlertRowStyle";
61+
import { useIsShiftKeyHeld } from "@/features/keyboard-shortcuts";
6162

6263
const AssigneeLabel = ({ email }: { email: string }) => {
6364
const user = useUser(email);
@@ -326,8 +327,10 @@ export function AlertTableServerSide({
326327
cel: resultCel,
327328
offset,
328329
limit,
329-
sortBy: sorting[0]?.id,
330-
sortDirection: sorting[0]?.desc ? "DESC" : "ASC",
330+
sortOptions: sorting.map((s) => ({
331+
sortBy: s.id,
332+
sortDirection: s.desc ? "DESC" : "ASC",
333+
})),
331334
};
332335

333336
alertsQueryRef.current = alertsQuery;
@@ -343,7 +346,6 @@ export function AlertTableServerSide({
343346
useEffect(() => {
344347
onReload && onReload(alertsQueryRef.current as AlertsQuery);
345348
}, [alertsQuery, onReload]);
346-
347349
const [selectedAlert, setSelectedAlert] = useState<AlertDto | null>(null);
348350
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
349351
const [isIncidentSelectorOpen, setIsIncidentSelectorOpen] =
@@ -353,6 +355,8 @@ export function AlertTableServerSide({
353355
? ["severity", "checkbox", "status", "source", "noise"]
354356
: ["severity", "checkbox", "status", "source"];
355357

358+
const isShiftPressed = useIsShiftKeyHeld();
359+
356360
const table = useReactTable({
357361
getRowId: (row) => row.fingerprint,
358362
data: alerts,
@@ -400,6 +404,7 @@ export function AlertTableServerSide({
400404
pageCount: Math.ceil(alertsTotalCount / paginationState.pageSize),
401405
onPaginationChange: setPaginationState,
402406
onGroupingChange: setGrouping,
407+
isMultiSortEvent: () => isShiftPressed,
403408
});
404409

405410
const selectedAlertsFingerprints = Object.keys(table.getState().rowSelection);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { useIsShiftKeyHeld } from "./useIsShiftKeyHeld";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { useEffect, useState } from "react";
2+
3+
export function useIsShiftKeyHeld() {
4+
const [isShiftPressed, setIsShiftPressed] = useState(false);
5+
6+
useEffect(() => {
7+
function handleKeyDown(e: KeyboardEvent) {
8+
if (e.key === "Shift") {
9+
setIsShiftPressed(true);
10+
}
11+
}
12+
13+
document.addEventListener("keydown", handleKeyDown);
14+
return () => document.removeEventListener("keydown", handleKeyDown);
15+
}, [setIsShiftPressed]);
16+
17+
useEffect(() => {
18+
function handleKeyUp(e: KeyboardEvent) {
19+
if (e.key === "Shift") {
20+
setIsShiftPressed(false);
21+
}
22+
}
23+
24+
document.addEventListener("keyup", handleKeyUp);
25+
return () => document.removeEventListener("keyup", handleKeyUp);
26+
}, [setIsShiftPressed]);
27+
28+
return isShiftPressed;
29+
}

keep-ui/utils/hooks/useAlerts.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from "react";
1+
import { useEffect, useMemo } from "react";
22
import { AlertDto } from "@/entities/alerts/model";
33
import useSWR, { SWRConfiguration } from "swr";
44
import { toDateObjectWithFallback } from "utils/helpers";
@@ -18,8 +18,7 @@ export interface AlertsQuery {
1818
cel?: string;
1919
offset?: number;
2020
limit?: number;
21-
sortBy?: string;
22-
sortDirection?: "ASC" | "DESC";
21+
sortOptions?: { sortBy: string; sortDirection?: "ASC" | "DESC" }[];
2322
}
2423

2524
export const useAlerts = () => {
@@ -178,16 +177,11 @@ export const useAlerts = () => {
178177
queryToPost.cel = query.cel;
179178
}
180179

181-
if (query?.sortBy) {
182-
queryToPost.sort_by = query.sortBy;
183-
184-
switch (query?.sortDirection) {
185-
case "DESC":
186-
queryToPost.sort_dir = "desc";
187-
break;
188-
default:
189-
queryToPost.sort_dir = "asc";
190-
}
180+
if (query?.sortOptions?.length) {
181+
queryToPost.sort_options = query.sortOptions.map((sortOption) => ({
182+
sort_by: sortOption.sortBy,
183+
sort_dir: sortOption.sortDirection?.toLocaleLowerCase(),
184+
}));
191185
}
192186

193187
const requestUrl = `/alerts/query`;
@@ -197,7 +191,7 @@ export const useAlerts = () => {
197191
? requestUrl +
198192
Object.entries(queryToPost)
199193
.sort(([fstKey], [scdKey]) => fstKey.localeCompare(scdKey))
200-
.map(([key, value]) => `${key}=${value}`)
194+
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
201195
.join("&")
202196
: null;
203197

0 commit comments

Comments
 (0)