Added the pnp-controls sample (#314)
This commit is contained in:
parent
face954dcd
commit
5bb3d181eb
|
@ -0,0 +1,25 @@
|
|||
# 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
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"version": "1.2.0",
|
||||
"libraryName": "component-test",
|
||||
"libraryId": "7d4d5b98-cea3-4361-8e3d-5143d5c86334",
|
||||
"environment": "spo"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
# SharePoint Framework PnP Controls Sample
|
||||
|
||||
## Summary
|
||||
|
||||
This is a sample project that contains a web part which makes use of the PnP SPFx Controls:
|
||||
|
||||
- [SharePoint Framework React Controls](https://www.npmjs.com/package/@pnp/spfx-controls-react)
|
||||
- [SharePoint Framework Property Controls](https://www.npmjs.com/package/@pnp/spfx-property-controls)
|
||||
|
||||
![Web part outcome](./assets/webpart-outcome.gif)
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/drop-1.2.0-green.svg)
|
||||
|
||||
## Which PnP SPFx controls are being used in this sample?
|
||||
|
||||
The sample makes use of the following controls:
|
||||
- PropertyFieldListPicker
|
||||
- PropertyFieldTermPicker
|
||||
- Placeholder
|
||||
- ListView (which also uses the FileTypeIcon control)
|
||||
|
||||
## Applies to
|
||||
|
||||
* [SharePoint Framework](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
pnp-controls|Elio Struyf (MVP, U2U, [@eliostruyf](https://twitter.com/eliostruyf))
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
0.0.1|September 20, 2017|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.**
|
||||
|
||||
---
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
To test out this web part, you need to have a library with a managed metadata field. In my case, I made use of a field called **Country**.
|
||||
|
||||
![Documents](./assets/documents.png)
|
||||
|
||||
Once you have such a library in place, you can copy the code and run the following commands:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
gulp serve --nobrowser
|
||||
```
|
||||
|
||||
![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/pnp-controls)
|
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.5 MiB |
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"pnp-controls-web-part": {
|
||||
"components": [{
|
||||
"entrypoint": "./lib/webparts/pnpControls/PnPControlsWebPart.js",
|
||||
"manifest": "./src/webparts/pnpControls/PnPControlsWebPart.manifest.json"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"PnPControlsWebPartStrings": "lib/webparts/pnpControls/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "component-test",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "component-test-client-side-solution",
|
||||
"id": "7d4d5b98-cea3-4361-8e3d-5143d5c86334",
|
||||
"version": "1.0.0.0",
|
||||
"skipFeatureDeployment": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/component-test.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"https": true,
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/core-build/tslint.schema.json",
|
||||
// Display errors as warnings
|
||||
"displayAsWarning": true,
|
||||
// The TSLint task may have been configured with several custom lint rules
|
||||
// before this config file is read (for example lint rules from the tslint-microsoft-contrib
|
||||
// project). If true, this flag will deactivate any of these rules.
|
||||
"removeExistingRules": true,
|
||||
// When true, the TSLint task is configured with some default TSLint "rules.":
|
||||
"useDefaultConfigAsBase": false,
|
||||
// Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
|
||||
// which are active, other than the list of rules below.
|
||||
"lintConfig": {
|
||||
// Opt-in to Lint rules which help to eliminate bugs in JavaScript
|
||||
"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-case": true,
|
||||
"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,
|
||||
"valid-typeof": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.initialize(gulp);
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "component-test",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "~1.2.0",
|
||||
"@microsoft/sp-webpart-base": "~1.2.0",
|
||||
"@pnp/spfx-controls-react": "1.0.0-beta.2",
|
||||
"@pnp/spfx-property-controls": "1.0.0-beta.1",
|
||||
"@types/react": "15.0.38",
|
||||
"@types/react-addons-shallow-compare": "0.14.17",
|
||||
"@types/react-addons-test-utils": "0.14.15",
|
||||
"@types/react-addons-update": "0.14.14",
|
||||
"@types/react-dom": "0.14.18",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
||||
"moment": "2.18.1",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.2.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.2.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.2.0",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { ICheckedTerms } from "@pnp/spfx-property-controls/lib/PropertyFieldTermPicker";
|
||||
|
||||
export interface IPnPControlsWebPartProps {
|
||||
lists: string | string[]; // Stores the list ID(s)
|
||||
terms: ICheckedTerms; // Keeps hold of the selected terms
|
||||
description: string;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "8909dae1-5562-4f0f-be6c-aa14eac34c66",
|
||||
"alias": "PnPControlsWebPart",
|
||||
"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": "8909dae1-5562-4f0f-be6c-aa14eac34c66",
|
||||
"group": {
|
||||
"default": "Under Development"
|
||||
},
|
||||
"title": {
|
||||
"default": "PnPControls"
|
||||
},
|
||||
"description": {
|
||||
"default": "Web part to test out the PnP SPFx controls"
|
||||
},
|
||||
"iconImageUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAcCAYAAAATFf3WAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAA6ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNy0wOS0xOVQxMjowOTozOTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjY8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzI8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI4PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CjwcPPMAAAP9SURBVFgJnZfLi49RGMdn3GsUCymXDM0wGCHFkin+ABZYTGTkmmxZoazYSuS2UZNEYiFFJJeFRimxYGE0CwvKXe6X7+c3z1dn3jnv/H6/+db397znnOd5zvd5znnfaRob8hip6cZY+iMLc5igyWaxTZwfdoXsAfG0OEr8JQ4bJMjhd2ESvynibLE9OE+2RWR+hJiCAgFFeq2syIpj2U+ZwCUKQMCCYKvsdHG8mAMFIQA7TvwrGhaGUObTNfuU2jKBDxXhI06D2cwbMs+m+NGx9Fq4az81T3Ec80sR4F+zSCeqRCY/JKAbbEByd4jkFGVaoKYGwEV0a/Z58Gh4kDtXfCzXZhBGohzZ3IKL647rkg8d9ZgYfHeIoOzk+leT37IO5ipkE7rJmuPYNAd8KOJtLH4PuzQscc4RU3lTk5NCEYevK7dQhOREModvkwi8T6eeN4s+Ac/jk0VVB0VZ3Fc97xUXi3z31oqfxJxIjpciekUwRnwg3hPPiOdEQG7i6wbJ6QIJqJbnNWIRfZpgzT6+c75rk7W2SaRzfH7AbpGYEwyE0aJPpjJRy48FesOeCJope1t8LB4SX4k5gds0nwOdBQdF4jpEo65OWuAPRZPoQmRZH2PmTLrsZxe0Pfw5WroDEZBeqV6N34iXRTpcFyzQG96JaC499wdB6fGXCSwenQXyV4o33HHYDWLNsEBEuEMrk+iNev4iktj3j2cX5A4WBXp8OGK/yfLyEXtfHARXNGghJjgWBILz4qrKU0PDWdnV8UwONqgHufuWmyvN6Q6ycZH7kqirse7O2ZZ10C/JQsV9KOTekuSt+miBPt6PhWTLI8ORmPfLVBQ41EvyQrHvxeviVjEL34nsoia5X/jcEHmT94uvxT4RTOo3g3595BZsBzpI0ZzCLJErc1OsG+6gO3Mpk2GG5t6JiKEQrAX5Q00BneI6cawIdon4nmIg0IBqjao4pj8W6I35JOwRF4lzRF6QJyIb2Td99pE9Ch/W7orXYnxR1qj2otpvgE035UjYwHRXU0Fecwe75M9xfo44Pif4ELtTNKqKq+qgTLz+iEQ04G8nnYV+K/U4AMSwzrcyRbcGx0X2heQdEmVnT7UpnNDzjBFRBvwQPzEcvE9PjIl3wTGVNzjm4A5wZCSiG66WtaHEafl/l68wENjnpHiMgUC+muDKis4+Oluv0xnfT0S6kxZs68J5e9sj5pkswMcnUZkY6qdM4DIFzRXTfzunadwk5mLoCJtiKcrd5r4+FQGi8alZHEG5zZjnrvi+MMZvqtgq0hFIAS0i/7i7087nTmqpIgxr0TzXDCcsBrChNyExx9oXvCVr8I98s8i3EdFtYofoO0a3hiVMcRX8A255OkxXy9tuAAAAAElFTkSuQmCC",
|
||||
"properties": {
|
||||
"description": "PnPControls",
|
||||
"fieldName": "Country"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneTextField
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
|
||||
import * as strings from 'PnPControlsWebPartStrings';
|
||||
import PnPControls from './components/PnPControls';
|
||||
import { IPnPControlsProps } from './components/IPnPControlsProps';
|
||||
import { IPnPControlsWebPartProps } from './IPnPControlsWebPartProps';
|
||||
|
||||
import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
|
||||
import { PropertyFieldTermPicker } from '@pnp/spfx-property-controls/lib/PropertyFieldTermPicker';
|
||||
|
||||
export default class PnPControlsWebPart extends BaseClientSideWebPart<IPnPControlsWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IPnPControlsProps> = React.createElement(
|
||||
PnPControls,
|
||||
{
|
||||
context: this.context,
|
||||
description: this.properties.description,
|
||||
list: this.properties.lists || "",
|
||||
terms: this.properties.terms || null
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected get disableReactivePropertyChanges(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('description', {
|
||||
label: strings.DescriptionFieldLabel
|
||||
}),
|
||||
PropertyFieldListPicker('lists', {
|
||||
label: 'Select a list',
|
||||
selectedList: this.properties.lists,
|
||||
includeHidden: false,
|
||||
orderBy: PropertyFieldListPickerOrderBy.Title,
|
||||
disabled: false,
|
||||
baseTemplate: 101,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
|
||||
properties: this.properties,
|
||||
context: this.context,
|
||||
onGetErrorMessage: null,
|
||||
deferredValidationTime: 0,
|
||||
key: 'listPickerFieldId'
|
||||
}),
|
||||
PropertyFieldTermPicker('terms', {
|
||||
label: 'Select a term',
|
||||
panelTitle: 'Select a term',
|
||||
initialValues: this.properties.terms,
|
||||
allowMultipleSelections: false,
|
||||
excludeSystemGroup: false,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged,
|
||||
properties: this.properties,
|
||||
context: this.context,
|
||||
onGetErrorMessage: null,
|
||||
deferredValidationTime: 0,
|
||||
key: 'termSetsPickerFieldId'
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { ICheckedTerms } from '@pnp/spfx-property-controls/lib/PropertyFieldTermPicker';
|
||||
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||
|
||||
export interface IPnPControlsProps {
|
||||
context: WebPartContext;
|
||||
description: string;
|
||||
list: string | string[];
|
||||
terms: ICheckedTerms;
|
||||
}
|
||||
|
||||
export interface IPnpControlsState {
|
||||
items?: any[];
|
||||
loading?: boolean;
|
||||
showPlaceholder?: boolean;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
.pnpControls {}
|
|
@ -0,0 +1,161 @@
|
|||
import * as React from 'react';
|
||||
import * as moment from 'moment';
|
||||
import styles from './PnPControls.module.scss';
|
||||
import { IPnPControlsProps, IPnpControlsState } from './IPnPControlsProps';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/components/Spinner';
|
||||
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
||||
import { ListView } from '@pnp/spfx-controls-react/lib/ListView';
|
||||
import { SPHttpClient } from '@microsoft/sp-http';
|
||||
import { IViewField } from '@pnp/spfx-controls-react/lib/controls/listView';
|
||||
|
||||
export default class PnPControls extends React.Component<IPnPControlsProps, IPnpControlsState> {
|
||||
// Specify the fields that need to be viewed in the listview
|
||||
private _viewFields: IViewField[] = [
|
||||
{
|
||||
name: "Id",
|
||||
displayName: "ID",
|
||||
maxWidth: 25,
|
||||
minWidth: 25,
|
||||
sorting: true
|
||||
},
|
||||
{
|
||||
name: "File.Name",
|
||||
linkPropertyName: "File.ServerRelativeUrl",
|
||||
displayName: "Name",
|
||||
sorting: true
|
||||
},
|
||||
{
|
||||
name: "File.TimeCreated",
|
||||
displayName: "Created",
|
||||
minWidth: 150,
|
||||
render: (item: any) => {
|
||||
const created = item["File.TimeCreated"];
|
||||
if (created) {
|
||||
const createdDate = moment(created);
|
||||
return <span>{createdDate.format('DD/MM/YYYY HH:mm:ss')}</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param props
|
||||
*/
|
||||
constructor(props: IPnPControlsProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
items: [],
|
||||
loading: false,
|
||||
showPlaceholder: (this.props.list === null || this.props.list === "")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* componentDidMount lifecycle hook
|
||||
*/
|
||||
public componentDidMount() {
|
||||
if (this.props.list !== null && this.props.list !== "") {
|
||||
this._getListItems();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* componentDidUpdate lifecycle hook
|
||||
* @param nextProps
|
||||
* @param nextState
|
||||
*/
|
||||
public componentDidUpdate(prevProps: IPnPControlsProps, prevState: IPnpControlsState) {
|
||||
if (this.props.list !== prevProps.list || this.props.terms !== prevProps.terms) {
|
||||
if (this.props.list !== null && this.props.list !== "") {
|
||||
this._getListItems();
|
||||
} else {
|
||||
this.setState({
|
||||
showPlaceholder: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves items for the specified list
|
||||
* @param listId
|
||||
*/
|
||||
private _getListItems() {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
|
||||
let restApi = `${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists(guid'${this.props.list.toString()}')/items?$expand=File`;
|
||||
|
||||
// Check if results need to be filtered
|
||||
if (typeof this.props.terms !== "undefined" && this.props.terms !== null && this.props.terms.length > 0) {
|
||||
// Get the first term (single selection)
|
||||
const term = this.props.terms[0];
|
||||
// Add the filter to the restApi URL
|
||||
restApi += `,TaxCatchAll&$select=*,TaxCatchAll/Term&$filter=TaxCatchAll/Term eq '${term.name}'`;
|
||||
}
|
||||
|
||||
this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1)
|
||||
.then(resp => { return resp.json(); })
|
||||
.then(items => {
|
||||
console.log('List Items:', items);
|
||||
this.setState({
|
||||
items: items.value ? items.value : [],
|
||||
loading: false,
|
||||
showPlaceholder: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens the web part property pane
|
||||
*/
|
||||
private _configureWebPart() {
|
||||
this.props.context.propertyPane.open();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* React render method
|
||||
*/
|
||||
public render(): React.ReactElement<IPnPControlsProps> {
|
||||
// Check if placeholder needs to be shown
|
||||
if (this.state.showPlaceholder) {
|
||||
return (
|
||||
<Placeholder
|
||||
iconName="Edit"
|
||||
iconText="List view web part configuration"
|
||||
description="Please configure the web part before you can show the list view."
|
||||
buttonLabel="Configure"
|
||||
onConfigure={this._configureWebPart.bind(this)} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.pnpControls}>
|
||||
{
|
||||
this.state.loading ?
|
||||
(
|
||||
<Spinner size={SpinnerSize.large} label="Retrieving results ..." />
|
||||
) : (
|
||||
this.state.items.length === 0 ?
|
||||
(
|
||||
<Placeholder
|
||||
iconName="InfoSolid"
|
||||
iconText="No items found"
|
||||
description="The list or library you selected does not contain items." />
|
||||
) : (
|
||||
<div>
|
||||
<p className="ms-font-xl">{this.props.description}</p>
|
||||
<ListView items={this.state.items} viewFields={this._viewFields} iconFieldName="File.ServerRelativeUrl" />
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
define([], function () {
|
||||
return {
|
||||
"PropertyPaneDescription": "Web Part Configuration",
|
||||
"BasicGroupName": "PnP Controls",
|
||||
"DescriptionFieldLabel": "List view title"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
declare interface IPnPControlsWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'PnPControlsWebPartStrings' {
|
||||
const strings: IPnPControlsWebPartStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/// <reference types="mocha" />
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
describe('PnPControlsWebPart', () => {
|
||||
it('should do something', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Type definitions for Microsoft ODSP projects
|
||||
// Project: ODSP
|
||||
|
||||
/* Global definition for UNIT_TEST builds
|
||||
Code that is wrapped inside an if(UNIT_TEST) {...}
|
||||
block will not be included in the final bundle when the
|
||||
--ship flag is specified */
|
||||
declare const UNIT_TEST: boolean;
|
||||
|
||||
/* Global defintion for SPO builds */
|
||||
declare const DATACENTER: boolean;
|
|
@ -0,0 +1 @@
|
|||
/// <reference path="@ms/odsp.d.ts" />
|
Loading…
Reference in New Issue