Skip to content

Commit

Permalink
Improves account and env view. Closes: #278 (#284)
Browse files Browse the repository at this point in the history
## 🎯 Aim

The aim is to make account and enviroment views more bulletproof and
properly display views when CLI command extecution gets rejected due to
lack of permission

## 📷 Result


![image](https://github.com/user-attachments/assets/4b49a22d-a33f-4785-ab31-e6b73afe21e9)


## ✅ What was done


- [X] Added simple error handling to cover the reject case

## 🔗 Related issue

Closes: #278
  • Loading branch information
Adam-it committed Sep 8, 2024
1 parent a11b50c commit f0512bd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 37 deletions.
5 changes: 4 additions & 1 deletion src/panels/CommandPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class CommandPanel {
const showServiceIncidentList = getExtensionSettings('showServiceIncidentList', true);
if (showServiceIncidentList === true) {
const healthInfoList = await CliActions.getTenantHealthInfo();
if (healthInfoList)
if (healthInfoList?.some)
{
const healthInfoItems: ActionTreeItem[] = [];
for (let i = 0; i < healthInfoList.length; i++) {
Expand Down Expand Up @@ -175,6 +175,9 @@ export class CommandPanel {
tenantWideExtensionsList.push(new ActionTreeItem(extension.Title, '', { name: 'spo-app', custom: true }, undefined, 'vscode.open', Uri.parse(extension.Url), 'sp-app-catalog-tenant-wide-extensions-url'));
});
}
else {
tenantWideExtensionsList.push(new ActionTreeItem('none', '', undefined, undefined, undefined, undefined, undefined));
}

environmentCommands.push(new ActionTreeItem('Tenant-wide Extensions', '', { name: 'spo-app-list', custom: true }, undefined, undefined, undefined, 'sp-app-catalog-tenant-wide-extensions', tenantWideExtensionsList));
}
Expand Down
84 changes: 48 additions & 36 deletions src/services/CliActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,25 @@ export class CliActions {
* @returns A promise that resolves to an array of app catalog URLs, or undefined if no app catalogs are found.
*/
public static async appCatalogUrlsGet(): Promise<string[] | undefined> {
const appCatalogUrls: string[] = [];
const tenantAppCatalog = (await CliExecuter.execute('spo tenant appcatalogurl get', 'json')).stdout || undefined;
const siteAppCatalogs = (await CliExecuter.execute('spo site appcatalog list', 'json')).stdout || undefined;
try {
const appCatalogUrls: string[] = [];
const tenantAppCatalog = (await CliExecuter.execute('spo tenant appcatalogurl get', 'json')).stdout || undefined;
const siteAppCatalogs = (await CliExecuter.execute('spo site appcatalog list', 'json')).stdout || undefined;

if (tenantAppCatalog) {
appCatalogUrls.push(JSON.parse(tenantAppCatalog));
}
if (tenantAppCatalog) {
appCatalogUrls.push(JSON.parse(tenantAppCatalog));
}

if (siteAppCatalogs) {
const siteAppCatalogsJson: SiteAppCatalog[] = JSON.parse(siteAppCatalogs);
siteAppCatalogsJson.forEach((siteAppCatalog) => appCatalogUrls.push(`${siteAppCatalog.AbsoluteUrl}/AppCatalog`));
}
if (siteAppCatalogs) {
const siteAppCatalogsJson: SiteAppCatalog[] = JSON.parse(siteAppCatalogs);
siteAppCatalogsJson.forEach((siteAppCatalog) => appCatalogUrls.push(`${siteAppCatalog.AbsoluteUrl}/AppCatalog`));
}

EnvironmentInformation.appCatalogUrls = appCatalogUrls ? appCatalogUrls : undefined;
return EnvironmentInformation.appCatalogUrls;
EnvironmentInformation.appCatalogUrls = appCatalogUrls ? appCatalogUrls : undefined;
return EnvironmentInformation.appCatalogUrls;
} catch {
return undefined;
}
}

/**
Expand All @@ -74,48 +78,56 @@ export class CliActions {
* @returns A promise that resolves to an array of objects containing the URL and title of each tenant-wide extension,
* or undefined if no extensions are found.
*/
public static async getTenantWideExtensions(tenantAppCatalogUrl: string): Promise<{Url: string, Title: string}[] | undefined> {
public static async getTenantWideExtensions(tenantAppCatalogUrl: string): Promise<{ Url: string, Title: string }[] | undefined> {
const origin = new URL(tenantAppCatalogUrl).origin;
const commandOptions: any = {
listUrl: `${tenantAppCatalogUrl.replace(origin, '')}/Lists/TenantWideExtensions`,
webUrl: tenantAppCatalogUrl
};
const tenantWideExtensions = (await CliExecuter.execute('spo listitem list', 'json', commandOptions)).stdout || undefined;
try {
const tenantWideExtensions = (await CliExecuter.execute('spo listitem list', 'json', commandOptions)).stdout || undefined;

if (!tenantWideExtensions) {
return undefined;
}

if (!tenantWideExtensions) {
const tenantWideExtensionsJson: any[] = JSON.parse(tenantWideExtensions);
const tenantWideExtensionList = tenantWideExtensionsJson.map((extension) => {
return {
Url: `${tenantAppCatalogUrl}/Lists/TenantWideExtensions/DispForm.aspx?ID=${extension.Id}`,
Title: extension.Title
};
});
return tenantWideExtensionList;
} catch {
return undefined;
}

const tenantWideExtensionsJson: any[] = JSON.parse(tenantWideExtensions);
const tenantWideExtensionList = tenantWideExtensionsJson.map((extension) => {
return {
Url: `${tenantAppCatalogUrl}/Lists/TenantWideExtensions/DispForm.aspx?ID=${extension.Id}`,
Title: extension.Title
};
});
return tenantWideExtensionList;
}

/**
* Retrieves the health information of the tenant services.
* @returns A promise that resolves to an array of objects containing the title and URL of the health information.
* Returns undefined if there is no health information available.
*/
public static async getTenantHealthInfo(): Promise<{Title: string, Url: string}[] | undefined> {
const healthInfo = (await CliExecuter.execute('tenant serviceannouncement health list', 'json')).stdout || undefined;
public static async getTenantHealthInfo(): Promise<{ Title: string, Url: string }[] | undefined> {
try {
const healthInfo = (await CliExecuter.execute('tenant serviceannouncement health list', 'json')).stdout || undefined;
if (!healthInfo) {
return undefined;
}

if (!healthInfo) {
const healthInfoJson: any[] = JSON.parse(healthInfo);
const healthInfoList = healthInfoJson.filter(service => service.status !== 'serviceOperational').map((service) => {
return {
Url: `https://admin.microsoft.com/#/servicehealth/:/currentIssues/${encodeURIComponent(service.service)}/`,
Title: service.service
};
});
return healthInfoList;
}
catch {
return undefined;
}

const healthInfoJson: any[] = JSON.parse(healthInfo);
const healthInfoList = healthInfoJson.filter(service => service.status !== 'serviceOperational').map((service) => {
return {
Url: `https://admin.microsoft.com/#/servicehealth/:/currentIssues/${encodeURIComponent(service.service)}/`,
Title: service.service
};
});
return healthInfoList;
}

/**
Expand Down

0 comments on commit f0512bd

Please sign in to comment.