mirror of
https://github.com/SigNoz/signoz.git
synced 2026-08-07 13:40:40 +01:00
* fix(logs): open log details in table (Column) format when activeId is set
Opening a log link (?activeLogId=...) and switching to Column/table format
left the highlighted row un-openable — clicking it did nothing.
Root cause: the shared TanStackTable decided open vs. close internally from
`isRowActive` + `onRowDeactivate`. LogsExplorerList had overloaded `isRowActive`
with `|| log.id === activeLogId`, so a URL-highlighted-but-closed row looked
"active" and the first click ran the deactivate (close) path instead of opening.
Fix (PR 1 of 2): move click routing to the consumer.
- Remove `onRowDeactivate` from TanStackTable; it took no args and only fired
when re-clicking the same active row (clicking A→B never deactivated A).
- `onRowClick` now receives a third `{ isActive }` context arg (additive; the
~14 existing consumers are unaffected).
- LogsExplorerList and LiveLogsList own the toggle:
`isActive ? handleCloseLogDetail() : handleSetActiveLog(log)`, and
`isRowActive` tracks only `activeLog?.id`.
The linked-row visual highlight (`isHighlighted`) is deferred to PR 2 (blocked
on a design decision for the highlight color); see
frontend/docs/tdd-tanstack-row-click-routing.md.
* feat(logs): highlight the URL-linked (activeLogId) row in table format (#12271)
Restores the linked-row highlight that the TanStack migration (#10946)
dropped from the table view, without coupling it to click routing.
Uses the table's existing `getRowClassName` hook (styling-only) — no new
shared-table prop:
- LogsExplorerList / LiveLogsList set getRowClassName to 'logs-linked-row'
when `log.id === activeLogId`.
- A global, lowest-specificity rule paints `.logs-linked-row td` using the
per-row `--row-active-bg` var (already set via getRowStyle). The table's own
:hover / .tableRowActive cell rules are higher-specificity !important, so
active/hover correctly win when a linked row is also open or hovered.
`isRowActive` stays `activeLog?.id` only, so the highlighted row still opens on
first click (relies on the routing fix in the base PR).
Color reuses --row-active-bg as a placeholder; a distinct "linked" token is a
follow-up pending design.
Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
* chore: remove comments
* chore: remove extra comments
* feat: add e2e for flows
* chore: add test id
* chore: chore: remove comment
* chore: remove comment
* chore: remove comment
* chore: add comment
* chore: remove comment
---------
Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
127 lines
3.9 KiB
TypeScript
127 lines
3.9 KiB
TypeScript
import type { MouseEvent } from 'react';
|
|
import { memo, useCallback } from 'react';
|
|
import { Row as TanStackRowModel } from '@tanstack/react-table';
|
|
|
|
import { TanStackRowCell } from './TanStackRowCell';
|
|
import { useIsRowHovered } from './TanStackTableStateContext';
|
|
import { TableRowContext } from './types';
|
|
|
|
import tableStyles from './TanStackTable.module.scss';
|
|
|
|
type TanStackRowCellsProps<TData, TItemKey = string> = {
|
|
row: TanStackRowModel<TData>;
|
|
context: TableRowContext<TData, TItemKey> | undefined;
|
|
itemKind: 'row' | 'expansion';
|
|
hasSingleColumn: boolean;
|
|
columnOrderKey: string;
|
|
columnVisibilityKey: string;
|
|
};
|
|
|
|
function TanStackRowCellsInner<TData, TItemKey = string>({
|
|
row,
|
|
context,
|
|
itemKind,
|
|
hasSingleColumn,
|
|
columnOrderKey: _columnOrderKey,
|
|
columnVisibilityKey: _columnVisibilityKey,
|
|
}: TanStackRowCellsProps<TData, TItemKey>): JSX.Element {
|
|
const hasHovered = useIsRowHovered(row.id);
|
|
const rowData = row.original;
|
|
const visibleCells = row.getVisibleCells();
|
|
const lastCellIndex = visibleCells.length - 1;
|
|
|
|
// Stable references via destructuring, keep them as is
|
|
const onRowClick = context?.onRowClick;
|
|
const onRowClickNewTab = context?.onRowClickNewTab;
|
|
const isRowActive = context?.isRowActive;
|
|
const getRowKeyData = context?.getRowKeyData;
|
|
const rowIndex = row.index;
|
|
|
|
const handleClick = useCallback(
|
|
(event: MouseEvent<HTMLTableCellElement>) => {
|
|
// Fall back to an empty key so row clicks still fire for consumers
|
|
// that don't provide getRowKey (e.g. Logs Explorer / Live Logs).
|
|
const keyData = getRowKeyData?.(rowIndex);
|
|
const itemKey = keyData?.itemKey ?? ('' as TItemKey);
|
|
|
|
// Handle ctrl+click or cmd+click (open in new tab)
|
|
if ((event.ctrlKey || event.metaKey) && onRowClickNewTab) {
|
|
onRowClickNewTab(rowData, itemKey);
|
|
return;
|
|
}
|
|
|
|
const isActive = isRowActive?.(rowData) ?? false;
|
|
onRowClick?.(rowData, itemKey, { isActive });
|
|
},
|
|
[isRowActive, onRowClick, onRowClickNewTab, rowData, getRowKeyData, rowIndex],
|
|
);
|
|
|
|
if (itemKind === 'expansion') {
|
|
const keyData = getRowKeyData?.(rowIndex);
|
|
return (
|
|
<td
|
|
colSpan={context?.colCount ?? 1}
|
|
className={tableStyles.tableCellExpansion}
|
|
>
|
|
{context?.renderExpandedRow?.(
|
|
rowData,
|
|
keyData?.finalKey ?? '',
|
|
keyData?.groupMeta,
|
|
)}
|
|
</td>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{visibleCells.map((cell, index) => {
|
|
const isLastCell = index === lastCellIndex;
|
|
return (
|
|
<TanStackRowCell
|
|
key={cell.id}
|
|
cell={cell}
|
|
hasSingleColumn={hasSingleColumn}
|
|
isLastCell={isLastCell}
|
|
hasHovered={hasHovered}
|
|
rowData={rowData}
|
|
onClick={handleClick}
|
|
renderRowActions={context?.renderRowActions}
|
|
/>
|
|
);
|
|
})}
|
|
</>
|
|
);
|
|
}
|
|
|
|
// Custom comparison - only re-render when row data changes
|
|
// If you add any new prop to context, remember to update this function
|
|
function areRowCellsPropsEqual<TData>(
|
|
prev: Readonly<TanStackRowCellsProps<TData>>,
|
|
next: Readonly<TanStackRowCellsProps<TData>>,
|
|
): boolean {
|
|
return (
|
|
prev.row.id === next.row.id &&
|
|
prev.itemKind === next.itemKind &&
|
|
prev.hasSingleColumn === next.hasSingleColumn &&
|
|
prev.columnOrderKey === next.columnOrderKey &&
|
|
prev.columnVisibilityKey === next.columnVisibilityKey &&
|
|
prev.context?.onRowClick === next.context?.onRowClick &&
|
|
prev.context?.onRowClickNewTab === next.context?.onRowClickNewTab &&
|
|
prev.context?.isRowActive === next.context?.isRowActive &&
|
|
prev.context?.getRowKeyData === next.context?.getRowKeyData &&
|
|
prev.context?.renderRowActions === next.context?.renderRowActions &&
|
|
prev.context?.renderExpandedRow === next.context?.renderExpandedRow &&
|
|
prev.context?.colCount === next.context?.colCount
|
|
);
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const TanStackRowCells = memo(
|
|
TanStackRowCellsInner,
|
|
areRowCellsPropsEqual as any,
|
|
) as <T, TItemKey = string>(
|
|
props: TanStackRowCellsProps<T, TItemKey>,
|
|
) => JSX.Element;
|
|
|
|
export default TanStackRowCells;
|