Skip to content

Commit 79a341a

Browse files
Use new Integrated Browser (1.109+) to open Management Portal in a VS Code tab (#310)
* Use new Integrated Browser (1.109+) * Bump vscode version requirement to 1.109 * Simplify code now that we require vscode 1.109 minimum * Remove remnants of Simple Browser use * Delete obsolete comment * Add Integrated Browser option to `...` menu of namespaces * Offer openPortalTab as alt for openPortalExternal button on server node * Cleanup * Remove code to provide CSPCHD on Portal uris * Prefer Integrated Browser tab when opening Portal * Remove commands to open Portal direct in external browser Still available from ... menu of Integrated Browser
1 parent 7872eee commit 79a341a

File tree

7 files changed

+59
-168
lines changed

7 files changed

+59
-168
lines changed

README.md

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,6 @@ Learn more about `isfs` and `isfs-readonly` folders in the [documentation](https
132132

133133
When you have a folder or a workspace (including a multi-root one) open in VS Code, Server Manager displays a 'Current' node at the start of its tree if your workspace references any server defined in Server Manager. The linking happens automatically if you added workspace folders from Server Manager as described above. If you are using the client-side mode of working, your `objectscript.conn` setting needs to use the `server` property.
134134

135-
## Launching Management Portal
136-
137-
When you hover over a server entry in the tree two command buttons let you launch InterSystems Management Portal.
138-
139-
The first button uses VS Code's Simple Browser feature, which creates a tab alongside any documents you may have open. The second button opens Portal in your workstation's default web browser.
140-
141-
### Notes About Simple Browser
142-
- There is only ever a single Simple Browser tab. Launching another server's Management Portal in it will replace the previous one.
143-
- If the server version is InterSystems IRIS 2020.1.1 or later you will need to change a setting on the suite of web applications that implement Management Portal. This is a consequence of change [SGM031 - Support SameSite for CSP session and user cookies](https://docs.intersystems.com/iris20201/csp/docbook/relnotes/index.html#SGM031). Simple Browser will not be permitted to store Portal's session management cookies, so Portal must be willing to fall back to using the CSPCHD query parameter mechanism.
144-
- Locate the five web applications whose path begins with `/csp/sys`
145-
![Portal web app list](images/README/portalWebApps.png)
146-
147-
- Alter the `Use Cookie for Session` setting on each of them so it is `Autodetect` instead of `Always`.
148-
![Portal web app detail](images/README/portalWebAppSetting.png)
149-
Remember to save the change. The change is not thought to have any adverse effects on the usage of Portal from ordinary browsers, which will continue to use session cookies.
150-
- When a 2020.1.1+ Portal has resorted to using CSPCHD (see above) a few inter-page links fail because they don't add the CSPCHD queryparam. One specific case is the breadcrumb links. Pending the arrival of an InterSystems correction (JIRA DP-404817) these links will take you to the login page. Either enter your credentials to proceed, or launch Simple Browser again from the Server Manager tree.
151-
152135
## Amending and Removing Servers
153136

154137
To manage your server definitions, including changing the username it connects with, [edit the relevant JSON file](https://code.visualstudio.com/docs/getstarted/settings).

package-lock.json

Lines changed: 12 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"multi-root ready"
1616
],
1717
"engines": {
18-
"vscode": "^1.93.0"
18+
"vscode": "^1.109.0"
1919
},
2020
"icon": "images/logo.png",
2121
"categories": [
@@ -57,7 +57,7 @@
5757
"@types/glob": "^7.1.1",
5858
"@types/mocha": "^9.0.0",
5959
"@types/node": "^20.14.0",
60-
"@types/vscode": "^1.93.0",
60+
"@types/vscode": "^1.109.0",
6161
"@vscode/test-electron": "^2.3.8",
6262
"@vscode/test-web": "^0.0.71",
6363
"glob": "^7.1.6",
@@ -277,19 +277,14 @@
277277
"command": "intersystems-community.servermanager.removeFromRecent",
278278
"title": "Remove from Recent"
279279
},
280-
{
281-
"command": "intersystems-community.servermanager.openPortalExternal",
282-
"title": "Open Management Portal in External Browser",
283-
"icon": "$(link-external)"
284-
},
285280
{
286281
"command": "intersystems-community.servermanager.openPortalTab",
287282
"title": "Open Management Portal in Tab",
288-
"icon": "$(tools)"
283+
"icon": "$(link-external)"
289284
},
290285
{
291-
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
292-
"title": "Open Management Portal Here in External Browser",
286+
"command": "intersystems-community.servermanager.openPortalExplorerTab",
287+
"title": "Open Management Portal Here in Tab",
293288
"icon": "$(link-external)"
294289
},
295290
{
@@ -396,12 +391,7 @@
396391
"menus": {
397392
"intersystems-community.servermanager.moreActions": [
398393
{
399-
"command": "intersystems-community.servermanager.openPortalTab",
400-
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
401-
"group": "1_builtin@10"
402-
},
403-
{
404-
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
394+
"command": "intersystems-community.servermanager.openPortalExplorerTab",
405395
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
406396
"group": "1_builtin@10"
407397
}
@@ -453,16 +443,12 @@
453443
"command": "intersystems-community.servermanager.removeFromRecent",
454444
"when": "false"
455445
},
456-
{
457-
"command": "intersystems-community.servermanager.openPortalExternal",
458-
"when": "false"
459-
},
460446
{
461447
"command": "intersystems-community.servermanager.openPortalTab",
462448
"when": "false"
463449
},
464450
{
465-
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
451+
"command": "intersystems-community.servermanager.openPortalExplorerTab",
466452
"when": "false"
467453
},
468454
{
@@ -611,7 +597,7 @@
611597
"group": "inline@20"
612598
},
613599
{
614-
"command": "intersystems-community.servermanager.openPortalExternal",
600+
"command": "intersystems-community.servermanager.openPortalTab",
615601
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
616602
"group": "inline@90"
617603
},

src/api/getPortalUri.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as vscode from "vscode";
2+
import { Uri } from "vscode";
3+
import { IServerSpec } from "@intersystems-community/intersystems-servermanager";
4+
import { extensionId } from "../commonActivate";
5+
6+
export async function getPortalUri(
7+
name: string,
8+
page = "/csp/sys/UtilHome.csp",
9+
namespace = "%SYS",
10+
scope?: vscode.ConfigurationScope,
11+
): Promise<Uri | undefined> {
12+
13+
// Use our own API so that the Recent folder updates with our activity
14+
const myApi = vscode.extensions.getExtension(extensionId)?.exports;
15+
16+
const spec: IServerSpec | undefined = await myApi.getServerSpec(name, scope);
17+
if (typeof spec !== "undefined") {
18+
19+
const webServer = spec.webServer;
20+
const queryString = `$NAMESPACE=${encodeURIComponent(namespace)}`;
21+
22+
return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}${page}?${queryString}`, true);
23+
}
24+
}

src/api/getPortalUriWithToken.ts

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/commonActivate.ts

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from "vscode";
22
import { IServerName, IServerSpec } from "@intersystems-community/intersystems-servermanager";
33
import { addServer } from "./api/addServer";
4-
import { BrowserTarget, getPortalUriWithToken } from "./api/getPortalUriWithToken";
4+
import { getPortalUri } from "./api/getPortalUri";
55
import { getServerNames } from "./api/getServerNames";
66
import { getServerSpec } from "./api/getServerSpec";
77
import { getServerSummary } from "./api/getServerSummary";
@@ -167,36 +167,30 @@ export function commonActivate(context: vscode.ExtensionContext, view: ServerMan
167167
await view.removeFromRecents(server.name);
168168
}
169169
}),
170-
vscode.commands.registerCommand(`${extensionId}.openPortalExternal`, (server?: ServerTreeItem) => {
170+
vscode.commands.registerCommand(`${extensionId}.openPortalTab`, async (server?: ServerTreeItem) => {
171171
if (server?.contextValue?.match(/\.server\./) && server.name) {
172-
getPortalUriWithToken(BrowserTarget.EXTERNAL, server.name, undefined, undefined, server?.params?.serverSummary?.scope).then((uriWithToken) => {
173-
if (uriWithToken) {
174-
vscode.env.openExternal(uriWithToken);
172+
// It is essential to pass skipEncoding=true when converting the uri to a string,
173+
// otherwise the querystring's & and = get encoded.
174+
// Use Integrated Browser which arrived in 1.109
175+
getPortalUri(server.name, undefined, undefined, server?.params?.serverSummary?.scope).then((uri) => {
176+
if (uri) {
177+
vscode.commands.executeCommand("workbench.action.browser.open", uri.toString(true));
175178
}
176179
});
177180
}
178181
}),
179-
vscode.commands.registerCommand(`${extensionId}.openPortalTab`, (server?: ServerTreeItem) => {
180-
if (server?.contextValue?.match(/\.server\./) && server.name) {
181-
getPortalUriWithToken(BrowserTarget.SIMPLE, server.name, undefined, undefined, server?.params?.serverSummary?.scope).then((uriWithToken) => {
182-
if (uriWithToken) {
183-
//
184-
// It is essential to pass skipEncoding=true when converting the uri to a string,
185-
// otherwise the querystring's & and = get encoded.
186-
vscode.commands.executeCommand("simpleBrowser.show", uriWithToken.toString(true));
187-
}
188-
});
189-
}
190-
}),
191-
vscode.commands.registerCommand(`${extensionId}.openPortalExplorerExternal`, (namespaceTreeItem?: NamespaceTreeItem) => {
182+
vscode.commands.registerCommand(`${extensionId}.openPortalExplorerTab`, (namespaceTreeItem?: NamespaceTreeItem) => {
192183
if (namespaceTreeItem) {
193184
const pathParts = namespaceTreeItem.id?.split(":");
194185
if (pathParts && pathParts.length === 4) {
195186
const serverName = pathParts[1];
196187
const namespace = pathParts[3];
197-
getPortalUriWithToken(BrowserTarget.EXTERNAL, serverName, "/csp/sys/exp/%25CSP.UI.Portal.ClassList.zen", namespace, namespaceTreeItem.parent?.parent?.params?.serverSummary?.scope).then((uriWithToken) => {
198-
if (uriWithToken) {
199-
vscode.env.openExternal(uriWithToken);
188+
getPortalUri(serverName, "/csp/sys/exp/%2525CSP.UI.Portal.ClassList.zen", namespace, namespaceTreeItem.parent?.parent?.params?.serverSummary?.scope).then((uri) => {
189+
if (uri) {
190+
// It is essential to pass skipEncoding=true when converting the uri to a string,
191+
// otherwise the querystring's & and = get encoded.
192+
// Use Integrated Browser which arrived in 1.109
193+
vscode.commands.executeCommand("workbench.action.browser.open", uri.toString(true));
200194
}
201195
});
202196
}

src/ui/serverManagerView.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,6 @@ export class ServerTreeItem extends SMTreeItem {
400400
"server-environment",
401401
color ? new vscode.ThemeColor("charts." + color) : undefined,
402402
);
403-
404-
// TODO If single click on server item should open Portal tab
405-
// this.command = {command: 'intersystems-community.servermanager.openPortalTab',
406-
// title: 'Open Management Portal in Simple Browser Tab', arguments: [this]};
407403
}
408404
}
409405

0 commit comments

Comments
 (0)