Skip to content

Commit

Permalink
Add support for project-based workflows (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
isc-bsaviano authored Apr 13, 2022
1 parent ddbf608 commit 9ac5fb0
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 5 deletions.
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,16 @@
"command": "intersystems-community.servermanager.viewNamespaceWebAppFiles",
"title": "View Web Application Files",
"icon": "$(telescope)"
},
{
"command": "intersystems-community.servermanager.editProject",
"title": "Edit Code in Project",
"icon": "$(edit)"
},
{
"command": "intersystems-community.servermanager.viewProject",
"title": "View Code in Project",
"icon": "$(eye)"
}
],
"submenus": [
Expand Down Expand Up @@ -433,6 +443,14 @@
{
"command": "intersystems-community.servermanager.viewNamespaceWebAppFiles",
"when": "false"
},
{
"command": "intersystems-community.servermanager.editProject",
"when": "false"
},
{
"command": "intersystems-community.servermanager.viewProject",
"when": "false"
}
],
"view/title": [
Expand Down Expand Up @@ -490,6 +508,16 @@
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
"group": "inline@20"
},
{
"command": "intersystems-community.servermanager.editProject",
"when": "view == intersystems-community_servermanager && viewItem == project",
"group": "inline@10"
},
{
"command": "intersystems-community.servermanager.viewProject",
"when": "view == intersystems-community_servermanager && viewItem == project",
"group": "inline@20"
},
{
"command": "intersystems-community.servermanager.openPortalTab",
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
Expand Down
21 changes: 17 additions & 4 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getServerNames } from './api/getServerNames';
import { getServerSpec } from './api/getServerSpec';
import { storePassword, clearPassword } from './commands/managePasswords';
import { importFromRegistry } from './commands/importFromRegistry';
import { ServerManagerView, ServerTreeItem, SMTreeItem } from './ui/serverManagerView';
import { NamespaceTreeItem, ProjectTreeItem, ServerManagerView, ServerTreeItem, SMTreeItem } from './ui/serverManagerView';
import { addServer } from './api/addServer';
import { getServerSummary } from './api/getServerSummary';
import { BrowserTarget, getPortalUriWithToken } from './api/getPortalUriWithToken';
Expand Down Expand Up @@ -204,7 +204,7 @@ export function activate(context: vscode.ExtensionContext) {
})
);

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

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

context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.editProject`, async (projectTreeItem?: ProjectTreeItem) => {
await addWorkspaceFolderAsync(false, false, <NamespaceTreeItem>projectTreeItem?.parent?.parent, projectTreeItem?.name);
})
);

context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.viewProject`, async (projectTreeItem?: ProjectTreeItem) => {
await addWorkspaceFolderAsync(true, false, <NamespaceTreeItem>projectTreeItem?.parent?.parent, projectTreeItem?.name);
})
);

// Listen for relevant configuration changes
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('intersystems.servers') || e.affectsConfiguration('objectscript.conn')) {
Expand Down
90 changes: 89 additions & 1 deletion src/ui/serverManagerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,98 @@ export class NamespaceTreeItem extends SMTreeItem {
parent: element.parent,
label: name,
id,
tooltip: `${name} on ${serverName}`
tooltip: `${name} on ${serverName}`,
getChildren: namespaceFeatures,
params: { serverName }
});
this.name = name;
this.contextValue = name === '%SYS' ? 'sysnamespace' : 'namespace';
this.iconPath = new vscode.ThemeIcon('archive');
}
}

/**
* getChildren function returning namespace features (the child nodes of a server),
*
* @param element parent
* @param params (unused)
* @returns feature folders of a namespace.
*/
async function namespaceFeatures(element: NamespaceTreeItem, params?: any): Promise<FeatureTreeItem[] | undefined> {
return [new ProjectsTreeItem({ parent: element, id: element.name, label: element.name }, params.serverName)];
}

export class ProjectsTreeItem extends FeatureTreeItem {
public readonly name: string;
constructor(
element: SMItem,
serverName: string
) {
const parentFolderId = element.parent?.id || '';
super({
parent: element.parent,
label: 'Projects',
id: parentFolderId + ':projects',
tooltip: `Projects in this namespace`,
getChildren: namespaceProjects,
params: { serverName, ns: element.label }
});
this.name = 'Projects';
this.contextValue = 'projects';
this.iconPath = new vscode.ThemeIcon('library');
}
}

/**
* getChildren function returning projects in a server namespace.
*
* @param element parent
* @param params { serverName }
* @returns projects in a server namespace.
*/
async function namespaceProjects(element: ProjectsTreeItem, params?: any): Promise<ProjectTreeItem[] | undefined> {
const children: ProjectTreeItem[] = [];

if (params?.serverName && params.ns) {
const name: string = params.serverName;
const serverSpec = await getServerSpec(name)
if (!serverSpec) {
return undefined
}

const response = await makeRESTRequest(
"POST",
serverSpec,
{ apiVersion: 1, namespace: params.ns, path: "/action/query" },
{ query: "SELECT Name, Description FROM %Studio.Project", parameters: [] }
);
if (response !== undefined) {
response.data.result.content.map((project) => {
children.push(new ProjectTreeItem({ parent: element, label: name, id: name }, project.Name, project.Description));
});
}
}

return children;
}

export class ProjectTreeItem extends SMTreeItem {
public readonly name: string;
constructor(
element: SMItem,
name: string,
description: string
) {
const parentFolderId = element.parent?.id || '';
const id = parentFolderId + ':' + name;
super({
parent: element.parent,
label: name,
id,
tooltip: description
});
this.name = name;
this.contextValue = 'project';
this.iconPath = new vscode.ThemeIcon('files');
}
}

0 comments on commit 9ac5fb0

Please sign in to comment.