diff --git a/web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx b/web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx index 9e3395f8e2..1c1512c5c3 100644 --- a/web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx +++ b/web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx @@ -5,11 +5,15 @@ import {Grid} from "antd" import type {ColumnsType} from "antd/es/table" import clsx from "clsx" +import {shouldIgnoreRowClick} from "@/oss/lib/tableRowClick" + import type {InfiniteDatasetStore} from "../createInfiniteDatasetStore" import type { - TableScopeConfig, - TableFeaturePagination, InfiniteVirtualTableFeatureProps, +import type { + InfiniteVirtualTableFeatureProps, + TableFeaturePagination, + TableScopeConfig, TableDeleteConfig, TableExportConfig, } from "../features/InfiniteVirtualTableFeatureShell" @@ -21,29 +25,6 @@ import type { import useTableExport from "./useTableExport" -/** - * Helper to detect if a click event should be ignored for row navigation - * Returns true if the click was on an interactive element (button, link, dropdown, etc.) - */ -export const shouldIgnoreRowClick = (event: MouseEvent): boolean => { - const target = event.target as HTMLElement - - // Check if clicking on interactive elements - if ( - target.closest("button") || - target.closest("a") || - target.closest(".ant-dropdown-trigger") || - target.closest(".ant-checkbox-wrapper") || - target.closest(".ant-select") || - target.closest("input") || - target.closest("textarea") - ) { - return true - } - - return false -} - export interface UseTableManagerConfig { /** The dataset store for this table */ datasetStore: InfiniteDatasetStore diff --git a/web/oss/src/components/VariantsComponents/Table/index.tsx b/web/oss/src/components/VariantsComponents/Table/index.tsx index 316d4086f5..a39242e79f 100644 --- a/web/oss/src/components/VariantsComponents/Table/index.tsx +++ b/web/oss/src/components/VariantsComponents/Table/index.tsx @@ -6,6 +6,8 @@ import {atom, useAtom} from "jotai" import useURL from "@/oss/hooks/useURL" import {EnhancedVariant} from "@/oss/lib/shared/variant/transformer/types" +import {shouldIgnoreRowClick} from "@/oss/lib/tableRowClick" +import {variantTableSelectionAtomFamily} from "../store/selectionAtoms" import ResizableTitle from "../../ResizableTitle" import {variantTableSelectionAtomFamily} from "../store/selectionAtoms" @@ -143,11 +145,15 @@ const VariantsTable = ({ onRow={(record: any, index) => ({ className: "variant-table-row", style: {cursor: "pointer"}, - "data-tour": index === 0 ? "version-row" : undefined, - onClick: () => { - onRowClick(record) - }, - })} +onRow={(record: any, index) => ({ + className: "variant-table-row", + style: {cursor: "pointer"}, + "data-tour": index === 0 ? "version-row" : undefined, + onClick: (event) => { + if (shouldIgnoreRowClick(event)) return + onRowClick(record) + }, +})} {...props} /> diff --git a/web/oss/src/components/pages/app-management/components/AppTable.tsx b/web/oss/src/components/pages/app-management/components/AppTable.tsx index d97e97d242..7303fb269b 100644 --- a/web/oss/src/components/pages/app-management/components/AppTable.tsx +++ b/web/oss/src/components/pages/app-management/components/AppTable.tsx @@ -9,6 +9,7 @@ import {useRouter} from "next/router" import NoResultsFound from "@/oss/components/Placeholders/NoResultsFound/NoResultsFound" import useURL from "@/oss/hooks/useURL" import {formatDay} from "@/oss/lib/helpers/dateTimeHelper" +import {shouldIgnoreRowClick} from "@/oss/lib/tableRowClick" import {ListAppsItem} from "@/oss/lib/Types" import {getAppTypeIcon} from "../../prompts/assets/iconHelpers" @@ -135,7 +136,10 @@ const AppTable = ({ bordered onRow={(record) => ({ style: {cursor: "pointer"}, - onClick: () => router.push(`${baseAppURL}/${record.app_id}/overview`), + onClick: (event) => { + if (shouldIgnoreRowClick(event)) return + router.push(`${baseAppURL}/${record.app_id}/overview`) + }, })} locale={{emptyText: }} /> diff --git a/web/oss/src/lib/tableRowClick.ts b/web/oss/src/lib/tableRowClick.ts new file mode 100644 index 0000000000..e9be7ea058 --- /dev/null +++ b/web/oss/src/lib/tableRowClick.ts @@ -0,0 +1,46 @@ +import type {MouseEvent} from "react" + +/** + * Determines if a row click event should be ignored because it originated from + * an interactive element within the row. + * + * This helper prevents accidental row navigation when users interact with: + * - Buttons (including dropdown triggers) + * - Links + * - Checkboxes and radio buttons + * - Select dropdowns + * - Input fields and textareas + * + * @param event - The mouse click event from the table row + * @returns `true` if the click should be ignored (don't trigger row action), `false` otherwise + * + * @example + * ```tsx + * ({ + * onClick: (event) => { + * if (shouldIgnoreRowClick(event)) return + * navigateToRecord(record) + * } + * })} + * /> + * ``` + */ +export const shouldIgnoreRowClick = (event: MouseEvent): boolean => { + const target = event.target as HTMLElement + + // Check if clicking on interactive elements + if ( + target.closest("button") || + target.closest("a") || + target.closest(".ant-dropdown-trigger") || + target.closest(".ant-checkbox-wrapper") || + target.closest(".ant-select") || + target.closest("input") || + target.closest("textarea") + ) { + return true + } + + return false +}