SharePoint CRUD sample updated to SPFx 1.6.0 (#666)
This commit is contained in:
parent
5723134c29
commit
277af705b0
|
@ -1,8 +1,11 @@
|
||||||
{
|
{
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
"version": "1.4.1",
|
"isCreatingSolution": false,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.6.0",
|
||||||
"libraryName": "sharepoint-crud",
|
"libraryName": "sharepoint-crud",
|
||||||
"libraryId": "037cc555-b7cd-4bdc-b661-0b38a09b5844",
|
"libraryId": "1409e8a2-1ce4-4888-87f8-1dc377b6b62e",
|
||||||
"environment": "spo"
|
"packageManager": "npm",
|
||||||
|
"componentType": "webpart"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
Sample Web Parts illustrating performing SharePoint CRUD operations in React, Angular, JavaScript without any framework and using the [SP PnP JS library](https://github.com/OfficeDev/PnP-JS-Core).
|
Sample Web Parts illustrating performing SharePoint CRUD operations in React, Angular, JavaScript without any framework and using the [@pnp/sp library](https://github.com/pnp/pnpjs).
|
||||||
|
|
||||||
![Sample To do SharePoint Framework Client-Side Web Part built using Angular and ngOfficeUIFabric](./assets/preview.png)
|
![Sample To do SharePoint Framework Client-Side Web Part built using Angular and ngOfficeUIFabric](./assets/preview.png)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
![drop](https://img.shields.io/badge/drop-1.4.1-green.svg)
|
![drop](https://img.shields.io/badge/drop-1.6.0-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ sharepoint-crud|Waldek Mastykarz (MVP, Rencore, @waldekm), Gautam Sheth (SharePo
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
|
1.3|November 1, 2018|Updated to SPFx 1.6.0
|
||||||
1.2|March 30, 2018|Updated to SPFx 1.4.1
|
1.2|March 30, 2018|Updated to SPFx 1.4.1
|
||||||
1.1|March 9, 2017|Updated to SPFx GA
|
1.1|March 9, 2017|Updated to SPFx GA
|
||||||
1.0|September 16, 2016|Initial release
|
1.0|September 16, 2016|Initial release
|
||||||
|
@ -58,7 +59,7 @@ This sample illustrates the following concepts on top of the SharePoint Framewor
|
||||||
- in React
|
- in React
|
||||||
- in Angular v1.x
|
- in Angular v1.x
|
||||||
- without a particular JavaScript framework
|
- without a particular JavaScript framework
|
||||||
- using the [SP PnP JS library](https://github.com/OfficeDev/PnP-JS-Core)
|
- using the [@pnp/sp library](https://github.com/PnP/PnPJS)
|
||||||
- using ETag to ensure data integrity when updating and deleting items
|
- using ETag to ensure data integrity when updating and deleting items
|
||||||
- chaining promises for performing multiple asynchronous operations as part of one use case
|
- chaining promises for performing multiple asynchronous operations as part of one use case
|
||||||
- breaking a chain of promises in case of an error and handling it gracefully
|
- breaking a chain of promises in case of an error and handling it gracefully
|
||||||
|
@ -72,8 +73,8 @@ This sample illustrates the following concepts on top of the SharePoint Framewor
|
||||||
- loading Angular and [ngOfficeUIFabric](http://ngofficeuifabric.com) from CDN
|
- loading Angular and [ngOfficeUIFabric](http://ngofficeuifabric.com) from CDN
|
||||||
- using conditional rendering for one-time Web Part setup
|
- using conditional rendering for one-time Web Part setup
|
||||||
- passing Web Part configuration to Angular and reacting to configuration changes in the Angular application
|
- passing Web Part configuration to Angular and reacting to configuration changes in the Angular application
|
||||||
- SP PnP JS library
|
- @pnp/sp library
|
||||||
- using the SP PnP JS library with SharePoint Framework Client-Side Web Parts
|
- using the @pnp/sp JS library with SharePoint Framework Client-Side Web Parts
|
||||||
- configuring global request headers and overriding them for specific requests
|
- configuring global request headers and overriding them for specific requests
|
||||||
- sorting and selecting top n items from a list using the fluent API
|
- sorting and selecting top n items from a list using the fluent API
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/config.2.0.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
"version": "2.0",
|
"version": "2.0",
|
||||||
"bundles": {
|
"bundles": {
|
||||||
"no-framework-crud-web-part": {
|
"no-framework-crud-web-part": {
|
||||||
|
@ -10,11 +10,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sp-pn-p-js-crud-web-part": {
|
"angular-crud-web-part": {
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"entrypoint": "./lib/webparts/spPnPJsCrud/SpPnPJsCrudWebPart.js",
|
"entrypoint": "./lib/webparts/angularCrud/AngularCrudWebPart.js",
|
||||||
"manifest": "./src/webparts/spPnPJsCrud/SpPnPJsCrudWebPart.manifest.json"
|
"manifest": "./src/webparts/angularCrud/AngularCrudWebPart.manifest.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -26,26 +26,26 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"angular-crud-web-part": {
|
"pnpjs-crud-web-part": {
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"entrypoint": "./lib/webparts/angularCrud/AngularCrudWebPart.js",
|
"entrypoint": "./lib/webparts/pnpjsCrud/PnpjsCrudWebPart.js",
|
||||||
"manifest": "./src/webparts/angularCrud/AngularCrudWebPart.manifest.json"
|
"manifest": "./src/webparts/pnpjsCrud/PnpjsCrudWebPart.manifest.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"externals": {
|
"externals": {
|
||||||
"angular": {
|
"angular": {
|
||||||
"path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js",
|
"path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js",
|
||||||
"globalName": "angular"
|
"globalName": "angular"
|
||||||
},
|
},
|
||||||
"ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.16.0/ngOfficeUiFabric.min.js"
|
"ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.16.1/ngOfficeUiFabric.min.js"
|
||||||
},
|
},
|
||||||
"localizedResources": {
|
"localizedResources": {
|
||||||
"NoFrameworkCrudWebPartStrings": "lib/webparts/noFrameworkCrud/loc/{locale}.js",
|
"NoFrameworkCrudWebPartStrings": "lib/webparts/noFrameworkCrud/loc/{locale}.js",
|
||||||
"SpPnPJsCrudWebPartStrings": "lib/webparts/spPnPJsCrud/loc/{locale}.js",
|
"AngularCrudWebPartStrings": "lib/webparts/angularCrud/loc/{locale}.js",
|
||||||
"ReactCrudWebPartStrings": "lib/webparts/reactCrud/loc/{locale}.js",
|
"ReactCrudWebPartStrings": "lib/webparts/reactCrud/loc/{locale}.js",
|
||||||
"AngularCrudWebPartStrings": "lib/webparts/angularCrud/loc/{locale}.js"
|
"PnpjsCrudWebPartStrings": "lib/webparts/pnpjsCrud/loc/{locale}.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||||
"deployCdnPath": "temp/deploy"
|
"deployCdnPath": "temp/deploy"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
"workingDir": "./temp/deploy/",
|
"workingDir": "./temp/deploy/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "sharepoint-crud",
|
"container": "sharepoint-crud",
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "sharepoint-crud-client-side-solution",
|
"name": "sharepoint-crud-client-side-solution",
|
||||||
"id": "c51ba9f2-6f5c-412a-a5fc-76610f39be8c",
|
"id": "1409e8a2-1ce4-4888-87f8-1dc377b6b62e",
|
||||||
"version": "1.1.0.0"
|
"version": "1.0.0.0",
|
||||||
|
"includeClientSideAssets": true
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/sharepoint-crud.sppkg"
|
"zippedPackage": "solution/sharepoint-crud.sppkg"
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||||
"port": 4321,
|
"port": 4321,
|
||||||
"initialPage": "https://localhost:5432/workbench",
|
|
||||||
"https": true,
|
"https": true,
|
||||||
|
"initialPage": "https://localhost:5432/workbench",
|
||||||
"api": {
|
"api": {
|
||||||
"port": 5432,
|
"port": 5432,
|
||||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "sharepoint-crud",
|
"name": "sharepoint-crud",
|
||||||
"version": "1.4.1",
|
"version": "1.6.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
|
@ -15,27 +15,30 @@
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "~1.4.1",
|
"@microsoft/sp-core-library": "1.6.0",
|
||||||
"@microsoft/sp-lodash-subset": "~1.4.1",
|
"@microsoft/sp-lodash-subset": "1.6.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "~1.4.1",
|
"@microsoft/sp-office-ui-fabric-core": "1.6.0",
|
||||||
"@microsoft/sp-webpart-base": "~1.4.1",
|
"@microsoft/sp-webpart-base": "1.6.0",
|
||||||
"@pnp/common": "^1.0.3",
|
"@pnp/common": "^1.2.3",
|
||||||
"@pnp/logging": "^1.0.3",
|
"@pnp/logging": "^1.2.3",
|
||||||
"@pnp/odata": "^1.0.3",
|
"@pnp/odata": "^1.2.3",
|
||||||
"@pnp/sp": "^1.0.3",
|
"@pnp/sp": "^1.2.3",
|
||||||
|
"@types/angular": "^1.6.51",
|
||||||
|
"@types/es6-promise": "0.0.33",
|
||||||
"@types/react": "15.6.6",
|
"@types/react": "15.6.6",
|
||||||
"@types/react-dom": "15.5.6",
|
"@types/react-dom": "15.5.6",
|
||||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
"@types/webpack-env": "1.13.1",
|
||||||
"react": "15.6.2",
|
"react": "15.6.2",
|
||||||
"react-dom": "15.6.2"
|
"react-dom": "15.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "~1.4.1",
|
"@microsoft/sp-build-web": "1.6.0",
|
||||||
"@microsoft/sp-module-interfaces": "~1.4.1",
|
"@microsoft/sp-module-interfaces": "1.6.0",
|
||||||
"@microsoft/sp-webpart-workbench": "~1.4.1",
|
"@microsoft/sp-webpart-workbench": "1.6.0",
|
||||||
|
"tslint-microsoft-contrib": "~5.0.0",
|
||||||
"gulp": "~3.9.1",
|
"gulp": "~3.9.1",
|
||||||
"@types/chai": ">=3.4.34 <3.6.0",
|
"@types/chai": "3.4.34",
|
||||||
"@types/mocha": ">=2.2.33 <2.6.0",
|
"@types/mocha": "2.2.38",
|
||||||
"ajv": "~5.2.2"
|
"ajv": "~5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "cceebf19-128e-4ffd-bb97-9989bf7c04d4",
|
"id": "74208436-1c27-40df-8cb4-1625cd764c2e",
|
||||||
"alias": "AngularCrudWebPart",
|
"alias": "AngularCrudWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
// The "*" signifies that the version should be taken from the package.json
|
// The "*" signifies that the version should be taken from the package.json
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
"default": "Angular CRUD"
|
"default": "Angular CRUD"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"default": "Sample implementation of SharePoint CRUD operations in Angular"
|
"default": "Sample implementation of SharePoint CRUD operations in AngularJS (1.x)"
|
||||||
},
|
},
|
||||||
"officeFabricIconFontName": "Page",
|
"officeFabricIconFontName": "Page",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
background-color: $ms-color-themeDark;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,38 +20,61 @@
|
||||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
:global .ms-Button {
|
.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
|
// Our button
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
||||||
// Primary Button
|
// Primary Button
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
background-color: #0078d7;
|
background-color: $ms-color-themePrimary;
|
||||||
border-color: #0078d7;
|
border-color: $ms-color-themePrimary;
|
||||||
|
color: $ms-color-white;
|
||||||
|
|
||||||
// Basic Button
|
// Basic Button
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
font-weight: 400;
|
font-weight: $ms-font-weight-regular;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|
||||||
:global .ms-Button-label {
|
.label {
|
||||||
font-weight: 600;
|
font-weight: $ms-font-weight-semibold;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled, &:disabled {
|
&.disabled, &:disabled {
|
||||||
|
|
|
@ -11,11 +11,13 @@ import * as strings from 'AngularCrudWebPartStrings';
|
||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import './app/app-module';
|
import './app/app-module';
|
||||||
|
|
||||||
|
|
||||||
export interface IAngularCrudWebPartProps {
|
export interface IAngularCrudWebPartProps {
|
||||||
listName: string;
|
listName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class AngularCrudWebPart extends BaseClientSideWebPart<IAngularCrudWebPartProps> {
|
export default class AngularCrudWebPart extends BaseClientSideWebPart<IAngularCrudWebPartProps> {
|
||||||
|
|
||||||
private $injector: angular.auto.IInjectorService;
|
private $injector: angular.auto.IInjectorService;
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define([], function () {
|
define([], function() {
|
||||||
return {
|
return {
|
||||||
"PropertyPaneDescription": "Configure settings",
|
"PropertyPaneDescription": "Configure settings",
|
||||||
"DataGroupName": "Data",
|
"DataGroupName": "Data",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "dd6cd5e1-46e0-46cc-a0c9-be9e9adedcad",
|
"id": "b724fd00-ee58-451d-95e1-8d496e6121f6",
|
||||||
"alias": "NoFrameworkCrudWebPart",
|
"alias": "NoFrameworkCrudWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
// The "*" signifies that the version should be taken from the package.json
|
// The "*" signifies that the version should be taken from the package.json
|
||||||
|
|
|
@ -8,13 +8,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
background-color: $ms-color-themeDark;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItem {
|
.column {
|
||||||
max-width: 715px;
|
@include ms-Grid-col;
|
||||||
margin: 5px auto 5px auto;
|
@include ms-lg10;
|
||||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
@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 {
|
.button {
|
||||||
|
@ -24,16 +44,17 @@
|
||||||
|
|
||||||
// Primary Button
|
// Primary Button
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
background-color: #0078d7;
|
background-color: $ms-color-themePrimary;
|
||||||
border-color: #0078d7;
|
border-color: $ms-color-themePrimary;
|
||||||
|
color: $ms-color-white;
|
||||||
|
|
||||||
// Basic Button
|
// Basic Button
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
font-weight: 400;
|
font-weight: $ms-font-weight-regular;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -41,14 +62,13 @@
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-weight: 600;
|
font-weight: $ms-font-weight-semibold;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled, &:disabled {
|
&.disabled, &:disabled {
|
||||||
|
@ -61,5 +81,6 @@
|
||||||
color: #a6a6a6;
|
color: #a6a6a6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,17 +4,22 @@ import {
|
||||||
IPropertyPaneConfiguration,
|
IPropertyPaneConfiguration,
|
||||||
PropertyPaneTextField
|
PropertyPaneTextField
|
||||||
} from '@microsoft/sp-webpart-base';
|
} from '@microsoft/sp-webpart-base';
|
||||||
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
|
||||||
import { IListItem } from './IListItem';
|
|
||||||
|
|
||||||
import styles from './NoFrameworkCrudWebPart.module.scss';
|
import styles from './NoFrameworkCrudWebPart.module.scss';
|
||||||
import * as strings from 'NoFrameworkCrudWebPartStrings';
|
import * as strings from 'NoFrameworkCrudWebPartStrings';
|
||||||
|
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
||||||
|
|
||||||
export interface INoFrameworkCrudWebPartProps {
|
export interface INoFrameworkCrudWebPartProps {
|
||||||
listName: string;
|
listName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IListItem {
|
||||||
|
Title?: string;
|
||||||
|
Id: number;
|
||||||
|
}
|
||||||
|
|
||||||
export default class NoFrameworkCrudWebPart extends BaseClientSideWebPart<INoFrameworkCrudWebPartProps> {
|
export default class NoFrameworkCrudWebPart extends BaseClientSideWebPart<INoFrameworkCrudWebPartProps> {
|
||||||
|
|
||||||
private listItemEntityTypeName: string = undefined;
|
private listItemEntityTypeName: string = undefined;
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
@ -95,32 +100,6 @@ export default class NoFrameworkCrudWebPart extends BaseClientSideWebPart<INoFra
|
||||||
this.domElement.querySelector('button.delete-Button').addEventListener('click', () => { webPart.deleteItem(); });
|
this.domElement.querySelector('button.delete-Button').addEventListener('click', () => { webPart.deleteItem(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get dataVersion(): Version {
|
|
||||||
return Version.parse('1.0');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
|
||||||
return {
|
|
||||||
pages: [
|
|
||||||
{
|
|
||||||
header: {
|
|
||||||
description: strings.PropertyPaneDescription
|
|
||||||
},
|
|
||||||
groups: [
|
|
||||||
{
|
|
||||||
groupName: strings.DataGroupName,
|
|
||||||
groupFields: [
|
|
||||||
PropertyPaneTextField('listName', {
|
|
||||||
label: strings.ListNameFieldLabel
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private listNotConfigured(): boolean {
|
private listNotConfigured(): boolean {
|
||||||
return this.properties.listName === undefined ||
|
return this.properties.listName === undefined ||
|
||||||
this.properties.listName === null ||
|
this.properties.listName === null ||
|
||||||
|
@ -375,4 +354,30 @@ export default class NoFrameworkCrudWebPart extends BaseClientSideWebPart<INoFra
|
||||||
private updateItemsHtml(items: IListItem[]): void {
|
private updateItemsHtml(items: IListItem[]): void {
|
||||||
this.domElement.querySelector('.items').innerHTML = items.map(item => `<li>${item.Title} (${item.Id})</li>`).join("");
|
this.domElement.querySelector('.items').innerHTML = items.map(item => `<li>${item.Title} (${item.Id})</li>`).join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get dataVersion(): Version {
|
||||||
|
return Version.parse('1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
return {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
header: {
|
||||||
|
description: strings.PropertyPaneDescription
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
groupName: strings.DataGroupName,
|
||||||
|
groupFields: [
|
||||||
|
PropertyPaneTextField('listName', {
|
||||||
|
label: strings.ListNameFieldLabel
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define([], function () {
|
define([], function() {
|
||||||
return {
|
return {
|
||||||
"PropertyPaneDescription": "Configure settings",
|
"PropertyPaneDescription": "Configure settings",
|
||||||
"DataGroupName": "Data",
|
"DataGroupName": "Data",
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
"id": "8019d2e5-c480-4ecd-a8ac-f59ac457af96",
|
||||||
|
"alias": "PnpjsCrudWebPart",
|
||||||
|
"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,
|
||||||
|
"preconfiguredEntries": [
|
||||||
|
{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
"group": {
|
||||||
|
"default": "Under Development"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"default": "PnP JS CRUD"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"default": "Sample implementation of SharePoint CRUD operations using @pnp/sp library"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"listName": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||||
|
|
||||||
|
.pnpjsCrud {
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled, &:disabled {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border-color: #f4f4f4;
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #a6a6a6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,288 @@
|
||||||
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
|
import {
|
||||||
|
BaseClientSideWebPart,
|
||||||
|
IPropertyPaneConfiguration,
|
||||||
|
PropertyPaneTextField
|
||||||
|
} from '@microsoft/sp-webpart-base';
|
||||||
|
|
||||||
|
import styles from './PnpjsCrudWebPart.module.scss';
|
||||||
|
import * as strings from 'PnpjsCrudWebPartStrings';
|
||||||
|
import { sp, Item, ItemAddResult, ItemUpdateResult } from '@pnp/sp';
|
||||||
|
|
||||||
|
export interface IPnpjsCrudWebPartProps {
|
||||||
|
listName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IListItem {
|
||||||
|
Title?: string;
|
||||||
|
Id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PnpjsCrudWebPart extends BaseClientSideWebPart<IPnpjsCrudWebPartProps> {
|
||||||
|
|
||||||
|
protected onInit(): Promise<void> {
|
||||||
|
return new Promise<void>((resolve: () => void, reject: (error?: any) => void): void => {
|
||||||
|
sp.setup({
|
||||||
|
sp: {
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json; odata=nometadata"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): void {
|
||||||
|
this.domElement.innerHTML = `
|
||||||
|
<div class="${styles.pnpjsCrud}">
|
||||||
|
<div class="${styles.container}">
|
||||||
|
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||||
|
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||||
|
<span class="ms-font-xl ms-fontColor-white">
|
||||||
|
Sample SharePoint CRUD operations using the SP PnP JS library
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||||
|
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||||
|
<button class="${styles.button} create-Button">
|
||||||
|
<span class="${styles.label}">Create item</span>
|
||||||
|
</button>
|
||||||
|
<button class="${styles.button} read-Button">
|
||||||
|
<span class="${styles.label}">Read item</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||||
|
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||||
|
<button class="${styles.button} readall-Button">
|
||||||
|
<span class="${styles.label}">Read all items</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||||
|
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||||
|
<button class="${styles.button} update-Button">
|
||||||
|
<span class="${styles.label}">Update item</span>
|
||||||
|
</button>
|
||||||
|
<button class="${styles.button} delete-Button">
|
||||||
|
<span class="${styles.label}">Delete item</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||||
|
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||||
|
<div class="status"></div>
|
||||||
|
<ul class="items"><ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
this.updateStatus(this.listNotConfigured() ? 'Please configure list in Web Part properties' : 'Ready');
|
||||||
|
this.setButtonsState();
|
||||||
|
this.setButtonsEventHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private setButtonsState(): void {
|
||||||
|
const buttons: NodeListOf<Element> = this.domElement.querySelectorAll(`button.${styles.button}`);
|
||||||
|
const listNotConfigured: boolean = this.listNotConfigured();
|
||||||
|
|
||||||
|
for (let i: number = 0; i < buttons.length; i++) {
|
||||||
|
const button: Element = buttons.item(i);
|
||||||
|
if (listNotConfigured) {
|
||||||
|
button.setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
button.removeAttribute('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setButtonsEventHandlers(): void {
|
||||||
|
const webPart: PnpjsCrudWebPart = this;
|
||||||
|
this.domElement.querySelector('button.create-Button').addEventListener('click', () => { webPart.createItem(); });
|
||||||
|
this.domElement.querySelector('button.read-Button').addEventListener('click', () => { webPart.readItem(); });
|
||||||
|
this.domElement.querySelector('button.readall-Button').addEventListener('click', () => { webPart.readItems(); });
|
||||||
|
this.domElement.querySelector('button.update-Button').addEventListener('click', () => { webPart.updateItem(); });
|
||||||
|
this.domElement.querySelector('button.delete-Button').addEventListener('click', () => { webPart.deleteItem(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
private listNotConfigured(): boolean {
|
||||||
|
return this.properties.listName === undefined ||
|
||||||
|
this.properties.listName === null ||
|
||||||
|
this.properties.listName.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private createItem(): void {
|
||||||
|
this.updateStatus('Creating item...');
|
||||||
|
sp.web.lists.getByTitle(this.properties.listName).items.add({
|
||||||
|
'Title': `Item ${new Date()}`
|
||||||
|
}).then((result: ItemAddResult): void => {
|
||||||
|
const item: IListItem = result.data as IListItem;
|
||||||
|
this.updateStatus(`Item '${item.Title}' (ID: ${item.Id}) successfully created`);
|
||||||
|
}, (error: any): void => {
|
||||||
|
this.updateStatus('Error while creating the item: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readItem(): void {
|
||||||
|
this.updateStatus('Loading latest items...');
|
||||||
|
this.getLatestItemId()
|
||||||
|
.then((itemId: number): Promise<IListItem> => {
|
||||||
|
if (itemId === -1) {
|
||||||
|
throw new Error('No items found in the list');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateStatus(`Loading information about item ID: ${itemId}...`);
|
||||||
|
return sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.getById(itemId).select('Title', 'Id').get();
|
||||||
|
})
|
||||||
|
.then((item: IListItem): void => {
|
||||||
|
this.updateStatus(`Item ID: ${item.Id}, Title: ${item.Title}`);
|
||||||
|
}, (error: any): void => {
|
||||||
|
this.updateStatus('Loading latest item failed with error: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getLatestItemId(): Promise<number> {
|
||||||
|
return new Promise<number>((resolve: (itemId: number) => void, reject: (error: any) => void): void => {
|
||||||
|
sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.orderBy('Id', false).top(1).select('Id').get()
|
||||||
|
.then((items: { Id: number }[]): void => {
|
||||||
|
if (items.length === 0) {
|
||||||
|
resolve(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(items[0].Id);
|
||||||
|
}
|
||||||
|
}, (error: any): void => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readItems(): void {
|
||||||
|
this.updateStatus('Loading all items...');
|
||||||
|
sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.select('Title', 'Id').get()
|
||||||
|
.then((items: IListItem[]): void => {
|
||||||
|
this.updateStatus(`Successfully loaded ${items.length} items`, items);
|
||||||
|
}, (error: any): void => {
|
||||||
|
this.updateStatus('Loading all items failed with error: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateItem(): void {
|
||||||
|
this.updateStatus('Loading latest items...');
|
||||||
|
let latestItemId: number = undefined;
|
||||||
|
let etag: string = undefined;
|
||||||
|
|
||||||
|
this.getLatestItemId()
|
||||||
|
.then((itemId: number): Promise<Item> => {
|
||||||
|
if (itemId === -1) {
|
||||||
|
throw new Error('No items found in the list');
|
||||||
|
}
|
||||||
|
|
||||||
|
latestItemId = itemId;
|
||||||
|
this.updateStatus(`Loading information about item ID: ${itemId}...`);
|
||||||
|
return sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.getById(itemId).get(undefined, {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json;odata=minimalmetadata'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then((item: Item): Promise<IListItem> => {
|
||||||
|
etag = item["odata.etag"];
|
||||||
|
return Promise.resolve((item as any) as IListItem);
|
||||||
|
})
|
||||||
|
.then((item: IListItem): Promise<ItemUpdateResult> => {
|
||||||
|
return sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.getById(item.Id).update({
|
||||||
|
'Title': `Item ${new Date()}`
|
||||||
|
}, etag);
|
||||||
|
})
|
||||||
|
.then((result: ItemUpdateResult): void => {
|
||||||
|
this.updateStatus(`Item with ID: ${latestItemId} successfully updated`);
|
||||||
|
}, (error: any): void => {
|
||||||
|
this.updateStatus('Loading latest item failed with error: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private deleteItem(): void {
|
||||||
|
if (!window.confirm('Are you sure you want to delete the latest item?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateStatus('Loading latest items...');
|
||||||
|
let latestItemId: number = undefined;
|
||||||
|
let etag: string = undefined;
|
||||||
|
this.getLatestItemId()
|
||||||
|
.then((itemId: number): Promise<Item> => {
|
||||||
|
if (itemId === -1) {
|
||||||
|
throw new Error('No items found in the list');
|
||||||
|
}
|
||||||
|
|
||||||
|
latestItemId = itemId;
|
||||||
|
this.updateStatus(`Loading information about item ID: ${latestItemId}...`);
|
||||||
|
return sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.getById(latestItemId).select('Id').get(undefined, {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json;odata=minimalmetadata'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then((item: Item): Promise<IListItem> => {
|
||||||
|
etag = item["odata.etag"];
|
||||||
|
return Promise.resolve((item as any) as IListItem);
|
||||||
|
})
|
||||||
|
.then((item: IListItem): Promise<void> => {
|
||||||
|
this.updateStatus(`Deleting item with ID: ${latestItemId}...`);
|
||||||
|
return sp.web.lists.getByTitle(this.properties.listName)
|
||||||
|
.items.getById(item.Id).delete(etag);
|
||||||
|
})
|
||||||
|
.then((): void => {
|
||||||
|
this.updateStatus(`Item with ID: ${latestItemId} successfully deleted`);
|
||||||
|
}, (error: any): void => {
|
||||||
|
this.updateStatus(`Error deleting item: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateStatus(status: string, items: IListItem[] = []): void {
|
||||||
|
this.domElement.querySelector('.status').innerHTML = status;
|
||||||
|
this.updateItemsHtml(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateItemsHtml(items: IListItem[]): void {
|
||||||
|
this.domElement.querySelector('.items').innerHTML = items.map(item => `<li>${item.Title} (${item.Id})</li>`).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get dataVersion(): Version {
|
||||||
|
return Version.parse('1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
return {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
header: {
|
||||||
|
description: strings.PropertyPaneDescription
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
groupName: strings.DataGroupName,
|
||||||
|
groupFields: [
|
||||||
|
PropertyPaneTextField('listName', {
|
||||||
|
label: strings.ListNameFieldLabel
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"PropertyPaneDescription": "Configure settings",
|
||||||
|
"DataGroupName": "Data",
|
||||||
|
"ListNameFieldLabel": "List Name"
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,10 @@
|
||||||
|
declare interface IPnpjsCrudWebPartStrings {
|
||||||
|
PropertyPaneDescription: string;
|
||||||
|
DataGroupName: string;
|
||||||
|
ListNameFieldLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'PnpjsCrudWebPartStrings' {
|
||||||
|
const strings: IPnpjsCrudWebPartStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "b1900cc3-964d-40be-95bc-633843494258",
|
"id": "3d06d75b-c339-4c4c-9fd6-ea6807f6dd1b",
|
||||||
"alias": "ReactCrudWebPart",
|
"alias": "ReactCrudWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
// The "*" signifies that the version should be taken from the package.json
|
// The "*" signifies that the version should be taken from the package.json
|
||||||
|
|
|
@ -30,6 +30,10 @@ export default class ReactCrudWebPart extends BaseClientSideWebPart<IReactCrudWe
|
||||||
ReactDom.render(element, this.domElement);
|
ReactDom.render(element, this.domElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected onDispose(): void {
|
||||||
|
ReactDom.unmountComponentAtNode(this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
protected get dataVersion(): Version {
|
protected get dataVersion(): Version {
|
||||||
return Version.parse('1.0');
|
return Version.parse('1.0');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export interface IListItem {
|
export interface IListItem {
|
||||||
Title?: string;
|
Title?: string;
|
||||||
Id: number;
|
Id: number;
|
||||||
}
|
}
|
|
@ -4,4 +4,4 @@ export interface IReactCrudProps {
|
||||||
listName: string;
|
listName: string;
|
||||||
spHttpClient: SPHttpClient;
|
spHttpClient: SPHttpClient;
|
||||||
siteUrl: string;
|
siteUrl: string;
|
||||||
}
|
}
|
|
@ -8,13 +8,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
background-color: $ms-color-themeDark;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItem {
|
.column {
|
||||||
max-width: 715px;
|
@include ms-Grid-col;
|
||||||
margin: 5px auto 5px auto;
|
@include ms-lg10;
|
||||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
@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 {
|
.button {
|
||||||
|
@ -24,16 +44,17 @@
|
||||||
|
|
||||||
// Primary Button
|
// Primary Button
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
background-color: #0078d7;
|
background-color: $ms-color-themePrimary;
|
||||||
border-color: #0078d7;
|
border-color: $ms-color-themePrimary;
|
||||||
|
color: $ms-color-white;
|
||||||
|
|
||||||
// Basic Button
|
// Basic Button
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
font-weight: 400;
|
font-weight: $ms-font-weight-regular;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -41,14 +62,13 @@
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-weight: 600;
|
font-weight: $ms-font-weight-semibold;
|
||||||
font-size: 14px;
|
font-size: $ms-font-size-m;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled, &:disabled {
|
&.disabled, &:disabled {
|
||||||
|
@ -61,5 +81,6 @@
|
||||||
color: #a6a6a6;
|
color: #a6a6a6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ import { IListItem } from './IListItem';
|
||||||
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
||||||
|
|
||||||
export default class ReactCrud extends React.Component<IReactCrudProps, IReactCrudState> {
|
export default class ReactCrud extends React.Component<IReactCrudProps, IReactCrudState> {
|
||||||
|
|
||||||
private listItemEntityTypeName: string = undefined;
|
private listItemEntityTypeName: string = undefined;
|
||||||
|
|
||||||
constructor(props: IReactCrudProps, state: IReactCrudState) {
|
constructor(props: IReactCrudProps, state: IReactCrudState) {
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "commonjs",
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types",
|
"./node_modules/@types",
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
|
@ -21,5 +23,12 @@
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,32 @@
|
||||||
{
|
{
|
||||||
"rulesDirectory": "./config"
|
"rulesDirectory": [
|
||||||
|
"tslint-microsoft-contrib"
|
||||||
|
],
|
||||||
|
"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