Added PnP JS Tester Webpart

Added new sample PnP JS Tester Webpart which allows to test PnP JS SharePoint method.

Co-Authored-By: Kunj Balkrishna Sangani <sangani.kunj@gmail.com>
This commit is contained in:
Siddharth 2020-08-16 13:56:49 +05:30
parent ece43214ca
commit 0d9630f8a0
29 changed files with 18478 additions and 0 deletions

View File

@ -0,0 +1,24 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# change these settings to your own preference
indent_style = space
indent_size = 2
# we recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[{package,bower}.json]
indent_style = space
indent_size = 2

32
samples/react-pnpjsexplorer/.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# Logs
logs
*.log
npm-debug.log*
# Dependency directories
node_modules
# Build generated files
dist
lib
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

View File

@ -0,0 +1,12 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": false,
"environment": "spo",
"version": "1.10.0",
"libraryName": "react-pnpjsexplorer",
"libraryId": "a41b7fa8-313e-40d1-ae85-1d85baddecf5",
"packageManager": "npm",
"isDomainIsolated": false,
"componentType": "webpart"
}
}

View File

@ -0,0 +1,83 @@
## SPFx webpart to Test PnpJS SharePoint Methods
This webpart will allow SPFx developers to test PnPjs methods and it displays response in JSON viewer to identify properties/attributes returned by method/api. This webpart can be used as seperate component to test PnP Js methods and know the response returned by a particular method/api. To maximise productivity, we should package and deploy it to a test(developer) site collection which then can be used side by side when we are doing development of SPFx solutions.
Note - As of now it only supports to test Pnp JS method from sp(SharePoint) packages which contains the fluent api used to call the SharePoint rest services.
You can refer to this blog [link](https://siddharthvaghasia.com/2020/08/16/usage-guide-on-spfx-pnpjs-tester-web-part/) for usage guidance on How to use this webpart.
WebPart in Action
![Webpart in action](assets/pnpjstesterinaction.gif?raw=true "Webpart in action")
Idea behind this webpart
* Most of the SharePoint developers are using PnP JS to develop SPFx solutions.
* During the development, there are times when we wanted to know what properties/attributes will be returned in response
* To get these details, we either use console.log to log response or debug the javascript and check what properties/attributes are returned etc.
* This webpart can be used so that we can quickly test any SharePoint rest api methods using PnP JS.
Feel free to connect on twitter:@siddh_me or twitter:@sanganikunj for any details.
### Notes on Webpart
* WebPart to test PnP JS SharePoint package methods
* Response will be displayed in a code format.
* By default, it will run in context of current site collection.
* Optional option to enter diffrent site collection or sub site url to set PnP JS context to diffrent url(other than current context)
* Support for Get and Post methods.
* Option to see some examples which can be copied and tested just by changing list/libraries/column names.
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/version-1.10.0-green.svg)
## Applies to
* [SharePoint Framework](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
* [Office 365 tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
### Package and Deploy
Note - If you don't want to build and package on your own, you can directly download package at this [location](./sharepoint/solution/react-pnpjsexplorer.sppkg) and upload to app catalog and install app on required site collection. Skip below steps and directly go to How to use section.
Clone the solution and make sure there is no error before packaging. Try first on local work bench.
```bash
git clone the repo
npm i
gulp serve
```
- Execute the following gulp task to bundle your solution. This executes a release build of your project by using a dynamic label as the host URL for your assets. This URL is automatically updated based on your tenant CDN settings:
```bash
gulp bundle --ship
```
- Execute the following task to package your solution. This creates an updated webpart.sppkg package on the sharepoint/solution folder.
```bash
gulp package-solution --ship
```
- Upload or drag and drop the newly created client-side solution package to the app catalog in your tenant.
- Based on your tenant settings, if you would not have CDN enabled in your tenant, and the includeClientSideAssets setting would be true in the package-solution.json, the loading URL for the assets would be dynamically updated and pointing directly to the ClientSideAssets folder located in the app catalog site collection.
## Solution
Solution|Author(s)
--------|---------
react-PnPjsTester | [Siddharth Vaghasia](https://www.linkedin.com/in/siddharthvaghasia/) and [Kunj Sangani](https://www.linkedin.com/in/kunj-sangani/)
## Version history
Version|Date|Comments
-------|----|--------
1.0.0|Aug 14, 2020|Initial Release
## Disclaimer
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
For any issue or help, Buzz us on twitter:([siddh_me](https://twitter.com/siddh_me/)) or ([sanganikunj](https://twitter.com/sanganikunj))
> Sharing is caring!
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-pnpjsexplorer" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,18 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"react-pn-pjs-tester-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/reactPnPjsTester/ReactPnPjsTesterWebPart.js",
"manifest": "./src/webparts/reactPnPjsTester/ReactPnPjsTesterWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"ReactPnPjsTesterWebPartStrings": "lib/webparts/reactPnPjsTester/loc/{locale}.js"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -0,0 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "react-pnpjsexplorer",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "react-pnpjsexplorer-client-side-solution",
"id": "a41b7fa8-313e-40d1-ae85-1d85baddecf5",
"version": "2.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false
},
"paths": {
"zippedPackage": "solution/react-pnpjsexplorer.sppkg"
}
}

View 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/"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}

View File

@ -0,0 +1,7 @@
'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.`);
build.initialize(require('gulp'));

17522
samples/react-pnpjsexplorer/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
{
"name": "react-pnpjsexplorer",
"version": "0.0.1",
"private": true,
"main": "lib/index.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.10.0",
"@microsoft/sp-lodash-subset": "1.10.0",
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
"@microsoft/sp-property-pane": "1.10.0",
"@microsoft/sp-webpart-base": "1.10.0",
"@pnp/sp": "^2.0.5",
"@types/es6-promise": "0.0.33",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@types/webpack-env": "1.13.1",
"ace-builds": "^1.4.11",
"office-ui-fabric-react": "6.189.2",
"react": "16.8.5",
"react-ace": "^9.1.1",
"react-dom": "16.8.5",
"react-json-view": "^1.19.1"
},
"resolutions": {
"@types/react": "16.8.8"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.10.0",
"@microsoft/sp-tslint-rules": "1.10.0",
"@microsoft/sp-module-interfaces": "1.10.0",
"@microsoft/sp-webpart-workbench": "1.10.0",
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
"gulp": "~3.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2"
}
}

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -0,0 +1,27 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "9dbf4d65-e0cc-4462-801a-2b96ea28de5a",
"alias": "ReactPnPjsTesterWebPart",
"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"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "react-PnPjsTester" },
"description": { "default": "This webpart will help in executing multiple rest api using PnPjs this would be helpful for developers" },
"officeFabricIconFontName": "Page",
"properties": {
"description": "react-PnPjsTester"
}
}]
}

View File

@ -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 'ReactPnPjsTesterWebPartStrings';
import ReactPnPjsTester from './components/ReactPnPjsTester';
import { IReactPnPjsTesterProps } from './components/IReactPnPjsTesterProps';
export interface IReactPnPjsTesterWebPartProps {
description: string;
}
export default class ReactPnPjsTesterWebPart extends BaseClientSideWebPart <IReactPnPjsTesterWebPartProps> {
public render(): void {
const element: React.ReactElement<IReactPnPjsTesterProps> = React.createElement(
ReactPnPjsTester,
{
description: this.properties.description,
spcontext: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
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,6 @@
import { WebPartContext } from "@microsoft/sp-webpart-base";
export interface IReactPnPjsTesterProps {
description: string;
spcontext:WebPartContext;
}

View File

@ -0,0 +1,134 @@
@import "~office-ui-fabric-react/dist/sass/References.scss";
.reactPnPjsTester {
.container {
// max-width: 800px;
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);
}
.jsonviewcont{
overflow-y: auto;
}
.row {
@include ms-Grid-row;
// @include ms-fontColor-white;
// background-color: $ms-color-themeDark;
padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg12;
@include ms-xl12;
}
.col1 {
@include ms-Grid-col;
@include ms-sm2;
}
.col11 {
@include ms-Grid-col;
@include ms-sm10;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-m;
}
.methodSelector {
:global {
.ms-Dropdown {
&:focus {
color: $ms-color-white;
}
}
.ms-Dropdown-title {
background-color: $ms-color-themePrimary;
color: $ms-color-white;
}
.ms-Dropdown-caretDownWrapper i {
color: $ms-color-white;
}
}
}
.collapse {
float: right;
margin-top: -20px;
margin-bottom: 20px;
}
.codeZone {
border: 1px solid;
border-color: $ms-color-neutralLight;
margin-bottom: 15px;
overflow-x: auto;
}
.icon {
margin-right: 5px;
}
.button {
// Our button
text-decoration: none;
height: 32px;
margin-right: 10px;
// 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;
}
}
}
:global {
.pageContent_ecefc8ba {
max-width: 1200px;
}
.ms-Button-label {
width: 440px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
}

View File

@ -0,0 +1,333 @@
import * as React from "react";
import styles from "./ReactPnPjsTester.module.scss";
import { IReactPnPjsTesterProps } from "./IReactPnPjsTesterProps";
import { sp } from "@pnp/sp/presets/all";
import {
TextField,
Panel,
PanelType,
Checkbox,
Icon,
Dropdown,
TooltipHost,
DirectionalHint,
Toggle,
Stack,
} from "office-ui-fabric-react";
// import AceEditor from "react-ace";
import { DefaultButton, ActionButton, IconButton } from "office-ui-fabric-react/lib/Button";
// import "ace-builds/src-noconflict/mode-json";
// import "ace-builds/src-noconflict/theme-github";
import ReactJson from "react-json-view";
const samples:ISamples = require("./Samples.json");
export interface ISamples{
samples:any[];
}
export interface IReactPnPjsTesterState {
jsonResponse: any;
pnpCommand: any;
displayDataTypes: boolean;
displayObjectSize: boolean;
enableClipboard: boolean;
openPanel: boolean;
isError: boolean;
errorMessage: any;
siteUrl: string;
isUpdate: boolean;
showAddUpdateInformation: boolean;
defaultCollapsed: boolean;
requestType: string;
isOtherSite: boolean;
}
var spObj = null;
export default class ReactPnPjsTester extends React.Component<
IReactPnPjsTesterProps,
IReactPnPjsTesterState
> {
private addCommand =
'sp.web.lists.getByTitle("CustomList").items.add({Title: "PnpJS Explorer"})';
private exampleJson = samples.samples;
// constructor to intialize state and pnp sp object.
constructor(props: IReactPnPjsTesterProps, state: IReactPnPjsTesterState) {
super(props);
this.state = {
requestType: "GET",
jsonResponse: null,
pnpCommand: null,
displayDataTypes: false,
displayObjectSize: false,
enableClipboard: false,
openPanel: false,
isError: false,
errorMessage: null,
siteUrl: "",
isUpdate: false,
showAddUpdateInformation: false,
defaultCollapsed: false,
isOtherSite: false,
};
}
private _reqBodyChanged = (val: string) => {
// this.setState({
// jsonResponse: val,
// });
}
public render(): React.ReactElement<IReactPnPjsTesterProps> {
return (
<div className={styles.reactPnPjsTester}>
<div className={styles.container}>
<div className={styles.row}>
<div className={styles.column}>
<TooltipHost
content="This webpart will allow SPFx developers to test PnPjs Sharepoint methods and it displays response in JSON viewer to identify properties/attributes returned by method"
id="tooltip"
directionalHint={DirectionalHint.rightCenter}
calloutProps={{ gapSpace: 0 }}
styles={{ root: { display: "inline-block" } }}
>
<h2 style={{ cursor: "pointer" }}>PnPjs Tester
<IconButton iconProps={{ iconName: 'InfoSolid' }} title="InfoSolid" ariaLabel="InfoSolid" />
</h2>
</TooltipHost>
</div>
</div>
<div className={styles.row}>
<div className={styles.col1}>
<Dropdown
selectedKey={this.state.requestType}
onChanged={(val) => {
let isUpdate = val.key === "POST" ? true : false;
this.setState({ isUpdate: isUpdate, requestType: val.text });
}}
className={styles.methodSelector}
options={[
{ key: "GET", text: "GET" },
{ key: "POST", text: "POST" },
]}
/>
</div>
<div className={styles.col11}>
<TextField
value={this.state.pnpCommand}
placeholder="Enter your query here e.g. sp.web.select('Title')"
onChange={(e) => this.setCommand(e.target)}
/>
</div>
</div>
<div className={styles.row}>
<div className={styles.column}>
<Checkbox
label="Use for other Site collection or Subsite"
onChange={(event, checked) => {
this.setState({ isOtherSite: checked });
}}
/>
</div>
<div
className={styles.column}
style={{
display: this.state.isOtherSite ? "block" : "none",
marginTop: 10,
}}
>
<TextField
placeholder="Enter site collection or subsite url"
value={this.state.siteUrl}
onChange={(e) => this.setSiteUrl(e.target)}
/>
</div>
</div>
<div className={styles.row}>
<div className={styles.column}>
<Panel
isLightDismiss
isOpen={this.state.openPanel}
headerText="Samples"
closeButtonAriaLabel="Close"
type={PanelType.custom}
customWidth={"600px"}
>
<p>{this.getPanelCommands()}</p>
</Panel>
   
<DefaultButton
onClick={() => this.executeCommand()}
className={styles.button}
>
<Icon className={styles.icon} iconName="LightningBolt" /> Run
query
</DefaultButton>
<DefaultButton
onClick={() => {
this.setState({ openPanel: true });
}}
className={styles.button}
>
<Icon className={styles.icon} iconName="ReadingMode"></Icon>
Samples
</DefaultButton>
<DefaultButton
onClick={() => {
window.open("https://pnp.github.io/pnpjs/sp/", "__blank");
}}
className={styles.button}
>
<Icon className={styles.icon} iconName="Info"></Icon>About PnPjs
</DefaultButton>
{this.state.jsonResponse && (
<div>
{/* <Checkbox
label="Wrap code"
className={styles.collapse}
onChange={() => this.onCollapseAll()}
checked={this.state.defaultCollapsed}
/> */}
<br></br>
{this.state.jsonResponse &&
<React.Fragment>
<Stack horizontal tokens={{ childrenGap: 25 }}>
<Toggle checked={this.state.displayDataTypes} label="Show Data Types" inlineLabel onChange={() => { this.setState({ displayDataTypes: !this.state.displayDataTypes }); }} />
<Toggle checked={this.state.displayObjectSize} label="Show Count" inlineLabel onChange={() => { this.setState({ displayObjectSize: !this.state.displayObjectSize }); }} />
<Toggle checked={this.state.enableClipboard} label="Enable Clipboard" inlineLabel onChange={() => { this.setState({ enableClipboard: !this.state.enableClipboard }); }}/>
<Toggle checked={this.state.defaultCollapsed} label="Collapse All" inlineLabel onChange={()=>this.onCollapseAll()}/>
{/* <Checkbox className={styles.collapse} label="Collapse All" /> */}
</Stack>
<div className={styles.jsonviewcont}>
<ReactJson src={this.state.jsonResponse} collapsed={this.state.defaultCollapsed} displayDataTypes={this.state.displayDataTypes} displayObjectSize={this.state.displayObjectSize} enableClipboard={this.state.enableClipboard} />
</div>
</React.Fragment>
}
{this.state.errorMessage &&
<div>{JSON.stringify(this.state.errorMessage)} </div>
}
{/* <AceEditor
mode="json"
theme="github"
className={styles.codeZone}
value={JSON.stringify(this.state.jsonResponse, null, 2)}
onChange={this._reqBodyChanged}
highlightActiveLine={true}
editorProps={{ $blockScrolling: true }}
setOptions={{
wrap: this.state.defaultCollapsed,
showPrintMargin: false,
}}
height="500px"
width="100%"
/> */}
</div>
)}
{this.state.errorMessage && (
<div>{JSON.stringify(this.state.errorMessage)} </div>
)}
</div>
</div>
</div>
</div>
);
}
private onCollapseAll = () => {
this.setState({ defaultCollapsed: !this.state.defaultCollapsed });
}
private setCommand = (element) => {
var val = (element as HTMLInputElement).value;
this.setState({ pnpCommand: val });
}
private setSiteUrl = (element) => {
var val = (element as HTMLInputElement).value;
this.setState({ siteUrl: val });
}
private setPnP = () => {
spObj = null;
if (this.state.siteUrl != "" && this.state.isOtherSite) {
sp.setup({
sp: {
headers: {
Accept: "application/json;odata=minimalmetadata",
},
baseUrl: this.state.siteUrl,
},
});
} else {
sp.setup({
spfxContext: this.props.spcontext
});
}
spObj = sp;
}
private executeCommand() {
this.setPnP();
this.setState({ jsonResponse: null, errorMessage: null,openPanel:false });
var command = this.state.pnpCommand;
command = command.replace("sp", "spObj");
command = command.replace(/"/g, "'");
command = command.replace(".get()", "");
command = command.replace(";", "");
command = command.replace("()", "");
var evalString = "try{" + command;
if (!this.state.isUpdate) {
evalString += "()";
}
evalString +=
".then(\
(result) => {\
debugger;\
console.log(result);\
this.setState({jsonResponse:result});\
}\
)\
.catch(\
(error) => {\
debugger;\
console.log(error);\
this.setState({jsonResponse:{error:error.message}});\
}\
);\
}\
catch(e){\
alert(e);\
}";
eval(evalString);
}
private getPanelCommands = () => {
return (
<React.Fragment>
{this.exampleJson.map((item: any, index: number) => (
<div>
<ActionButton
onClick={() => {
this.setState({ pnpCommand: item.command, openPanel: false });
}}
iconProps={{ iconName: "Copy" }}
title="Copy"
ariaLabel="Copy"
>
{item.command}
</ActionButton>
</div>
))}
</React.Fragment>
);
}
}

View File

@ -0,0 +1,49 @@
{
"samples": [
{
"command": "sp.web.select('Title')"
},
{
"command": "sp.web.currentUser.get()"
},
{
"command": "sp.web.lists.getByTitle('My List').items"
},
{
"command": "sp.web.lists.getByTitle('My List').items.select('Title','Description').top(5).orderBy('Modified', true).get()"
},
{
"command": "sp.web.lists.getByTitle('My List').items.getById(1).get()"
},
{
"command": "sp.web.lists.getByTitle('BigList').items.getAll()"
},
{
"command": "sp.web.lists.getByTitle('LookupList').items.getById(1).select('Title','Lookup/Title','Lookup/ID').expand('Lookup').get()"
},
{
"command": "sp.web.lists.getByTitle('Pages').items.select('Title','FileRef','FieldValuesAsText/MetaInfo').expand('FieldValuesAsText').get()"
},
{
"command": "sp.web.lists.getByTitle('CustomList').items.add({Title: 'PnpJS Explorer'})"
},
{
"command": "sp.web.lists.getByTitle('My List').items.getById(1).delete()"
},
{
"command": "sp.web.associatedVisitorGroup()"
},
{
"command": "sp.web.lists.getByTitle('My List').views()"
},
{
"command": "sp.web.lists.getByTitle('My List').views.getByTitle('All Items')()"
},
{
"command": "sp.web.userCustomActions()"
},
{
"command": "sp.web.lists.getByTitle('Documents').rootFolder.folders()"
}
]
}

View File

@ -0,0 +1,7 @@
define([], function() {
return {
"PropertyPaneDescription": "Description",
"BasicGroupName": "Group Name",
"DescriptionFieldLabel": "Description Field"
}
});

View File

@ -0,0 +1,10 @@
declare interface IReactPnPjsTesterWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
}
declare module 'ReactPnPjsTesterWebPartStrings' {
const strings: IReactPnPjsTesterWebPartStrings;
export = strings;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,38 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/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": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

@ -0,0 +1,30 @@
{
"extends": "@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
}
}