Skip to content

Commit

Permalink
Add Modify Project Metadata... command (#1326)
Browse files Browse the repository at this point in the history
  • Loading branch information
isc-bsaviano authored Mar 4, 2024
1 parent 954f3f1 commit 9e2d826
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 44 deletions.
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@
"when": "view == ObjectScriptProjectsExplorer && viewItem == dataNode:projectNode",
"group": "5_objectscript_prj@7"
},
{
"command": "vscode-objectscript.modifyProjectMetadata",
"when": "view == ObjectScriptProjectsExplorer && viewItem == dataNode:projectNode",
"group": "5_objectscript_prj@8"
},
{
"command": "vscode-objectscript.explorer.project.closeOtherServerNs",
"when": "view == ObjectScriptProjectsExplorer && viewItem == projectsServerNsNode:extra",
Expand Down Expand Up @@ -598,6 +603,11 @@
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && explorerResourceIsRoot",
"group": "objectscript_prj@2"
},
{
"command": "vscode-objectscript.modifyProjectMetadata",
"when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ && resource =~ /project%3D/ && explorerResourceIsRoot",
"group": "objectscript_prj@3"
},
{
"command": "vscode-objectscript.importLocalFilesServerSide",
"when": "vscode-objectscript.connectActive && resourceScheme == isfs && explorerResourceIsRoot",
Expand Down Expand Up @@ -1033,6 +1043,11 @@
"title": "Remove Items from Project...",
"category": "ObjectScript"
},
{
"command": "vscode-objectscript.modifyProjectMetadata",
"title": "Modify Project Metadata...",
"category": "ObjectScript"
},
{
"command": "vscode-objectscript.removeFromProject",
"title": "Remove from Project",
Expand Down
118 changes: 89 additions & 29 deletions src/commands/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,35 +706,9 @@ export async function modifyProject(
nodeOrUri: NodeBase | vscode.Uri | undefined,
type: "add" | "remove"
): Promise<any> {
let node: NodeBase;
let api: AtelierAPI;
let project: string;
if (nodeOrUri instanceof NodeBase) {
// Called from Projects Explorer
node = nodeOrUri;
api = new AtelierAPI(node.workspaceFolderUri);
api.setNamespace(node.namespace);
project = node.options.project;
} else if (nodeOrUri instanceof vscode.Uri) {
// Called from files explorer
api = new AtelierAPI(nodeOrUri);
project = new URLSearchParams(nodeOrUri.query).get("project");
} else {
// Function was called from the command palette so there's no first argument
// Have the user pick a server and namespace
const picks = await pickServerAndNamespace();
if (picks == undefined) {
return;
}
const { serverName, namespace } = picks;
api = new AtelierAPI(vscode.Uri.parse(`isfs://${serverName}:${namespace}/`));
}
if (project === undefined) {
project = await pickProject(api);
if (project === undefined) {
return;
}
}
const args = await handleCommandArg(nodeOrUri);
if (!args) return;
const { node, api, project } = args;

// Technically a project is a "document", so tell the server that we're opening it
await new StudioActions().fireProjectUserAction(api, project, OtherStudioAction.OpenedDocument).catch(() => {
Expand Down Expand Up @@ -1177,3 +1151,89 @@ export function addWorkspaceFolderForProject(node: ProjectNode): void {
// Switch to Explorer view so user sees the outcome
vscode.commands.executeCommand("workbench.view.explorer");
}

async function handleCommandArg(
nodeOrUri: NodeBase | vscode.Uri | undefined
): Promise<{ node: NodeBase; api: AtelierAPI; project: string } | undefined> {
let node: NodeBase;
let api: AtelierAPI;
let project: string;
if (nodeOrUri instanceof NodeBase) {
// Called from Projects Explorer
node = nodeOrUri;
api = new AtelierAPI(node.workspaceFolderUri);
api.setNamespace(node.namespace);
project = node.options.project;
} else if (nodeOrUri instanceof vscode.Uri) {
// Called from files explorer
api = new AtelierAPI(nodeOrUri);
project = new URLSearchParams(nodeOrUri.query).get("project");
} else {
// Function was called from the command palette so there's no first argument
// Have the user pick a server and namespace
const picks = await pickServerAndNamespace();
if (picks == undefined) {
return;
}
const { serverName, namespace } = picks;
api = new AtelierAPI(vscode.Uri.parse(`isfs://${serverName}:${namespace}/`));
}
if (project === undefined) {
project = await pickProject(api);
if (project === undefined) {
return;
}
}
return { node, api, project };
}

export async function modifyProjectMetadata(nodeOrUri: NodeBase | vscode.Uri | undefined): Promise<void> {
const args = await handleCommandArg(nodeOrUri);
if (!args) return;
const { api, project } = args;

// Technically a project is a "document", so tell the server that we're opening it
await new StudioActions().fireProjectUserAction(api, project, OtherStudioAction.OpenedDocument).catch(() => {
// Swallow error because showing it is more disruptive than using a potentially outdated project definition
});

try {
const oldDesc: string = await api
.actionQuery("SELECT Description FROM %Studio.Project WHERE Name = ?", [project])
.then((data) => data.result.content[0]?.Description);
const newDesc = await vscode.window.showInputBox({
prompt: `Enter a description for project '${project}'`,
value: oldDesc,
});
if (!newDesc || newDesc == oldDesc) return;

// Technically a project is a "document", so tell the server that we're editing it
const studioActions = new StudioActions();
await studioActions.fireProjectUserAction(api, project, OtherStudioAction.AttemptedEdit);
if (studioActions.projectEditAnswer != "1") {
// Don't perform the edit
if (studioActions.projectEditAnswer == "-1") {
// Source control action failed
vscode.window.showErrorMessage(
`'AttemptedEdit' source control action failed for project '${project}'. Check the 'ObjectScript' Output channel for details.`,
"Dismiss"
);
}
return;
}

// Modify the project
await api.actionQuery("UPDATE %Studio.Project SET Description = ? WHERE Name = ?", [newDesc, project]);

// Refesh the explorer
projectsExplorerProvider.refresh();
} catch (error) {
let message = `Failed to modify metadata of project '${project}'.`;
if (error && error.errorText && error.errorText !== "") {
outputChannel.appendLine("\n" + error.errorText);
outputChannel.show(true);
message += " Check 'ObjectScript' output channel for details.";
}
vscode.window.showErrorMessage(message, "Dismiss");
}
}
22 changes: 7 additions & 15 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ import {
deleteProject,
exportProjectContents,
modifyProject,
modifyProjectMetadata,
} from "./commands/project";
import { NodeBase } from "./explorer/models/nodeBase";
import { loadStudioColors, loadStudioSnippets } from "./commands/studioMigration";
Expand Down Expand Up @@ -1094,25 +1095,16 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
}
}),
vscode.commands.registerCommand("vscode-objectscript.addItemsToProject", (item) => {
if (item instanceof NodeBase || item instanceof vscode.Uri) {
return modifyProject(item, "add");
} else {
return modifyProject(undefined, "add");
}
return modifyProject(item instanceof NodeBase || item instanceof vscode.Uri ? item : undefined, "add");
}),
vscode.commands.registerCommand("vscode-objectscript.removeFromProject", (item) => {
if (item instanceof NodeBase || item instanceof vscode.Uri) {
return modifyProject(item, "remove");
} else {
return modifyProject(undefined, "remove");
}
return modifyProject(item instanceof NodeBase || item instanceof vscode.Uri ? item : undefined, "remove");
}),
vscode.commands.registerCommand("vscode-objectscript.removeItemsFromProject", (item) => {
if (item instanceof NodeBase || item instanceof vscode.Uri) {
return modifyProject(item, "remove");
} else {
return modifyProject(undefined, "remove");
}
return modifyProject(item instanceof NodeBase || item instanceof vscode.Uri ? item : undefined, "remove");
}),
vscode.commands.registerCommand("vscode-objectscript.modifyProjectMetadata", (item) => {
return modifyProjectMetadata(item instanceof NodeBase || item instanceof vscode.Uri ? item : undefined);
}),
vscode.commands.registerCommand("vscode-objectscript.createProject", (node) => createProject(node)),
vscode.commands.registerCommand("vscode-objectscript.deleteProject", (node) => deleteProject(node)),
Expand Down

0 comments on commit 9e2d826

Please sign in to comment.