refactor(ui): simplify table selection and clarify mobile label rendering

Addresses PR feedback:
- Removes over-abstracted useTableSelection hook, inlines selection logic
- Replaces triple-condition with explicit hideMobileLabel bool flag
- Removes unsafe Record<string, never> casting

Fixes #3602
This commit is contained in:
harsh-aghara committed 2026-05-05 17:06:48 +05:30
1 parent 657a35e948
commit 387cb35494
4 files changed
+41 -98

No files matched your search

@@ -36,6 +36,7 @@ export type Header<T> = {
id: number | string;
content: React.ReactNode;
mobileLabel?: React.ReactNode;
hideMobileLabel?: boolean;
align?: "left" | "center" | "right" | "justify" | "inherit";
onClick?: (event: React.MouseEvent<HTMLTableCellElement | null>, row: T) => void;
render: (row: T) => React.ReactNode;
@@ -111,7 +112,7 @@ export function DataTable<
key={key}
>
{headers.map((header) => {
if (header.mobileLabel === null) {
if (header.hideMobileLabel) {
return (
<Grid2
container
@@ -143,9 +144,7 @@ export function DataTable<
component="div"
color={theme.palette.text.primary}
>
{header.mobileLabel !== undefined
? header.mobileLabel
: header.content}
{header.mobileLabel ?? header.content}
</Typography>
</Grid2>
<Grid2
-74
View File
@@ -1,74 +0,0 @@
import { useMemo, useCallback } from "react";
interface SelectableItem {
id: string;
}
interface UseTableSelectionReturn {
isAllSelected: boolean;
isSomeSelected: boolean;
handleSelectAll: (checked: boolean) => void;
handleSelectRow: (itemId: string, checked: boolean) => void;
isRowSelected: (itemId: string) => boolean;
}
export const useTableSelection = (
items: SelectableItem[],
selectedIds: string[],
onSelectionChange?: (selected: string[]) => void
): UseTableSelectionReturn => {
const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
const isAllSelected = useMemo(
() =>
items.length > 0 &&
items.every((item) => selectedSet.has(item.id)) &&
selectedIds.length >= items.length,
[items, selectedSet, selectedIds.length]
);
const isSomeSelected = useMemo(
() => selectedIds.length > 0 && !isAllSelected,
[selectedIds.length, isAllSelected]
);
const handleSelectAll = useCallback(
(checked: boolean) => {
if (onSelectionChange) {
if (checked) {
const allIds = items.map((item) => item.id);
onSelectionChange(allIds);
} else {
onSelectionChange([]);
}
}
},
[items, onSelectionChange]
);
const handleSelectRow = useCallback(
(itemId: string, checked: boolean) => {
if (onSelectionChange) {
if (checked) {
onSelectionChange([...selectedIds, itemId]);
} else {
onSelectionChange(selectedIds.filter((id) => id !== itemId));
}
}
},
[selectedIds, onSelectionChange]
);
const isRowSelected = useCallback(
(itemId: string) => selectedSet.has(itemId),
[selectedSet]
);
return {
isAllSelected,
isSomeSelected,
handleSelectAll,
handleSelectRow,
isRowSelected,
};
};
@@ -14,7 +14,6 @@ import { usePost } from "@/Hooks/UseApi";
import type { Monitor } from "@/Types/Monitor";
import { Checkbox } from "@/Components/inputs";
import { useTableSelection } from "@/Hooks/useTableSelection";
interface InfraMonitorsTableProps {
monitors: Monitor[];
@@ -55,13 +54,23 @@ export const InfraMonitorsTable = ({
const navigate = useNavigate();
const { post } = usePost<Record<string, never>, Monitor>();
const {
isAllSelected,
isSomeSelected,
handleSelectAll,
handleSelectRow,
isRowSelected,
} = useTableSelection(monitors, selectedRows, onSelectionChange);
const selectedSet = new Set(selectedRows);
const isAllSelected =
monitors.length > 0 && monitors.every((m) => selectedSet.has(m.id));
const isSomeSelected = selectedRows.length > 0 && !isAllSelected;
const handleSelectAll = (checked: boolean) => {
onSelectionChange?.(checked ? monitors.map((m) => m.id) : []);
};
const handleSelectRow = (id: string, checked: boolean) => {
if (!onSelectionChange) return;
onSelectionChange(
checked ? [...selectedRows, id] : selectedRows.filter((rowId) => rowId !== id)
);
};
const isRowSelected = (id: string) => selectedSet.has(id);
const handlePageChange = (
_e: React.MouseEvent<HTMLButtonElement> | null,
@@ -121,7 +130,7 @@ export const InfraMonitorsTable = ({
? t("common.buttons.resume")
: t("common.buttons.pause"),
action: async () => {
await post(`/monitors/pause/${monitor.id}`, {} as Record<string, never>);
await post(`/monitors/pause/${monitor.id}`, {});
refetch();
},
closeMenu: true,
@@ -168,7 +177,7 @@ export const InfraMonitorsTable = ({
onChange={(e) => handleSelectAll(e.target.checked)}
/>
),
mobileLabel: null,
hideMobileLabel: true,
render: (row) => (
<Checkbox
aria-label={t("pages.common.monitors.actions.selectMonitor", {
@@ -21,7 +21,6 @@ import type { Monitor } from "@/Types/Monitor";
import type { ActionMenuItem } from "@/Components/actions-menu";
import type { RootState } from "@/Types/state";
import { Checkbox } from "@/Components/inputs";
import { useTableSelection } from "@/Hooks/useTableSelection";
interface MonitorTableProps {
monitors: Monitor[];
@@ -62,13 +61,23 @@ export const MonitorTable = ({
const chartType = useSelector((state: RootState) => state.ui?.chartType ?? "histogram");
const { post } = usePost<Record<string, never>, Monitor>();
const {
isAllSelected,
isSomeSelected,
handleSelectAll,
handleSelectRow,
isRowSelected,
} = useTableSelection(monitors, selectedRows, onSelectionChange);
const selectedSet = new Set(selectedRows);
const isAllSelected =
monitors.length > 0 && monitors.every((m) => selectedSet.has(m.id));
const isSomeSelected = selectedRows.length > 0 && !isAllSelected;
const handleSelectAll = (checked: boolean) => {
onSelectionChange?.(checked ? monitors.map((m) => m.id) : []);
};
const handleSelectRow = (id: string, checked: boolean) => {
if (!onSelectionChange) return;
onSelectionChange(
checked ? [...selectedRows, id] : selectedRows.filter((rowId) => rowId !== id)
);
};
const isRowSelected = (id: string) => selectedSet.has(id);
const handleSort = (e: React.MouseEvent, field: string) => {
e.preventDefault();
@@ -129,7 +138,7 @@ export const MonitorTable = ({
? t("pages.common.monitors.actions.resume")
: t("pages.common.monitors.actions.pause"),
action: async () => {
await post(`/monitors/pause/${monitor.id}`, {} as Record<string, never>);
await post(`/monitors/pause/${monitor.id}`, {});
refetch();
},
closeMenu: true,
@@ -175,7 +184,7 @@ export const MonitorTable = ({
onChange={(e) => handleSelectAll(e.target.checked)}
/>
),
mobileLabel: null,
hideMobileLabel: true,
render: (row) => (
<Checkbox
aria-label={t("pages.common.monitors.actions.selectMonitor", {