Skip to content

React application m365 service health #1500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .hintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": [
"development"
],
"hints": {
"no-inline-styles": "off"
}
}
319 changes: 319 additions & 0 deletions samples/react-application-m365-service-health/.eslintrc.js

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions samples/react-application-m365-service-health/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Logs
logs
*.log
npm-debug.log*

# Dependency directories
node_modules

# Build generated files
dist
lib
release
solution
temp
*.sppkg
.heft

# Coverage directory used by tools like istanbul
coverage

# OSX
.DS_Store

# Visual Studio files
.ntvs_analysis.dat
.vs
bin
obj

# Resx Generated Code
*.resx.ts

# Styles Generated Code
*.scss.ts
8 changes: 8 additions & 0 deletions samples/react-application-m365-service-health/.hintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": [
"development"
],
"hints": {
"no-inline-styles": "off"
}
}
16 changes: 16 additions & 0 deletions samples/react-application-m365-service-health/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
!dist
config

gulpfile.js

release
src
temp

tsconfig.json
tslint.json

*.log

.yo-rc.json
.vscode
1 change: 1 addition & 0 deletions samples/react-application-m365-service-health/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.14.0
22 changes: 22 additions & 0 deletions samples/react-application-m365-service-health/.yo-rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"@microsoft/generator-sharepoint": {
"whichFolder": "subdir",
"solutionName": "M365 Service Health Extension",
"componentType": "extension",
"extensionType": "ApplicationCustomizer",
"template": "none",
"componentName": "m365ServiceHealth",
"plusBeta": false,
"isCreatingSolution": true,
"nodeVersion": "22.14.0",
"sdksVersions": {},
"version": "1.21.1",
"libraryName": "m-365-service-health-extension",
"libraryId": "ed2728bd-0f80-41e2-9f9f-66bdcbcc71a8",
"environment": "spo",
"packageManager": "npm",
"solutionShortDescription": "M365 Service Health Extension description",
"skipFeatureDeployment": true,
"isDomainIsolated": false
}
}
105 changes: 105 additions & 0 deletions samples/react-application-m365-service-health/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# m-365-service-health-extension

## Summary

This extension provides real-time monitoring of Microsoft 365 service health directly within your SharePoint environment. It enables users to quickly check the availability status of core M365 services, helping organizations stay informed about outages or incidents.

The extesnio create a bottom on the footer of the SharePoint site, which when clicked, opens a dialog showing the service health status. The extension can be configured to show service health information to either tenant administrators only or to all users in the tenant.

![Service Health Extension](./src/assets/m365ServiceHealth01.png)
![Service Health Extension Dialog](./src/assets/m365ServiceHealth02.png)
![Service Health Extension Details](./src/assets/m365ServiceHealth03.png)

### Key Features

- **Service Health Monitoring:** Displays up-to-date status for Microsoft 365 services such as Exchange, SharePoint, Teams, and more.
- **Configurable Scope:**
- **Admins Only:** Restrict visibility so only tenant administrators can view service health information.
- **All Users:** Allow all users to access service health data.
> **Note:** When the scope is set to "All", an Azure Function must be deployed and online to securely provide service health data to non-admin users.

### Technologies Used

- **SharePoint Framework (SPFx):** For seamless integration with SharePoint Online.
- **Microsoft Graph API:** To retrieve service health status from Microsoft 365.
- **Azure Functions:** Required when exposing service health to all users.

### Configuration

- **Scope Property:**
- Set the `scope` property to either `Admin` or `All` based on your organization's requirements.
- If `All` is selected, ensure the associated Azure Function is deployed and operational.

### Example Usage

- **Admin Scope:**
Only SharePoint admins will see the service health extension on their sites.
- **All Scope:**
All users in the tenant can view service health, (nned to deploy an Azure Function).

[picture of the solution in action, if possible]

## Used SharePoint Framework Version

![version](https://img.shields.io/badge/version-1.21.1-green.svg)

## Applies to

- [SharePoint Framework](https://aka.ms/spfx)
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)

> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)

## Prerequisites

If you want to use the solution with the `All` scope, you need to deploy an Azure Function that will provide the service health data to non-admin users. The Azure Function should be configured to call the Microsoft Graph API and return the service health information securely. You can find the project for the Azure Function in the [Azure Function project](react-application-service-health-azfn.zip).

## Solution

| Solution | Author(s) |
| ----------- | ------------------------------------------------------- |
| folder name | João Mendes - [joaojmendes](https://twitter.com/joaojmendes) |

## Version history

| Version | Date | Comments |
| ------- | ---------------- | --------------- |
| 1.0 | May 24, 2021 | Initial release |

## Disclaimer

**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**

---

## requirements

This required the Microsoft Graph API permissions to access service health data. The following permissions are needed:

- `ServiceHealth.Read.All` - Allows reading service health information for all services in the tenant. for Admin scope.

If Scope is set to `All`, the Azure Function must be configured and a Application must be created with the necessary Application permissions to access service health data. Please see the project to configure the Azure Function and the required permissions.

## Solution Deployment

Recreate Package and deploy the solution to your SharePoint Online App catalog and approve the Microsoft Graph permissions on the API Access:

```bash
# Build the solution
gulp build
## Bundle the solution
gulp bundle --ship
# Package the solution
gulp package-solution


# Upload the package to your SharePoint Online App Catalog
```

## References

- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
18 changes: 18 additions & 0 deletions samples/react-application-m365-service-health/config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"m-365-service-health-application-customizer": {
"components": [
{
"entrypoint": "./lib/extensions/m365ServiceHealth/M365ServiceHealthApplicationCustomizer.js",
"manifest": "./src/extensions/m365ServiceHealth/M365ServiceHealthApplicationCustomizer.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"M365ServiceHealthApplicationCustomizerStrings": "lib/extensions/m365ServiceHealth/loc/{locale}.js"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./release/assets/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "m-365-service-health-extension",
"accessKey": "<!-- ACCESS KEY -->"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "m-365-service-health-extension-client-side-solution",
"id": "ed2728bd-0f80-41e2-9f9f-66bdcbcc71a8",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false,
"webApiPermissionRequests": [
{
"resource": "Microsoft Graph",
"scope": "ServiceHealth.Read.All"
}
],
"developer": {
"name": "",
"websiteUrl": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"mpnId": "Undefined-1.21.1"
},
"metadata": {
"shortDescription": {
"default": "M365 Service Health Extension description"
},
"longDescription": {
"default": "M365 Service Health Extension description"
},
"screenshotPaths": [],
"videoUrl": "",
"categories": []
},
"features": [
{
"title": "Application Extension - Deployment of custom action",
"description": "Deploys a custom action with ClientSideComponentId association",
"id": "f2688107-7b27-452f-8119-875534924380",
"version": "1.0.0.0",
"assets": {
"elementManifests": [
"elements.xml",
"ClientSideInstance.xml"
]
}
}
]
},
"paths": {
"zippedPackage": "solution/m-365-service-health-extension.sppkg"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json"
}
29 changes: 29 additions & 0 deletions samples/react-application-m365-service-health/config/serve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
"port": 4321,
"https": true,
"serveConfigurations": {
"default": {
"pageUrl": "https://spteck.sharepoint.com/sites/HumanResources/SitePages/Home.aspx",
"customActions": {
"cb906b84-c26d-4356-b0ba-fdf4fa522f51": {
"location": "ClientSideExtension.ApplicationCustomizer",
"properties": {
"scope": "admins"
}
}
}
},
"m365ServiceHealth": {
"pageUrl": "https://spteck.sharepoint.com/sites/HumanResources/SitePages/Home.aspx",
"customActions": {
"cb906b84-c26d-4356-b0ba-fdf4fa522f51": {
"location": "ClientSideExtension.ApplicationCustomizer",
"properties": {
"scope": "admins"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}
16 changes: 16 additions & 0 deletions samples/react-application-m365-service-health/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const build = require('@microsoft/sp-build-web');

build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);

var getTasks = build.rig.getTasks;
build.rig.getTasks = function () {
var result = getTasks.call(build.rig);

result.set('serve', result.get('serve-deprecated'));

return result;
};

build.initialize(require('gulp'));
Loading
Loading