mirror of
https://github.com/pnp/sp-dev-fx-webparts.git
synced 2025-02-18 19:07:12 +00:00
Merge pull request #1980 from giuleon/main
This commit is contained in:
commit
f4a1f0c0b6
33
samples/react-cross-device-data/.gitignore
vendored
Normal file
33
samples/react-cross-device-data/.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Build generated files
|
||||
dist
|
||||
lib
|
||||
release
|
||||
solution
|
||||
temp
|
||||
*.sppkg
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Visual Studio files
|
||||
.ntvs_analysis.dat
|
||||
.vs
|
||||
bin
|
||||
obj
|
||||
|
||||
# Resx Generated Code
|
||||
*.resx.ts
|
||||
|
||||
# Styles Generated Code
|
||||
*.scss.ts
|
12
samples/react-cross-device-data/.yo-rc.json
Normal file
12
samples/react-cross-device-data/.yo-rc.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"version": "1.12.1",
|
||||
"libraryName": "react-cross-device-data",
|
||||
"libraryId": "e542e0b9-3afa-4e6f-aeab-8ea701e5eeca",
|
||||
"environment": "spo",
|
||||
"packageManager": "npm",
|
||||
"isCreatingSolution": true,
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
77
samples/react-cross-device-data/README.md
Normal file
77
samples/react-cross-device-data/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
# Cross-Device Data
|
||||
|
||||
## Summary
|
||||
|
||||
This solution demonstrates how to use the OneDrive special folder **Apps** in order to save user's preferencies cross-device.
|
||||
|
||||

|
||||
|
||||
## Compatibility
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Applies to
|
||||
|
||||
- [SharePoint Framework](https://aka.ms/spfx)
|
||||
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
In order to use this solution is necessary to approve the usage of Microsoft Graph API `Files.ReadWrite` in the SharePoint Admin Center
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react-cross-device-data | [Giuliano De Luca](https://github.com/giuleon) ([@delucagiulian](https://twitter.com/delucagiulian))
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|July 26, 2021|Initial release
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository
|
||||
- Ensure that you are at the solution folder
|
||||
- in the command-line run:
|
||||
- **npm install**
|
||||
- **gulp serve**
|
||||
|
||||
## Features
|
||||
|
||||
This web part illustrates the following concepts:
|
||||
|
||||
- How to store user data in the OneDrive special folder
|
||||
- How to leverage the capabilities of Microsoft Graph API
|
||||
|
||||
## References
|
||||
|
||||
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
|
||||
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
|
||||
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
||||
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
||||
|
||||
## Disclaimer
|
||||
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||
|
||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-cross-device-data&authors=@giuleon&title=react-cross-device-data%20-%20).
|
||||
|
||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-cross-device-data&authors=@giuleon&title=react-cross-device-data%20-%20).
|
||||
|
||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-cross-device-data&authors=@giuleon&title=react-cross-device-data%20-%20).
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-cross-device-data" />
|
BIN
samples/react-cross-device-data/assets/Preview.jpg
Normal file
BIN
samples/react-cross-device-data/assets/Preview.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 282 KiB |
50
samples/react-cross-device-data/assets/sample.json
Normal file
50
samples/react-cross-device-data/assets/sample.json
Normal file
@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"name": "pnp-sp-dev-spfx-web-parts-react-cross-device-data",
|
||||
"source": "pnp",
|
||||
"title": "Cross-Device Data",
|
||||
"shortDescription": "This solution demonstrates how to use the OneDrive special folder Apps in order to save user's preferencies cross-device.",
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-cross-device-data",
|
||||
"longDescription": [
|
||||
"This solution demonstrates how to use the OneDrive special folder Apps in order to save user's preferencies cross-device."
|
||||
],
|
||||
"creationDateTime": "2021-07-26",
|
||||
"updateDateTime": "2021-07-26",
|
||||
"products": [
|
||||
"SharePoint",
|
||||
"Office"
|
||||
],
|
||||
"metadata": [
|
||||
{
|
||||
"key": "CLIENT-SIDE-DEV",
|
||||
"value": "React"
|
||||
},
|
||||
{
|
||||
"key": "SPFX-VERSION",
|
||||
"value": "1.12.1"
|
||||
}
|
||||
],
|
||||
"thumbnails": [
|
||||
{
|
||||
"type": "image",
|
||||
"order": 100,
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-cross-device-data/assets/Preview.jpg",
|
||||
"alt": "Preview"
|
||||
}
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"gitHubAccount": "giuleon",
|
||||
"pictureUrl": "https://github.com/giuleon.png",
|
||||
"name": "Giuliano De Luca"
|
||||
}
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"name": "Build your first SharePoint client-side web part",
|
||||
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
|
||||
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
18
samples/react-cross-device-data/config/config.json
Normal file
18
samples/react-cross-device-data/config/config.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"hello-world-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/helloWorld/HelloWorldWebPart.js",
|
||||
"manifest": "./src/webparts/helloWorld/HelloWorldWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"HelloWorldWebPartStrings": "lib/webparts/helloWorld/loc/{locale}.js"
|
||||
}
|
||||
}
|
4
samples/react-cross-device-data/config/copy-assets.json
Normal file
4
samples/react-cross-device-data/config/copy-assets.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "./release/assets/"
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./release/assets/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "react-cross-device-data",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
27
samples/react-cross-device-data/config/package-solution.json
Normal file
27
samples/react-cross-device-data/config/package-solution.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "react-cross-device-data-client-side-solution",
|
||||
"id": "e542e0b9-3afa-4e6f-aeab-8ea701e5eeca",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "",
|
||||
"websiteUrl": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": ""
|
||||
},
|
||||
"webApiPermissionRequests": [
|
||||
{
|
||||
"resource": "Microsoft Graph",
|
||||
"scope": "Files.ReadWrite"
|
||||
}
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-cross-device-data.sppkg"
|
||||
}
|
||||
}
|
10
samples/react-cross-device-data/config/serve.json
Normal file
10
samples/react-cross-device-data/config/serve.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
16
samples/react-cross-device-data/gulpfile.js
vendored
Normal file
16
samples/react-cross-device-data/gulpfile.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||
|
||||
var getTasks = build.rig.getTasks;
|
||||
build.rig.getTasks = function () {
|
||||
var result = getTasks.call(build.rig);
|
||||
|
||||
result.set('serve', result.get('serve-deprecated'));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
build.initialize(require('gulp'));
|
21339
samples/react-cross-device-data/package-lock.json
generated
Normal file
21339
samples/react-cross-device-data/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
34
samples/react-cross-device-data/package.json
Normal file
34
samples/react-cross-device-data/package.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "react-cross-device-data",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/microsoft-graph-types": "^1.41.0",
|
||||
"@microsoft/sp-core-library": "1.12.1",
|
||||
"@microsoft/sp-lodash-subset": "1.12.1",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.12.1",
|
||||
"@microsoft/sp-property-pane": "1.12.1",
|
||||
"@microsoft/sp-webpart-base": "1.12.1",
|
||||
"office-ui-fabric-react": "7.156.0",
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "16.9.36",
|
||||
"@types/react-dom": "16.9.8",
|
||||
"@microsoft/sp-build-web": "1.12.1",
|
||||
"@microsoft/sp-tslint-rules": "1.12.1",
|
||||
"@microsoft/sp-module-interfaces": "1.12.1",
|
||||
"@microsoft/sp-webpart-workbench": "1.12.1",
|
||||
"@microsoft/rush-stack-compiler-3.7": "0.2.3",
|
||||
"gulp": "~4.0.2",
|
||||
"ajv": "~5.2.2",
|
||||
"@types/webpack-env": "1.13.1"
|
||||
}
|
||||
}
|
1
samples/react-cross-device-data/src/index.ts
Normal file
1
samples/react-cross-device-data/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "a8aaf7ce-6775-479d-be91-5d7c14128001",
|
||||
"alias": "CrossDeviceApp",
|
||||
"componentType": "WebPart",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": ["SharePointWebPart","TeamsPersonalApp"],
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "Cross Device User Data" },
|
||||
"description": { "default": "HelloWorld description" },
|
||||
"officeFabricIconFontName": "Devices2",
|
||||
"properties": {
|
||||
"description": "HelloWorld"
|
||||
}
|
||||
}]
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneTextField
|
||||
} from '@microsoft/sp-property-pane';
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
|
||||
import * as strings from 'HelloWorldWebPartStrings';
|
||||
import HelloWorld from './components/HelloWorld';
|
||||
import { IHelloWorldProps } from './components/IHelloWorldProps';
|
||||
|
||||
export interface IHelloWorldWebPartProps {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IHelloWorldProps> = React.createElement(
|
||||
HelloWorld,
|
||||
{
|
||||
description: this.properties.description,
|
||||
context: this.context,
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected onDispose(): void {
|
||||
ReactDom.unmountComponentAtNode(this.domElement);
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('description', {
|
||||
label: strings.DescriptionFieldLabel
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.helloWorld {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.rowLight {
|
||||
@include ms-Grid-row;
|
||||
@include ms-fontColor-themeDark;
|
||||
background-color: $ms-color-themeLight;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.rowDark {
|
||||
@include ms-Grid-row;
|
||||
@include ms-fontColor-white;
|
||||
background-color: $ms-color-themeDark;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.column {
|
||||
@include ms-Grid-col;
|
||||
@include ms-lg10;
|
||||
@include ms-xl8;
|
||||
@include ms-xlPush2;
|
||||
@include ms-lgPush1;
|
||||
}
|
||||
|
||||
.title {
|
||||
@include ms-font-xl;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: $ms-color-themePrimary;
|
||||
border-color: $ms-color-themePrimary;
|
||||
color: $ms-color-white;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: $ms-font-size-m;
|
||||
font-weight: $ms-font-weight-regular;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: $ms-font-weight-semibold;
|
||||
font-size: $ms-font-size-m;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.textFieldcssStyledLight {
|
||||
label {
|
||||
color: $ms-color-themeDark;
|
||||
}
|
||||
}
|
||||
.textFieldcssStyledDark {
|
||||
label {
|
||||
color: $ms-color-themeLight;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
import * as React from 'react';
|
||||
import styles from './HelloWorld.module.scss';
|
||||
import { IHelloWorldProps } from './IHelloWorldProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import {
|
||||
PrimaryButton,
|
||||
TextField,
|
||||
Toggle,
|
||||
Spinner,
|
||||
SpinnerSize
|
||||
} from 'office-ui-fabric-react';
|
||||
import { MSGraphClient } from '@microsoft/sp-http';
|
||||
|
||||
interface IUserData {
|
||||
Theme: string;
|
||||
Token: string;
|
||||
Preference1: string;
|
||||
}
|
||||
|
||||
let _Theme: string = '';
|
||||
let _Token: string = '';
|
||||
let _Preference1: string = '';
|
||||
|
||||
const Dashboard: React.FunctionComponent<IHelloWorldProps> = (props) => {
|
||||
const [userSettings, setUserSettings] = React.useState<IUserData | null>(null);
|
||||
const [currentTheme, setTheme] = React.useState<string>(null);
|
||||
const [isLoading, setIsLoading] = React.useState<boolean>(true);
|
||||
|
||||
const setUserData = async () => {
|
||||
props.context.msGraphClientFactory
|
||||
.getClient()
|
||||
.then((client: MSGraphClient) => {
|
||||
client
|
||||
.api("me/drive/special/approot:/CrossDeviceApp/settings.json:/content")
|
||||
.version("v1.0")
|
||||
.put(`{"Theme": "${_Theme}", "Token": "${_Token}", "Preference1": "${_Preference1}"}`, (err, res) => {
|
||||
console.log(err, res);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const getUserData = async () => {
|
||||
|
||||
try {
|
||||
const msGraphClient = await props.context.msGraphClientFactory.getClient();
|
||||
const result = await msGraphClient
|
||||
.api("me/drive/special/approot:/CrossDeviceApp/settings.json?select=@microsoft.graph.downloadUrl")
|
||||
.version("v1.0")
|
||||
.get();
|
||||
console.log(result);
|
||||
const response = await fetch(`${result['@microsoft.graph.downloadUrl']}`);
|
||||
console.log('response', response);
|
||||
const userData: IUserData = await response.json();
|
||||
_Theme = userData.Theme;
|
||||
_Token = userData.Token;
|
||||
_Preference1 = userData.Preference1;
|
||||
console.log('userData', userData);
|
||||
return userData;
|
||||
} catch (error) {
|
||||
const userData: IUserData = JSON.parse(`{"Theme": "", "Token": "", "Preference1": ""}`);
|
||||
return userData;
|
||||
}
|
||||
};
|
||||
|
||||
const loadUserData = async () => {
|
||||
return await getUserData();
|
||||
};
|
||||
|
||||
const onChangeTheme = (ev: React.MouseEvent<HTMLElement>, checked?: boolean): void => {
|
||||
if (checked) {
|
||||
_Theme = 'Dark';
|
||||
} else {
|
||||
_Theme = 'Light';
|
||||
}
|
||||
setTheme(_Theme);
|
||||
};
|
||||
const onChangeToken = (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newText: string): void => {
|
||||
_Token = newText;
|
||||
};
|
||||
const onChangePreference1 = (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newText: string): void => {
|
||||
_Preference1 = newText;
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log('useEffect');
|
||||
(async () => {
|
||||
let data = await loadUserData();
|
||||
console.log('loadUserData', data);
|
||||
setUserSettings(data);
|
||||
setIsLoading(false);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
let view: any = <Spinner size={SpinnerSize.large} />;
|
||||
if (isLoading !== true) {
|
||||
let theme: any =
|
||||
userSettings.Theme == 'Dark'
|
||||
? <Toggle label="Which Theme do you prefer?" defaultChecked onText="Dark" offText="Light" onChange={onChangeTheme} className={(_Theme === 'Dark') ? styles.textFieldcssStyledDark : styles.textFieldcssStyledLight} />
|
||||
: <Toggle label="Which Theme do you prefer?" onText="Dark" offText="Light" onChange={onChangeTheme} className={(_Theme === 'Dark') ? styles.textFieldcssStyledDark : styles.textFieldcssStyledLight} />;
|
||||
if (userSettings !== null) {
|
||||
view =
|
||||
<div>
|
||||
<div className={(_Theme === 'Dark') ? styles.rowDark : styles.rowLight}>
|
||||
<div className={styles.column}>
|
||||
{theme}
|
||||
{/* <TextField label="Theme:" underlined placeholder="Enter text here" defaultValue={userSettings.Theme} onChange={onChangeTheme} className={styles.textFieldcssStyled} /> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className={(_Theme === 'Dark') ? styles.rowDark : styles.rowLight}>
|
||||
<div className={styles.column}>
|
||||
<TextField label="Token:" underlined placeholder="Enter text here" defaultValue={userSettings.Token} onChange={onChangeToken} className={(_Theme === 'Dark') ? styles.textFieldcssStyledDark : styles.textFieldcssStyledLight} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={(_Theme === 'Dark') ? styles.rowDark : styles.rowLight}>
|
||||
<div className={styles.column}>
|
||||
<TextField label="Preference1:" underlined placeholder="Enter text here" defaultValue={userSettings.Preference1} onChange={onChangePreference1} className={(_Theme === 'Dark') ? styles.textFieldcssStyledDark : styles.textFieldcssStyledLight} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={(_Theme === 'Dark') ? styles.rowDark : styles.rowLight}>
|
||||
<div className={styles.column}>
|
||||
<PrimaryButton text='Save current user data' onClick={setUserData} ></PrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className={(_Theme === 'Dark') ? styles.rowDark : styles.rowLight}>
|
||||
<div className={styles.column}>
|
||||
<PrimaryButton text='Get current user data' onClick={getUserData} ></PrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.helloWorld}>
|
||||
<div className={styles.container}>
|
||||
{view}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
@ -0,0 +1,6 @@
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
|
||||
export interface IHelloWorldProps {
|
||||
description: string;
|
||||
context: WebPartContext;
|
||||
}
|
7
samples/react-cross-device-data/src/webparts/helloWorld/loc/en-us.js
vendored
Normal file
7
samples/react-cross-device-data/src/webparts/helloWorld/loc/en-us.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field"
|
||||
}
|
||||
});
|
10
samples/react-cross-device-data/src/webparts/helloWorld/loc/mystrings.d.ts
vendored
Normal file
10
samples/react-cross-device-data/src/webparts/helloWorld/loc/mystrings.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
declare interface IHelloWorldWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'HelloWorldWebPartStrings' {
|
||||
const strings: IHelloWorldWebPartStrings;
|
||||
export = strings;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 383 B |
35
samples/react-cross-device-data/tsconfig.json
Normal file
35
samples/react-cross-device-data/tsconfig.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.7/includes/tsconfig-web.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "lib",
|
||||
"inlineSources": false,
|
||||
"strictNullChecks": false,
|
||||
"noUnusedLocals": false,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./node_modules/@microsoft"
|
||||
],
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection",
|
||||
"es2015.promise"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
]
|
||||
}
|
30
samples/react-cross-device-data/tslint.json
Normal file
30
samples/react-cross-device-data/tslint.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"export-name": false,
|
||||
"forin": false,
|
||||
"label-position": false,
|
||||
"member-access": true,
|
||||
"no-arg": false,
|
||||
"no-console": false,
|
||||
"no-construct": false,
|
||||
"no-duplicate-variable": true,
|
||||
"no-eval": false,
|
||||
"no-function-expression": true,
|
||||
"no-internal-module": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-unnecessary-semicolons": true,
|
||||
"no-unused-expression": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user