diff --git a/apps/vscode/src/main.ts b/apps/vscode/src/main.ts index 4603be90fb..1b6a8b03d4 100644 --- a/apps/vscode/src/main.ts +++ b/apps/vscode/src/main.ts @@ -90,6 +90,7 @@ export async function activate(c: ExtensionContext) { cliTaskProvider, runTargetTreeView, contextMenuUri, + generator: runTargetTreeItem.generator, }); } ); diff --git a/apps/vscode/src/package.json b/apps/vscode/src/package.json index 420a73112d..1d81572815 100644 --- a/apps/vscode/src/package.json +++ b/apps/vscode/src/package.json @@ -74,6 +74,16 @@ "command": "nx.run.fileexplorer", "group": "2_workspace" }, + { + "when": "isNxWorkspace && config.nxConsole.enableGenerateFromContextMenu", + "command": "nx.move.fileexplorer", + "group": "2_workspace" + }, + { + "when": "isNxWorkspace && config.nxConsole.enableGenerateFromContextMenu", + "command": "nx.remove.fileexplorer", + "group": "2_workspace" + }, { "when": "isNxWorkspace && explorerResourceIsFolder && resourcePath in nxAppsDir && config.nxConsole.enableGenerateFromContextMenu && nx.hasApplicationGenerators", "command": "nx.generate.ui.app.fileexplorer", @@ -563,6 +573,16 @@ "title": "Nx generate...", "command": "nx.generate.ui.fileexplorer" }, + { + "category": "Nx", + "title": "Move Nx Project...", + "command": "nx.move.fileexplorer" + }, + { + "category": "Nx", + "title": "Remove Nx Project...", + "command": "nx.move.fileexplorer" + }, { "category": "Nx", "title": "Nx run", diff --git a/libs/vscode/nx-run-target-view/src/lib/run-target-tree-item.ts b/libs/vscode/nx-run-target-view/src/lib/run-target-tree-item.ts index 652d3a5163..5e9be4bf74 100644 --- a/libs/vscode/nx-run-target-view/src/lib/run-target-tree-item.ts +++ b/libs/vscode/nx-run-target-view/src/lib/run-target-tree-item.ts @@ -50,7 +50,8 @@ export class RunTargetTreeItem extends TreeItem { readonly configurationFilePath: string, readonly route: string, readonly extensionPath: string, - readonly generatorType?: GeneratorType + readonly generatorType?: GeneratorType, + readonly generator?: string ) { super(route, TreeItemCollapsibleState.None); } diff --git a/libs/vscode/nx-workspace/src/index.ts b/libs/vscode/nx-workspace/src/index.ts index e69a7e408b..ba0baca1d9 100644 --- a/libs/vscode/nx-workspace/src/index.ts +++ b/libs/vscode/nx-workspace/src/index.ts @@ -4,3 +4,4 @@ export * from './lib/workspace-codelens-provider'; export * from './lib/verify-workspace'; export * from './lib/get-nx-config'; export * from './lib/get-nx-workspace-config'; +export * from './lib/nx-version'; diff --git a/libs/vscode/tasks/src/lib/cli-task-commands.ts b/libs/vscode/tasks/src/lib/cli-task-commands.ts index f1fef38a41..3fd812b583 100644 --- a/libs/vscode/tasks/src/lib/cli-task-commands.ts +++ b/libs/vscode/tasks/src/lib/cli-task-commands.ts @@ -1,6 +1,6 @@ import { commands, ExtensionContext, window, Uri } from 'vscode'; -import { verifyWorkspace } from '@nx-console/vscode/nx-workspace'; +import { nxVersion, verifyWorkspace } from '@nx-console/vscode/nx-workspace'; import { verifyBuilderDefinition } from '@nx-console/vscode/verify'; import { RunTargetTreeItem } from '@nx-console/vscode/nx-run-target-view'; import { CliTaskProvider } from './cli-task-provider'; @@ -9,6 +9,7 @@ import { selectFlags } from './select-flags'; import { GeneratorType, Option, OptionType } from '@nx-console/schema'; import { WorkspaceJsonConfiguration } from '@nrwl/devkit'; import { selectGenerator } from './select-generator'; +import { getGenerators } from '@nx-console/server'; const CLI_COMMAND_LIST = [ 'build', @@ -67,6 +68,73 @@ export function registerCliTaskCommands( selectCliCommandAndPromptForFlags('run', await getCliProjectFromUri(uri)) ); + /** + * move and remove were release in patch 8.11 + */ + const version = nxVersion(); + if (version && version >= 8) { + commands.registerCommand(`${cli}.move.fileexplorer`, async (uri: Uri) => { + /** + * Bit of a hack - always runs angular/move if it is installed. + * + * As of the date of implementation, no issues with running this angular generator + * on non-angular projects. BUT THIS MIGHT CHANGE IN THE FUTURE. + * + * Also, future may hold other framework specific move/remove generators - this + * solution won't work when that happens. + */ + const getCorrectMoveGenerator = async () => { + const workspacePath = cliTaskProvider.getWorkspacePath(); + const generators = await getGenerators(workspacePath); + return generators.find( + (generator) => generator.name === '@nrwl/angular:move' + ) + ? '@nrwl/angular:move' + : '@nrwl/workspace:move'; + }; + const generator = await getCorrectMoveGenerator(); + selectCliCommandAndShowUi( + 'generate', + context.extensionPath, + uri, + GeneratorType.Other, + generator + ); + }); + + commands.registerCommand( + `${cli}.remove.fileexplorer`, + async (uri: Uri) => { + /** + * Bit of a hack - always runs angular/remove if it is installed. + * + * As of the date of implementation, no issues with running this angular generator + * on non-angular projects. BUT THIS MIGHT CHANGE IN THE FUTURE. + * + * Also, future may hold other framework specific move/remove generators - this + * solution won't work when that happens. + */ + const getCorrectRemoveGenerator = async () => { + const workspacePath = cliTaskProvider.getWorkspacePath(); + const generators = await getGenerators(workspacePath); + return generators.find( + (generator) => generator.name === '@nrwl/angular:remove' + ) + ? '@nrwl/angular:remove' + : '@nrwl/workspace:remove'; + }; + const generator = await getCorrectRemoveGenerator(); + selectCliCommandAndShowUi( + 'generate', + context.extensionPath, + uri, + GeneratorType.Other, + generator + ); + } + ); + } + commands.registerCommand(`${cli}.generate`, () => selectGeneratorAndPromptForFlags() ); @@ -137,7 +205,8 @@ async function selectCliCommandAndShowUi( command: string, extensionPath: string, uri?: Uri, - generatorType?: GeneratorType + generatorType?: GeneratorType, + generator?: string ) { const workspacePath = cliTaskProvider.getWorkspacePath(); if (!workspacePath) { @@ -153,9 +222,10 @@ async function selectCliCommandAndShowUi( } const workspaceTreeItem = new RunTargetTreeItem( configurationFilePath, - `${command[0].toUpperCase()}${command.slice(1)}`, + command, extensionPath, - generatorType + generatorType, + generator ); commands.executeCommand( @@ -320,7 +390,7 @@ export async function selectCliProject( if (!items.length) { window.showInformationMessage( - `No projects have an target command for ${command}` + `No projects have a target command for ${command}` ); return; diff --git a/libs/vscode/tasks/src/lib/select-generator.ts b/libs/vscode/tasks/src/lib/select-generator.ts index 2098d62748..d0064f7447 100644 --- a/libs/vscode/tasks/src/lib/select-generator.ts +++ b/libs/vscode/tasks/src/lib/select-generator.ts @@ -75,7 +75,8 @@ export async function getGeneratorOptions( export async function selectGenerator( workspacePath: string, workspaceType: 'nx' | 'ng', - generatorType?: GeneratorType + generatorType?: GeneratorType, + generator?: { collection: string; name: string } ): Promise { interface GenerateQuickPickItem extends QuickPickItem { collectionName: string; @@ -105,7 +106,13 @@ export async function selectGenerator( } if (generators) { - const selection = await window.showQuickPick(generatorsQuickPicks); + const selection = generator + ? generatorsQuickPicks.find( + (quickPick) => + quickPick.generator.collection === generator.collection && + quickPick.generator.name === generator.name + ) + : await window.showQuickPick(generatorsQuickPicks); if (selection) { const options = selection.generator.options || diff --git a/libs/vscode/webview/src/lib/get-task-execution-schema.ts b/libs/vscode/webview/src/lib/get-task-execution-schema.ts index 215ece5fd2..e3e0b8f5d7 100644 --- a/libs/vscode/webview/src/lib/get-task-execution-schema.ts +++ b/libs/vscode/webview/src/lib/get-task-execution-schema.ts @@ -18,7 +18,8 @@ export async function getTaskExecutionSchema( cliTaskProvider: CliTaskProvider, command = 'run', contextMenuUri?: Uri, - generatorType?: GeneratorType + generatorType?: GeneratorType, + incomingGenerator?: string ): Promise { try { if (!cliTaskProvider.getWorkspacePath()) { @@ -89,7 +90,13 @@ export async function getTaskExecutionSchema( const generator = await selectGenerator( cliTaskProvider.getWorkspacePath(), workspaceType, - generatorType + generatorType, + incomingGenerator + ? { + collection: incomingGenerator.split(':')[0], + name: incomingGenerator.split(':')[1], + } + : undefined ); if (!generator) { diff --git a/libs/vscode/webview/src/lib/webview.ts b/libs/vscode/webview/src/lib/webview.ts index face4275bc..505df9c355 100644 --- a/libs/vscode/webview/src/lib/webview.ts +++ b/libs/vscode/webview/src/lib/webview.ts @@ -26,6 +26,7 @@ interface RevealWebViewPanelConfig { cliTaskProvider: CliTaskProvider; runTargetTreeView: TreeView; contextMenuUri?: Uri; + generator?: string; } export async function revealWebViewPanel({ @@ -34,13 +35,15 @@ export async function revealWebViewPanel({ runTargetTreeItem, runTargetTreeView, contextMenuUri, + generator, }: RevealWebViewPanelConfig) { const { label, generatorType } = runTargetTreeItem; const schema = await getTaskExecutionSchema( cliTaskProvider, label, contextMenuUri, - generatorType + generatorType, + generator ); if (!schema) {