added new sample to show how to manage data in onedrive applications folder
|
@ -0,0 +1,108 @@
|
|||
# react-save-to-onedrive-app-personal-folder
|
||||
|
||||
## Summary
|
||||
|
||||
This solution shows how to manage data stored in user application's personal folder in OneDrive which is one of many good methods to store application data/configuration which may be easily used in apps added to SharePoint page or Teams. The solution is built of two compontents. Spfx library which provides the functionality to manage data saved to OneDrive application personal folder and Spfx webpart component which is a very simple solution that uses the library and gets or saves data.
|
||||
|
||||
![image](./assets/to-all-sites.png)
|
||||
when adding solution to appcatalog make it available to all sites
|
||||
|
||||
![image](./assets/data-saved-on-onedrive.png)
|
||||
|
||||
![image](./assets/data.png)
|
||||
data saved on onedrive in application personal folder
|
||||
|
||||
![image](./assets/in-sharepoint.png)
|
||||
webpart added to sharepoint page
|
||||
|
||||
![image](./assets/in-teams.png)
|
||||
webpart added to teams
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.13.0](https://img.shields.io/badge/SPFx-1.13.0-green.svg)
|
||||
![Node.js v14 | v12](https://img.shields.io/badge/Node.js-v14%20%7C%20v12-green.svg)
|
||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-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)
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react-save-to-onedrive-app-personal-folder | [Adam Wójcik](https://github.com/Adam-it)
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|Februaru 21, 2022|Initial release
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-save-to-onedrive-app-personal-folder) then unzip it)
|
||||
- Ensure that you are at the solution folder
|
||||
- go to library folder
|
||||
- in the command-line run:
|
||||
- `npm install`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- Add to AppCatalog and deploy (check option to make this solution available to all sites)
|
||||
- Approve the MS Graph API permissions in SharePoint Admin page
|
||||
- go to webpart folder
|
||||
- in the command-line run:
|
||||
- `npm install`
|
||||
- `gulp serve`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- Add to AppCatalog and deploy
|
||||
|
||||
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit https://aka.ms/spfx-devcontainer for further instructions.
|
||||
|
||||
## Features
|
||||
|
||||
Description of the extension that expands upon high-level summary above.
|
||||
|
||||
This extension illustrates the following concepts:
|
||||
|
||||
- how to use Spfx library code in webpart
|
||||
- how to use Microsoft Graph api to use special approot on user OneDrive
|
||||
- how to save/update data in a json file special approot folder on user OneDrive as a place to keep data a use in SharePoint or Teams
|
||||
|
||||
## 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
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but 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're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||
|
||||
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-save-to-onedrive-app-personal-folder%22) to see if anybody else is having the same issues.
|
||||
|
||||
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-save-to-onedrive-app-personal-folder) and see what the community is saying.
|
||||
|
||||
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%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=bug-report.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aquestion%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=question.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aenhancement%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=suggestion.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%20-%20).
|
||||
|
||||
## 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.**
|
||||
|
||||
<img src="https://pnptelemetry.azurewebsites.net/sp-dev-fx-webparts/samples/react-save-to-onedrive-app-personal-folder" />
|
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 143 KiB |
|
@ -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,16 @@
|
|||
!dist
|
||||
config
|
||||
|
||||
gulpfile.js
|
||||
|
||||
release
|
||||
src
|
||||
temp
|
||||
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
|
||||
*.log
|
||||
|
||||
.yo-rc.json
|
||||
.vscode
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"plusBeta": true,
|
||||
"isCreatingSolution": true,
|
||||
"version": "1.14.0-beta.5",
|
||||
"libraryName": "manage-data",
|
||||
"libraryId": "cc04d03e-418c-44fc-a125-9fb84d9e9b33",
|
||||
"environment": "spo",
|
||||
"packageManager": "npm",
|
||||
"solutionName": "manage-data",
|
||||
"solutionShortDescription": "manage-data description",
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "library"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
# manage-data
|
||||
|
||||
## Summary
|
||||
|
||||
This is a Spfx library component which provides functionality to manage data stored in user application's personal folder in OneDrive which is one of many good methods to store application data/configuration which may be easily used in apps added to SharePoint page or Teams.
|
||||
|
||||
![image](../assets/to-all-sites.png)
|
||||
when adding solution to appcatalog make it available to all sites
|
||||
|
||||
![image](../assets/data-saved-on-onedrive.png)
|
||||
|
||||
![image](../assets/data.png)
|
||||
data saved on onedrive in application personal folder
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.13.0](https://img.shields.io/badge/SPFx-1.13.0-green.svg)
|
||||
![Node.js v14 | v12](https://img.shields.io/badge/Node.js-v14%20%7C%20v12-green.svg)
|
||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-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)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
As this solution uses Microsoft Graph to manage data on user OneDrive it is required to approve all web api permission requests in SharePoint Admin page https://YourCoolTenantNameHere-admin.sharepoint.com/_layouts/15/online/AdminHome.aspx#/webApiPermissionManagement
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
manage-data | [Adam Wójcik](https://github.com/Adam-it)
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|Februaru 21, 2022|Initial release
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-save-to-onedrive-app-personal-folder) then unzip it)
|
||||
- Ensure that you are at the solution folder
|
||||
- in the command-line run:
|
||||
- `npm install`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- Add to AppCatalog and deploy (check option to make this solution available to all sites)
|
||||
- Approve the MS Graph API permissions in SharePoint Admin page
|
||||
|
||||
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit https://aka.ms/spfx-devcontainer for further instructions.
|
||||
|
||||
## Features
|
||||
|
||||
Description of the extension that expands upon high-level summary above.
|
||||
|
||||
This extension illustrates the following concepts:
|
||||
|
||||
- how to use Microsoft Graph api to use special approot on user OneDrive
|
||||
- how to save/update data in a json file special approot folder on user OneDrive as a place to keep data a use in SharePoint or Teams
|
||||
|
||||
## 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
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but 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're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||
|
||||
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-save-to-onedrive-app-personal-folder%22) to see if anybody else is having the same issues.
|
||||
|
||||
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-save-to-onedrive-app-personal-folder) and see what the community is saying.
|
||||
|
||||
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%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=bug-report.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aquestion%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=question.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aenhancement%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=suggestion.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%20-%20).
|
||||
|
||||
## 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.**
|
||||
|
||||
<img src="https://pnptelemetry.azurewebsites.net/sp-dev-fx-webparts/samples/react-save-to-onedrive-app-personal-folder" />
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"manage-data-library": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/index.js",
|
||||
"manifest": "./src/libraries/manageData/ManageDataLibrary.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"ManageDataLibraryStrings": "lib/libraries/manageData/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -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": "manage-data",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "manage-data-client-side-solution",
|
||||
"id": "cc04d03e-418c-44fc-a125-9fb84d9e9b33",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "",
|
||||
"websiteUrl": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "Undefined-1.14.0-beta.5"
|
||||
},
|
||||
"webApiPermissionRequests": [
|
||||
{
|
||||
"resource": "Microsoft Graph",
|
||||
"scope": "Sites.ReadWrite.All"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"shortDescription": {
|
||||
"default": "manage-data description"
|
||||
},
|
||||
"longDescription": {
|
||||
"default": "manage-data description"
|
||||
},
|
||||
"screenshotPaths": [],
|
||||
"videoUrl": "",
|
||||
"categories": []
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/manage-data.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true
|
||||
}
|
|
@ -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'));
|
21812
samples/react-save-to-onedrive-app-personal-folder/library/package-lock.json
generated
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "manage-data",
|
||||
"version": "0.0.1",
|
||||
"private": false,
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-webpart-base": "^1.14.0-beta.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "1.14.0-beta.5",
|
||||
"@microsoft/sp-tslint-rules": "1.14.0-beta.5",
|
||||
"@microsoft/sp-module-interfaces": "1.14.0-beta.5",
|
||||
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
|
||||
"gulp": "~4.0.2",
|
||||
"ajv": "~5.2.2",
|
||||
"@types/webpack-env": "1.13.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export { ManageDataLibrary } from './libraries/manageData/ManageDataLibrary';
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"id": "a02d4028-02fe-451e-94e3-512872a414c9",
|
||||
"alias": "ManageDataLibrary",
|
||||
"componentType": "Library",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
import {
|
||||
MSGraphClient,
|
||||
HttpClient,
|
||||
HttpClientResponse
|
||||
} from '@microsoft/sp-http';
|
||||
import IAppData from './model/IAppData';
|
||||
|
||||
export class ManageDataLibrary {
|
||||
|
||||
private static appDataFolderName: string = 'appData';
|
||||
private static appDataFileName: string = 'savedData.json';
|
||||
private mSGraphClient: MSGraphClient = null;
|
||||
private httpClient: HttpClient = null;
|
||||
|
||||
constructor(
|
||||
mSGraphClient: MSGraphClient,
|
||||
httpClient: HttpClient) {
|
||||
this.mSGraphClient = mSGraphClient;
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public async getData(): Promise<IAppData> {
|
||||
return new Promise<IAppData>((resolve) =>
|
||||
this.checkIfAppDataFolderExists()
|
||||
.then(async folderExists => {
|
||||
if (!folderExists) {
|
||||
await this.createAppDataFolder();
|
||||
}
|
||||
this.mSGraphClient
|
||||
.api(`/me/drive/special/approot:/${ManageDataLibrary.appDataFolderName}:/children?$filter=name eq '${ManageDataLibrary.appDataFileName}'`)
|
||||
.version('v1.0')
|
||||
.get((error, response: any, rawResponse?: any) => {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.value.length === 0) {
|
||||
resolve(
|
||||
{
|
||||
data: null
|
||||
} as IAppData);
|
||||
}
|
||||
|
||||
const downloadUrl = response.value.filter(item => item.name === ManageDataLibrary.appDataFileName)[0]['@microsoft.graph.downloadUrl'];
|
||||
this.httpClient
|
||||
.get(downloadUrl, HttpClient.configurations.v1)
|
||||
.then((innerResponse: HttpClientResponse): Promise<string> => {
|
||||
if (innerResponse.ok) {
|
||||
return innerResponse.text();
|
||||
}
|
||||
|
||||
return Promise.reject(innerResponse.statusText);
|
||||
})
|
||||
.then((savedData: string) => {
|
||||
const settings: IAppData = JSON.parse(savedData);
|
||||
resolve(settings);
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public saveData(appData: IAppData): Promise<any> {
|
||||
return this.getAppDataFolder()
|
||||
.then(response => {
|
||||
const id = response.value.filter(item => item.name === ManageDataLibrary.appDataFolderName)[0].id;
|
||||
const stream = JSON.stringify(appData);
|
||||
|
||||
this.mSGraphClient
|
||||
.api(`/me/drive/items/${id}:/${ManageDataLibrary.appDataFileName}:/content`)
|
||||
.version('v1.0')
|
||||
.put(stream);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async createAppDataFolder(): Promise<string> {
|
||||
const driveItem = {
|
||||
name: ManageDataLibrary.appDataFolderName,
|
||||
folder: {},
|
||||
'@microsoft.graph.conflictBehavior': 'fail'
|
||||
};
|
||||
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
this.mSGraphClient
|
||||
.api('/me/drive/special/approot/children')
|
||||
.version('v1.0')
|
||||
.post(driveItem)
|
||||
.then(result => {
|
||||
if (result != null) {
|
||||
resolve(result.name.toString());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private async checkIfAppDataFolderExists(): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
resolve(this.getAppDataFolder().then(result => {
|
||||
const isError = result.errorCode !== undefined;
|
||||
return !isError ? result.value.some(item => item.name === ManageDataLibrary.appDataFolderName) : false;
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private async getAppDataFolder(): Promise<any> {
|
||||
return new Promise<any>((resolve, reject) =>
|
||||
this.mSGraphClient
|
||||
.api(`/me/drive/special/approot/children?$filter=name eq '${ManageDataLibrary.appDataFolderName}'`)
|
||||
.version('v1.0')
|
||||
.get((error, response: any, rawResponse?: any) => {
|
||||
if (error) {
|
||||
resolve(error);
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
define([], function() {
|
||||
return {}
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
declare interface IManageDataLibraryStrings {}
|
||||
|
||||
declare module 'ManageDataLibraryStrings' {
|
||||
const strings: IManageDataLibraryStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default interface IAppData {
|
||||
data: any;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.9/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,29 @@
|
|||
{
|
||||
"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-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
|
@ -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,16 @@
|
|||
!dist
|
||||
config
|
||||
|
||||
gulpfile.js
|
||||
|
||||
release
|
||||
src
|
||||
temp
|
||||
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
|
||||
*.log
|
||||
|
||||
.yo-rc.json
|
||||
.vscode
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"plusBeta": true,
|
||||
"isCreatingSolution": true,
|
||||
"version": "1.14.0-beta.5",
|
||||
"libraryName": "client-webpart",
|
||||
"libraryId": "68771efc-fba0-4f85-8592-c2f447e14c63",
|
||||
"environment": "spo",
|
||||
"packageManager": "npm",
|
||||
"solutionName": "client-webpart",
|
||||
"solutionShortDescription": "client-webpart description",
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
# client-webpart
|
||||
|
||||
## Summary
|
||||
|
||||
This is a very simple Spfx webpart which presents how to use your own Spfx library in your solution. The webpart uses two methods from Spfx manage-data library to get and save data in user application's personal folder in OneDrive.
|
||||
|
||||
![image](../assets/in-sharepoint.png)
|
||||
webpart added to sharepoint page
|
||||
|
||||
![image](../assets/in-teams.png)
|
||||
webpart added to teams
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.13.0](https://img.shields.io/badge/SPFx-1.13.0-green.svg)
|
||||
![Node.js v14 | v12](https://img.shields.io/badge/Node.js-v14%20%7C%20v12-green.svg)
|
||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-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)
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
client-webpart | [Adam Wójcik](https://github.com/Adam-it)
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|Februaru 21, 2022|Initial release
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-save-to-onedrive-app-personal-folder) then unzip it)
|
||||
- Ensure that you are at the solution folder
|
||||
- in the command-line run:
|
||||
- `npm install`
|
||||
- `gulp serve`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- Add to AppCatalog and deploy
|
||||
|
||||
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit https://aka.ms/spfx-devcontainer for further instructions.
|
||||
|
||||
## Features
|
||||
|
||||
Description of the extension that expands upon high-level summary above.
|
||||
|
||||
This extension illustrates the following concepts:
|
||||
|
||||
- how to use Spfx library code in webpart
|
||||
|
||||
## 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
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but 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're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||
|
||||
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-save-to-onedrive-app-personal-folder%22) to see if anybody else is having the same issues.
|
||||
|
||||
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-save-to-onedrive-app-personal-folder) and see what the community is saying.
|
||||
|
||||
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%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=bug-report.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aquestion%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=question.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%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%3Aenhancement%2Csample%3A%20react-save-to-onedrive-app-personal-folder&template=suggestion.yml&sample=react-save-to-onedrive-app-personal-folder&authors=@Adam-it&title=react-save-to-onedrive-app-personal-folder%20-%20).
|
||||
|
||||
## 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.**
|
||||
|
||||
<img src="https://pnptelemetry.azurewebsites.net/sp-dev-fx-webparts/samples/react-save-to-onedrive-app-personal-folder" />
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"client-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/client/ClientWebPart.js",
|
||||
"manifest": "./src/webparts/client/ClientWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"ClientWebPartStrings": "lib/webparts/client/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -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": "client-webpart",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "client-webpart-client-side-solution",
|
||||
"id": "68771efc-fba0-4f85-8592-c2f447e14c63",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "",
|
||||
"websiteUrl": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "Undefined-1.14.0-beta.5"
|
||||
},
|
||||
"metadata": {
|
||||
"shortDescription": {
|
||||
"default": "client-webpart description"
|
||||
},
|
||||
"longDescription": {
|
||||
"default": "client-webpart description"
|
||||
},
|
||||
"screenshotPaths": [],
|
||||
"videoUrl": "",
|
||||
"categories": []
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"title": "client-webpart Feature",
|
||||
"description": "The feature that activates elements of the client-webpart solution.",
|
||||
"id": "9cadc74a-410a-43a5-ba7f-1bd8ae9e88ed",
|
||||
"version": "1.0.0.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/client-webpart.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://tenanttocheck.sharepoint.com/sites/hr-life/_layouts/workbench.aspx"
|
||||
}
|
|
@ -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'));
|
22046
samples/react-save-to-onedrive-app-personal-folder/webpart/package-lock.json
generated
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "client-webpart",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"office-ui-fabric-react": "7.174.1",
|
||||
"manage-data": "0.0.1",
|
||||
"@microsoft/sp-core-library": "1.14.0-beta.5",
|
||||
"@microsoft/sp-property-pane": "1.14.0-beta.5",
|
||||
"@microsoft/sp-webpart-base": "1.14.0-beta.5",
|
||||
"@microsoft/sp-lodash-subset": "1.14.0-beta.5",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.14.0-beta.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "16.9.51",
|
||||
"@types/react-dom": "16.9.8",
|
||||
"@microsoft/sp-build-web": "1.14.0-beta.5",
|
||||
"@microsoft/sp-tslint-rules": "1.14.0-beta.5",
|
||||
"@microsoft/sp-module-interfaces": "1.14.0-beta.5",
|
||||
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
|
||||
"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,28 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "a6603137-966f-40c1-9897-4d2bb2250128",
|
||||
"alias": "ClientWebPart",
|
||||
"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", "TeamsTab", "SharePointFullPage"],
|
||||
"supportsThemeVariants": true,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "Client" },
|
||||
"description": { "default": "Client description" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "Client"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
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 { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
import * as strings from 'ClientWebPartStrings';
|
||||
import Client from './components/Client';
|
||||
import { IClientProps } from './components/IClientProps';
|
||||
|
||||
export interface IClientWebPartProps {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export default class ClientWebPart extends BaseClientSideWebPart<IClientWebPartProps> {
|
||||
|
||||
private _isDarkTheme: boolean = false;
|
||||
private _environmentMessage: string = '';
|
||||
|
||||
protected onInit(): Promise<void> {
|
||||
this._environmentMessage = this._getEnvironmentMessage();
|
||||
|
||||
return super.onInit();
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IClientProps> = React.createElement(
|
||||
Client,
|
||||
{
|
||||
description: this.properties.description,
|
||||
isDarkTheme: this._isDarkTheme,
|
||||
environmentMessage: this._environmentMessage,
|
||||
hasTeamsContext: !!this.context.sdks.microsoftTeams,
|
||||
userDisplayName: this.context.pageContext.user.displayName,
|
||||
context: this.context
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
private _getEnvironmentMessage(): string {
|
||||
if (!!this.context.sdks.microsoftTeams) { // running in Teams
|
||||
return this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
|
||||
}
|
||||
|
||||
return this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment;
|
||||
}
|
||||
|
||||
protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
|
||||
if (!currentTheme) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDarkTheme = !!currentTheme.isInverted;
|
||||
const {
|
||||
semanticColors
|
||||
} = currentTheme;
|
||||
this.domElement.style.setProperty('--bodyText', semanticColors.bodyText);
|
||||
this.domElement.style.setProperty('--link', semanticColors.link);
|
||||
this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered);
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,34 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.client {
|
||||
overflow: hidden;
|
||||
padding: 1em;
|
||||
color: "[theme:bodyText, default: #323130]";
|
||||
color: var(--bodyText);
|
||||
&.teams {
|
||||
font-family: $ms-font-family-fallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
.welcome {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcomeImage {
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
.links {
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: "[theme:link, default:#03787c]";
|
||||
color: var(--link); // note: CSS Custom Properties support is limited to modern browsers only
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
color: "[theme:linkHovered, default: #014446]";
|
||||
color: var(--linkHovered); // note: CSS Custom Properties support is limited to modern browsers only
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { MSGraphClient } from '@microsoft/sp-http';
|
||||
import * as React from 'react';
|
||||
import styles from './Client.module.scss';
|
||||
import { IClientProps } from './IClientProps';
|
||||
import * as ManageData from 'manage-data';
|
||||
import { IClientState } from './IClientState';
|
||||
|
||||
export default class Client extends React.Component<IClientProps, IClientState> {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
manageDataLibrary: null,
|
||||
savedData: ''
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.props.context.msGraphClientFactory
|
||||
.getClient()
|
||||
.then(async (client: MSGraphClient): Promise<void> => {
|
||||
const manageDataLibrary = new ManageData.ManageDataLibrary(client, this.props.context.httpClient);
|
||||
const savedData = await manageDataLibrary.getData();
|
||||
this.setState({
|
||||
manageDataLibrary,
|
||||
savedData: savedData.data
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IClientProps> {
|
||||
const {
|
||||
isDarkTheme,
|
||||
environmentMessage,
|
||||
hasTeamsContext,
|
||||
} = this.props;
|
||||
|
||||
const { savedData } = this.state;
|
||||
|
||||
return (
|
||||
<section className={`${styles.client} ${hasTeamsContext ? styles.teams : ''}`}>
|
||||
<div className={styles.welcome}>
|
||||
<img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} />
|
||||
<div>{environmentMessage}</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Manage data in application personal folder in OneDrive</h3>
|
||||
<TextField label="Data:" value={savedData} onChange={(e) => this.handleDocumentChange(e)} />
|
||||
<ActionButton iconProps={{ iconName: 'Download' }} onClick={() => this.get()}>Get</ActionButton>
|
||||
<ActionButton iconProps={{ iconName: 'Save' }} onClick={() => this.save()}>Save</ActionButton>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
private get(): void {
|
||||
this.state.manageDataLibrary.getData().then(result => this.setState({ savedData: result.data }));
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
const dataToSave = this.state.savedData;
|
||||
this.state.manageDataLibrary.saveData({ data: dataToSave }).then(response => {
|
||||
this.get();
|
||||
});
|
||||
}
|
||||
|
||||
private handleDocumentChange(event): void {
|
||||
const text: string = event.target.value;
|
||||
this.setState({ savedData: text });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||
|
||||
export interface IClientProps {
|
||||
description: string;
|
||||
isDarkTheme: boolean;
|
||||
environmentMessage: string;
|
||||
hasTeamsContext: boolean;
|
||||
userDisplayName: string;
|
||||
context: WebPartContext;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import * as ManageData from 'manage-data';
|
||||
|
||||
export interface IClientState {
|
||||
savedData: string;
|
||||
manageDataLibrary: ManageData.ManageDataLibrary;
|
||||
}
|
11
samples/react-save-to-onedrive-app-personal-folder/webpart/src/webparts/client/loc/en-us.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field",
|
||||
"AppLocalEnvironmentSharePoint": "The app is running on your local environment as SharePoint web part",
|
||||
"AppLocalEnvironmentTeams": "The app is running on your local environment as Microsoft Teams app",
|
||||
"AppSharePointEnvironment": "The app is running on SharePoint page",
|
||||
"AppTeamsTabEnvironment": "The app is running in Microsoft Teams"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
declare interface IClientWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
AppLocalEnvironmentSharePoint: string;
|
||||
AppLocalEnvironmentTeams: string;
|
||||
AppSharePointEnvironment: string;
|
||||
AppTeamsTabEnvironment: string;
|
||||
}
|
||||
|
||||
declare module 'ClientWebPartStrings' {
|
||||
const strings: IClientWebPartStrings;
|
||||
export = strings;
|
||||
}
|
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 542 B |
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.9/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,29 @@
|
|||
{
|
||||
"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-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|