Skip to content

Commit 9ac5fb0

Browse files
authored
Add support for project-based workflows (#131)
Companion of intersystems-community/vscode-objectscript#927
1 parent ddbf608 commit 9ac5fb0

File tree

3 files changed

+134
-5
lines changed

3 files changed

+134
-5
lines changed

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,16 @@
326326
"command": "intersystems-community.servermanager.viewNamespaceWebAppFiles",
327327
"title": "View Web Application Files",
328328
"icon": "$(telescope)"
329+
},
330+
{
331+
"command": "intersystems-community.servermanager.editProject",
332+
"title": "Edit Code in Project",
333+
"icon": "$(edit)"
334+
},
335+
{
336+
"command": "intersystems-community.servermanager.viewProject",
337+
"title": "View Code in Project",
338+
"icon": "$(eye)"
329339
}
330340
],
331341
"submenus": [
@@ -433,6 +443,14 @@
433443
{
434444
"command": "intersystems-community.servermanager.viewNamespaceWebAppFiles",
435445
"when": "false"
446+
},
447+
{
448+
"command": "intersystems-community.servermanager.editProject",
449+
"when": "false"
450+
},
451+
{
452+
"command": "intersystems-community.servermanager.viewProject",
453+
"when": "false"
436454
}
437455
],
438456
"view/title": [
@@ -490,6 +508,16 @@
490508
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
491509
"group": "inline@20"
492510
},
511+
{
512+
"command": "intersystems-community.servermanager.editProject",
513+
"when": "view == intersystems-community_servermanager && viewItem == project",
514+
"group": "inline@10"
515+
},
516+
{
517+
"command": "intersystems-community.servermanager.viewProject",
518+
"when": "view == intersystems-community_servermanager && viewItem == project",
519+
"group": "inline@20"
520+
},
493521
{
494522
"command": "intersystems-community.servermanager.openPortalTab",
495523
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",

src/extension.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getServerNames } from './api/getServerNames';
77
import { getServerSpec } from './api/getServerSpec';
88
import { storePassword, clearPassword } from './commands/managePasswords';
99
import { importFromRegistry } from './commands/importFromRegistry';
10-
import { ServerManagerView, ServerTreeItem, SMTreeItem } from './ui/serverManagerView';
10+
import { NamespaceTreeItem, ProjectTreeItem, ServerManagerView, ServerTreeItem, SMTreeItem } from './ui/serverManagerView';
1111
import { addServer } from './api/addServer';
1212
import { getServerSummary } from './api/getServerSummary';
1313
import { BrowserTarget, getPortalUriWithToken } from './api/getPortalUriWithToken';
@@ -204,7 +204,7 @@ export function activate(context: vscode.ExtensionContext) {
204204
})
205205
);
206206

207-
const addWorkspaceFolderAsync = async (readonly: boolean, csp: boolean, namespaceTreeItem?: ServerTreeItem) => {
207+
const addWorkspaceFolderAsync = async (readonly: boolean, csp: boolean, namespaceTreeItem?: ServerTreeItem, project?: string) => {
208208
if (namespaceTreeItem) {
209209
const pathParts = namespaceTreeItem.id?.split(':');
210210
if (pathParts && pathParts.length === 4) {
@@ -228,9 +228,10 @@ export function activate(context: vscode.ExtensionContext) {
228228
return;
229229
}
230230

231-
const uri = vscode.Uri.parse(`isfs${readonly ? "-readonly" : ""}://${serverName}:${namespace}/${csp ? '?csp' : ''}`);
231+
const params = [ csp ? "csp" : "", project ? `project=${project}` : ""].filter(e => e != "").join("&");
232+
const uri = vscode.Uri.parse(`isfs${readonly ? "-readonly" : ""}://${serverName}:${namespace}/${params ? `?${params}` : ""}`);
232233
if ((vscode.workspace.workspaceFolders || []).filter((workspaceFolder) => workspaceFolder.uri.toString() === uri.toString()).length === 0) {
233-
const label = `${serverName}:${namespace}${csp ? ' webfiles' : ''}${readonly ? " (read-only)" : ""}`;
234+
const label = `${project ? `${project} - ` : ""}${serverName}:${namespace}${csp ? ' web files' : ''}${readonly && project == undefined ? " (read-only)" : ""}`;
234235
const added = vscode.workspace.updateWorkspaceFolders(
235236
vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0,
236237
0,
@@ -267,6 +268,18 @@ export function activate(context: vscode.ExtensionContext) {
267268
vscode.commands.registerCommand(`${extensionId}.viewNamespaceWebAppFiles`, async (namespaceTreeItem?: ServerTreeItem) => {await addWorkspaceFolderAsync(true, true, namespaceTreeItem)})
268269
);
269270

271+
context.subscriptions.push(
272+
vscode.commands.registerCommand(`${extensionId}.editProject`, async (projectTreeItem?: ProjectTreeItem) => {
273+
await addWorkspaceFolderAsync(false, false, <NamespaceTreeItem>projectTreeItem?.parent?.parent, projectTreeItem?.name);
274+
})
275+
);
276+
277+
context.subscriptions.push(
278+
vscode.commands.registerCommand(`${extensionId}.viewProject`, async (projectTreeItem?: ProjectTreeItem) => {
279+
await addWorkspaceFolderAsync(true, false, <NamespaceTreeItem>projectTreeItem?.parent?.parent, projectTreeItem?.name);
280+
})
281+
);
282+
270283
// Listen for relevant configuration changes
271284
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => {
272285
if (e.affectsConfiguration('intersystems.servers') || e.affectsConfiguration('objectscript.conn')) {

src/ui/serverManagerView.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,10 +427,98 @@ export class NamespaceTreeItem extends SMTreeItem {
427427
parent: element.parent,
428428
label: name,
429429
id,
430-
tooltip: `${name} on ${serverName}`
430+
tooltip: `${name} on ${serverName}`,
431+
getChildren: namespaceFeatures,
432+
params: { serverName }
431433
});
432434
this.name = name;
433435
this.contextValue = name === '%SYS' ? 'sysnamespace' : 'namespace';
434436
this.iconPath = new vscode.ThemeIcon('archive');
435437
}
436438
}
439+
440+
/**
441+
* getChildren function returning namespace features (the child nodes of a server),
442+
*
443+
* @param element parent
444+
* @param params (unused)
445+
* @returns feature folders of a namespace.
446+
*/
447+
async function namespaceFeatures(element: NamespaceTreeItem, params?: any): Promise<FeatureTreeItem[] | undefined> {
448+
return [new ProjectsTreeItem({ parent: element, id: element.name, label: element.name }, params.serverName)];
449+
}
450+
451+
export class ProjectsTreeItem extends FeatureTreeItem {
452+
public readonly name: string;
453+
constructor(
454+
element: SMItem,
455+
serverName: string
456+
) {
457+
const parentFolderId = element.parent?.id || '';
458+
super({
459+
parent: element.parent,
460+
label: 'Projects',
461+
id: parentFolderId + ':projects',
462+
tooltip: `Projects in this namespace`,
463+
getChildren: namespaceProjects,
464+
params: { serverName, ns: element.label }
465+
});
466+
this.name = 'Projects';
467+
this.contextValue = 'projects';
468+
this.iconPath = new vscode.ThemeIcon('library');
469+
}
470+
}
471+
472+
/**
473+
* getChildren function returning projects in a server namespace.
474+
*
475+
* @param element parent
476+
* @param params { serverName }
477+
* @returns projects in a server namespace.
478+
*/
479+
async function namespaceProjects(element: ProjectsTreeItem, params?: any): Promise<ProjectTreeItem[] | undefined> {
480+
const children: ProjectTreeItem[] = [];
481+
482+
if (params?.serverName && params.ns) {
483+
const name: string = params.serverName;
484+
const serverSpec = await getServerSpec(name)
485+
if (!serverSpec) {
486+
return undefined
487+
}
488+
489+
const response = await makeRESTRequest(
490+
"POST",
491+
serverSpec,
492+
{ apiVersion: 1, namespace: params.ns, path: "/action/query" },
493+
{ query: "SELECT Name, Description FROM %Studio.Project", parameters: [] }
494+
);
495+
if (response !== undefined) {
496+
response.data.result.content.map((project) => {
497+
children.push(new ProjectTreeItem({ parent: element, label: name, id: name }, project.Name, project.Description));
498+
});
499+
}
500+
}
501+
502+
return children;
503+
}
504+
505+
export class ProjectTreeItem extends SMTreeItem {
506+
public readonly name: string;
507+
constructor(
508+
element: SMItem,
509+
name: string,
510+
description: string
511+
) {
512+
const parentFolderId = element.parent?.id || '';
513+
const id = parentFolderId + ':' + name;
514+
super({
515+
parent: element.parent,
516+
label: name,
517+
id,
518+
tooltip: description
519+
});
520+
this.name = name;
521+
this.contextValue = 'project';
522+
this.iconPath = new vscode.ThemeIcon('files');
523+
}
524+
}

0 commit comments

Comments
 (0)