mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
fix: Update "Copy Object" in line viewer to work with nested objects and arrays (#1274)
Fixes: HDX-2617
This commit is contained in:
parent
4cfbd7579c
commit
065cabdb47
3 changed files with 84 additions and 12 deletions
5
.changeset/shy-carrots-wash.md
Normal file
5
.changeset/shy-carrots-wash.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
fix: Update "Copy Object" in line viewer to work with nested objects and arrays
|
||||
|
|
@ -52,15 +52,6 @@ describe('DBRowJsonViewer', () => {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
// Helper function to simulate clicking a button in a line
|
||||
const clickLineButton = (fieldText: string, buttonText: string) => {
|
||||
const line = screen.getByText(fieldText).closest('.line')! as HTMLElement;
|
||||
fireEvent.mouseEnter(line);
|
||||
const lineMenu = line.querySelector('.lineMenu')! as HTMLElement;
|
||||
const button = within(lineMenu).getByText(buttonText);
|
||||
fireEvent.click(button);
|
||||
};
|
||||
|
||||
// Helper to render component
|
||||
const renderComponent = (data: any) => {
|
||||
return renderWithMantine(
|
||||
|
|
@ -70,6 +61,33 @@ describe('DBRowJsonViewer', () => {
|
|||
);
|
||||
};
|
||||
|
||||
// Helper to click a button on a line
|
||||
const clickLineButton = (fieldText: string, buttonText: string) => {
|
||||
const line = screen.getByText(fieldText).closest('.line')! as HTMLElement;
|
||||
fireEvent.mouseEnter(line);
|
||||
const button = within(line).getByText(buttonText);
|
||||
fireEvent.click(button);
|
||||
};
|
||||
|
||||
// Helper to expand a field and click a button on a nested field
|
||||
const expandAndClickButton = (
|
||||
parentField: string,
|
||||
childField: string,
|
||||
buttonText: string,
|
||||
) => {
|
||||
const parentLine = screen
|
||||
.getByText(parentField)
|
||||
.closest('.line')! as HTMLElement;
|
||||
fireEvent.click(parentLine);
|
||||
|
||||
const childLine = screen
|
||||
.getByText(childField)
|
||||
.closest('.line')! as HTMLElement;
|
||||
fireEvent.mouseEnter(childLine);
|
||||
const button = within(childLine).getByText(buttonText);
|
||||
fireEvent.click(button);
|
||||
};
|
||||
|
||||
it('formats log attributes correctly', () => {
|
||||
renderComponent(logData);
|
||||
clickLineButton('field1', 'Search');
|
||||
|
|
@ -136,4 +154,45 @@ describe('DBRowJsonViewer', () => {
|
|||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('copy functionality', () => {
|
||||
const mockClipboard = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
Object.assign(navigator, {
|
||||
clipboard: { writeText: mockClipboard },
|
||||
});
|
||||
});
|
||||
|
||||
it('copies array elements from expanded stringified JSON', () => {
|
||||
const arrayObject = { status: 'True', type: 'PodReady' };
|
||||
const data = { conditions: JSON.stringify([arrayObject]) };
|
||||
|
||||
renderComponent(data);
|
||||
expandAndClickButton('conditions', '0', 'Copy Object');
|
||||
|
||||
expect(mockClipboard).toHaveBeenCalledWith(
|
||||
JSON.stringify(arrayObject, null, 2),
|
||||
);
|
||||
});
|
||||
|
||||
it('copies entire stringified value when not expanded', () => {
|
||||
const arrayData = [{ type: 'Ready' }, { type: 'Init' }];
|
||||
const data = { conditions: JSON.stringify(arrayData) };
|
||||
|
||||
renderComponent(data);
|
||||
clickLineButton('conditions', 'Copy Value');
|
||||
|
||||
expect(mockClipboard).toHaveBeenCalledWith(JSON.stringify(arrayData));
|
||||
});
|
||||
|
||||
it('copies regular nested objects', () => {
|
||||
renderComponent(logData);
|
||||
clickLineButton('nested', 'Copy Object');
|
||||
|
||||
expect(mockClipboard).toHaveBeenCalledWith(
|
||||
JSON.stringify({ field3: 'nested value' }, null, 2),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { useAtom, useAtomValue } from 'jotai';
|
|||
import { atomWithStorage } from 'jotai/utils';
|
||||
import get from 'lodash/get';
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
|
|
@ -344,8 +343,17 @@ export function DBRowJsonViewer({
|
|||
}
|
||||
|
||||
const handleCopyObject = () => {
|
||||
const copiedObj =
|
||||
keyPath.length === 0 ? rowData : get(rowData, keyPath);
|
||||
let copiedObj;
|
||||
|
||||
// When in parsed JSON context (e.g., expanded stringified JSON),
|
||||
// use the value directly since keyPath doesn't match rowData structure
|
||||
if (isInParsedJson && parsedJsonRootPath) {
|
||||
copiedObj = value;
|
||||
} else {
|
||||
// For regular nested objects, use keyPath to navigate rowData
|
||||
copiedObj = keyPath.length === 0 ? rowData : get(rowData, keyPath);
|
||||
}
|
||||
|
||||
window.navigator.clipboard.writeText(
|
||||
JSON.stringify(copiedObj, null, 2),
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue