Skip to content

Commit cf874ec

Browse files
committed
feat: add shareable copy url button to previewable data
1 parent eaa3675 commit cf874ec

File tree

3 files changed

+70
-61
lines changed

3 files changed

+70
-61
lines changed

src/components/DatasetDetailPage/FileTree/FileTree.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@ import React from "react";
88
type Props = {
99
title: string;
1010
tree: TreeNode[];
11-
filesCount: number;
12-
totalBytes: number;
11+
// filesCount: number;
12+
// totalBytes: number;
1313
// for preview in tree row
1414
onPreview: (src: string | any, index: number, isInternal?: boolean) => void;
1515
getInternalByPath: (path: string) => { data: any; index: number } | undefined;
1616
getJsonByPath?: (path: string) => any;
1717
highlightText?: string;
1818
};
1919

20-
const formatSize = (n: number) => {
21-
if (n < 1024) return `${n} B`;
22-
if (n < 1024 ** 2) return `${(n / 1024).toFixed(1)} KB`;
23-
if (n < 1024 ** 3) return `${(n / 1024 ** 2).toFixed(2)} MB`;
24-
if (n < 1024 ** 4) return `${(n / 1024 ** 3).toFixed(2)} GB`;
25-
return `${(n / 1024 ** 4).toFixed(2)} TB`;
26-
};
20+
// const formatSize = (n: number) => {
21+
// if (n < 1024) return `${n} B`;
22+
// if (n < 1024 ** 2) return `${(n / 1024).toFixed(1)} KB`;
23+
// if (n < 1024 ** 3) return `${(n / 1024 ** 2).toFixed(2)} MB`;
24+
// if (n < 1024 ** 4) return `${(n / 1024 ** 3).toFixed(2)} GB`;
25+
// return `${(n / 1024 ** 4).toFixed(2)} TB`;
26+
// };
2727

2828
const FileTree: React.FC<Props> = ({
2929
title,
3030
tree,
31-
filesCount,
32-
totalBytes,
31+
// filesCount,
32+
// totalBytes,
3333
onPreview,
3434
getInternalByPath,
3535
getJsonByPath,

src/components/DatasetDetailPage/FileTree/utils.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,15 @@ export const buildTreeFromDoc = (
8787
if (Array.isArray(doc)) {
8888
doc.forEach((item, i) => {
8989
const path = `${curPath}/[${i}]`;
90+
if (linkMap.has(path)) {
91+
// console.log("PATH", path);
92+
// console.log("has exact", linkMap.has(path));
93+
// console.log("has _DataLink_", linkMap.has(`${path}/_DataLink_`));
94+
} else {
95+
// console.log("nothing matching in array docs");
96+
}
97+
9098
const linkHere = linkMap.get(path) || linkMap.get(`${path}/_DataLink_`);
91-
// For primitive items, show "1: value" in the *name*
9299
const isPrimitive =
93100
item === null || ["string", "number", "boolean"].includes(typeof item);
94101
const label = isPrimitive ? `${i}: ${formatLeafValue(item)}` : String(i); // objects/arrays just show "1", "2", ...
@@ -97,7 +104,7 @@ export const buildTreeFromDoc = (
97104
out.push({
98105
kind: "folder",
99106
// name: `[${i}]`,
100-
name: label,
107+
name: label, // For primitive items, show "1: value" in the name
101108
path,
102109
link: linkHere,
103110
children: buildTreeFromDoc(item, linkMap, path),
@@ -113,12 +120,21 @@ export const buildTreeFromDoc = (
113120
});
114121
}
115122
});
123+
// console.log("out", out);
116124
return out;
117125
}
118126

119127
Object.keys(doc).forEach((key) => {
120128
const val = doc[key];
121129
const path = `${curPath}/${key}`;
130+
if (linkMap.has(path)) {
131+
// console.log("PATH", path);
132+
// console.log("has exact", linkMap.has(path));
133+
// console.log("has _DataLink_", linkMap.has(`${path}/_DataLink_`));
134+
} else {
135+
// console.log("nothing match in object keys");
136+
}
137+
122138
const linkHere = linkMap.get(path) || linkMap.get(`${path}/_DataLink_`);
123139

124140
if (val && typeof val === "object") {

src/pages/UpdatedDatasetDetailPage.tsx

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
Alert,
1414
Button,
1515
Collapse,
16-
Snackbar,
16+
Tooltip,
1717
} from "@mui/material";
1818
import FileTree from "components/DatasetDetailPage/FileTree/FileTree";
1919
import {
@@ -56,29 +56,17 @@ interface InternalDataLink {
5656
const UpdatedDatasetDetailPage: React.FC = () => {
5757
const { dbName, docId } = useParams<{ dbName: string; docId: string }>();
5858
const navigate = useNavigate();
59-
const [searchParams, setSearchParams] = useSearchParams();
60-
// for highlight
61-
const focus = searchParams.get("focus") || undefined;
62-
63-
// for revision
64-
const rev = searchParams.get("rev") || undefined;
65-
66-
const handleSelectRevision = (newRev?: string | null) => {
67-
setSearchParams((prev) => {
68-
const p = new URLSearchParams(prev); // copy of the query url
69-
if (newRev) p.set("rev", newRev);
70-
else p.delete("rev");
71-
return p;
72-
});
73-
};
74-
7559
const dispatch = useAppDispatch();
7660
const {
7761
selectedDocument: datasetDocument,
7862
loading,
7963
error,
8064
datasetViewInfo: dbViewInfo,
8165
} = useAppSelector(NeurojsonSelector);
66+
// get params from url
67+
const [searchParams, setSearchParams] = useSearchParams();
68+
const focus = searchParams.get("focus") || undefined; // get highlight from url
69+
const rev = searchParams.get("rev") || undefined; // get revision from url
8270

8371
const [externalLinks, setExternalLinks] = useState<ExternalDataLink[]>([]);
8472
const [internalLinks, setInternalLinks] = useState<InternalDataLink[]>([]);
@@ -90,6 +78,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
9078
const [isExternalExpanded, setIsExternalExpanded] = useState(true);
9179
const [jsonSize, setJsonSize] = useState<number>(0);
9280
const [previewIndex, setPreviewIndex] = useState<number>(0);
81+
const [isPreviewLoading, setIsPreviewLoading] = useState(false);
9382
const [copiedToast, setCopiedToast] = useState<{
9483
open: boolean;
9584
text: string;
@@ -98,6 +87,14 @@ const UpdatedDatasetDetailPage: React.FC = () => {
9887
text: "",
9988
});
10089
const aiSummary = datasetDocument?.[".datainfo"]?.AISummary ?? "";
90+
const handleSelectRevision = (newRev?: string | null) => {
91+
setSearchParams((prev) => {
92+
const p = new URLSearchParams(prev); // copy of the query url
93+
if (newRev) p.set("rev", newRev);
94+
else p.delete("rev");
95+
return p;
96+
});
97+
};
10198

10299
const linkMap = useMemo(() => makeLinkMap(externalLinks), [externalLinks]); // => external Link Map
103100

@@ -107,18 +104,17 @@ const UpdatedDatasetDetailPage: React.FC = () => {
107104
);
108105

109106
const treeTitle = "Files";
110-
const filesCount = externalLinks.length;
111-
const totalBytes = useMemo(() => {
112-
let bytes = 0;
113-
for (const l of externalLinks) {
114-
const m = l.url.match(/size=(\d+)/);
115-
if (m) bytes += parseInt(m[1], 10);
116-
}
117-
return bytes;
118-
}, [externalLinks]);
107+
// const filesCount = externalLinks.length;
108+
// const totalBytes = useMemo(() => {
109+
// let bytes = 0;
110+
// for (const l of externalLinks) {
111+
// const m = l.url.match(/size=(\d+)/);
112+
// if (m) bytes += parseInt(m[1], 10);
113+
// }
114+
// return bytes;
115+
// }, [externalLinks]);
119116

120117
// add spinner
121-
const [isPreviewLoading, setIsPreviewLoading] = useState(false);
122118

123119
const formatSize = (sizeInBytes: number): string => {
124120
if (sizeInBytes < 1024) {
@@ -159,7 +155,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
159155
links.push({
160156
name: `${label} (${size}) [/${subpath}]`,
161157
size,
162-
path: currentPath, // keep full JSON path for file placement
158+
path: currentPath, // parent path (not include _DataLink_)
163159
url: correctedUrl,
164160
index: links.length,
165161
});
@@ -203,7 +199,6 @@ const UpdatedDatasetDetailPage: React.FC = () => {
203199
obj.MeshNode?.hasOwnProperty("_ArrayZipData_") &&
204200
typeof obj.MeshNode["_ArrayZipData_"] === "string"
205201
) {
206-
// console.log("path", path);
207202
internalLinks.push({
208203
name: "JMesh",
209204
data: obj,
@@ -252,7 +247,6 @@ const UpdatedDatasetDetailPage: React.FC = () => {
252247
});
253248
}
254249
}
255-
256250
return internalLinks;
257251
};
258252
// Build a shareable preview URL for a JSON path in this dataset
@@ -442,14 +436,14 @@ const UpdatedDatasetDetailPage: React.FC = () => {
442436
idx: number,
443437
isInternal: boolean = false
444438
) => {
445-
console.log(
446-
"🟢 Preview button clicked for:",
447-
dataOrUrl,
448-
"Index:",
449-
idx,
450-
"Is Internal:",
451-
isInternal
452-
);
439+
// console.log(
440+
// "🟢 Preview button clicked for:",
441+
// dataOrUrl,
442+
// "Index:",
443+
// idx,
444+
// "Is Internal:",
445+
// isInternal
446+
// );
453447

454448
// Clear any stale preview type from last run
455449
delete (window as any).__previewType;
@@ -588,7 +582,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
588582
},
589583
[datasetDocument]
590584
);
591-
585+
// check if the url has preview param
592586
useEffect(() => {
593587
const p = searchParams.get("preview");
594588
if (!p || !datasetDocument) return;
@@ -613,8 +607,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
613607
externalLinks,
614608
searchParams,
615609
internalMap,
616-
// externalMap,
617-
linkMap,
610+
linkMap, // externalMap
618611
]);
619612

620613
const handleClosePreview = () => {
@@ -892,8 +885,8 @@ const UpdatedDatasetDetailPage: React.FC = () => {
892885
<FileTree
893886
title={treeTitle}
894887
tree={treeData}
895-
filesCount={filesCount}
896-
totalBytes={totalBytes}
888+
// filesCount={filesCount}
889+
// totalBytes={totalBytes}
897890
onPreview={handlePreview} // pass the function down to FileTree
898891
getInternalByPath={getInternalByPath}
899892
getJsonByPath={getJsonByPath}
@@ -1051,7 +1044,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
10511044
>
10521045
Preview
10531046
</Button>
1054-
{/* <Button
1047+
<Button
10551048
variant="outlined"
10561049
size="small"
10571050
sx={{
@@ -1070,7 +1063,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
10701063
>
10711064
<ContentCopyIcon sx={{ fontSize: 16, mr: 0.5 }} />
10721065
Copy URL
1073-
</Button> */}
1066+
</Button>
10741067
</Box>
10751068
</Box>
10761069
))
@@ -1205,7 +1198,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
12051198
Preview
12061199
</Button>
12071200
)}
1208-
{/* {isPreviewable && (
1201+
{isPreviewable && (
12091202
<Button
12101203
variant="outlined"
12111204
size="small"
@@ -1226,7 +1219,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
12261219
<ContentCopyIcon sx={{ fontSize: 16, mr: 0.5 }} />
12271220
Copy URL
12281221
</Button>
1229-
)} */}
1222+
)}
12301223
</Box>
12311224
</Box>
12321225
);
@@ -1282,7 +1275,7 @@ const UpdatedDatasetDetailPage: React.FC = () => {
12821275
<CircularProgress color="inherit" />
12831276
</Backdrop>
12841277

1285-
{/* Preview Modal Component - Add Here */}
1278+
{/* Preview Modal Component */}
12861279
<PreviewModal
12871280
isOpen={previewOpen}
12881281
dataKey={previewDataKey}

0 commit comments

Comments
 (0)