From 2ed802ee1c0d49225051c28e5cc4311c3ac00e5a Mon Sep 17 00:00:00 2001 From: Saurabh Tripathi Date: Sun, 24 Nov 2024 00:45:28 +0100 Subject: [PATCH] Upgrades an app to the latest version available in the app catalog. Closes: #351 (#357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 🎯 Aim Upgrades an app to the latest version available in the app catalog for the specified site ## 📷 Result ![image](https://github.com/user-attachments/assets/3c9255b0-28de-4365-9bce-d12452c611be) ## ✅ What was done - [X] New action to upgrade an app in the specified site. - [X] Prompt for the site URL only when upgrading tenant app catalog apps. For site collection app catalog apps, it uses the site collection app catalog URL and scope. ## 🔗 Related issue Closes: #351 --- README.md | 1 + assets/walkthrough/tenant-details.md | 1 + package.json | 10 ++++++ src/constants/Commands.ts | 1 + src/constants/ContextKeys.ts | 3 +- src/panels/CommandPanel.ts | 6 ++-- src/services/actions/CliActions.ts | 50 ++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 044805e..e16a119 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ After successful sign in, an additional view is presented that shows a list of l - **Remove**: Removes the app from the app catalog. - **Enable**: Allows end users to add the solution to their SharePoint sites. - **Disable**: Hides the solution from end users, preventing them from adding it to sites. +- **Upgrade**: Upgrades the solution to the latest version available in the app catalog for the specified site. Additionally, it will show you all tenant-wide extensions installed on your tenant. diff --git a/assets/walkthrough/tenant-details.md b/assets/walkthrough/tenant-details.md index e3f439a..5ffe9a7 100644 --- a/assets/walkthrough/tenant-details.md +++ b/assets/walkthrough/tenant-details.md @@ -29,6 +29,7 @@ After successful sign in, an additional view is presented that shows a list of l - **Remove**: Removes the app from the app catalog. - **Enable**: Allows end users to add the solution to their SharePoint sites. - **Disable**: Hides the solution from end users, preventing them from adding it to sites. +- **Upgrade**: Upgrades the solution to the latest version available in the app catalog for the specified site. Additionally, it will show you all tenant-wide extensions installed on your tenant. diff --git a/package.json b/package.json index f9eaceb..0ef1559 100644 --- a/package.json +++ b/package.json @@ -460,6 +460,12 @@ "category": "SharePoint Framework Toolkit", "icon": "$(circle-slash)" }, + { + "command": "spfx-toolkit.upgradeAppCatalogApp", + "title": "Upgrade", + "category": "SharePoint Framework Toolkit", + "icon": "$(sync)" + }, { "command": "spfx-toolkit.showMoreActions", "title": "...", @@ -531,6 +537,10 @@ { "command": "spfx-toolkit.disableAppCatalogApp", "group": "actions.more@4" + }, + { + "command": "spfx-toolkit.upgradeAppCatalogApp", + "group": "actions.more@5" } ], "explorer/context": [ diff --git a/src/constants/Commands.ts b/src/constants/Commands.ts index aca7637..f26f472 100644 --- a/src/constants/Commands.ts +++ b/src/constants/Commands.ts @@ -59,5 +59,6 @@ export const Commands = { removeAppCatalogApp: `${EXTENSION_NAME}.removeAppCatalogApp`, enableAppCatalogApp: `${EXTENSION_NAME}.enableAppCatalogApp`, disableAppCatalogApp: `${EXTENSION_NAME}.disableAppCatalogApp`, + upgradeAppCatalogApp: `${EXTENSION_NAME}.upgradeAppCatalogApp`, showMoreActions: `${EXTENSION_NAME}.showMoreActions` }; \ No newline at end of file diff --git a/src/constants/ContextKeys.ts b/src/constants/ContextKeys.ts index fa7f9b9..6ab7676 100644 --- a/src/constants/ContextKeys.ts +++ b/src/constants/ContextKeys.ts @@ -8,5 +8,6 @@ export const ContextKeys = { retractApp: 'pnp.etv.app.retract', removeApp: 'pnp.etv.app.remove', enableApp: 'pnp.etv.app.enable', - disableApp: 'pnp.etv.app.disable' + disableApp: 'pnp.etv.app.disable', + upgradeApp: 'pnp.etv.app.upgrade' }; \ No newline at end of file diff --git a/src/panels/CommandPanel.ts b/src/panels/CommandPanel.ts index f5b2968..d357887 100644 --- a/src/panels/CommandPanel.ts +++ b/src/panels/CommandPanel.ts @@ -211,7 +211,8 @@ export class CommandPanel { new ActionTreeItem('Retract', '', undefined, undefined, Commands.retractAppCatalogApp, [app.ID, app.Title, undefined, app.Deployed], ContextKeys.retractApp), new ActionTreeItem('Remove', '', undefined, undefined, Commands.removeAppCatalogApp, [app.ID, app.Title], ContextKeys.removeApp), new ActionTreeItem('Enable', '', undefined, undefined, Commands.enableAppCatalogApp, [app.Title, tenantAppCatalogUrl, app.Enabled], ContextKeys.enableApp), - new ActionTreeItem('Disable', '', undefined, undefined, Commands.disableAppCatalogApp, [app.Title, tenantAppCatalogUrl, app.Enabled], ContextKeys.disableApp) + new ActionTreeItem('Disable', '', undefined, undefined, Commands.disableAppCatalogApp, [app.Title, tenantAppCatalogUrl, app.Enabled], ContextKeys.disableApp), + new ActionTreeItem('Upgrade', '', undefined, undefined, Commands.upgradeAppCatalogApp, [app.ID, app.Title], ContextKeys.upgradeApp) ] ) ); @@ -250,7 +251,8 @@ export class CommandPanel { new ActionTreeItem('Retract', '', undefined, undefined, Commands.retractAppCatalogApp, [app.ID, app.Title, siteAppCatalogUrl, app.Deployed], ContextKeys.retractApp), new ActionTreeItem('Remove', '', undefined, undefined, Commands.removeAppCatalogApp, [app.ID, app.Title, siteAppCatalogUrl], ContextKeys.removeApp), new ActionTreeItem('Enable', '', undefined, undefined, Commands.enableAppCatalogApp, [app.Title, siteAppCatalogUrl, app.Enabled], ContextKeys.enableApp), - new ActionTreeItem('Disable', '', undefined, undefined, Commands.disableAppCatalogApp, [app.Title, siteAppCatalogUrl, app.Enabled], ContextKeys.disableApp) + new ActionTreeItem('Disable', '', undefined, undefined, Commands.disableAppCatalogApp, [app.Title, siteAppCatalogUrl, app.Enabled], ContextKeys.disableApp), + new ActionTreeItem('Upgrade', '', undefined, undefined, Commands.upgradeAppCatalogApp, [app.ID, app.Title, siteAppCatalogUrl], ContextKeys.upgradeApp) ] ) ); diff --git a/src/services/actions/CliActions.ts b/src/services/actions/CliActions.ts index 9203587..324c180 100644 --- a/src/services/actions/CliActions.ts +++ b/src/services/actions/CliActions.ts @@ -66,6 +66,9 @@ export class CliActions { CliActions.toggleAppEnabled(node, ContextKeys.disableApp, 'disable') ) ); + subscriptions.push( + commands.registerCommand(Commands.upgradeAppCatalogApp, CliActions.upgradeAppCatalogApp) + ); } /** @@ -224,6 +227,53 @@ export class CliActions { } } + /** + * Upgrades an app to a newer version available in the app catalog. + * + * @param node The tree item representing the app to be upgraded. + */ + public static async upgradeAppCatalogApp(node: ActionTreeItem) { + try { + const actionNode = node.children?.find(child => child.contextValue === ContextKeys.upgradeApp); + + if (!actionNode?.command?.arguments) { + Notifications.error('Failed to retrieve app details for upgrade.'); + return; + } + + const [appID, appTitle, appCatalogUrl] = actionNode.command.arguments; + + const siteUrl = appCatalogUrl?.trim() || await window.showInputBox({ + prompt: 'Enter the URL of the site to upgrade the app in', + placeHolder: 'https://contoso.sharepoint.com/sites/sales', + validateInput: (input) => (input.trim() ? undefined : 'Site URL cannot be empty') + }); + + if (!siteUrl) { + Notifications.warning('No site URL provided. App upgrade aborted.'); + return; + } + + const commandOptions: any = { + id: appID, + ...(appCatalogUrl?.trim() + ? { appCatalogScope: 'sitecollection', siteUrl, } + : { siteUrl }) + }; + + await CliExecuter.execute('spo app upgrade', 'json', commandOptions); + + Notifications.info(`App '${appTitle}' has been successfully upgraded.`); + + // refresh the environmentTreeView + await commands.executeCommand('spfx-toolkit.refreshAppCatalogTreeView'); + + } catch (e: any) { + const message = e?.message || 'An unexpected error occurred during the app upgrade.'; + Notifications.error(message); + } + } + /** * Enables or disables the app in the tenant or site app catalog. *