feat: Toggle columns from LogSidePanel (#82)

Allow to toggle columns from LogSidePanel

<img width="821" alt="Screenshot 2023-11-03 at 10 39 13 PM" src="https://github.com/hyperdxio/hyperdx/assets/20255948/b997cd3d-edf1-4df5-a201-affdbea27cb6">


Co-authored-by: Shorpo <149748269+svc-shorpo@users.noreply.github.com>
This commit is contained in:
Ernest Iliiasov 2023-11-06 23:06:20 -05:00 committed by GitHub
parent ef0fb17e09
commit bf8af29d68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 1 deletions

View file

@ -0,0 +1,5 @@
---
'@hyperdx/app': minor
---
feat: Toggle columns from LogSidePanel

View file

@ -482,6 +482,8 @@ function TraceSubpanel({
onPropertyAddClick,
generateChartUrl,
generateSearchUrl,
displayedColumns,
toggleColumn,
}: {
logData: any;
onClose: () => void;
@ -493,6 +495,8 @@ function TraceSubpanel({
}) => string;
onPropertyAddClick?: (name: string, value: string) => void;
displayedColumns?: string[];
toggleColumn?: (column: string) => void;
}) {
const date = new Date(logData.timestamp);
const start = add(date, { minutes: -240 });
@ -681,6 +685,8 @@ function TraceSubpanel({
generateSearchUrl={generateSearchUrl}
onClose={onClose}
generateChartUrl={generateChartUrl}
displayedColumns={displayedColumns}
toggleColumn={toggleColumn}
/>
</ErrorBoundary>
</>
@ -1300,6 +1306,8 @@ function PropertySubpanel({
generateSearchUrl,
onClose,
generateChartUrl,
displayedColumns,
toggleColumn,
}: {
logData: any;
generateSearchUrl: (query?: string, timeRange?: [Date, Date]) => string;
@ -1312,6 +1320,8 @@ function PropertySubpanel({
}) => string;
onPropertyAddClick?: (key: string, value: string) => void;
displayedColumns?: string[];
toggleColumn?: (column: string) => void;
}) {
const [propertySearchValue, setPropertySearchValue] = useState('');
const [isNestedView, setIsNestedView] = useLocalStorage(
@ -1582,6 +1592,8 @@ function PropertySubpanel({
}}
valueRenderer={(raw, value, ...rawKeyPath) => {
const keyPath = rawKeyPath.slice().reverse();
const keyPathString = keyPath.join('.');
return (
<div className="parent-hover-trigger d-inline-block px-2">
<pre
@ -1648,6 +1660,24 @@ function PropertySubpanel({
</Button>
</Link>
) : null}
{!!toggleColumn && keyPath.length === 1 ? (
<Button
className="fs-8 text-muted-hover child-hover-trigger p-0"
variant="link"
as="a"
title={
displayedColumns?.includes(keyPathString)
? `Remove ${keyPathString} column from results table`
: `Add ${keyPathString} column to results table`
}
style={{ width: 20 }}
onClick={() => toggleColumn(keyPathString)}
>
<i className="bi bi-table" />
</Button>
) : null}
<CopyToClipboard
text={value}
onCopy={() => {
@ -2032,6 +2062,8 @@ export default function LogSidePanel({
generateChartUrl,
sortKey,
isNestedPanel = false,
displayedColumns,
toggleColumn,
}: {
logId: string | undefined;
onClose: () => void;
@ -2048,6 +2080,8 @@ export default function LogSidePanel({
}) => string;
sortKey: string | undefined;
isNestedPanel?: boolean;
displayedColumns?: string[];
toggleColumn?: (column: string) => void;
}) {
const contextZIndex = useZIndex();
@ -2222,6 +2256,8 @@ export default function LogSidePanel({
generateSearchUrl={generateSearchUrl}
generateChartUrl={generateChartUrl}
onClose={_onClose}
displayedColumns={displayedColumns}
toggleColumn={toggleColumn}
/>
<EventTagSubpanel
logData={logData}
@ -2251,6 +2287,8 @@ export default function LogSidePanel({
generateSearchUrl={generateSearchUrl}
generateChartUrl={generateChartUrl}
onClose={_onClose}
displayedColumns={displayedColumns}
toggleColumn={toggleColumn}
/>
</div>
) : null}

View file

@ -784,6 +784,8 @@ export default function LogTable({
onEnd,
onShowPatternsClick,
tableId,
displayedColumns,
setDisplayedColumns,
}: {
config: {
where: string;
@ -802,10 +804,11 @@ export default function LogTable({
onEnd?: () => void;
onShowPatternsClick?: () => void;
tableId?: string;
displayedColumns: string[];
setDisplayedColumns: (columns: string[]) => void;
}) {
const [instructionsOpen, setInstructionsOpen] = useState(false);
const [settingsOpen, setSettingsOpen] = useState(false);
const [displayedColumns, setDisplayedColumns] = useState<string[]>([]);
const [wrapLines, setWrapLines] = useState(false);
const prevQueryConfig = usePrevious({ searchedQuery, isLive });

View file

@ -4,6 +4,7 @@ import usePortal from 'react-useportal';
import type { LogView } from './types';
import LogSidePanel from './LogSidePanel';
import LogTable from './LogTable';
import { useDisplayedColumns } from './useDisplayedColumns';
export function LogTableWithSidePanel({
config,
@ -82,6 +83,9 @@ export function LogTableWithSidePanel({
const voidFn = useCallback(() => {}, []);
const { displayedColumns, setDisplayedColumns, toggleColumn } =
useDisplayedColumns();
return (
<>
{openedLog != null ? (
@ -95,6 +99,8 @@ export function LogTableWithSidePanel({
onPropertyAddClick={onPropertyAddClick}
generateSearchUrl={generateSearchUrl}
generateChartUrl={generateChartUrl}
displayedColumns={displayedColumns}
toggleColumn={toggleColumn}
/>
</Portal>
) : null}
@ -114,6 +120,8 @@ export function LogTableWithSidePanel({
[setOpenedLog, onRowExpandClick],
)}
onEnd={onSettled}
displayedColumns={displayedColumns}
setDisplayedColumns={setDisplayedColumns}
/>
</>
);

View file

@ -45,6 +45,7 @@ import SearchPageActionBar from './SearchPageActionBar';
import { useTimeQuery } from './timeQuery';
import { MemoPatternTableWithSidePanel } from './PatternTableWithSidePanel';
import { ErrorBoundary } from 'react-error-boundary';
import { useDisplayedColumns } from './useDisplayedColumns';
const formatDate = (
date: Date,
@ -323,6 +324,9 @@ const LogViewerContainer = memo(function LogViewerContainer({
[setOpenedLogQuery],
);
const { displayedColumns, setDisplayedColumns, toggleColumn } =
useDisplayedColumns();
return (
<>
<ErrorBoundary
@ -346,6 +350,8 @@ const LogViewerContainer = memo(function LogViewerContainer({
onPropertyAddClick={onPropertyAddClick}
generateSearchUrl={generateSearchUrl}
generateChartUrl={generateChartUrl}
displayedColumns={displayedColumns}
toggleColumn={toggleColumn}
/>
</ErrorBoundary>
<LogTable
@ -373,6 +379,8 @@ const LogViewerContainer = memo(function LogViewerContainer({
[setOpenedLog, setIsLive],
)}
onShowPatternsClick={onShowPatternsClick}
displayedColumns={displayedColumns}
setDisplayedColumns={setDisplayedColumns}
/>
</>
);

View file

@ -0,0 +1,16 @@
import { useState } from 'react';
// TODO: Instead of prop drilling additional columns, we can consider using React.Context or Jotai
export const useDisplayedColumns = () => {
const [displayedColumns, setDisplayedColumns] = useState<string[]>([]);
const toggleColumn = (column: string) => {
if (displayedColumns.includes(column)) {
setDisplayedColumns(displayedColumns.filter(c => c !== column));
} else {
setDisplayedColumns([...displayedColumns, column]);
}
};
return { displayedColumns, setDisplayedColumns, toggleColumn };
};