Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Panel management #118

Merged
merged 40 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7e0d7e6
assertIsVariableDefinition (#116-2)
bmingles Sep 5, 2024
137bd4a
Removed assertion utils (#116-2)
bmingles Sep 5, 2024
f767c6e
Split out treeviewutils and added some variable panel utils (#116-2)
bmingles Sep 6, 2024
255b670
Show variables associated with connections (#116-2)
bmingles Sep 6, 2024
0e49793
Started wiring up open panel cmd (#116-2)
bmingles Sep 6, 2024
30cf04c
Fixed type (#116-2)
bmingles Sep 6, 2024
c4bf77e
Import missing type (#116-2)
bmingles Sep 6, 2024
c435fcd
Added panelService back to DhService (#116-2)
bmingles Sep 6, 2024
fe76577
Pass array of variables (#116-2)
bmingles Sep 6, 2024
848820b
Added logger (#116-2)
bmingles Sep 6, 2024
d5366d6
Panel refresh management (#116-2)
bmingles Sep 17, 2024
ed2d796
Moved panel update commands to PanelController (#116-2)
bmingles Sep 9, 2024
8c0ffe9
Removed debug log (#116-2)
bmingles Sep 9, 2024
afbe101
Made event handlers private (#116-2)
bmingles Sep 9, 2024
76b90d1
Added consoleType to cn node (#116-2)
bmingles Sep 9, 2024
cc6a9cb
dh icon font (#116-2)
bmingles Sep 9, 2024
5a97d39
Updated icon font (#116-2)
bmingles Sep 10, 2024
8c7f9d3
Fixed rebase (#116-2)
bmingles Sep 10, 2024
6d699cd
Updated table unicode icon (#116-2)
bmingles Sep 10, 2024
f53de3e
Don't steal focus with pip check terminal (#116-2)
bmingles Sep 10, 2024
ff32a1a
Removed unused variable (#116-2)
bmingles Sep 10, 2024
0b640ab
Removed commented out code (#116-2)
bmingles Sep 11, 2024
2ac060d
Refresh panels on theme change (#116-2)
bmingles Sep 11, 2024
7936da2
Added a waitFor(0) (#116-2)
bmingles Sep 11, 2024
43ea53e
Consolidated sorting (#116-2)
bmingles Sep 11, 2024
d8d1fb7
Changed types (#116-2)
bmingles Sep 11, 2024
323d066
Comments (#116-2)
bmingles Sep 11, 2024
1587733
Reorder (#116-2)
bmingles Sep 11, 2024
d032d61
Delete panel (#116-2)
bmingles Sep 11, 2024
85c627e
Unit tests (#116-2)
bmingles Sep 11, 2024
880c728
Fixed regression (#116-2)
bmingles Sep 11, 2024
6966319
Unit tests (#116-2)
bmingles Sep 11, 2024
c836e4f
Added cases to switch (#116-2)
bmingles Sep 11, 2024
bc65bdd
Added comment (#116-2)
bmingles Sep 11, 2024
660e884
Renamed vars (#116-2)
bmingles Sep 11, 2024
cacc985
Unit tests (#116-2)
bmingles Sep 11, 2024
3a539e8
Updated type + comments (#116-2)
bmingles Sep 11, 2024
50df32d
Backed out broken pip servers (#116-2)
bmingles Sep 12, 2024
cdac84c
Removed auto show panel for now (#116-2)
bmingles Sep 12, 2024
2a1dc80
Update src/services/PanelService.ts
bmingles Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/dh-icons.woff
Binary file not shown.
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@
"command": "vscode-deephaven.openVariablePanels",
"title": "Deephaven: Open Variable Panels"
},
{
"command": "vscode-deephaven.refreshVariablePanels",
"title": "Deephaven: Refresh Variable Panels"
},
{
"command": "vscode-deephaven.refreshServerTree",
"title": "Deephaven: Refresh Server Tree",
Expand Down Expand Up @@ -611,6 +615,10 @@
{
"command": "vscode-deephaven.refreshServerConnectionTree",
"when": "false"
},
{
"command": "vscode-deephaven.refreshVariablePanels",
"when": "false"
}
],
"editor/context": [
Expand Down Expand Up @@ -707,6 +715,11 @@
"id": "vscode-deephaven.serverConnectionTree",
"name": "Connections",
"type": "tree"
},
{
"id": "vscode-deephaven.serverConnectionPanelTree",
"name": "Panels",
"type": "tree"
}
]
}
Expand Down
1 change: 1 addition & 0 deletions src/common/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const OPEN_IN_BROWSER_CMD = `${EXTENSION_ID}.openInBrowser`;
export const OPEN_VARIABLE_PANELS_CMD = `${EXTENSION_ID}.openVariablePanels`;
export const REFRESH_SERVER_TREE_CMD = `${EXTENSION_ID}.refreshServerTree`;
export const REFRESH_SERVER_CONNECTION_TREE_CMD = `${EXTENSION_ID}.refreshServerConnectionTree`;
export const REFRESH_VARIABLE_PANELS_CMD = `${EXTENSION_ID}.refreshVariablePanels`;
export const RUN_CODE_COMMAND = `${EXTENSION_ID}.runCode`;
export const RUN_SELECTION_COMMAND = `${EXTENSION_ID}.runSelection`;
export const SELECT_CONNECTION_COMMAND = `${EXTENSION_ID}.selectConnection`;
Expand Down
14 changes: 13 additions & 1 deletion src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const TMP_DIR_ROOT = path.join(__dirname, '..', 'tmp');
export const VIEW_ID = {
serverTree: `${EXTENSION_ID}.serverTree`,
serverConnectionTree: `${EXTENSION_ID}.serverConnectionTree`,
serverConnectionPanelTree: `${EXTENSION_ID}.serverConnectionPanelTree`,
} as const;

export const ICON_ID = {
Expand All @@ -61,14 +62,25 @@ export const ICON_ID = {
serverConnected: 'circle-large-filled',
serverRunning: 'circle-large-outline',
serverStopped: 'circle-slash',
varFigure: 'graph',
varElement: 'preview',
varPandas: 'dh-pandas',
varTable: 'dh-table',
} as const;

/* eslint-disable @typescript-eslint/naming-convention */
export const VARIABLE_UNICODE_ICONS = {
'deephaven.plot.express.DeephavenFigure': '📈',
'deephaven.ui.Element': '✨',
Figure: '📈',
Table: '⬜',
HierarchicalTable: '▤',
OtherWidget: '⬜',
'pandas.DataFrame': '🐼',
PartitionedTable: '▤',
Table: '▤',
TableMap: '▤',
Treemap: '▤',
TreeTable: '▤',
} as const satisfies Record<VariableType, string>;
/* eslint-enable @typescript-eslint/naming-convention */

Expand Down
47 changes: 30 additions & 17 deletions src/controllers/ExtensionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
DISCONNECT_FROM_SERVER_CMD,
DOWNLOAD_LOGS_CMD,
OPEN_IN_BROWSER_CMD,
OPEN_VARIABLE_PANELS_CMD,
REFRESH_SERVER_CONNECTION_TREE_CMD,
REFRESH_SERVER_TREE_CMD,
RUN_CODE_COMMAND,
Expand All @@ -30,6 +29,7 @@ import {
RunCommandCodeLensProvider,
ServerTreeProvider,
ServerConnectionTreeProvider,
ServerConnectionPanelTreeProvider,
runSelectedLinesHoverProvider,
} from '../providers';
import { DhcServiceFactory, PanelService, ServerManager } from '../services';
Expand All @@ -41,10 +41,11 @@ import type {
IPanelService,
IServerManager,
IToastService,
ServerConnectionPanelNode,
ServerConnectionPanelTreeView,
ServerConnectionTreeView,
ServerState,
ServerTreeView,
VariableDefintion,
} from '../types';
import { ServerConnectionTreeDragAndDropController } from './ServerConnectionTreeDragAndDropController';
import { ConnectionController } from './ConnectionController';
Expand Down Expand Up @@ -76,7 +77,6 @@ export class ExtensionController implements Disposable {
'Congratulations, your extension "vscode-deephaven" is now active!'
);

this._outputChannel?.show();
this._outputChannel?.appendLine('Deephaven extension activated');
}

Expand All @@ -89,11 +89,19 @@ export class ExtensionController implements Disposable {
private _pipServerController: PipServerController | null = null;
private _dhcServiceFactory: IDhServiceFactory | null = null;
private _serverManager: IServerManager | null = null;

// Tree providers
private _serverTreeProvider: ServerTreeProvider | null = null;
private _serverConnectionTreeProvider: ServerConnectionTreeProvider | null =
null;
private _serverConnectionPanelTreeProvider: ServerConnectionPanelTreeProvider | null =
null;

// Tree views
private _serverTreeView: ServerTreeView | null = null;
private _serverConnectionTreeView: ServerConnectionTreeView | null = null;
private _serverConnectionPanelTreeView: ServerConnectionPanelTreeView | null =
null;

private _pythonDiagnostics: vscode.DiagnosticCollection | null = null;
private _outputChannel: vscode.OutputChannel | null = null;
Expand Down Expand Up @@ -239,6 +247,7 @@ export class ExtensionController implements Disposable {
this._context.subscriptions.push(this._panelService);

this._dhcServiceFactory = new DhcServiceFactory(
this._panelService,
this._pythonDiagnostics,
this._outputChannel,
this._toaster
Expand Down Expand Up @@ -314,9 +323,6 @@ export class ExtensionController implements Disposable {
/** Open server in browser */
this.registerCommand(OPEN_IN_BROWSER_CMD, this.onOpenInBrowser);

/** Open variable panel */
this.registerCommand(OPEN_VARIABLE_PANELS_CMD, this.onOpenVariablePanels);

/** Run all code in active editor */
this.registerCommand(RUN_CODE_COMMAND, this.onRunCode);

Expand Down Expand Up @@ -349,6 +355,7 @@ export class ExtensionController implements Disposable {
* Register web views for the extension.
*/
initializeWebViews = (): void => {
assertDefined(this._panelService, 'panelService');
assertDefined(this._serverManager, 'serverManager');

// Server tree
Expand All @@ -374,10 +381,25 @@ export class ExtensionController implements Disposable {
}
);

// Connection Panel tree
this._serverConnectionPanelTreeProvider =
new ServerConnectionPanelTreeProvider(
this._serverManager,
this._panelService
);
this._serverConnectionPanelTreeView =
vscode.window.createTreeView<ServerConnectionPanelNode>(
VIEW_ID.serverConnectionPanelTree,
{
showCollapseAll: true,
treeDataProvider: this._serverConnectionPanelTreeProvider,
}
);

this._context.subscriptions.push(
this._serverManager,
this._serverTreeView,
this._serverConnectionTreeView
this._serverConnectionTreeView,
this._serverConnectionPanelTreeView
);
};

Expand Down Expand Up @@ -490,15 +512,6 @@ export class ExtensionController implements Disposable {
);
};

/**
* Open panels for given url and variables.
* @param url Connection url to open panels for.
* @param variables Variables to open panels for.
*/
onOpenVariablePanels = (url: URL, variables: VariableDefintion[]): void => {
this._panelController?.openPanels(url, variables);
};

onRefreshServerStatus = async (): Promise<void> => {
await this._pipServerController?.syncManagedServers();
await this._serverManager?.updateStatus();
Expand Down
78 changes: 75 additions & 3 deletions src/controllers/PanelController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,59 @@ import type {
IServerManager,
VariableDefintion,
} from '../types';
import { assertDefined, getDHThemeKey, getPanelHtml, Logger } from '../util';
import { getEmbedWidgetUrl } from '../dh/dhc';
import { assertDefined, getDHThemeKey, getPanelHtml } from '../util';
import { DhcService } from '../services';
import {
OPEN_VARIABLE_PANELS_CMD,
REFRESH_VARIABLE_PANELS_CMD,
} from '../common';
import { waitFor } from '../util/promiseUtils';

const logger = new Logger('PanelController');

export class PanelController implements Disposable {
constructor(serverManager: IServerManager, panelService: IPanelService) {
this._panelService = panelService;
this._serverManager = serverManager;
this._subscriptions = [];

this._subscriptions.push(
vscode.commands.registerCommand(
OPEN_VARIABLE_PANELS_CMD,
this._onOpenPanels
),
vscode.commands.registerCommand(
REFRESH_VARIABLE_PANELS_CMD,
this._onRefreshPanelsContent
),
vscode.window.onDidChangeActiveColorTheme(
this._onDidChangeActiveColorTheme
)
);
}

private readonly _panelService: IPanelService;
private readonly _serverManager: IServerManager;
private readonly _subscriptions: vscode.Disposable[];

dispose = async (): Promise<void> => {};
dispose = async (): Promise<void> => {
for (const subscription of this._subscriptions) {
subscription.dispose();
}
this._subscriptions.length = 0;
};

openPanels = async (
private _onOpenPanels = async (
serverUrl: URL,
variables: VariableDefintion[]
): Promise<void> => {
logger.debug('openPanels', serverUrl, variables);

// Waiting for next tick seems to decrease the occurrences of a subtle bug
// where the `editor/title/run` menu gets stuck on a previous selection.
await waitFor(0);

let lastPanel: vscode.WebviewPanel | null = null;

for (const { id, title } of variables) {
Expand Down Expand Up @@ -73,5 +107,43 @@ export class PanelController implements Disposable {
}

lastPanel?.reveal();
this._onRefreshPanelsContent(serverUrl, variables);
};

/**
* Reload the html content for all panels associated with the given server url
* + variables.
* @param serverUrl The server url.
* @param variables Variables identifying the panels to refresh.
*/
private _onRefreshPanelsContent = (
serverUrl: URL,
variables: VariableDefintion[]
): void => {
const connection = this._serverManager.getConnection(serverUrl);
assertDefined(connection, 'connection');

for (const { id, title } of variables) {
const panel = this._panelService.getPanelOrThrow(serverUrl, id);

const iframeUrl = getEmbedWidgetUrl(
serverUrl,
title,
getDHThemeKey(),
connection instanceof DhcService ? connection.getPsk() : undefined
);

panel.webview.html = getPanelHtml(iframeUrl, title);
}
};

/**
* Whenever active theme changes, refresh any open panels.
*/
private _onDidChangeActiveColorTheme = (): void => {
for (const url of this._panelService.getPanelUrls()) {
const variables = this._panelService.getPanelVariables(url);
this._onRefreshPanelsContent(url, [...variables]);
}
};
}
50 changes: 50 additions & 0 deletions src/providers/ServerConnectionPanelTreeProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as vscode from 'vscode';
import type {
IDhService,
IPanelService,
IServerManager,
ServerConnectionPanelNode,
} from '../types';
import { TreeDataProviderBase } from './TreeDataProviderBase';
import {
getPanelConnectionTreeItem,
getPanelVariableTreeItem,
sortByStringProp,
} from '../util';

export class ServerConnectionPanelTreeProvider extends TreeDataProviderBase<ServerConnectionPanelNode> {
constructor(serverManager: IServerManager, panelService: IPanelService) {
super(serverManager);
this._panelService = panelService;

this._panelService.onDidUpdate(() => {
this._onDidChangeTreeData.fire();
});
}

private readonly _panelService: IPanelService;

getTreeItem = async (
connectionOrVariable: ServerConnectionPanelNode
): Promise<vscode.TreeItem> => {
if (Array.isArray(connectionOrVariable)) {
return getPanelVariableTreeItem(connectionOrVariable);
}

return getPanelConnectionTreeItem(connectionOrVariable);
};

getChildren = (
connectionOrRoot?: IDhService
): vscode.ProviderResult<ServerConnectionPanelNode[]> => {
if (connectionOrRoot == null) {
return this.serverManager
.getConnections()
.sort(sortByStringProp('serverUrl'));
}

return [...this._panelService.getVariables(connectionOrRoot.serverUrl)]
.sort(sortByStringProp('title'))
.map(variable => [connectionOrRoot.serverUrl, variable]);
};
}
Loading