Skip to content

Commit bc57300

Browse files
committed
feat: add show more and show less for long string values in node tree; refs #88
1 parent f71f3e4 commit bc57300

File tree

2 files changed

+116
-36
lines changed

2 files changed

+116
-36
lines changed

src/components/DatasetDetailPage/FileTree/FileTreeRow.tsx

Lines changed: 114 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,65 @@ import VisibilityIcon from "@mui/icons-material/Visibility";
1212
import { Box, Button, Collapse, Typography } from "@mui/material";
1313
import { Tooltip, IconButton } from "@mui/material";
1414
import { Colors } from "design/theme";
15-
import React from "react";
15+
import React, { useState } from "react";
16+
17+
// FileTreeRow.tsx (top of file, below imports)
18+
const LeafString: React.FC<{ value: string }> = ({ value }) => {
19+
const LIMIT = 120;
20+
const [expanded, setExpanded] = React.useState(false);
21+
22+
const isLong = value.length > LIMIT;
23+
const display = expanded
24+
? value
25+
: isLong
26+
? value.slice(0, LIMIT) + "…"
27+
: value;
28+
29+
return (
30+
<Box
31+
sx={{
32+
display: "flex",
33+
alignItems: "baseline",
34+
gap: 1,
35+
mt: 0.25,
36+
minWidth: 0,
37+
}}
38+
>
39+
<Typography
40+
sx={{
41+
fontFamily: "monospace",
42+
fontSize: "0.85rem",
43+
color: "text.secondary",
44+
45+
// collapsed: clamp to 2 lines; expanded: fully wrap
46+
display: expanded ? "block" : "-webkit-box",
47+
WebkitBoxOrient: "vertical",
48+
WebkitLineClamp: expanded ? ("unset" as any) : 2,
49+
whiteSpace: expanded ? "pre-wrap" : "normal",
50+
overflow: expanded ? "visible" : "hidden",
51+
textOverflow: expanded ? "unset" : "ellipsis",
52+
flex: 1,
53+
}}
54+
>
55+
{display}
56+
</Typography>
57+
58+
{isLong && (
59+
<Button
60+
size="small"
61+
variant="text"
62+
onClick={(e) => {
63+
e.stopPropagation(); // don’t toggle the row
64+
setExpanded((v) => !v);
65+
}}
66+
sx={{ px: 0.5, minWidth: "auto" }}
67+
>
68+
{expanded ? "Show less" : "Show more"}
69+
</Button>
70+
)}
71+
</Box>
72+
);
73+
};
1674

1775
type Props = {
1876
node: TreeNode;
@@ -50,8 +108,9 @@ const FileTreeRow: React.FC<Props> = ({
50108
getInternalByPath,
51109
getJsonByPath,
52110
}) => {
53-
const [open, setOpen] = React.useState(false);
54-
const [copied, setCopied] = React.useState(false);
111+
const [open, setOpen] = useState(false);
112+
const [copied, setCopied] = useState(false);
113+
const [showFull, setShowFull] = useState(false);
55114
// const internal = getInternalByPath?.(node.path);
56115
// const internal = getInternalByPath ? getInternalByPath(node.path) : undefined;
57116
const internal = getInternalByPath(node.path);
@@ -69,14 +128,13 @@ const FileTreeRow: React.FC<Props> = ({
69128
};
70129

71130
if (node.kind === "folder") {
72-
// const isSubject = /^sub-/i.test(node.name); // subject folders only
73131
const isJson = /\.json$/i.test(node.name); // end with .json only
74132
return (
75133
<>
76134
<Box
77135
sx={{
78136
display: "flex",
79-
alignItems: "center",
137+
alignItems: "flex-start",
80138
gap: 1,
81139
py: 0.5,
82140
px: 1,
@@ -188,7 +246,9 @@ const FileTreeRow: React.FC<Props> = ({
188246
}
189247
// if the node is a file
190248
return (
191-
<Box sx={{ display: "flex", alignItems: "center", gap: 1, py: 0.5, px: 1 }}>
249+
<Box
250+
sx={{ display: "flex", alignItems: "flex-start", gap: 1, py: 0.5, px: 1 }}
251+
>
192252
<Box sx={{ pl: level * 1.25, pt: "2px" }}>
193253
<InsertDriveFileIcon
194254
fontSize="small"
@@ -200,7 +260,6 @@ const FileTreeRow: React.FC<Props> = ({
200260
<Typography
201261
title={node.name}
202262
sx={{
203-
// fontWeight: 500,
204263
whiteSpace: "nowrap",
205264
overflow: "hidden",
206265
textOverflow: "ellipsis",
@@ -209,7 +268,36 @@ const FileTreeRow: React.FC<Props> = ({
209268
{node.name}
210269
</Typography>
211270

212-
{!node.link && node.value !== undefined && (
271+
{!node.link &&
272+
node.value !== undefined &&
273+
(typeof node.value === "string" ? (
274+
<LeafString value={node.value} />
275+
) : (
276+
<Typography
277+
title={
278+
node.name === "_ArrayZipData_"
279+
? "[compressed data]"
280+
: typeof node.value === "string"
281+
? node.value
282+
: JSON.stringify(node.value)
283+
}
284+
sx={{
285+
fontFamily: "monospace",
286+
fontSize: "0.85rem",
287+
color: "text.secondary",
288+
whiteSpace: "nowrap",
289+
overflow: "hidden",
290+
textOverflow: "ellipsis",
291+
mt: 0.25,
292+
}}
293+
>
294+
{node.name === "_ArrayZipData_"
295+
? "[compressed data]"
296+
: formatLeafValue(node.value)}
297+
</Typography>
298+
))}
299+
300+
{/* {!node.link && node.value !== undefined && (
213301
<Typography
214302
title={
215303
node.name === "_ArrayZipData_"
@@ -232,24 +320,26 @@ const FileTreeRow: React.FC<Props> = ({
232320
? "[compressed data]"
233321
: formatLeafValue(node.value)}
234322
</Typography>
235-
)}
323+
)} */}
236324
</Box>
237325
{/* ALWAYS show copy for files, even when no external/internal */}
238-
<Tooltip title={copied ? "Copied!" : "Copy JSON"} arrow>
239-
<span>
240-
<IconButton
241-
size="small"
242-
onClick={handleCopy}
243-
disabled={!getJsonByPath} // optional safety
244-
>
245-
{copied ? (
246-
<CheckIcon fontSize="inherit" />
247-
) : (
248-
<ContentCopyIcon fontSize="inherit" />
249-
)}
250-
</IconButton>
251-
</span>
252-
</Tooltip>
326+
<Box sx={{ alignSelf: "flex-start" }}>
327+
<Tooltip title={copied ? "Copied!" : "Copy JSON"} arrow>
328+
<span>
329+
<IconButton
330+
size="small"
331+
onClick={handleCopy}
332+
disabled={!getJsonByPath} // optional safety
333+
>
334+
{copied ? (
335+
<CheckIcon fontSize="inherit" />
336+
) : (
337+
<ContentCopyIcon fontSize="inherit" />
338+
)}
339+
</IconButton>
340+
</span>
341+
</Tooltip>
342+
</Box>
253343
{/* Placeholder to align with folder chevron */}
254344
<Box sx={{ width: 28 }} />
255345
{(externalUrl || internal) && (

src/pages/UpdatedDatasetDetailPage.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
11241124
</Box>
11251125

11261126
{/* JSON */}
1127-
<Box
1127+
{/* <Box
11281128
sx={{
11291129
flex: 1,
11301130
minHeight: 240,
@@ -1161,18 +1161,8 @@ const UpdatedDatasetDetailPage: React.FC = () => {
11611161
collapsed={1}
11621162
style={{ fontSize: "14px", fontFamily: "monospace" }}
11631163
/>
1164-
</Box>
1164+
</Box> */}
11651165
</Box>
1166-
1167-
{/* <ReactJson
1168-
src={transformedDataset || datasetDocument}
1169-
name={false}
1170-
enableClipboard={true}
1171-
displayDataTypes={false}
1172-
displayObjectSize={true}
1173-
collapsed={searchTerm.length >= 3 ? false : 1} // 🔍 Expand during search
1174-
style={{ fontSize: "14px", fontFamily: "monospace" }}
1175-
/> */}
11761166
</Box>
11771167

11781168
{/* Data panels (right panel) */}

0 commit comments

Comments
 (0)