├── 14 - Angular App ├── src │ ├── assets │ │ └── .gitkeep │ ├── app │ │ ├── app.component.scss │ │ ├── nav-bar │ │ │ ├── nav-bar.component.scss │ │ │ ├── nav-bar.component.ts │ │ │ ├── nav-bar.component.spec.ts │ │ │ └── nav-bar.component.html │ │ ├── angular-agenda │ │ │ ├── angular-agenda.component.scss │ │ │ ├── angular-agenda.component.spec.ts │ │ │ ├── angular-agenda.component.html │ │ │ └── angular-agenda.component.ts │ │ ├── app.component.html │ │ ├── app.module.ts │ │ ├── app.component.ts │ │ └── app.component.spec.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.scss │ ├── index.html │ ├── main.ts │ ├── test.ts │ └── polyfills.ts ├── tailwind.config.js ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── webpack.config.js ├── tsconfig.json ├── README.md ├── .gitignore ├── karma.conf.js ├── package.json ├── tslint.json └── angular.json ├── 13 - React App ├── src │ ├── react-app-env.d.ts │ ├── tailwind.css │ ├── setupTests.ts │ ├── index.css │ ├── index.tsx │ ├── app.tsx │ ├── navBar.tsx │ ├── agendaReact.tsx │ ├── agendaWC.tsx │ └── serviceWorker.ts ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── .gitignore ├── tsconfig.json ├── LICENSE ├── package.json └── README.md ├── 04 - Customize Components ├── .vscode │ └── settings.json ├── index.html ├── sample-tasks.html ├── sample-tasks2.html ├── sample1.html ├── sample2.html ├── sample3.html └── sample4.html ├── 07 - Providers ├── .vscode │ └── settings.json └── index.html ├── 02 - Zero to Hero ├── .vscode │ └── settings.json ├── index.html └── Zero to Hero.md ├── 05 - Templating ├── .vscode │ └── settings.json └── index.html ├── 10 - Teams Provider ├── .vscode │ └── settings.json ├── auth.html └── index.html ├── 06 - Power of mgt-get ├── .vscode │ └── settings.json └── index.html ├── 09 - SharePoint Provider └── helloworld-mgt │ ├── .vscode │ ├── extensions.json │ ├── settings.json │ └── launch.json │ ├── src │ ├── index.ts │ └── webparts │ │ └── helloMgt │ │ ├── loc │ │ ├── en-us.js │ │ └── mystrings.d.ts │ │ ├── HelloMgtWebPart.manifest.json │ │ ├── HelloMgtWebPart.ts │ │ └── HelloMgtWebPart.module.scss │ ├── config │ ├── copy-assets.json │ ├── write-manifests.json │ ├── deploy-azure-storage.json │ ├── serve.json │ ├── config.json │ └── package-solution.json │ ├── teams │ ├── 0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_color.png │ └── 0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_outline.png │ ├── gulpfile.js │ ├── .yo-rc.json │ ├── .gitignore │ ├── .editorconfig │ ├── README.md │ ├── tslint.json │ ├── tsconfig.json │ └── package.json ├── 01 - Microsoft Graph Toolkit Overview └── Microsoft Graph Toolkit Overview.md ├── 00 - Announcement └── Announcement.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md └── SECURITY.md /14 - Angular App/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/nav-bar/nav-bar.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/angular-agenda/angular-agenda.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /13 - React App/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /04 - Customize Components/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /13 - React App/src/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /13 - React App/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /14 - Angular App/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /07 - Providers/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.host": "localhost", 3 | "liveServer.settings.port": 3000 4 | } -------------------------------------------------------------------------------- /14 - Angular App/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/14 - Angular App/src/favicon.ico -------------------------------------------------------------------------------- /02 - Zero to Hero/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.host": "localhost", 3 | "liveServer.settings.port": 3000 4 | } -------------------------------------------------------------------------------- /05 - Templating/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.host": "localhost", 3 | "liveServer.settings.port": 3000 4 | } -------------------------------------------------------------------------------- /10 - Teams Provider/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.host": "localhost", 3 | "liveServer.settings.port": 3000 4 | } -------------------------------------------------------------------------------- /13 - React App/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/13 - React App/public/favicon.ico -------------------------------------------------------------------------------- /13 - React App/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/13 - React App/public/logo192.png -------------------------------------------------------------------------------- /13 - React App/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/13 - React App/public/logo512.png -------------------------------------------------------------------------------- /14 - Angular App/src/styles.scss: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss/base'; 2 | @import 'tailwindcss/components'; 3 | @import 'tailwindcss/utilities'; -------------------------------------------------------------------------------- /06 - Power of mgt-get/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.host": "localhost", 3 | "liveServer.settings.port": 3000 4 | } -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "msjsdiag.debugger-for-chrome" 4 | ] 5 | } -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/index.ts: -------------------------------------------------------------------------------- 1 | // A file is required to be in the root of the /src directory by the TypeScript compiler 2 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /14 - Angular App/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [], 3 | theme: { 4 | extend: {}, 5 | }, 6 | variants: {}, 7 | plugins: [], 8 | } 9 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/copy-assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json", 3 | "deployCdnPath": "temp/deploy" 4 | } 5 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/write-manifests.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json", 3 | "cdnBasePath": "" 4 | } -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/teams/0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/09 - SharePoint Provider/helloworld-mgt/teams/0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_color.png -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/teams/0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/mgtLap-TryItOut/master/09 - SharePoint Provider/helloworld-mgt/teams/0c8532f4-1b2f-4468-9cd5-e4d7cac3e539_outline.png -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/webparts/helloMgt/loc/en-us.js: -------------------------------------------------------------------------------- 1 | define([], function() { 2 | return { 3 | "PropertyPaneDescription": "Description", 4 | "BasicGroupName": "Group Name", 5 | "DescriptionFieldLabel": "Description Field" 6 | } 7 | }); -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const build = require('@microsoft/sp-build-web'); 4 | 5 | build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`); 6 | 7 | build.initialize(require('gulp')); 8 | -------------------------------------------------------------------------------- /13 - React App/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /14 - Angular App/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /14 - Angular App/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/deploy-azure-storage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json", 3 | "workingDir": "./temp/deploy/", 4 | "account": "", 5 | "container": "helloworld-mgt", 6 | "accessKey": "" 7 | } -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/webparts/helloMgt/loc/mystrings.d.ts: -------------------------------------------------------------------------------- 1 | declare interface IHelloMgtWebPartStrings { 2 | PropertyPaneDescription: string; 3 | BasicGroupName: string; 4 | DescriptionFieldLabel: string; 5 | } 6 | 7 | declare module 'HelloMgtWebPartStrings' { 8 | const strings: IHelloMgtWebPartStrings; 9 | export = strings; 10 | } 11 | -------------------------------------------------------------------------------- /14 - Angular App/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /14 - Angular App/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/serve.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json", 3 | "port": 4321, 4 | "https": true, 5 | "initialPage": "https://localhost:5432/workbench", 6 | "api": { 7 | "port": 5432, 8 | "entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /10 - Teams Provider/auth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /14 - Angular App/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DemoMgtAngular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /14 - Angular App/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/nav-bar/nav-bar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-nav-bar', 5 | templateUrl: './nav-bar.component.html', 6 | styleUrls: ['./nav-bar.component.scss'] 7 | }) 8 | export class NavBarComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /01 - Microsoft Graph Toolkit Overview/Microsoft Graph Toolkit Overview.md: -------------------------------------------------------------------------------- 1 | # [Day 1 - An Overview of Microsoft Graph Toolkit](https://developer.microsoft.com/en-us/graph/blogs/a-lap-around-microsoft-graph-toolkit-in-day-1-an-overview-of-microsoft-graph-toolkit/) 2 | 3 | 1. [W3C HTML Spec](https://www.webcomponents.org/specs) 4 | 2. [Try it out repo](https://github.com/microsoftgraph/mgtLap-TryItOut) 5 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "@microsoft/generator-sharepoint": { 3 | "isCreatingSolution": true, 4 | "environment": "spo", 5 | "version": "1.10.0", 6 | "libraryName": "helloworld-mgt", 7 | "libraryId": "8ae291c3-b697-41a9-9159-30b42bd75c99", 8 | "packageManager": "npm", 9 | "isDomainIsolated": true, 10 | "componentType": "webpart" 11 | } 12 | } -------------------------------------------------------------------------------- /02 - Zero to Hero/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Welcome to MGT!

9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /13 - React App/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /13 - React App/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /14 - Angular App/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /14 - Angular App/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | // Configure glob patterns for excluding files and folders in the file explorer. 4 | "files.exclude": { 5 | "**/.git": true, 6 | "**/.DS_Store": true, 7 | "**/bower_components": true, 8 | "**/coverage": true, 9 | "**/lib-amd": true, 10 | "src/**/*.scss.ts": true 11 | }, 12 | "typescript.tsdk": ".\\node_modules\\typescript\\lib" 13 | } -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Dependency directories 7 | node_modules 8 | 9 | # Build generated files 10 | dist 11 | lib 12 | solution 13 | temp 14 | *.sppkg 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # OSX 20 | .DS_Store 21 | 22 | # Visual Studio files 23 | .ntvs_analysis.dat 24 | .vs 25 | bin 26 | obj 27 | 28 | # Resx Generated Code 29 | *.resx.ts 30 | 31 | # Styles Generated Code 32 | *.scss.ts 33 | -------------------------------------------------------------------------------- /00 - Announcement/Announcement.md: -------------------------------------------------------------------------------- 1 | # [Announcing “A Lap Around Microsoft Graph Toolkit” Blog Series](https://aka.ms/mgtLap) 2 | 3 | 1. [Microsoft Graph Toolkit docs](https://docs.microsoft.com/en-us/graph/toolkit/overview) 4 | 2. [Try it out repo](https://github.com/microsoftgraph/mgtLap-TryItOut) 5 | 3. [30 Days of Graph Blog Post Series](https://aka.ms/30DaysMSGraph) 6 | 4. [Visual Studio Code Download](https://code.visualstudio.com/Download) 7 | 5. [Microsoft 365 Developer Program](https://developer.microsoft.com/en-us/microsoft-365/dev-program) 8 | 6. [Survey Link](https://aka.ms/mgtLap-Survey) -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) 11 | -------------------------------------------------------------------------------- /14 - Angular App/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | module: { 3 | rules: [ 4 | { 5 | test: /\.scss$/, 6 | loader: 'postcss-loader', 7 | options: { 8 | ident: 'postcss', 9 | syntax: 'postcss-scss', 10 | plugins: () => [ 11 | require('postcss-import'), 12 | require('tailwindcss'), 13 | require('autoprefixer'), 14 | ] 15 | } 16 | } 17 | ] 18 | } 19 | }; -------------------------------------------------------------------------------- /14 - Angular App/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json", 3 | "version": "2.0", 4 | "bundles": { 5 | "hello-mgt-web-part": { 6 | "components": [ 7 | { 8 | "entrypoint": "./lib/webparts/helloMgt/HelloMgtWebPart.js", 9 | "manifest": "./src/webparts/helloMgt/HelloMgtWebPart.manifest.json" 10 | } 11 | ] 12 | } 13 | }, 14 | "externals": {}, 15 | "localizedResources": { 16 | "HelloMgtWebPartStrings": "lib/webparts/helloMgt/loc/{locale}.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /13 - React App/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "noEmit": true, 20 | "jsx": "react" 21 | }, 22 | "include": [ 23 | "src" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # we recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | 23 | [{package,bower}.json] 24 | indent_style = space 25 | indent_size = 2 -------------------------------------------------------------------------------- /13 - React App/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/README.md: -------------------------------------------------------------------------------- 1 | ## helloworld-mgt 2 | 3 | This is where you include your WebPart documentation. 4 | 5 | ### Building the code 6 | 7 | ```bash 8 | git clone the repo 9 | npm i 10 | npm i -g gulp 11 | gulp 12 | ``` 13 | 14 | This package produces the following: 15 | 16 | * lib/* - intermediate-stage commonjs build artifacts 17 | * dist/* - the bundled script, along with other resources 18 | * deploy/* - all resources which should be uploaded to a CDN. 19 | 20 | ### Build options 21 | 22 | gulp clean - TODO 23 | gulp test - TODO 24 | gulp serve - TODO 25 | gulp bundle - TODO 26 | gulp package-solution - TODO 27 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { NavBarComponent } from './nav-bar/nav-bar.component'; 6 | import { AngularAgendaComponent } from './angular-agenda/angular-agenda.component'; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | AppComponent, 11 | NavBarComponent, 12 | AngularAgendaComponent 13 | ], 14 | imports: [ 15 | BrowserModule 16 | ], 17 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 18 | providers: [], 19 | bootstrap: [AppComponent] 20 | }) 21 | export class AppModule { } 22 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Providers, MsalProvider, TemplateHelper, ProviderState} from '@microsoft/mgt'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.scss'] 8 | }) 9 | export class AppComponent implements OnInit { 10 | title = 'demo-mgt-angular'; 11 | 12 | public isLoggedIn(){ 13 | return Providers.globalProvider.state === ProviderState.SignedIn; 14 | } 15 | 16 | ngOnInit() 17 | { 18 | Providers.globalProvider = new MsalProvider({ clientId: '[YOUR-CLIENT-ID]' }); 19 | TemplateHelper.setBindingSyntax('[[', ']]'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /14 - Angular App/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /14 - Angular App/README.md: -------------------------------------------------------------------------------- 1 | # DemoMgtAngular 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.5. 4 | 5 | ## Getting Started 6 | The is the sample code explained in Day 14 - How to use Microsoft Graph Toolkit with Angular 7 | 8 | 1. Run `npm install` (to download all dependant npm packages) 9 | 2. Create an Azure App Registration with the following Graph API permissions 10 | * openid 11 | * profile 12 | * user.read 13 | * calendars.read 14 | 2. Modify src/app/app.component.ts and replace [YOUR-CLIENT-ID] with an Azure App Registration client id 15 | 3. Run `ng serve` for a local dev server and navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 16 | -------------------------------------------------------------------------------- /14 - Angular App/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('demo-mgt-angular app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/nav-bar/nav-bar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NavBarComponent } from './nav-bar.component'; 4 | 5 | describe('NavBarComponent', () => { 6 | let component: NavBarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ NavBarComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(NavBarComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /13 - React App/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './app'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | declare global { 8 | namespace JSX { 9 | interface IntrinsicElements { 10 | 'mgt-login': any; 11 | 'mgt-agenda': any; 12 | 'mgt-person': any; 13 | } 14 | } 15 | } 16 | 17 | ReactDOM.render( 18 | 19 | 20 | , 21 | document.getElementById('root') 22 | ); 23 | 24 | // If you want your app to work offline and load faster, you can change 25 | // unregister() to register() below. Note this comes with some pitfalls. 26 | // Learn more about service workers: https://bit.ly/CRA-PWA 27 | serviceWorker.unregister(); 28 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/angular-agenda/angular-agenda.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { AngularAgendaComponent } from './angular-agenda.component'; 3 | 4 | describe('AngularAgendaComponent', () => { 5 | let component: AngularAgendaComponent; 6 | let fixture: ComponentFixture; 7 | 8 | beforeEach(async(() => { 9 | TestBed.configureTestingModule({ 10 | declarations: [ AngularAgendaComponent ] 11 | }) 12 | .compileComponents(); 13 | })); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(AngularAgendaComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /14 - Angular App/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /14 - Angular App/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@microsoft/sp-tslint-rules/base-tslint.json", 3 | "rules": { 4 | "class-name": false, 5 | "export-name": false, 6 | "forin": false, 7 | "label-position": false, 8 | "member-access": true, 9 | "no-arg": false, 10 | "no-console": false, 11 | "no-construct": false, 12 | "no-duplicate-variable": true, 13 | "no-eval": false, 14 | "no-function-expression": true, 15 | "no-internal-module": true, 16 | "no-shadowed-variable": true, 17 | "no-switch-case-fall-through": true, 18 | "no-unnecessary-semicolons": true, 19 | "no-unused-expression": true, 20 | "no-with-statement": true, 21 | "semicolon": true, 22 | "trailing-comma": false, 23 | "typedef": false, 24 | "typedef-whitespace": false, 25 | "use-named-parameter": true, 26 | "variable-name": false, 27 | "whitespace": false 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /14 - Angular App/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/@microsoft/rush-stack-compiler-3.7/includes/tsconfig-web.json", 3 | "compilerOptions": { 4 | "target": "es5", 5 | "forceConsistentCasingInFileNames": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "jsx": "react", 9 | "declaration": true, 10 | "sourceMap": true, 11 | "experimentalDecorators": true, 12 | "skipLibCheck": true, 13 | "outDir": "lib", 14 | "inlineSources": false, 15 | "strictNullChecks": false, 16 | "noUnusedLocals": false, 17 | "typeRoots": [ 18 | "./node_modules/@types", 19 | "./node_modules/@microsoft" 20 | ], 21 | "types": [ 22 | "es6-promise", 23 | "webpack-env" 24 | ], 25 | "lib": [ 26 | "es5", 27 | "dom", 28 | "es2015.collection" 29 | ] 30 | }, 31 | "include": [ 32 | "src/**/*.ts" 33 | ], 34 | "exclude": [ 35 | "node_modules", 36 | "lib" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /02 - Zero to Hero/Zero to Hero.md: -------------------------------------------------------------------------------- 1 | # [Zero to Hero with Microsoft Graph Toolkit](https://developer.microsoft.com/en-us/graph/blogs/a-lap-around-microsoft-graph-toolkit-day-2-zero-to-hero/) 2 | 3 | 1. [Join the Microsoft 365 Developer Program](https://developer.microsoft.com/en-us/microsoft-365/dev-program) 4 | 2. [Setup a developer subscription](https://docs.microsoft.com/en-us/office/developer-program/microsoft-365-developer-program-get-started) 5 | 3. [Visual Studio Code](https://code.visualstudio.com/download) 6 | 4. [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) 7 | 5. [Azure Portal](https://portal.azure.com/) 8 | 6. [Microsoft Graph Toolkit Providers](https://docs.microsoft.com/en-us/graph/toolkit/providers) 9 | 8. [Microsoft Graph Toolkit MSAL Provider](https://docs.microsoft.com/en-us/graph/toolkit/providers/msal) 10 | 7. [Microsoft Graph Toolkit Login Component](https://docs.microsoft.com/en-us/graph/toolkit/components/login) 11 | 8. [Microsoft Graph Toolkit Agenda Component](https://docs.microsoft.com/en-us/graph/toolkit/components/agenda) -------------------------------------------------------------------------------- /14 - Angular App/src/app/angular-agenda/angular-agenda.component.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'demo-mgt-angular'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.componentInstance; 22 | expect(app.title).toEqual('demo-mgt-angular'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.nativeElement; 29 | expect(compiled.querySelector('.content span').textContent).toContain('demo-mgt-angular app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/nav-bar/nav-bar.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Microsoft Graph 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /13 - React App/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Fabio Franzini 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /14 - Angular App/src/app/angular-agenda/angular-agenda.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-angular-agenda', 5 | templateUrl: './angular-agenda.component.html', 6 | styleUrls: ['./angular-agenda.component.scss'] 7 | }) 8 | export class AngularAgendaComponent implements OnInit { 9 | @ViewChild('myagenda', {static: true}) agendaElement: any; 10 | 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | this.agendaElement.nativeElement.templateContext = { 15 | openWebLink: (e: any, context: { event: { webLink: string | undefined; }; }, root: any) => { 16 | window.open(context.event.webLink, '_blank'); 17 | }, 18 | getDate: (dateString: string) => { 19 | const dateObject = new Date(dateString); 20 | return dateObject.setHours(0, 0, 0, 0); 21 | }, 22 | getTime: (dateString: string) => { 23 | const dateObject = new Date(dateString); 24 | return dateObject.getHours().toString().padEnd(2, '0') 25 | + ':' + dateObject.getMinutes().toString().padEnd(2, '0'); 26 | } 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /14 - Angular App/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/demo-mgt-angular'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld-mgt", 3 | "version": "0.0.1", 4 | "private": true, 5 | "main": "lib/index.js", 6 | "engines": { 7 | "node": ">=0.10.0" 8 | }, 9 | "scripts": { 10 | "build": "gulp bundle", 11 | "clean": "gulp clean", 12 | "test": "gulp test" 13 | }, 14 | "dependencies": { 15 | "@microsoft/mgt": "^1.3.0-preview.3", 16 | "@microsoft/sp-core-library": "1.10.0", 17 | "@microsoft/sp-lodash-subset": "1.10.0", 18 | "@microsoft/sp-office-ui-fabric-core": "1.10.0", 19 | "@microsoft/sp-property-pane": "1.10.0", 20 | "@microsoft/sp-webpart-base": "1.10.0", 21 | "@types/es6-promise": "0.0.33", 22 | "@types/webpack-env": "1.13.1" 23 | }, 24 | "devDependencies": { 25 | "@microsoft/rush-stack-compiler-3.3": "0.3.5", 26 | "@microsoft/rush-stack-compiler-3.7": "^0.3.2", 27 | "@microsoft/sp-build-web": "1.10.0", 28 | "@microsoft/sp-module-interfaces": "1.10.0", 29 | "@microsoft/sp-tslint-rules": "1.10.0", 30 | "@microsoft/sp-webpart-workbench": "1.10.0", 31 | "@types/chai": "3.4.34", 32 | "@types/mocha": "2.2.38", 33 | "ajv": "~5.2.2", 34 | "gulp": "~3.9.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/webparts/helloMgt/HelloMgtWebPart.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json", 3 | "id": "0c8532f4-1b2f-4468-9cd5-e4d7cac3e539", 4 | "alias": "HelloMgtWebPart", 5 | "componentType": "WebPart", 6 | 7 | // The "*" signifies that the version should be taken from the package.json 8 | "version": "*", 9 | "manifestVersion": 2, 10 | 11 | // If true, the component can only be installed on sites where Custom Script is allowed. 12 | // Components that allow authors to embed arbitrary script code should set this to true. 13 | // https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f 14 | "requiresCustomScript": false, 15 | "supportedHosts": ["SharePointWebPart"], 16 | 17 | "preconfiguredEntries": [{ 18 | "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other 19 | "group": { "default": "Other" }, 20 | "title": { "default": "HelloMGT" }, 21 | "description": { "default": "Hello MGT" }, 22 | "officeFabricIconFontName": "Page", 23 | "properties": { 24 | "description": "HelloMGT" 25 | } 26 | }] 27 | } 28 | -------------------------------------------------------------------------------- /04 - Customize Components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 19 | 20 | 21 |

Welcome to Day 4 -- Customize Components!

22 | 23 | 24 | 32 | 33 | -------------------------------------------------------------------------------- /04 - Customize Components/sample-tasks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using Properties to Filter Tasks

27 | 28 | 29 |

<mgt-tasks /> filtered by category

30 | 31 | 32 | 33 | 39 | 40 | 41 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mgtLap-TryItOut 2 | 3 | The files in this repo correspond to the Try It Out exercises from the [A Lap Around Microsoft Graph Toolkit](https://aka.ms/mgtLap) blog series. Each blog post has a corresponding Markdown file consisting of resource links, hands-on exercises, or sample projects. 4 | 5 | ## Contributing 6 | 7 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 8 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 9 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 10 | 11 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 12 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 13 | provided by the bot. You will only need to do this once across all repos using our CLA. 14 | 15 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 16 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 17 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 18 | -------------------------------------------------------------------------------- /04 - Customize Components/sample-tasks2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using Properties to Filter Tasks

27 | 28 | 29 | 30 |

<mgt-tasks /> Filtered by Title

31 |
This sample is filtering every task assigned to "me" with a title that contains "Launch"
32 | 33 | 34 | 41 | 42 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /13 - React App/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-mgt-react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@microsoft/mgt": "^1.3.0", 7 | "@testing-library/jest-dom": "^4.2.4", 8 | "@testing-library/react": "^9.5.0", 9 | "@testing-library/user-event": "^7.2.1", 10 | "@types/jest": "^24.9.1", 11 | "@types/node": "^12.12.47", 12 | "@types/react": "^16.9.36", 13 | "@types/react-dom": "^16.9.8", 14 | "mgt-react": "^1.3.0-preview.2", 15 | "react": "^16.13.1", 16 | "react-dom": "^16.13.1", 17 | "react-scripts": "3.4.1", 18 | "tailwindcss": "^1.4.6", 19 | "typescript": "^3.7.5" 20 | }, 21 | "scripts": { 22 | "build:tailwind": "tailwindcss build src/tailwind.css -o src/tailwind.generated.css", 23 | "prestart": "npm run build:tailwind", 24 | "prebuild": "npm run build:tailwind", 25 | "start": "react-scripts start", 26 | "build": "react-scripts build", 27 | "test": "react-scripts test", 28 | "eject": "react-scripts eject" 29 | }, 30 | "eslintConfig": { 31 | "extends": "react-app" 32 | }, 33 | "browserslist": { 34 | "production": [ 35 | ">0.2%", 36 | "not dead", 37 | "not op_mini all" 38 | ], 39 | "development": [ 40 | "last 1 chrome version", 41 | "last 1 firefox version", 42 | "last 1 safari version" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /13 - React App/src/app.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Providers, MsalProvider, ProviderState } from '@microsoft/mgt'; 3 | import './tailwind.generated.css'; 4 | import AgendaWC from './agendaWC' 5 | import AgendaReact from './agendaReact'; 6 | import NavBar from './navBar' 7 | 8 | function App() { 9 | 10 | const [isLoggedIn, setIsLoggedIn] = useState(false); 11 | 12 | Providers.globalProvider = new MsalProvider({ clientId: '[CLIENT_ID]' }); 13 | Providers.globalProvider.onStateChanged((e) => { 14 | if (Providers.globalProvider.state !== ProviderState.Loading) 15 | setIsLoggedIn(Providers.globalProvider.state === ProviderState.SignedIn); 16 | }); 17 | 18 | return ( 19 |
20 | 21 | {(isLoggedIn) ? 22 |
23 |
24 |

25 | Agenda 26 |

27 | 28 |
29 |
30 |

31 | Agenda (Using mgt-react) 32 |

33 | 34 |
35 |
36 | : 37 |
38 | Login to show data 39 |
40 | } 41 |
42 | ); 43 | } 44 | 45 | export default App; 46 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | * Install Chrome Debugger Extension for Visual Studio Code to debug your components with the 4 | * Chrome browser: https://aka.ms/spfx-debugger-extensions 5 | */ 6 | "version": "0.2.0", 7 | "configurations": [{ 8 | "name": "Local workbench", 9 | "type": "chrome", 10 | "request": "launch", 11 | "url": "https://localhost:4321/temp/workbench.html", 12 | "webRoot": "${workspaceRoot}", 13 | "sourceMaps": true, 14 | "sourceMapPathOverrides": { 15 | "webpack:///.././src/*": "${webRoot}/src/*", 16 | "webpack:///../../../src/*": "${webRoot}/src/*", 17 | "webpack:///../../../../src/*": "${webRoot}/src/*", 18 | "webpack:///../../../../../src/*": "${webRoot}/src/*" 19 | }, 20 | "runtimeArgs": [ 21 | "--remote-debugging-port=9222" 22 | ] 23 | }, 24 | { 25 | "name": "Hosted workbench", 26 | "type": "chrome", 27 | "request": "launch", 28 | "url": "https://enter-your-SharePoint-site/_layouts/workbench.aspx", 29 | "webRoot": "${workspaceRoot}", 30 | "sourceMaps": true, 31 | "sourceMapPathOverrides": { 32 | "webpack:///.././src/*": "${webRoot}/src/*", 33 | "webpack:///../../../src/*": "${webRoot}/src/*", 34 | "webpack:///../../../../src/*": "${webRoot}/src/*", 35 | "webpack:///../../../../../src/*": "${webRoot}/src/*" 36 | }, 37 | "runtimeArgs": [ 38 | "--remote-debugging-port=9222", 39 | "-incognito" 40 | ] 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /13 - React App/src/navBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '@microsoft/mgt'; 3 | import './tailwind.generated.css'; 4 | 5 | const NavBar = () => { 6 | return ( 7 | 28 | ); 29 | } 30 | 31 | export default NavBar; -------------------------------------------------------------------------------- /04 - Customize Components/sample1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using Properties and Attributes

27 | 28 | 29 |

<mgt-people />

30 | 31 | 32 |

<mgt-people show-max="10" />

33 | 34 | 35 |

<mtg-person person-query="me" />

36 | 37 | 38 |

<mgt-person person-query="me" show-name show-email />

39 |
This example uses attributes.
40 | 41 | 42 | 43 | 44 |

<mtg-person person-query="me" /> + script

45 |
This example sets properties using script.
46 | 47 | 48 | 49 | 54 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /14 - Angular App/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-mgt-angular", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~9.1.6", 15 | "@angular/common": "~9.1.6", 16 | "@angular/compiler": "~9.1.6", 17 | "@angular/core": "~9.1.6", 18 | "@angular/forms": "~9.1.6", 19 | "@angular/platform-browser": "~9.1.6", 20 | "@angular/platform-browser-dynamic": "~9.1.6", 21 | "@angular/router": "~9.1.6", 22 | "@microsoft/mgt": "^1.3.0", 23 | "rxjs": "~6.5.4", 24 | "tslib": "^1.10.0", 25 | "zone.js": "~0.10.2" 26 | }, 27 | "devDependencies": { 28 | "@angular-builders/custom-webpack": "^9.1.0", 29 | "@angular-devkit/build-angular": "~0.901.5", 30 | "@angular/cli": "~9.1.5", 31 | "@angular/compiler-cli": "~9.1.6", 32 | "@types/jasmine": "~3.5.0", 33 | "@types/jasminewd2": "~2.0.3", 34 | "@types/node": "^12.11.1", 35 | "codelyzer": "^5.1.2", 36 | "jasmine-core": "~3.5.0", 37 | "jasmine-spec-reporter": "~4.2.1", 38 | "karma": "~5.0.0", 39 | "karma-chrome-launcher": "~3.1.0", 40 | "karma-coverage-istanbul-reporter": "~2.1.0", 41 | "karma-jasmine": "~3.0.1", 42 | "karma-jasmine-html-reporter": "^1.4.2", 43 | "postcss-import": "^12.0.1", 44 | "postcss-loader": "^3.0.0", 45 | "postcss-scss": "^2.1.1", 46 | "protractor": "~5.4.3", 47 | "tailwindcss": "^1.4.6", 48 | "ts-node": "~8.3.0", 49 | "tslint": "~6.1.0", 50 | "typescript": "~3.8.3" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/webparts/helloMgt/HelloMgtWebPart.ts: -------------------------------------------------------------------------------- 1 | import { Version } from '@microsoft/sp-core-library'; 2 | import { 3 | IPropertyPaneConfiguration, 4 | PropertyPaneTextField 5 | } from '@microsoft/sp-property-pane'; 6 | import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; 7 | import { escape } from '@microsoft/sp-lodash-subset'; 8 | 9 | import styles from './HelloMgtWebPart.module.scss'; 10 | import * as strings from 'HelloMgtWebPartStrings'; 11 | 12 | import { Providers, SharePointProvider } from '@microsoft/mgt'; 13 | 14 | export interface IHelloMgtWebPartProps { 15 | description: string; 16 | } 17 | 18 | export default class HelloMgtWebPart extends BaseClientSideWebPart { 19 | 20 | protected async onInit() { 21 | Providers.globalProvider = new SharePointProvider(this.context); 22 | } 23 | 24 | public render(): void { 25 | this.domElement.innerHTML = ` 26 | 27 | 28 | `; 29 | } 30 | 31 | 32 | protected get dataVersion(): Version { 33 | return Version.parse('1.0'); 34 | } 35 | 36 | protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { 37 | return { 38 | pages: [ 39 | { 40 | header: { 41 | description: strings.PropertyPaneDescription 42 | }, 43 | groups: [ 44 | { 45 | groupName: strings.BasicGroupName, 46 | groupFields: [ 47 | PropertyPaneTextField('description', { 48 | label: strings.DescriptionFieldLabel 49 | }) 50 | ] 51 | } 52 | ] 53 | } 54 | ] 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/config/package-solution.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json", 3 | "solution": { 4 | "name": "helloworld-mgt-client-side-solution", 5 | "id": "8ae291c3-b697-41a9-9159-30b42bd75c99", 6 | "version": "1.0.0.0", 7 | "includeClientSideAssets": true, 8 | "isDomainIsolated": false, 9 | "webApiPermissionRequests": [ 10 | { 11 | "resource": "Microsoft Graph", 12 | "scope": "User.Read" 13 | }, 14 | { 15 | "resource": "Microsoft Graph", 16 | "scope": "User.Read.All" 17 | }, 18 | { 19 | "resource": "Microsoft Graph", 20 | "scope": "User.ReadBasic.All" 21 | }, 22 | { 23 | "resource": "Microsoft Graph", 24 | "scope": "People.Read" 25 | }, 26 | { 27 | "resource": "Microsoft Graph", 28 | "scope": "Calendars.Read" 29 | }, 30 | { 31 | "resource": "Microsoft Graph", 32 | "scope": "Contacts.Read" 33 | }, 34 | { 35 | "resource": "Microsoft Graph", 36 | "scope": "Group.Read.All" 37 | }, 38 | { 39 | "resource": "Microsoft Graph", 40 | "scope": "Group.ReadWrite.All" 41 | }, 42 | { 43 | "resource": "Microsoft Graph", 44 | "scope": "Tasks.Read" 45 | }, 46 | { 47 | "resource": "Microsoft Graph", 48 | "scope": "Tasks.ReadWrite" 49 | }, 50 | { 51 | "resource": "Microsoft Graph", 52 | "scope": "Presence.Read" 53 | }, 54 | { 55 | "resource": "Microsoft Graph", 56 | "scope": "Presence.Read.All" 57 | } 58 | ] 59 | }, 60 | "paths": { 61 | "zippedPackage": "solution/helloworld-mgt.sppkg" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /13 - React App/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /09 - SharePoint Provider/helloworld-mgt/src/webparts/helloMgt/HelloMgtWebPart.module.scss: -------------------------------------------------------------------------------- 1 | @import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss'; 2 | 3 | .helloMgt { 4 | .container { 5 | max-width: 700px; 6 | margin: 0px auto; 7 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); 8 | } 9 | 10 | .row { 11 | @include ms-Grid-row; 12 | @include ms-fontColor-white; 13 | background-color: $ms-color-themeDark; 14 | padding: 20px; 15 | } 16 | 17 | .column { 18 | @include ms-Grid-col; 19 | @include ms-lg10; 20 | @include ms-xl8; 21 | @include ms-xlPush2; 22 | @include ms-lgPush1; 23 | } 24 | 25 | .title { 26 | @include ms-font-xl; 27 | @include ms-fontColor-white; 28 | } 29 | 30 | .subTitle { 31 | @include ms-font-l; 32 | @include ms-fontColor-white; 33 | } 34 | 35 | .description { 36 | @include ms-font-l; 37 | @include ms-fontColor-white; 38 | } 39 | 40 | .button { 41 | // Our button 42 | text-decoration: none; 43 | height: 32px; 44 | 45 | // Primary Button 46 | min-width: 80px; 47 | background-color: $ms-color-themePrimary; 48 | border-color: $ms-color-themePrimary; 49 | color: $ms-color-white; 50 | 51 | // Basic Button 52 | outline: transparent; 53 | position: relative; 54 | font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif; 55 | -webkit-font-smoothing: antialiased; 56 | font-size: $ms-font-size-m; 57 | font-weight: $ms-font-weight-regular; 58 | border-width: 0; 59 | text-align: center; 60 | cursor: pointer; 61 | display: inline-block; 62 | padding: 0 16px; 63 | 64 | .label { 65 | font-weight: $ms-font-weight-semibold; 66 | font-size: $ms-font-size-m; 67 | height: 32px; 68 | line-height: 32px; 69 | margin: 0 4px; 70 | vertical-align: top; 71 | display: inline-block; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /04 - Customize Components/sample2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using Custom CSS Properties

27 | 28 | 44 |

<mgt-person />

45 |
However name to view profile card
46 | 51 | 52 |

<mgt-person /> + Custom CSS

53 |
However name to view custom style profile card
54 | 60 | 61 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /13 - React App/src/agendaReact.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '@microsoft/mgt'; 3 | import { Agenda, MgtTemplateProps } from 'mgt-react'; 4 | import './tailwind.generated.css'; 5 | 6 | const AgendaReact = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | 15 | const Event = (props: MgtTemplateProps) => { 16 | const { event } = props.dataContext; 17 | 18 | const openWebLink = () => { 19 | window.open(event.webLink, '_blank'); 20 | }; 21 | 22 | const getDate = (dateString: string) => { 23 | let dateObject = new Date(dateString); 24 | return dateObject.setHours(0, 0, 0, 0); 25 | }; 26 | 27 | const getTime = (dateString: string) => { 28 | let dateObject = new Date(dateString); 29 | return dateObject.getHours().toString().padStart(2, '0') 30 | + ':' + dateObject.getMinutes().toString().padStart(2, '0'); 31 | }; 32 | 33 | return ( 34 |
35 |
{ openWebLink(); }}> 36 | {event.subject} 37 |
38 | 39 | {(getDate(event.start.dateTime) === getDate(event.end.dateTime)) ? 40 |
41 | from {getTime(event.start.dateTime)} to {getTime(event.end.dateTime)} 42 |
43 | : null 44 | } 45 | {(event.body.content !== '') ? 46 |
49 | : null 50 | } 51 |
52 | ); 53 | }; 54 | 55 | const NoData = (props: MgtTemplateProps) => { 56 | return
57 | No events to show 58 |
59 | }; 60 | 61 | export default AgendaReact; -------------------------------------------------------------------------------- /13 - React App/src/agendaWC.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect } from 'react'; 2 | import '@microsoft/mgt'; 3 | import './tailwind.generated.css'; 4 | 5 | const AgendaWC = () => { 6 | const agendaRef = useRef(null); 7 | 8 | useEffect(() => { 9 | agendaRef.current.templateContext = { 10 | openWebLink: (e: any, context: { event: { webLink: string | undefined; }; }, root: any) => { 11 | window.open(context.event.webLink, '_blank'); 12 | }, 13 | getDate: (dateString: string) => { 14 | let dateObject = new Date(dateString); 15 | return dateObject.setHours(0, 0, 0, 0); 16 | }, 17 | getTime: (dateString: string) => { 18 | let dateObject = new Date(dateString); 19 | return dateObject.getHours().toString().padStart(2, '0') 20 | + ':' + dateObject.getMinutes().toString().padStart(2, '0'); 21 | } 22 | } 23 | }, []); 24 | 25 | return ( 26 | 27 | 39 | 44 | 45 | ); 46 | } 47 | 48 | export default AgendaWC; 49 | -------------------------------------------------------------------------------- /06 - Power of mgt-get/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 67 | 70 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /13 - React App/README.md: -------------------------------------------------------------------------------- 1 | # demo-mgt-react 2 | Simple demo that use MGT (Microsoft Graph Toolkit) in a React App using TypeScript and Tailwind CSS 3 | 4 | Before starting, edit the app.tsx file to insert the correct clientId: 5 | 6 | `Providers.globalProvider = new MsalProvider({ clientId: '[CLIENT_ID]' });` 7 | 8 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 9 | 10 | ## Available Scripts 11 | 12 | In the project directory, you can run: 13 | 14 | ### `npm start` 15 | 16 | Runs the app in the development mode.
17 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 18 | 19 | The page will reload if you make edits.
20 | You will also see any lint errors in the console. 21 | 22 | ### `npm test` 23 | 24 | Launches the test runner in the interactive watch mode.
25 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 26 | 27 | ### `npm run build` 28 | 29 | Builds the app for production to the `build` folder.
30 | It correctly bundles React in production mode and optimizes the build for the best performance. 31 | 32 | The build is minified and the filenames include the hashes.
33 | Your app is ready to be deployed! 34 | 35 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 36 | 37 | ### `npm run eject` 38 | 39 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 40 | 41 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 42 | 43 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 44 | 45 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 46 | 47 | ## Learn More 48 | 49 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 50 | 51 | To learn React, check out the [React documentation](https://reactjs.org/). 52 | -------------------------------------------------------------------------------- /10 - Teams Provider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 29 | 30 | 31 | Welcome to MGT! 32 | 33 | 34 | 52 | 55 | 58 | 59 | 74 | 75 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /14 - Angular App/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /14 - Angular App/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "align": { 5 | "options": [ 6 | "parameters", 7 | "statements" 8 | ] 9 | }, 10 | "array-type": false, 11 | "arrow-return-shorthand": true, 12 | "curly": true, 13 | "deprecation": { 14 | "severity": "warning" 15 | }, 16 | "component-class-suffix": true, 17 | "contextual-lifecycle": true, 18 | "directive-class-suffix": true, 19 | "directive-selector": [ 20 | true, 21 | "attribute", 22 | "app", 23 | "camelCase" 24 | ], 25 | "component-selector": [ 26 | true, 27 | "element", 28 | "app", 29 | "kebab-case" 30 | ], 31 | "eofline": true, 32 | "import-blacklist": [ 33 | true, 34 | "rxjs/Rx" 35 | ], 36 | "import-spacing": true, 37 | "indent": { 38 | "options": [ 39 | "spaces" 40 | ] 41 | }, 42 | "max-classes-per-file": false, 43 | "max-line-length": [ 44 | true, 45 | 140 46 | ], 47 | "member-ordering": [ 48 | true, 49 | { 50 | "order": [ 51 | "static-field", 52 | "instance-field", 53 | "static-method", 54 | "instance-method" 55 | ] 56 | } 57 | ], 58 | "no-console": [ 59 | true, 60 | "debug", 61 | "info", 62 | "time", 63 | "timeEnd", 64 | "trace" 65 | ], 66 | "no-empty": false, 67 | "no-inferrable-types": [ 68 | true, 69 | "ignore-params" 70 | ], 71 | "no-non-null-assertion": true, 72 | "no-redundant-jsdoc": true, 73 | "no-switch-case-fall-through": true, 74 | "no-var-requires": false, 75 | "object-literal-key-quotes": [ 76 | true, 77 | "as-needed" 78 | ], 79 | "quotemark": [ 80 | true, 81 | "single" 82 | ], 83 | "semicolon": { 84 | "options": [ 85 | "always" 86 | ] 87 | }, 88 | "space-before-function-paren": { 89 | "options": { 90 | "anonymous": "never", 91 | "asyncArrow": "always", 92 | "constructor": "never", 93 | "method": "never", 94 | "named": "never" 95 | } 96 | }, 97 | "typedef-whitespace": { 98 | "options": [ 99 | { 100 | "call-signature": "nospace", 101 | "index-signature": "nospace", 102 | "parameter": "nospace", 103 | "property-declaration": "nospace", 104 | "variable-declaration": "nospace" 105 | }, 106 | { 107 | "call-signature": "onespace", 108 | "index-signature": "onespace", 109 | "parameter": "onespace", 110 | "property-declaration": "onespace", 111 | "variable-declaration": "onespace" 112 | } 113 | ] 114 | }, 115 | "variable-name": { 116 | "options": [ 117 | "ban-keywords", 118 | "check-format", 119 | "allow-pascal-case" 120 | ] 121 | }, 122 | "whitespace": { 123 | "options": [ 124 | "check-branch", 125 | "check-decl", 126 | "check-operator", 127 | "check-separator", 128 | "check-type", 129 | "check-typecast" 130 | ] 131 | }, 132 | "no-conflicting-lifecycle": true, 133 | "no-host-metadata-property": true, 134 | "no-input-rename": true, 135 | "no-inputs-metadata-property": true, 136 | "no-output-native": true, 137 | "no-output-on-prefix": true, 138 | "no-output-rename": true, 139 | "no-outputs-metadata-property": true, 140 | "template-banana-in-box": true, 141 | "template-no-negated-async": true, 142 | "use-lifecycle-interface": true, 143 | "use-pipe-transform-interface": true 144 | }, 145 | "rulesDirectory": [ 146 | "codelyzer" 147 | ] 148 | } -------------------------------------------------------------------------------- /05 - Templating/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | 17 | 43 | 44 | 45 | 46 |

Customizing mgt-agenda using templates

47 | 48 | 49 | 68 | 73 | 78 | 79 | 80 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /07 - Providers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 76 | 77 | 78 | 79 | 80 | 81 | 83 | 99 | 102 | 105 | 106 | 107 | 126 | 127 | -------------------------------------------------------------------------------- /14 - Angular App/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "demo-mgt-angular": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "style": "scss" 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-builders/custom-webpack:browser", 19 | "options": { 20 | "customWebpackConfig": { 21 | "path": "./webpack.config.js" 22 | }, 23 | "outputPath": "dist/demo-mgt-angular", 24 | "index": "src/index.html", 25 | "main": "src/main.ts", 26 | "polyfills": "src/polyfills.ts", 27 | "tsConfig": "tsconfig.app.json", 28 | "aot": true, 29 | "assets": [ 30 | "src/favicon.ico", 31 | "src/assets" 32 | ], 33 | "styles": [ 34 | "src/styles.scss" 35 | ], 36 | "scripts": [] 37 | }, 38 | "configurations": { 39 | "production": { 40 | "fileReplacements": [ 41 | { 42 | "replace": "src/environments/environment.ts", 43 | "with": "src/environments/environment.prod.ts" 44 | } 45 | ], 46 | "optimization": true, 47 | "outputHashing": "all", 48 | "sourceMap": false, 49 | "extractCss": true, 50 | "namedChunks": false, 51 | "extractLicenses": true, 52 | "vendorChunk": false, 53 | "buildOptimizer": true, 54 | "budgets": [ 55 | { 56 | "type": "initial", 57 | "maximumWarning": "2mb", 58 | "maximumError": "5mb" 59 | }, 60 | { 61 | "type": "anyComponentStyle", 62 | "maximumWarning": "6kb", 63 | "maximumError": "10kb" 64 | } 65 | ] 66 | } 67 | } 68 | }, 69 | "serve": { 70 | "builder": "@angular-builders/custom-webpack:dev-server", 71 | "options": { 72 | "browserTarget": "demo-mgt-angular:build", 73 | "customWebpackConfig": { 74 | "path": "./webpack.config.js" 75 | } 76 | }, 77 | "configurations": { 78 | "production": { 79 | "browserTarget": "demo-mgt-angular:build:production" 80 | } 81 | } 82 | }, 83 | "extract-i18n": { 84 | "builder": "@angular-devkit/build-angular:extract-i18n", 85 | "options": { 86 | "browserTarget": "demo-mgt-angular:build" 87 | } 88 | }, 89 | "test": { 90 | "builder": "@angular-devkit/build-angular:karma", 91 | "options": { 92 | "main": "src/test.ts", 93 | "polyfills": "src/polyfills.ts", 94 | "tsConfig": "tsconfig.spec.json", 95 | "karmaConfig": "karma.conf.js", 96 | "assets": [ 97 | "src/favicon.ico", 98 | "src/assets" 99 | ], 100 | "styles": [ 101 | "src/styles.scss" 102 | ], 103 | "scripts": [] 104 | } 105 | }, 106 | "lint": { 107 | "builder": "@angular-devkit/build-angular:tslint", 108 | "options": { 109 | "tsConfig": [ 110 | "tsconfig.app.json", 111 | "tsconfig.spec.json", 112 | "e2e/tsconfig.json" 113 | ], 114 | "exclude": [ 115 | "**/node_modules/**" 116 | ] 117 | } 118 | }, 119 | "e2e": { 120 | "builder": "@angular-devkit/build-angular:protractor", 121 | "options": { 122 | "protractorConfig": "e2e/protractor.conf.js", 123 | "devServerTarget": "demo-mgt-angular:serve" 124 | }, 125 | "configurations": { 126 | "production": { 127 | "devServerTarget": "demo-mgt-angular:serve:production" 128 | } 129 | } 130 | } 131 | } 132 | }}, 133 | "defaultProject": "demo-mgt-angular" 134 | } 135 | -------------------------------------------------------------------------------- /13 - React App/src/serviceWorker.ts: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | type Config = { 24 | onSuccess?: (registration: ServiceWorkerRegistration) => void; 25 | onUpdate?: (registration: ServiceWorkerRegistration) => void; 26 | }; 27 | 28 | export function register(config?: Config) { 29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 30 | // The URL constructor is available in all browsers that support SW. 31 | const publicUrl = new URL( 32 | process.env.PUBLIC_URL, 33 | window.location.href 34 | ); 35 | if (publicUrl.origin !== window.location.origin) { 36 | // Our service worker won't work if PUBLIC_URL is on a different origin 37 | // from what our page is served on. This might happen if a CDN is used to 38 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 39 | return; 40 | } 41 | 42 | window.addEventListener('load', () => { 43 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 44 | 45 | if (isLocalhost) { 46 | // This is running on localhost. Let's check if a service worker still exists or not. 47 | checkValidServiceWorker(swUrl, config); 48 | 49 | // Add some additional logging to localhost, pointing developers to the 50 | // service worker/PWA documentation. 51 | navigator.serviceWorker.ready.then(() => { 52 | console.log( 53 | 'This web app is being served cache-first by a service ' + 54 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 55 | ); 56 | }); 57 | } else { 58 | // Is not localhost. Just register service worker 59 | registerValidSW(swUrl, config); 60 | } 61 | }); 62 | } 63 | } 64 | 65 | function registerValidSW(swUrl: string, config?: Config) { 66 | navigator.serviceWorker 67 | .register(swUrl) 68 | .then(registration => { 69 | registration.onupdatefound = () => { 70 | const installingWorker = registration.installing; 71 | if (installingWorker == null) { 72 | return; 73 | } 74 | installingWorker.onstatechange = () => { 75 | if (installingWorker.state === 'installed') { 76 | if (navigator.serviceWorker.controller) { 77 | // At this point, the updated precached content has been fetched, 78 | // but the previous service worker will still serve the older 79 | // content until all client tabs are closed. 80 | console.log( 81 | 'New content is available and will be used when all ' + 82 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 83 | ); 84 | 85 | // Execute callback 86 | if (config && config.onUpdate) { 87 | config.onUpdate(registration); 88 | } 89 | } else { 90 | // At this point, everything has been precached. 91 | // It's the perfect time to display a 92 | // "Content is cached for offline use." message. 93 | console.log('Content is cached for offline use.'); 94 | 95 | // Execute callback 96 | if (config && config.onSuccess) { 97 | config.onSuccess(registration); 98 | } 99 | } 100 | } 101 | }; 102 | }; 103 | }) 104 | .catch(error => { 105 | console.error('Error during service worker registration:', error); 106 | }); 107 | } 108 | 109 | function checkValidServiceWorker(swUrl: string, config?: Config) { 110 | // Check if the service worker can be found. If it can't reload the page. 111 | fetch(swUrl, { 112 | headers: { 'Service-Worker': 'script' } 113 | }) 114 | .then(response => { 115 | // Ensure service worker exists, and that we really are getting a JS file. 116 | const contentType = response.headers.get('content-type'); 117 | if ( 118 | response.status === 404 || 119 | (contentType != null && contentType.indexOf('javascript') === -1) 120 | ) { 121 | // No service worker found. Probably a different app. Reload the page. 122 | navigator.serviceWorker.ready.then(registration => { 123 | registration.unregister().then(() => { 124 | window.location.reload(); 125 | }); 126 | }); 127 | } else { 128 | // Service worker found. Proceed as normal. 129 | registerValidSW(swUrl, config); 130 | } 131 | }) 132 | .catch(() => { 133 | console.log( 134 | 'No internet connection found. App is running in offline mode.' 135 | ); 136 | }); 137 | } 138 | 139 | export function unregister() { 140 | if ('serviceWorker' in navigator) { 141 | navigator.serviceWorker.ready 142 | .then(registration => { 143 | registration.unregister(); 144 | }) 145 | .catch(error => { 146 | console.error(error.message); 147 | }); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /04 - Customize Components/sample3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using specific CSS

27 | 28 | 59 |

<mgt-person />

60 |
61 | 62 | 63 | 64 | 65 | 66 | 67 |
68 | 225 | 226 | 229 | 230 | 231 | -------------------------------------------------------------------------------- /04 - Customize Components/sample4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 |

Using specific CSS

27 | 28 | 29 | 76 |

<mgt-person />

77 |
78 | 79 | 80 | 81 | 82 | 83 | 84 |
85 | 242 | 243 | 246 | 247 | 248 | --------------------------------------------------------------------------------