Skip to content

Commit

Permalink
added ability to move throught search results
Browse files Browse the repository at this point in the history
  • Loading branch information
molotgor committed Feb 4, 2025
1 parent 5d1ac1f commit 44d8798
Show file tree
Hide file tree
Showing 9 changed files with 587 additions and 126 deletions.
32 changes: 26 additions & 6 deletions src/components/JSONViewer/DisplayTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ import { PanelType } from '../../stores/JSONViewer/JSONViewerStore';

const shownCapacity = 50;

const DisplayTable = ({ value }: { value: string[][] | undefined; type: PanelType }) => {
const DisplayTable = ({
value,
type,
id,
}: {
value: string[][] | undefined;
type: PanelType;
id: string;
}) => {
const JSONViewerStore = useJSONViewerStore();
const [shownSize, setShownSize] = React.useState(shownCapacity);
if (!value) return <div className='display-table-error'>#display-table is undefined</div>;
Expand All @@ -21,7 +29,13 @@ const DisplayTable = ({ value }: { value: string[][] | undefined; type: PanelTyp
<tr>
{header.map((key, index) => (
<th key={index}>
{multiTokenSplit(key, JSONViewerStore.tokens).map((contentPart, i) => (
{JSONViewerStore.compareTableResults(
type,
id,
0,
index,
multiTokenSplit(key, JSONViewerStore.tokens),
).map((contentPart, i) => (
<span
key={i}
className={contentPart.token != null ? 'found-content' : undefined}
Expand All @@ -39,15 +53,21 @@ const DisplayTable = ({ value }: { value: string[][] | undefined; type: PanelTyp
<tr key={index}>
{row.slice(0, header.length).map((val, ind) => (
<td key={ind}>
{multiTokenSplit(
typeof val === 'string' ? `"${val}"` : String(val),
JSONViewerStore.tokens,
{JSONViewerStore.compareTableResults(
type,
id,
index + 1,
ind,
multiTokenSplit(
typeof val === 'string' ? `"${val}"` : String(val),
JSONViewerStore.tokens,
),
).map((contentPart, i) => (
<span
key={i}
className={contentPart.token != null ? 'found-content' : undefined}
style={{ backgroundColor: contentPart.token?.color }}>
{contentPart.content}
{contentPart.content} {i}
</span>
))}
</td>
Expand Down
4 changes: 2 additions & 2 deletions src/components/JSONViewer/FileChoosing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,13 @@ const FileChoosing = ({
<>
<button
disabled={selectedFiles.length === 0 || isLoading}
className='load-JSON-button'
className='JSON-load-button'
onClick={() => setSelectedFiles([])}>
Reset Selection
</button>
<button
disabled={selectedFiles.length === 0 || isLoading}
className='load-JSON-button'
className='JSON-load-button'
onClick={getFiles}>
Load {selectedFiles.length} Files
</button>
Expand Down
36 changes: 33 additions & 3 deletions src/components/JSONViewer/JSONPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,57 @@ const JSONPanel = ({ type }: { type: PanelType }) => {
<div className='JSON-header-wrapper'>
<div className='JSON-buttons-wrapper'>
<button
className='load-JSON-button'
className='JSON-load-button'
title='Load Executable(s) From Server'
onClick={() =>
JSONViewerStore.setIsModalOpen(!JSONViewerStore.isModalOpen[type], 'notebooks', type)
}>
Load Notebook(s)
</button>
<button
className='load-JSON-button'
className='JSON-load-button'
title='Load Result(s) From Server'
onClick={() =>
JSONViewerStore.setIsModalOpen(!JSONViewerStore.isModalOpen[type], 'results', type)
}>
Load Server Result(s)
</button>
<button
className='load-JSON-button'
className='JSON-load-button'
title='Load Local Result(s)'
onClick={() => inputJSONRef.current?.click()}>
Load Local Result(s)
</button>
{!JSONViewerStore.activeSearch[type] && (
<>
<button
className='JSON-load-button'
title='Previous search result'
disabled={JSONViewerStore.treeNodes[type].length === 0}
onClick={() => JSONViewerStore.activateSearch(type)}>
Search
</button>
</>
)}
{JSONViewerStore.activeSearch[type] && (
<div className='JSON-search-control'>
<button
className='search-controls__prev'
title='Previous search result'
onClick={() => JSONViewerStore.prevSearchResult(type)}
/>
{Math.min(
JSONViewerStore.currentSearchResult[type] + 1,
JSONViewerStore.searchResults[type].length,
)}{' '}
of {JSONViewerStore.searchResults[type].length}
<button
className='search-controls__next'
title='Next search result'
onClick={() => JSONViewerStore.nextSearchResult(type)}
/>
</div>
)}
</div>
</div>
<input
Expand Down
6 changes: 3 additions & 3 deletions src/components/JSONViewer/JSONSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const JSONSearch = () => {
return (
<div className={'JSON-search-header'}>
<button
className='load-JSON-button'
className='JSON-load-button'
onClick={() => JSONViewerStore.toggleMode()}
style={{ width: '120px' }}>
Switch mode to {JSONViewerStore.isCompare ? 'table' : 'compare'}
Expand Down Expand Up @@ -76,12 +76,12 @@ const JSONSearch = () => {
disabled={true}
/>
<div
className='import-JSON-button'
className='import-button'
onClick={() => inputSearchRef.current?.click()}
title='Import Search'
/>
<div
className='export-JSON-button'
className='export-button'
onClick={() => JSONViewerStore.exportSearch()}
title='Export Search'
/>
Expand Down
35 changes: 30 additions & 5 deletions src/components/JSONViewer/JSONViewSimpleField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { createBemElement } from '../../helpers/styleCreators';
import SearchToken from '../../models/search/SearchToken';
import { getKeyValueTokens } from '../../helpers/search/getSpecificTokens';
import multiTokenSplit from '../../helpers/search/multiTokenSplit';
import { useJSONViewerStore } from '../../hooks/useJSONViewerStore';
import { PanelType } from '../../stores/JSONViewer/JSONViewerStore';

const BEAUTIFIED_PAD_VALUE = 15;

interface JSONViewProps {
type: PanelType;
node: TreeNode;
isBeautified: boolean;
isArrayElement?: boolean;
Expand All @@ -18,6 +21,8 @@ interface JSONViewProps {
}

interface JSONViewFieldsReqProps {
id: string;
type: PanelType;
label: string;
isBeautified: boolean;
isArrayElement?: boolean;
Expand All @@ -27,21 +32,24 @@ interface JSONViewFieldsReqProps {
}

const JSONViewSimpleField = ({
id,
type,
label,
field,
isBeautified,
isArrayElement,
setIsHighlighted,
tokens,
}: JSONViewFieldsReqProps) => {
const JSONViewerStore = useJSONViewerStore();
const highlight = React.useMemo(() => debounce(() => setIsHighlighted(true), 60), []);
const valueString =
typeof field === 'object'
? JSON.stringify(field)
: typeof field === 'string'
? `"${field}"`
: String(field);
const keyValueTokens = getKeyValueTokens(tokens, true).filter(
const row = `${label}:${field}`;
const keyValueTokens = getKeyValueTokens(JSONViewerStore.tokens, true).filter(
({ isOne, keyToken, valueToken }) =>
!isOne ||
(`${label}:`.endsWith(keyToken.pattern) && valueString.startsWith(valueToken.pattern)),
Expand All @@ -66,7 +74,13 @@ const JSONViewSimpleField = ({
onMouseLeave={removeHighlight}
className='mc-body__field-label'>
{label && !isArrayElement
? multiTokenSplit(`${label}: `, keyTokens).map((contentPart, index) => (
? JSONViewerStore.compareBodyResults(
type,
id,
row,
'key',
multiTokenSplit(`${label}: `, keyTokens),
).map((contentPart, index) => (
<span
key={index}
className={contentPart.token != null ? 'found-content' : undefined}
Expand All @@ -80,7 +94,13 @@ const JSONViewSimpleField = ({
onMouseEnter={highlight}
onMouseLeave={removeHighlight}
className='mc-body__field-simple-value'>
{multiTokenSplit(valueString, valueTokens).map((contentPart, index) => (
{JSONViewerStore.compareBodyResults(
type,
id,
row,
'value',
multiTokenSplit(valueString, valueTokens),
).map((contentPart, index) => (
<span
key={index}
className={contentPart.token != null ? 'found-content' : undefined}
Expand All @@ -94,12 +114,14 @@ const JSONViewSimpleField = ({
};

const JSONView = ({
type,
node,
isBeautified,
setIsHighlighted,
isArrayElement,
tokens,
}: JSONViewProps) => {
const JSONViewerStore = useJSONViewerStore();
const [areSameContext, highlightSameContext] = React.useState(false);
const keyValueTokens = getKeyValueTokens(tokens, true).filter(
({ isOne, keyToken, valueToken }) =>
Expand Down Expand Up @@ -152,8 +174,10 @@ const JSONView = ({
paddingLeft: isBeautified ? BEAUTIFIED_PAD_VALUE : undefined,
}}>
{node.simpleFields.map(({ key, value }, idx, arr) => (
<React.Fragment key={key}>
<React.Fragment key={`${key}-${JSONViewerStore.currentSearchResult[type]}`}>
<JSONViewSimpleField
id={node.id}
type={type}
label={key}
field={value}
isArrayElement={node.isArray}
Expand All @@ -170,6 +194,7 @@ const JSONView = ({
{node.complexFields.map((n, idx, arr) => (
<React.Fragment key={n.id}>
<JSONView
type={type}
node={n}
isArrayElement={node.isArray}
isBeautified={isBeautified}
Expand Down
10 changes: 8 additions & 2 deletions src/components/JSONViewer/TreeLeaf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ const TreeLeaf = ({
[`borderBottom${otherBorderSide}Radius`]: isNextDifferentChunk ? '0px' : undefined,
};

const splitContent = multiTokenSplit(nodeName, JSONViewerStore.tokens);
const splitContent = JSONViewerStore.compareNameResults(
type,
treeNode.id,
multiTokenSplit(nodeName, JSONViewerStore.tokens),
);

useEffect(() => {
const isChildDisplay =
Expand Down Expand Up @@ -207,6 +211,7 @@ const TreeLeaf = ({
}}>
<div className={createBemBlock('event-status-icon')} />
<span style={{ color: treeNode.isGeneratedKey ? '#333333' : undefined }}>
{treeNode.id} ={'>'} {treeNode.parentIds.join(', ')} {' '}
{splitContent.map((contentPart, index) => (
<span
key={index}
Expand Down Expand Up @@ -251,12 +256,13 @@ const TreeLeaf = ({
)}
</div>
{!treeNode.isRoot && open && viewType === TreeViewType.DISPLAY_TABLE && (
<DisplayTable value={treeNode.displayTable} type={type} />
<DisplayTable id={treeNode.id} value={treeNode.displayTable} type={type} />
)}
{!treeNode.isRoot && (viewType === TreeViewType.JSON || viewType === TreeViewType.PRETTY) && (
<div className='message-card-wrapper'>
<div className='mc__mc-body mc-body'>
<JSONView
type={type}
isBeautified={viewType === TreeViewType.PRETTY}
node={treeNode}
tokens={JSONViewerStore.tokens}
Expand Down
8 changes: 4 additions & 4 deletions src/helpers/JSONViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const convertJSONtoNode = (
i.toString(),
true,
defaultViewType,
[id, ...parentIds],
[...parentIds, id],
depth + 1,
);
if (!failed && val.failed) failed = false;
Expand Down Expand Up @@ -75,7 +75,7 @@ export const convertJSONtoNode = (
entryKey,
false,
defaultViewType,
[id, ...parentIds],
[...parentIds, id],
depth + 1,
);
if (!failed && val.failed) failed = false;
Expand Down Expand Up @@ -277,7 +277,7 @@ export const convertParameterToInput = (parameter: NotebookParameter): InputNote
export const getFlatListFromTree = (tree: TreeNode) => {
const flatten = (node: TreeNode, parentIds: string[] = []): TreeNode[] => [
{ ...node, parentIds, childIds: node.complexFields.map(f => f.id) },
...node.complexFields.flatMap(child => flatten(child, [node.id, ...parentIds])),
...node.complexFields.flatMap(child => flatten(child, [...parentIds, node.id])),
];
return flatten(tree);
};
Expand All @@ -286,7 +286,7 @@ export const getFlatListFromTreeWSimple = (tree: TreeNode) => {
const flatten = (node: TreeNode, parentIds: string[] = []): (TreeNode | SimpleField)[] => [
{ ...node, parentIds, complexFields: [], childIds: node.complexFields.map(f => f.id) },
...node.simpleFields.flatMap(child => ({ ...child, parentIds: [...parentIds, node.id] })),
...node.complexFields.flatMap(child => flatten(child, [node.id, ...parentIds])),
...node.complexFields.flatMap(child => flatten(child, [...parentIds, node.id])),
];
return flatten(tree);
};
Expand Down
Loading

0 comments on commit 44d8798

Please sign in to comment.