Skip to content

Commit 20d3f62

Browse files
Merge pull request #185 from gjsjohnmurray/portal-explorer
Add shortcut to Explorer section of Portal at namespace level
2 parents f6b7904 + cc512ea commit 20d3f62

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@
302302
"title": "Open Management Portal in Tab",
303303
"icon": "$(tools)"
304304
},
305+
{
306+
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
307+
"title": "Open Management Portal Here in External Browser",
308+
"icon": "$(link-external)"
309+
},
305310
{
306311
"command": "intersystems-community.servermanager.retryServer",
307312
"title": "Refresh",
@@ -445,6 +450,10 @@
445450
"command": "intersystems-community.servermanager.openPortalTab",
446451
"when": "false"
447452
},
453+
{
454+
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
455+
"when": "false"
456+
},
448457
{
449458
"command": "intersystems-community.servermanager.retryServer",
450459
"when": "false"
@@ -595,6 +604,11 @@
595604
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
596605
"group": "inline@90"
597606
},
607+
{
608+
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
609+
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
610+
"group": "inline@80"
611+
},
598612
{
599613
"command": "intersystems-community.servermanager.retryServer",
600614
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",

src/api/getPortalUriWithToken.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ export enum BrowserTarget {
1111

1212
const allTokens = [new Map<string, string>(), new Map<string, string>()];
1313

14+
const simpleBrowserCompatible = new Map<string, boolean>();
15+
1416
export async function getPortalUriWithToken(
1517
target: BrowserTarget,
1618
name: string,
19+
page = "/csp/sys/UtilHome.csp",
20+
namespace = "%SYS",
1721
scope?: vscode.ConfigurationScope,
1822
): Promise<Uri | undefined> {
1923

20-
const PORTAL_HOME = "/csp/sys/UtilHome.csp";
21-
2224
// Use our own API so that the Recent folder updates with our activity
2325
const myApi = vscode.extensions.getExtension(extensionId)?.exports;
2426

@@ -32,8 +34,8 @@ export async function getPortalUriWithToken(
3234
const response = await makeRESTRequest(
3335
"POST",
3436
spec,
35-
{ apiVersion: 1, namespace: "%SYS", path: "/action/query" },
36-
{ query: "select %Atelier_v1_Utils.General_GetCSPToken(?, ?) token", parameters: [PORTAL_HOME, token] },
37+
{ apiVersion: 1, namespace, path: "/action/query" },
38+
{ query: "select %Atelier_v1_Utils.General_GetCSPToken(?, ?) token", parameters: [page, token] },
3739
);
3840

3941
if (!response) {
@@ -45,9 +47,35 @@ export async function getPortalUriWithToken(
4547
allTokens[target].set(name, token);
4648
}
4749

50+
if (target === BrowserTarget.SIMPLE && !simpleBrowserCompatible.has(name)) {
51+
// Check that the portal webapps have all been altered so they don't require session cookie support, which Simple Browser cannot provide
52+
const response = await makeRESTRequest(
53+
"POST",
54+
spec,
55+
{ apiVersion: 1, namespace: "%SYS", path: "/action/query" },
56+
{ query: "SELECT Name FROM Security.Applications WHERE {fn CONCAT(Name, '/')} %STARTSWITH '/csp/sys/' AND UseCookies = 2" },
57+
);
58+
if (response) {
59+
const appsRequiringCookie = (response.data?.result?.content as any[]).map((row) => {
60+
return row.Name as string;
61+
});
62+
if (appsRequiringCookie.length > 0) {
63+
await vscode.window.showWarningMessage(`Portal web apps cannot be used in the Simple Browser tab if their 'UseCookies' property is set to 'Always' (the default). To resolve this, use Portal's security section to change it to 'Autodetect' in these apps: ${appsRequiringCookie.join(", ")}`, { modal: true });
64+
return;
65+
}
66+
else {
67+
simpleBrowserCompatible.set(name, true);
68+
}
69+
}
70+
else {
71+
vscode.window.showWarningMessage(`Unable to check the Portal web apps for compatibility with Simple Browser.`);
72+
simpleBrowserCompatible.set(name, true);
73+
}
74+
}
75+
4876
const webServer = spec.webServer;
49-
const queryString = token ? `CSPCHD=${encodeURIComponent(token)}` : "";
77+
const queryString = `$NAMESPACE=${encodeURIComponent(namespace)}${token ? `&CSPCHD=${encodeURIComponent(token)}` : ""}`;
5078

51-
return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}${PORTAL_HOME}?${queryString}`, true);
79+
return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}${page}?${queryString}`, true);
5280
}
5381
}

src/extension.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,29 @@ export function activate(context: vscode.ExtensionContext) {
105105
if (uriWithToken) {
106106
//
107107
// It is essential to pass skipEncoding=true when converting the uri to a string,
108-
// otherwise the encoding done within Simple Browser / webview causes double-encoding
109-
// of the querystring.
108+
// otherwise the querystring's & and = get encoded.
110109
vscode.commands.executeCommand("simpleBrowser.show", uriWithToken.toString(true));
111110
}
112111
});
113112
}
114113
}),
115114
);
115+
context.subscriptions.push(
116+
vscode.commands.registerCommand(`${extensionId}.openPortalExplorerExternal`, (namespaceTreeItem?: NamespaceTreeItem) => {
117+
if (namespaceTreeItem) {
118+
const pathParts = namespaceTreeItem.id?.split(":");
119+
if (pathParts && pathParts.length === 4) {
120+
const serverName = pathParts[1];
121+
const namespace = pathParts[3];
122+
getPortalUriWithToken(BrowserTarget.EXTERNAL, serverName, "/csp/sys/exp/%25CSP.UI.Portal.ClassList.zen", namespace).then((uriWithToken) => {
123+
if (uriWithToken) {
124+
vscode.env.openExternal(uriWithToken);
125+
}
126+
});
127+
}
128+
}
129+
}),
130+
);
116131
context.subscriptions.push(
117132
vscode.commands.registerCommand(`${extensionId}.editSettings`, (server?: ServerTreeItem) => {
118133
// Until there's a dedicated settings editor the best we can do is jump to the right section

0 commit comments

Comments
 (0)