Skip to content

Commit

Permalink
Adds grant API permissions action. Closes: #8 (#79)
Browse files Browse the repository at this point in the history
## 🎯 Aim

The aim is to add a new action which will allow to grant API
permissions.

## 📷 Result


![image](https://github.com/pnp/vscode-viva/assets/58668583/2b095b10-88c1-490a-8cce-35a24d846160)

## ✅ What was done

- [X] Along the way renamed all 'solution' word to 'project'
- [X] Added new command
- [X] Added new CLI action

## 🔗 Related issue

Closes: #8
  • Loading branch information
Adam-it authored Sep 2, 2023
1 parent 0cb1e41 commit 11447ba
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 58 deletions.
56 changes: 33 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,27 @@
{
"id": "pnp-view-account",
"name": "Account",
"when": "pnp.project.isSPFxSolution"
"when": "pnp.project.isSPFxProject"
},
{
"id": "pnp-view-environment",
"name": "Environment details",
"when": "pnp.project.isSPFxSolution && pnp.project.isLoggedIn"
"when": "pnp.project.isSPFxProject && pnp.project.isLoggedIn"
},
{
"id": "pnp-view-tasks",
"name": "Tasks",
"when": "pnp.project.isSPFxSolution"
"when": "pnp.project.isSPFxProject"
},
{
"id": "pnp-view-actions",
"name": "Actions",
"when": "pnp.project.isSPFxSolution"
"when": "pnp.project.isSPFxProject"
},
{
"id": "pnp-view-help",
"name": "Help and feedback",
"when": "pnp.project.isSPFxSolution"
"when": "pnp.project.isSPFxProject"
}
]
},
Expand Down Expand Up @@ -118,38 +118,48 @@
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.upgradeSolution",
"title": "Upgrade solution to latest SPFx version",
"command": "viva-connections-toolkit.upgradeProject",
"title": "Upgrade project to latest SPFx version",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.deploySolution",
"title": "Viva Connections Toolkit: Deploy the solution"
"command": "viva-connections-toolkit.deployProject",
"title": "Deploy the project",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.showACESampleGallery",
"title": "Viva Connections Toolkit: Open the Adaptive Card Extensions (ACEs) Samples gallery"
"title": "Open the Adaptive Card Extensions (ACEs) Samples gallery",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.showACEScenariosGallery",
"title": "Viva Connections Toolkit: Open the Adaptive Card Extensions (ACEs) Scenarios gallery"
"title": "Open the Adaptive Card Extensions (ACEs) Scenarios gallery",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.showExtensionsSampleGallery",
"title": "Viva Connections Toolkit: Open the SharePoint Framework Client-Side Web Part Samples gallery"
"title": "Open the SharePoint Framework Client-Side Web Part Samples gallery",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.showWebpartSampleGallery",
"title": "Viva Connections Toolkit: Open the SharePoint Framework Extensions Samples gallery"
"title": "Open the SharePoint Framework Extensions Samples gallery",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.validateProject",
"title": "Validate project",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.validateSolution",
"title": "Validate current solution",
"command": "viva-connections-toolkit.renameProject",
"title": "Rename project",
"category": "Viva Connections Toolkit"
},
{
"command": "viva-connections-toolkit.renameSolution",
"title": "Rename current solution",
"command": "viva-connections-toolkit.grantAPIPermissions",
"title": "Grant API permissions",
"category": "Viva Connections Toolkit"
},
{
Expand All @@ -173,15 +183,15 @@
},
{
"command": "viva-connections-toolkit.addToProject",
"when": "pnp.project.isSPFxSolution"
"when": "pnp.project.isSPFxProject"
},
{
"command": "viva-connections-toolkit.upgradeSolution",
"when": "pnp.project.isSPFxSolution"
"command": "viva-connections-toolkit.upgradeProject",
"when": "pnp.project.isSPFxProject"
},
{
"command": "viva-connections-toolkit.validateSolution",
"when": "pnp.project.isSPFxSolution"
"command": "viva-connections-toolkit.validateProject",
"when": "pnp.project.isSPFxProject"
}
],
"view/item/context": [
Expand All @@ -193,7 +203,7 @@
],
"explorer/context": [
{
"command": "viva-connections-toolkit.deploySolution",
"command": "viva-connections-toolkit.deployProject",
"group": "pnp.project@1",
"when": "resourceExtname == '.sppkg' && pnp.project.hasAppCatalog"
}
Expand Down
13 changes: 8 additions & 5 deletions src/constants/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ export const Commands = {
executeTerminalCommand: `${EXTENSION_NAME}.executeTerminalCommand`,

// Upgrade
upgradeSolution: `${EXTENSION_NAME}.upgradeSolution`,
upgradeProject: `${EXTENSION_NAME}.upgradeProject`,

// Deployment
deploySolution: `${EXTENSION_NAME}.deploySolution`,
deployProject: `${EXTENSION_NAME}.deployProject`,

// Validation
validateSolution: `${EXTENSION_NAME}.validateSolution`,
validateProject: `${EXTENSION_NAME}.validateProject`,

// Rename
renameSolution: `${EXTENSION_NAME}.renameSolution`,
renameProject: `${EXTENSION_NAME}.renameProject`,

// Grant API permissions
grantAPIPermissions: `${EXTENSION_NAME}.grantAPIPermissions`,

// Webviews
showACESampleGallery: `${EXTENSION_NAME}.showACESampleGallery`,
Expand All @@ -39,5 +42,5 @@ export const Commands = {
showWebpartSampleGallery: `${EXTENSION_NAME}.showWebpartSampleGallery`,

// Serving
serveSolution: `${EXTENSION_NAME}.serveSolution`,
serveProject: `${EXTENSION_NAME}.serveProject`,
};
2 changes: 1 addition & 1 deletion src/constants/ContextKeys.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const ContextKeys = {
showWelcome: 'pnp.project.showWelcome',
isSPFxSolution: 'pnp.project.isSPFxSolution',
isSPFxProject: 'pnp.project.isSPFxProject',
isLoggedIn: 'pnp.project.isLoggedIn',
hasAppCatalog: 'pnp.project.hasAppCatalog',
};
13 changes: 7 additions & 6 deletions src/panels/CommandPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class CommandPanel {
return;
}

commands.executeCommand('setContext', ContextKeys.isSPFxSolution, true);
commands.executeCommand('setContext', ContextKeys.isSPFxProject, true);
commands.executeCommand('setContext', ContextKeys.showWelcome, false);

CommandPanel.registerTreeview();
Expand Down Expand Up @@ -142,7 +142,7 @@ export class CommandPanel {
new ActionTreeItem('Package (production)', '', { name: 'debug-start', custom: false }, undefined, Commands.executeTerminalCommand, 'gulp package-solution --ship'),
new ActionTreeItem('Serve', '', { name: 'debug-start', custom: false }, undefined, Commands.executeTerminalCommand, 'gulp serve'),
new ActionTreeItem('Serve (nobrowser)', '', { name: 'debug-start', custom: false }, undefined, Commands.executeTerminalCommand, 'gulp serve --nobrowser'),
new ActionTreeItem('Serve from configuration', '', { name: 'debug-start', custom: false }, undefined, Commands.serveSolution),
new ActionTreeItem('Serve from configuration', '', { name: 'debug-start', custom: false }, undefined, Commands.serveProject),
];

window.registerTreeDataProvider('pnp-view-tasks', new ActionTreeviewProvider(taskCommands));
Expand All @@ -153,10 +153,11 @@ export class CommandPanel {
*/
private static async actionsTreeView() {
const actionCommands: ActionTreeItem[] = [
new ActionTreeItem('Upgrade solution', '', { name: 'arrow-up', custom: false }, undefined, Commands.upgradeSolution),
new ActionTreeItem('Validate current project', '', { name: 'check-all', custom: false }, undefined, Commands.validateSolution),
new ActionTreeItem('Rename current project', '', { name: 'whole-word', custom: false }, undefined, Commands.renameSolution),
new ActionTreeItem('Deploy solution (sppkg)', '', { name: 'cloud-upload', custom: false }, undefined, Commands.deploySolution),
new ActionTreeItem('Upgrade project', '', { name: 'arrow-up', custom: false }, undefined, Commands.upgradeProject),
new ActionTreeItem('Validate current project', '', { name: 'check-all', custom: false }, undefined, Commands.validateProject),
new ActionTreeItem('Rename current project', '', { name: 'whole-word', custom: false }, undefined, Commands.renameProject),
new ActionTreeItem('Grant API permissions', '', { name: 'workspace-trusted', custom: false }, undefined, Commands.grantAPIPermissions),
new ActionTreeItem('Deploy project (sppkg)', '', { name: 'cloud-upload', custom: false }, undefined, Commands.deployProject),
new ActionTreeItem('Add new component', '', { name: 'add', custom: false }, undefined, Commands.addToProject),
new ActionTreeItem('View SPFx web part samples', '', { name: 'library', custom: false }, undefined, Commands.showWebpartSampleGallery),
new ActionTreeItem('View SPFx extension samples', '', { name: 'library', custom: false }, undefined, Commands.showExtensionsSampleGallery),
Expand Down
83 changes: 60 additions & 23 deletions src/services/CliActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ export class CliActions {
const subscriptions: Subscription[] = Extension.getInstance().subscriptions;

subscriptions.push(
commands.registerCommand(Commands.upgradeSolution, CliActions.upgrade)
commands.registerCommand(Commands.upgradeProject, CliActions.upgrade)
);
subscriptions.push(
commands.registerCommand(Commands.deploySolution, CliActions.deploy)
commands.registerCommand(Commands.deployProject, CliActions.deploy)
);
subscriptions.push(
commands.registerCommand(Commands.validateSolution, CliActions.validateSolution)
commands.registerCommand(Commands.validateProject, CliActions.validateProject)
);
subscriptions.push(
commands.registerCommand(Commands.renameSolution, CliActions.renameSolution)
commands.registerCommand(Commands.renameProject, CliActions.renameProject)
);
subscriptions.push(
commands.registerCommand(Commands.serveSolution, CliActions.serveSolution)
commands.registerCommand(Commands.grantAPIPermissions, CliActions.grantAPIPermissions)
);
subscriptions.push(
commands.registerCommand(Commands.serveProject, CliActions.serveProject)
);
}

Expand All @@ -57,10 +60,10 @@ export class CliActions {
}

/**
* Upgrade the solution
* Upgrade the Project
*/
private static async upgrade() {
// Change the current working directory to the root of the solution
// Change the current working directory to the root of the Project
const wsFolder = await Folders.getWorkspaceFolder();
if (wsFolder) {
process.chdir(wsFolder.uri.fsPath);
Expand Down Expand Up @@ -91,10 +94,10 @@ export class CliActions {
}

/**
* Renames the current solution
* Renames the current Project
*/
private static async renameSolution() {
// Change the current working directory to the root of the solution
private static async renameProject() {
// Change the current working directory to the root of the Project
const wsFolder = await Folders.getWorkspaceFolder();
if (wsFolder) {
process.chdir(wsFolder.uri.fsPath);
Expand All @@ -118,7 +121,7 @@ export class CliActions {
}

const shouldGenerateNewIdAnswer = await window.showQuickPick(['Yes', 'No'], {
title: 'Generate a new solution ID for the project?',
title: 'Generate a new ID for the project?',
ignoreFocusOut: true,
canPickMany: false
});
Expand All @@ -127,7 +130,7 @@ export class CliActions {

await window.withProgress({
location: ProgressLocation.Notification,
title: 'Renaming the current solution...',
title: 'Renaming the current project...',
cancellable: true
// eslint-disable-next-line no-unused-vars
}, async (progress: Progress<{ message?: string; increment?: number }>) => {
Expand All @@ -150,18 +153,52 @@ export class CliActions {
}

/**
* Validates the current solution
* grant API permissions for the current Project
*/
private static async grantAPIPermissions() {
// Change the current working directory to the root of the Project
const wsFolder = await Folders.getWorkspaceFolder();
if (wsFolder) {
process.chdir(wsFolder.uri.fsPath);
}

await window.withProgress({
location: ProgressLocation.Notification,
title: 'Granting API permissions for the current project...',
cancellable: true
// eslint-disable-next-line no-unused-vars
}, async (progress: Progress<{ message?: string; increment?: number }>) => {
try {
const result: CommandOutput = await CliExecuter.execute('spfx project permissions grant', 'json');

if (result.stderr) {
Notifications.error(result.stderr);
}
Notifications.info('API permissions granted successfully.');
} catch (e: any) {
const message = e?.error?.message;
if (message.toString().indexOf('webApiPermissionsRequest is not iterable') > -1) {
Notifications.error('No API permissions found in the current project.');
} else {
Notifications.error(message);
}
}
});
}

/**
* Validates the current Project
*/
private static async validateSolution() {
// Change the current working directory to the root of the solution
private static async validateProject() {
// Change the current working directory to the root of the Project
const wsFolder = await Folders.getWorkspaceFolder();
if (wsFolder) {
process.chdir(wsFolder.uri.fsPath);
}

await window.withProgress({
location: ProgressLocation.Notification,
title: 'Validating the current solution...',
title: 'Validating the current project...',
cancellable: true
// eslint-disable-next-line no-unused-vars
}, async (progress: Progress<{ message?: string; increment?: number }>) => {
Expand All @@ -184,14 +221,14 @@ export class CliActions {
}

/**
* Deploy the solution
* Deploy the Project
*/
private static async deploy(file: Uri | undefined) {
const authInstance = AuthProvider.getInstance();
const account = await authInstance.getAccount();

if (!account) {
Notifications.error('You must be logged in to deploy a solution.');
Notifications.error('You must be logged in to deploy a project.');
return;
}

Expand Down Expand Up @@ -249,7 +286,7 @@ export class CliActions {

await window.withProgress({
location: ProgressLocation.Notification,
title: `Deploying the ${basename(file.fsPath)} solution. Check [output window](command:${Commands.showOutputChannel}) to follow the progress.`,
title: `Deploying the ${basename(file.fsPath)} project. Check [output window](command:${Commands.showOutputChannel}) to follow the progress.`,
cancellable: false
// eslint-disable-next-line no-unused-vars
}, async (progress: Progress<{ message?: string; increment?: number }>) => {
Expand All @@ -263,7 +300,7 @@ export class CliActions {

const data: SolutionAddResult = JSON.parse(addResult.stdout);
if (!data.UniqueId) {
Notifications.error('We haven\'t been able to find the unique ID of the solution.Make sure the solution was added correctly.');
Notifications.error('We haven\'t been able to find the unique ID of the project. Make sure the project was added correctly.');
}

// Check if skip feature deployment
Expand All @@ -283,7 +320,7 @@ export class CliActions {
return;
}

Notifications.info('The solution has been deployed successfully.');
Notifications.info('The project has been deployed successfully.');
} catch (e: any) {
const message = e?.error?.message;
Notifications.error(message);
Expand All @@ -292,9 +329,9 @@ export class CliActions {
}

/**
* Serve the solution
* Serve the Project
*/
public static async serveSolution() {
public static async serveProject() {
const wsFolder = Folders.getWorkspaceFolder();
if (!wsFolder) {
return;
Expand Down

0 comments on commit 11447ba

Please sign in to comment.