Merge pull request #1980 from giuleon/main
This commit is contained in:
commit
f4a1f0c0b6
|
@ -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
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
||||
![Preview](./assets/Preview.jpg)
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
- [SharePoint Framework](https://aka.ms/spfx)
|
||||
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
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" />
|
Binary file not shown.
After Width: | Height: | Size: 282 KiB |
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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 -->"
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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 -->"
|
||||
}
|
|
@ -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'));
|
File diff suppressed because it is too large
Load Diff
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field"
|
||||
}
|
||||
});
|
|
@ -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 |
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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…
Reference in New Issue