Skip to content

Commit 5d17603

Browse files
author
Fred Wu
committed
Data viewer update
1 parent 632e0ee commit 5d17603

4 files changed

Lines changed: 102 additions & 13 deletions

File tree

R/session/vsc.R

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) {
456456

457457
show_view <- !identical(getOption("vsc.view", "Two"), FALSE)
458458
if (show_view) {
459+
# Create registry to track dataview UUIDs by title
460+
dataview_registry <- new.env(parent = emptyenv())
461+
459462
get_column_def <- function(name, field, value) {
460463
filter <- TRUE
461464
tooltip <- sprintf(
@@ -535,10 +538,24 @@ if (show_view) {
535538
return(.data)
536539
}
537540

541+
# Generate a dataview_uuid (separate from the LiveShare uuid)
542+
dataview_uuid <- NULL
538543
if (missing(title)) {
539544
sub <- substitute(x)
540545
title <- deparse(sub, nlines = 1)
541546
}
547+
548+
# Generate a unique ID for this dataview based on the title
549+
title_key <- title
550+
if (exists(title_key, envir = dataview_registry, inherits = FALSE)) {
551+
dataview_uuid <- get(title_key, envir = dataview_registry, inherits = FALSE)
552+
logger("Reusing existing dataview UUID for title:", title, "UUID:", dataview_uuid)
553+
} else {
554+
dataview_uuid <- paste0("dataview-", format(Sys.time(), "%Y%m%d%H%M%S"), "-", sample(1000:9999, 1))
555+
assign(title_key, dataview_uuid, envir = dataview_registry)
556+
logger("Created new dataview UUID for title:", title, "UUID:", dataview_uuid)
557+
}
558+
542559
if (inherits(x, "ArrowTabular")) {
543560
x <- as_truncated_data(x)
544561
x <- as.data.frame(x)
@@ -602,21 +619,21 @@ if (show_view) {
602619
file <- tempfile(tmpdir = tempdir, fileext = ".json")
603620
jsonlite::write_json(data, file, na = "string", null = "null", auto_unbox = TRUE, force = TRUE)
604621
request("dataview", source = "table", type = "json",
605-
title = title, file = file, viewer = viewer, uuid = uuid
622+
title = title, file = file, viewer = viewer, uuid = uuid, dataview_uuid = dataview_uuid
606623
)
607624
} else if (is.list(x)) {
608625
tryCatch({
609626
file <- tempfile(tmpdir = tempdir, fileext = ".json")
610627
jsonlite::write_json(x, file, na = "string", null = "null", auto_unbox = TRUE, force = TRUE)
611628
request("dataview", source = "list", type = "json",
612-
title = title, file = file, viewer = viewer, uuid = uuid
629+
title = title, file = file, viewer = viewer, uuid = uuid, dataview_uuid = dataview_uuid
613630
)
614631
}, error = function(e) {
615632
file <- file.path(tempdir, paste0(make.names(title), ".txt"))
616633
text <- utils::capture.output(print(x))
617634
writeLines(text, file)
618635
request("dataview", source = "object", type = "txt",
619-
title = title, file = file, viewer = viewer, uuid = uuid
636+
title = title, file = file, viewer = viewer, uuid = uuid, dataview_uuid = dataview_uuid
620637
)
621638
})
622639
} else {
@@ -628,7 +645,7 @@ if (show_view) {
628645
}
629646
writeLines(code, file)
630647
request("dataview", source = "object", type = "R",
631-
title = title, file = file, viewer = viewer, uuid = uuid
648+
title = title, file = file, viewer = viewer, uuid = uuid, dataview_uuid = dataview_uuid
632649
)
633650
}
634651
}

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"activationEvents": [
3232
"workspaceContains:**/*.{rproj,Rproj,r,R,rd,Rd,rmd,Rmd}",
3333
"onCommand:r.runSelectionInActiveTerm",
34-
"onWebviewPanel:rhelp"
34+
"onWebviewPanel:rhelp",
35+
"onWebviewPanel:rdataviewer"
3536
],
3637
"main": "./dist/extension",
3738
"contributes": {
@@ -1872,6 +1873,11 @@
18721873
},
18731874
"additionalProperties": false
18741875
},
1876+
"r.dataViewer.reuseWindow": {
1877+
"type": "boolean",
1878+
"default": true,
1879+
"markdownDescription": "Reuse the existing data viewer window when `View()` is called multiple times. When enabled, only one data viewer window will be shown and refreshed with new data."
1880+
},
18751881
"r.rtermSendDelay": {
18761882
"type": "integer",
18771883
"default": 8,

src/liveShare/shareSession.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface IRequest {
3636
url?: string;
3737
requestPath?: string;
3838
uuid?: number;
39+
dataview_uuid?: string; // Add this property
3940
tempdir?: string;
4041
version?: string;
4142
info?: {
@@ -149,7 +150,7 @@ export async function updateGuestRequest(file: string, force: boolean = false):
149150
if (request.source && request.type && request.title && request.file
150151
&& request.viewer !== undefined) {
151152
await showDataView(request.source,
152-
request.type, request.title, request.file, request.viewer);
153+
request.type, request.title, request.file, request.viewer, request.dataview_uuid);
153154
}
154155
break;
155156
}

src/session.ts

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ let activeBrowserPanel: WebviewPanel | undefined;
6767
let activeBrowserUri: Uri | undefined;
6868
let activeBrowserExternalUri: Uri | undefined;
6969

70+
// Add a map to track dataview panels by UUID
71+
const dataviewPanels = new Map<string, WebviewPanel>();
72+
7073
export function deploySessionWatcher(extensionPath: string): void {
7174
console.info(`[deploySessionWatcher] extensionPath: ${extensionPath}`);
7275
resDir = path.join(extensionPath, 'dist', 'resources');
@@ -334,15 +337,59 @@ export async function showWebView(file: string, title: string, viewer: string |
334337
console.info('[showWebView] Done');
335338
}
336339

337-
export async function showDataView(source: string, type: string, title: string, file: string, viewer: string): Promise<void> {
338-
console.info(`[showDataView] source: ${source}, type: ${type}, title: ${title}, file: ${file}, viewer: ${viewer}`);
340+
export async function showDataView(source: string, type: string, title: string, file: string, viewer: string, dataview_uuid?: string): Promise<void> {
341+
console.info(`[showDataView] source: ${source}, type: ${type}, title: ${title}, file: ${file}, viewer: ${viewer}, dataview_uuid: ${dataview_uuid}`);
339342

340343
if (isGuestSession) {
341344
resDir = guestResDir;
342345
}
343346

347+
// Check if we have an existing panel with this UUID
348+
let panel: WebviewPanel | undefined;
349+
if (dataview_uuid && dataviewPanels.has(dataview_uuid)) {
350+
panel = dataviewPanels.get(dataview_uuid);
351+
// Panel might have been closed, check if it's still valid
352+
if (panel) {
353+
try {
354+
panel.title = title; // Update title
355+
panel.reveal(ViewColumn[viewer as keyof typeof ViewColumn]);
356+
357+
if (source === 'table') {
358+
// Update existing panel content
359+
const content = await getTableHtml(panel.webview, file);
360+
panel.webview.html = content;
361+
} else if (source === 'list') {
362+
const content = await getListHtml(panel.webview, file);
363+
panel.webview.html = content;
364+
} else {
365+
// For other types, we'll still reopen, but use the existing panel
366+
if (isGuestSession) {
367+
const fileContent = await rGuestService?.requestFileContent(file, 'utf8');
368+
if (fileContent) {
369+
await openVirtualDoc(file, fileContent, true, true, ViewColumn[viewer as keyof typeof ViewColumn]);
370+
}
371+
} else {
372+
await commands.executeCommand('vscode.open', Uri.file(file), {
373+
preserveFocus: true,
374+
preview: true,
375+
viewColumn: ViewColumn[viewer as keyof typeof ViewColumn],
376+
});
377+
}
378+
}
379+
console.info('[showDataView] Updated existing panel');
380+
return;
381+
} catch (e) {
382+
console.log(`Panel was disposed, creating new one: ${e}`);
383+
// Panel was disposed, remove from registry
384+
dataviewPanels.delete(dataview_uuid);
385+
panel = undefined;
386+
}
387+
}
388+
}
389+
390+
// Create a new panel if needed
344391
if (source === 'table') {
345-
const panel = window.createWebviewPanel('dataview', title,
392+
panel = window.createWebviewPanel('dataview', title,
346393
{
347394
preserveFocus: true,
348395
viewColumn: ViewColumn[viewer as keyof typeof ViewColumn],
@@ -356,8 +403,16 @@ export async function showDataView(source: string, type: string, title: string,
356403
const content = await getTableHtml(panel.webview, file);
357404
panel.iconPath = new UriIcon('open-preview');
358405
panel.webview.html = content;
406+
407+
// Register panel if we have a UUID
408+
if (dataview_uuid) {
409+
dataviewPanels.set(dataview_uuid, panel);
410+
panel.onDidDispose(() => {
411+
dataviewPanels.delete(dataview_uuid!);
412+
});
413+
}
359414
} else if (source === 'list') {
360-
const panel = window.createWebviewPanel('dataview', title,
415+
panel = window.createWebviewPanel('dataview', title,
361416
{
362417
preserveFocus: true,
363418
viewColumn: ViewColumn[viewer as keyof typeof ViewColumn],
@@ -371,6 +426,14 @@ export async function showDataView(source: string, type: string, title: string,
371426
const content = await getListHtml(panel.webview, file);
372427
panel.iconPath = new UriIcon('open-preview');
373428
panel.webview.html = content;
429+
430+
// Register panel if we have a UUID
431+
if (dataview_uuid) {
432+
dataviewPanels.set(dataview_uuid, panel);
433+
panel.onDidDispose(() => {
434+
dataviewPanels.delete(dataview_uuid!);
435+
});
436+
}
374437
} else {
375438
if (isGuestSession) {
376439
const fileContent = await rGuestService?.requestFileContent(file, 'utf8');
@@ -738,7 +801,8 @@ export async function writeSuccessResponse(responseSessionDir: string): Promise<
738801

739802
type ISessionRequest = {
740803
plot_url?: string,
741-
server?: SessionServer
804+
server?: SessionServer,
805+
dataview_uuid?: string // Add this property to match the R code
742806
} & IRequest;
743807

744808
async function updateRequest(sessionStatusBarItem: StatusBarItem) {
@@ -753,7 +817,7 @@ async function updateRequest(sessionStatusBarItem: StatusBarItem) {
753817
console.info(`[updateRequest] request: ${requestContent}`);
754818
const request = JSON.parse(requestContent) as ISessionRequest;
755819
if (request.wd && isFromWorkspace(request.wd)) {
756-
if (request.uuid === null || request.uuid === undefined || request.uuid === UUID) {
820+
if (request.uuid === null || request.uuid === undefined || String(request.uuid) === String(UUID)) {
757821
switch (request.command) {
758822
case 'help': {
759823
if (globalRHelp && request.requestPath) {
@@ -818,8 +882,9 @@ async function updateRequest(sessionStatusBarItem: StatusBarItem) {
818882
}
819883
case 'dataview': {
820884
if (request.source && request.type && request.file && request.title && request.viewer !== undefined) {
885+
// Use dataview_uuid for panel tracking, preserve uuid for LiveShare
821886
await showDataView(request.source,
822-
request.type, request.title, request.file, request.viewer);
887+
request.type, request.title, request.file, request.viewer, request.dataview_uuid);
823888
}
824889
break;
825890
}

0 commit comments

Comments
 (0)