Merge pull request #2 from pnp/master

Get the latest
This commit is contained in:
Ravi Chandra 2021-01-05 13:49:06 -08:00 committed by GitHub
commit 769ca40646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1014 changed files with 530461 additions and 100671 deletions

4
.gitignore vendored
View File

@ -32,4 +32,6 @@ obj
# Styles Generated Code
*.scss.ts
packages/
packages/
samples/react-teams-send-notification/MyNotes.md
samples/react-teams-send-notification/teams/teams.zip

View File

@ -1,14 +1,23 @@
# title of the sample
# Title of the sample
> This is how you want the sample to appear in the samples browser.
> When naming your sample, try to give it a friendly name that describes what it does. Avoid using terms like `SharePoint` and `WebPart` -- because that's what all the samples in this repo is all about. Also, don't use `React`, `Angular`, `JavaScript`, etc. in your sample title -- unless that's what the sample is about.
## Summary
Short summary on functionality and used technologies.
[picture of the web part in action]
> Please provide a high-quality screenshot of your web parts below. It should be stored in a folder called `assets`.
> If possible, use a resolution of 1920x1080.
> If your web part uses a placeholder screen and requires the user to configure it, please use a screenshot of the web part as it appears **after** it has been configured.
> You can add as many screen shots as you'd like to help users understand your web part without having to download it and install it.
> DELETE THIS PARAGRAPH BEFORE SUBMITTING
![picture of the web part in action](assets/preview.png)
## Used SharePoint Framework Version
![1.10.0](https://img.shields.io/badge/version-1.10.0-green.svg)
![SPFx 1.11.0](https://img.shields.io/badge/version-1.11.0-green.svg)
## Applies to

View File

@ -3450,8 +3450,8 @@ inherits@2.0.1:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
ini@^1.3.4, ini@~1.3.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
version "1.3.7"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
inpath@~1.0.2:
version "1.0.2"

View File

@ -15,7 +15,7 @@ extensions:
createdDate: 2/15/2020 12:00:00 AM
---
# AngularJS Greeting client-side web part
# AngularJS Greeting
## Summary

View File

@ -17,7 +17,7 @@ extensions:
- AngularJS
createdDate: 2/16/2017 12:00:00 AM
---
## Angular MS Graph Web Part Built with Angular v1.x
# Angular MS Graph Web Part Built with Angular v1.x
## Summary
This is a sample MS Graph web part that connects to Microsoft Graph and pulls SharePoint information from your

View File

@ -20,7 +20,7 @@ extensions:
Set of sample web parts illustrating how to use Angular Elements in the SharePoint Framework.
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-1.4.1-green.svg)
![SPFx 1.4.1](https://img.shields.io/badge/spfx-1.4.1-green.svg)
## Applies to
@ -67,4 +67,4 @@ This web part illustrates the following concepts on top of the SharePoint Framew
* calling the SharePoint REST API from an Angular Element using PnPjs
* calling the Microsoft Graph from an Angular Element using PnPjs
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/angularelements-helloworld" />
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/angularelements-helloworld" />

View File

@ -14,7 +14,7 @@ extensions:
- jQuery
createdDate: 5/1/2017 12:00:00 AM
---
## Bootstrap Slider Built with jQuery v1.x and Boostrap v3.x
# Bootstrap Slider Built with jQuery v1.x and Boostrap v3.x
## Summary
Sample bootstrap slider which pulls the slides from a list inside the SharePoint site. The list is automatically deployed once the app is installed in the SharePoint site.

View File

@ -13,7 +13,7 @@ extensions:
- Handlebars
createdDate: 3/5/2017 12:00:00 AM
---
## SPFx Sample with Handlebars.js
# SPFx Sample with Handlebars.js
This sample demonstrate how to set up SPFx to use [Handlebars](http://handlebarsjs.com) through [webpack loader](https://webpack.github.io/docs/loaders.html).

View File

@ -15,7 +15,7 @@ extensions:
- JQuery
createdDate: 1/1/2016 12:00:00 AM
---
# JQuery, Photopile.JS & Office UI Fabric Client-Side Web Part
# JQuery, Photopile.JS & Office UI Fabric Client-Side Web Part
## Summary
@ -83,4 +83,4 @@ This web part illustrates the following concepts on top of the SharePoint Framew
* Etc.
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/jquery-photopile" />
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/jquery-photopile" />

View File

@ -11,7 +11,7 @@ extensions:
- SharePoint Framework
createdDate: 5/15/2017 12:00:00 AM
---
# Display List JavaScript Client-Side Web Part
# Display List
## Summary

View File

@ -13,7 +13,7 @@ extensions:
- react
createdDate: 8/1/2017 12:00:00 AM
---
# Display Employee Spotlight JavaScript Client-Side Web Part
# Employee Spotlight
## Summary
Simple Web Part that demonstrates the use of SharePoint Framework for show casing Employee Spotlight. The web part pulls data from a configured list and User Profile service.

View File

@ -4348,8 +4348,8 @@ inherits@^2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
ini@^1.3.4, ini@~1.3.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
version "1.3.7"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
inline-style-prefixer@^3.0.6:
version "3.0.8"

View File

@ -1,11 +1,11 @@
# GitHub Badge
# GitHub Badge (JavaScript version)
## Summary
Displays information from GitHub for a specified user.
![drop](./assets/1.png)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/version-GA-green.svg)
![SPFx 1.8.0](https://img.shields.io/badge/version-1.8.0-green.svg)
## Applies to
@ -50,4 +50,4 @@ Future samples will refactor this into something more professional that follows
Ultimately, this sample along with its yet-to-be-created future samples could be a useful teaching tool to developers new to SPFx as well as developers who aren't well-versed in SPFx coding patterns or the various frameworks available.
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-gitHubBadge" />
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-gitHubBadge" />

View File

@ -1,4 +1,4 @@
# SPFx My Flows Web Part
# My Flows
## Summary

View File

@ -14,54 +14,54 @@ extensions:
- JQuery
createdDate: 1/1/2016 12:00:00 AM
---
# Embed a PowerBI report in a Client-Side Web Part
## Summary
This sample SharePoint Framework client-side web part embedding a PowerBI report using PowerBI Embedded without any server-side code.
![PowerBI Embedded Client-SideWeb Part in the SharePoint Workbench](./assets/screenshot_powerbi_embedded_spfx.png)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-drop2-red.svg)
## Solution
Solution|Author(s)
--------|---------
powerbi-embedded|Roland Oldengarm (Provoke Solutions, @rolandoldengarm)
## Version history
Version|Date|Comments
-------|----|--------
1.0|September 13, 2016|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.**
---
## Prerequisites
- Created a Workspace and a Workspace collection in Azure
- PowerBI report saved as PBIX
- PBIX uploaded to the Workspace
- Report Access Token generated
Please refer to [this blog post](http://rolandoldengarm.com/index.php/2016/09/13/part-3-how-to-embed-a-power-bi-report-in-sharepoint-with-the-sharepoint-framework/) for detailed instructions how to do this.
## Minimal Path to Awesome
- clone this repo
- `$ npm i`
- `$ gulp serve`
## Features
The _PowerBI Embedded_ Client-Side Web Part is built on the SharePoint Framework using React and uses [PowerBI Embedded](https://azure.microsoft.com/en-us/services/power-bi-embedded/) to securely display a report.
All authentication and rendering happens client-side, there is no server-side component required.
It uses the [PowerBI Client](https://www.npmjs.com/package/powerbi-client) for rendering the PowerBI report.
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-powerbi-embedded" />
# Embed a PowerBI Report
## Summary
This sample SharePoint Framework client-side web part embedding a PowerBI report using PowerBI Embedded without any server-side code.
![PowerBI Embedded Client-SideWeb Part in the SharePoint Workbench](./assets/screenshot_powerbi_embedded_spfx.png)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-drop2-red.svg)
## Solution
Solution|Author(s)
--------|---------
powerbi-embedded|Roland Oldengarm (Provoke Solutions, @rolandoldengarm)
## Version history
Version|Date|Comments
-------|----|--------
1.0|September 13, 2016|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.**
---
## Prerequisites
- Created a Workspace and a Workspace collection in Azure
- PowerBI report saved as PBIX
- PBIX uploaded to the Workspace
- Report Access Token generated
Please refer to [this blog post](http://rolandoldengarm.com/index.php/2016/09/13/part-3-how-to-embed-a-power-bi-report-in-sharepoint-with-the-sharepoint-framework/) for detailed instructions how to do this.
## Minimal Path to Awesome
- clone this repo
- `$ npm i`
- `$ gulp serve`
## Features
The _PowerBI Embedded_ Client-Side Web Part is built on the SharePoint Framework using React and uses [PowerBI Embedded](https://azure.microsoft.com/en-us/services/power-bi-embedded/) to securely display a report.
All authentication and rendering happens client-side, there is no server-side component required.
It uses the [PowerBI Client](https://www.npmjs.com/package/powerbi-client) for rendering the PowerBI report.
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-powerbi-embedded" />

View File

@ -1,4 +1,4 @@
# JS Property Controls SVG
# Dynamic Scalable Vector Graphics (SVG) image using propertie
## Summary
An SPFx webpart that displays a Scalable Vector Graphics (SVG) image using properties to customize how it is rendered. The webpart utilizes the PnP SPFx Property Controls package (specifially the SpinButton and ColorPicker) to set these properties.
@ -54,4 +54,4 @@ This Web Part illustrates the following concepts on top of the SharePoint Framew
![Screenshot](./assets/js-propertycontrols-svg.png)
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-propertycontrols-svg" />
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-propertycontrols-svg" />

View File

@ -26,7 +26,7 @@ Note: This approach will not "pollute" your solution with additional resources o
## Used SharePoint Framework Version
![1.10.0](https://img.shields.io/badge/drop-1.10.0-green.svg)
![1.11.0](https://img.shields.io/badge/drop-1.11.0-green.svg)
## Applies to

View File

@ -5,7 +5,14 @@
"id": "5d6f4a5a-9d2b-4a93-a283-16b8f5ea75d6",
"version": "1.5.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true
"skipFeatureDeployment": true,
"developer": {
"name": "Contoso",
"privacyUrl": "https://contoso.com/privacy",
"termsOfUseUrl": "https://contoso.com/terms-of-use",
"websiteUrl": "https://contoso.com/my-app",
"mpnId": "000000"
}
},
"paths": {
"zippedPackage": "solution/workbench-customizer.sppkg"

View File

@ -1,6 +1,6 @@
{
"name": "workbench-customizer",
"version": "1.4.0",
"version": "1.5.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,338 +0,0 @@
# Upgrade project C:\Users\joelf\dev\GitHub\sp-dev-fx-webparts\samples\js-workbench-customizer to v1.10.0
Date: 1/21/2020
## Findings
Following is the list of steps required to upgrade your project to SharePoint Framework version 1.10.0. [Summary](#Summary) of the modifications is included at the end of the report.
### FN001001 @microsoft/sp-core-library | Required
Upgrade SharePoint Framework dependency package @microsoft/sp-core-library
Execute the following command:
```sh
pnpm i -E @microsoft/sp-core-library@1.10.0
```
File: [./package.json](./package.json)
### FN001002 @microsoft/sp-lodash-subset | Required
Upgrade SharePoint Framework dependency package @microsoft/sp-lodash-subset
Execute the following command:
```sh
pnpm i -E @microsoft/sp-lodash-subset@1.10.0
```
File: [./package.json](./package.json)
### FN001003 @microsoft/sp-office-ui-fabric-core | Required
Upgrade SharePoint Framework dependency package @microsoft/sp-office-ui-fabric-core
Execute the following command:
```sh
pnpm i -E @microsoft/sp-office-ui-fabric-core@1.10.0
```
File: [./package.json](./package.json)
### FN001004 @microsoft/sp-webpart-base | Required
Upgrade SharePoint Framework dependency package @microsoft/sp-webpart-base
Execute the following command:
```sh
pnpm i -E @microsoft/sp-webpart-base@1.10.0
```
File: [./package.json](./package.json)
### FN001021 @microsoft/sp-property-pane | Required
Install SharePoint Framework dependency package @microsoft/sp-property-pane
Execute the following command:
```sh
pnpm i -E @microsoft/sp-property-pane@1.10.0
```
File: [./package.json](./package.json)
### FN002001 @microsoft/sp-build-web | Required
Upgrade SharePoint Framework dev dependency package @microsoft/sp-build-web
Execute the following command:
```sh
pnpm i -DE @microsoft/sp-build-web@1.10.0
```
File: [./package.json](./package.json)
### FN002002 @microsoft/sp-module-interfaces | Required
Upgrade SharePoint Framework dev dependency package @microsoft/sp-module-interfaces
Execute the following command:
```sh
pnpm i -DE @microsoft/sp-module-interfaces@1.10.0
```
File: [./package.json](./package.json)
### FN002003 @microsoft/sp-webpart-workbench | Required
Upgrade SharePoint Framework dev dependency package @microsoft/sp-webpart-workbench
Execute the following command:
```sh
pnpm i -DE @microsoft/sp-webpart-workbench@1.10.0
```
File: [./package.json](./package.json)
### FN002009 @microsoft/sp-tslint-rules | Required
Upgrade SharePoint Framework dev dependency package @microsoft/sp-tslint-rules
Execute the following command:
```sh
pnpm i -DE @microsoft/sp-tslint-rules@1.10.0
```
File: [./package.json](./package.json)
### FN002012 @microsoft/rush-stack-compiler-3.3 | Required
Install SharePoint Framework dev dependency package @microsoft/rush-stack-compiler-3.3
Execute the following command:
```sh
pnpm i -DE @microsoft/rush-stack-compiler-3.3@0.3.5
```
File: [./package.json](./package.json)
### FN010001 .yo-rc.json version | Recommended
Update version in .yo-rc.json
In file [./.yo-rc.json](./.yo-rc.json) update the code as follows:
```json
{
"@microsoft/generator-sharepoint": {
"version": "1.10.0"
}
}
```
File: [./.yo-rc.json](./.yo-rc.json)
### FN012017 tsconfig.json extends property | Required
Update tsconfig.json extends property
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
```json
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json"
}
```
File: [./tsconfig.json](./tsconfig.json)
### FN016004 Property pane property import change to @microsoft/sp-property-pane | Required
Refactor the code to import property pane property from the @microsoft/sp-property-pane npm package instead of the @microsoft/sp-webpart-base package
In file [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts) update the code as follows:
```ts
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import { IPropertyPaneConfiguration, PropertyPaneToggle } from "@microsoft/sp-property-pane";
```
File: [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts:2:1](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts)
### FN021001 main | Required
Add package.json property
In file [./package.json](./package.json) update the code as follows:
```json
{
"main": "lib/index.js"
}
```
File: [./package.json](./package.json)
### FN011011 Web part manifest supportedHosts | Required
Update the supportedHosts property in the manifest
In file [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json) update the code as follows:
```json
{
"supportedHosts": ["SharePointWebPart"]
}
```
File: [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json)
### FN012014 tsconfig.json compiler options inlineSources | Required
Update tsconfig.json inlineSources value
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
```json
{
"compilerOptions": {
"inlineSources": false
}
}
```
File: [./tsconfig.json](./tsconfig.json)
### FN012015 tsconfig.json compiler options strictNullChecks | Required
Update tsconfig.json strictNullChecks value
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
```json
{
"compilerOptions": {
"strictNullChecks": false
}
}
```
File: [./tsconfig.json](./tsconfig.json)
### FN012016 tsconfig.json compiler options noUnusedLocals | Required
Update tsconfig.json noUnusedLocals value
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
```json
{
"compilerOptions": {
"noUnusedLocals": false
}
}
```
File: [./tsconfig.json](./tsconfig.json)
## Summary
### Execute script
```sh
pnpm i -E @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-webpart-base@1.10.0 @microsoft/sp-property-pane@1.10.0
pnpm i -DE @microsoft/sp-build-web@1.10.0 @microsoft/sp-module-interfaces@1.10.0 @microsoft/sp-webpart-workbench@1.10.0 @microsoft/sp-tslint-rules@1.10.0 @microsoft/rush-stack-compiler-3.3@0.3.5
```
### Modify files
#### [./.yo-rc.json](./.yo-rc.json)
Update version in .yo-rc.json:
```json
{
"@microsoft/generator-sharepoint": {
"version": "1.10.0"
}
}
```
#### [./tsconfig.json](./tsconfig.json)
Update tsconfig.json extends property:
```json
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json"
}
```
Update tsconfig.json inlineSources value:
```json
{
"compilerOptions": {
"inlineSources": false
}
}
```
Update tsconfig.json strictNullChecks value:
```json
{
"compilerOptions": {
"strictNullChecks": false
}
}
```
Update tsconfig.json noUnusedLocals value:
```json
{
"compilerOptions": {
"noUnusedLocals": false
}
}
```
#### [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.ts)
Refactor the code to import property pane property from the @microsoft/sp-property-pane npm package instead of the @microsoft/sp-webpart-base package:
```ts
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import { IPropertyPaneConfiguration, PropertyPaneToggle } from "@microsoft/sp-property-pane";
```
#### [./package.json](./package.json)
Add package.json property:
```json
{
"main": "lib/index.js"
}
```
#### [src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json](src\webparts\workbenchCustomizer\WorkbenchCustomizerWebPart.manifest.json)
Update the supportedHosts property in the manifest:
```json
{
"supportedHosts": ["SharePointWebPart"]
}
```

View File

@ -13,7 +13,7 @@ extensions:
- Knockout
createdDate: 1/1/2016 12:00:00 AM
---
# Sample Web Part implementing dependent properties in Property Pane
# Dependent Property Pane Properties
## Summary
Sample Web Part illustrating

View File

@ -13,7 +13,7 @@ extensions:
- Knockout
createdDate: 3/1/2017 12:00:00 AM
---
# Sample showing the use of @pnp/sp library with Knockoutjs
# Using @pnp/sp with Knockoutjs
## Summary
@ -62,4 +62,4 @@ Version|Date|Comments
Demonstrates integration of @pnp/sp js with the SharePoint Framework GA release. Also shows the use of mock data in the local workbench.
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/knockout-sp-pnp-js" />
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/knockout-sp-pnp-js" />

View File

@ -6342,12 +6342,6 @@
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
"bundled": true,
"dev": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
@ -8083,9 +8077,9 @@
"dev": true
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
"inpath": {

View File

@ -13,7 +13,7 @@ extensions:
- knockout
createdDate: 1/1/2016 12:00:00 AM
---
# Taxonomy Web Part
# Taxonomy
## Summary
Sample Web Part illustrating

15278
samples/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,12 @@
{
"@microsoft/generator-sharepoint": {
"version": "1.2.0",
"version": "1.11.0",
"libraryName": "component-test",
"libraryId": "7d4d5b98-cea3-4361-8e3d-5143d5c86334",
"environment": "spo"
"environment": "spo",
"isDomainIsolated": false,
"isCreatingSolution": true,
"packageManager": "npm",
"componentType": "webpart"
}
}

View File

@ -24,16 +24,25 @@ This is a sample project that contains a web part which makes use of the PnP SPF
![Web part outcome](./assets/webpart-outcome.gif)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-1.4.1-green.svg)
## Compatibility
![SPFx 1.11](https://img.shields.io/badge/spfx-1.11.0-green.svg)
![Node.js LTS 10.x](https://img.shields.io/badge/Node.js-LTS%2010.x-green.svg)
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-red.svg)
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
![Workbench Local (Partially) | Hosted](https://img.shields.io/badge/Workbench-Local%20(Partial)%20%7C%20Hosted-yellow.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)
- `PropertyFieldListPicker`
- `PropertyFieldTermPicker`
- `Placeholder`
- `ListView` (which also uses the `FileTypeIcon` control)
## Applies to
@ -44,15 +53,18 @@ The sample makes use of the following controls:
Solution|Author(s)
--------|---------
pnp-controls|Elio Struyf (MVP, U2U, [@eliostruyf](https://twitter.com/eliostruyf))
pnp-controls|Swaminathan Sriram ([@SwaminathanSri3](https://twitter.com/SwaminathanSri3))
## Version history
Version|Date|Comments
-------|----|--------
0.0.1|September 20, 2017|Initial release
0.0.2|March 03, 2018|Update to 1.4.1
1.0.1|September 20, 2017|Initial release
1.0.2|March 03, 2018|Update to 1.4.1
1.0.3|December 16, 2020|Update to 1.11.0
## 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.**
---

View File

@ -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",
"bundles": {
"pnp-controls-web-part": {

View File

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

View File

@ -1,5 +1,5 @@
{
"$schema": "https://dev.office.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "component-test",

View File

@ -1,12 +1,21 @@
{
"$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"
}
}
{
"$schema": "https://developer.microsoft.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.3.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": false,
"isDomainIsolated": false,
"developer": {
"name": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"websiteUrl": "",
"mpnId": ""
}
},
"paths": {
"zippedPackage": "solution/component-test.sppkg"
}
}

View File

@ -1,5 +1,5 @@
{
"$schema": "https://dev.office.com/json-schemas/core-build/serve.schema.json",
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"port": 4321,
"initialPage": "https://localhost:5432/workbench",
"https": true,

View File

@ -1,45 +0,0 @@
{
"$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
}
}
}

View File

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

View File

@ -2,5 +2,5 @@
const gulp = require('gulp');
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(gulp);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
{
"name": "component-test",
"version": "0.0.2",
"version": "1.0.3",
"private": true,
"main": "lib/index.js",
"engines": {
"node": ">=0.10.0"
},
@ -11,26 +12,32 @@
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "^1.4.1",
"@microsoft/sp-webpart-base": "^1.4.1",
"@pnp/spfx-controls-react": "^1.2.2",
"@pnp/spfx-property-controls": "^1.4.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",
"@microsoft/sp-core-library": "1.11.0",
"@microsoft/sp-property-pane": "1.11.0",
"@microsoft/sp-webpart-base": "1.11.0",
"@pnp/spfx-controls-react": "2.3.0",
"@pnp/spfx-property-controls": "2.2.0",
"@types/react": "16.8.8",
"moment": "2.18.1",
"react": "15.4.2",
"react-dom": "15.4.2"
"natives": "^1.1.6",
"office-ui-fabric-react": "6.214.0",
"react": "16.8.5",
"react-dom": "16.8.5"
},
"devDependencies": {
"@microsoft/sp-build-web": "^1.4.1",
"@microsoft/sp-module-interfaces": "^1.4.1",
"@microsoft/sp-webpart-workbench": "^1.4.1",
"@types/chai": ">=3.4.34 <3.6.0",
"@types/mocha": ">=2.2.33 <2.6.0",
"gulp": "~3.9.1"
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
"@microsoft/sp-build-web": "1.11.0",
"@microsoft/sp-module-interfaces": "1.11.0",
"@microsoft/sp-tslint-rules": "1.11.0",
"@microsoft/sp-webpart-workbench": "1.11.0",
"@types/chai": "3.4.34",
"@types/es6-promise": "0.0.33",
"@types/mocha": "2.2.38",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@types/webpack-env": "1.13.1",
"ajv": "5.2.2",
"gulp": "~3.9.1",
"tslint-microsoft-contrib": "5.0.0"
}
}

View File

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

View File

@ -1,7 +1,7 @@
import { ICheckedTerms } from "@pnp/spfx-property-controls/lib/PropertyFieldTermPicker";
import { IPickerTerms } 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
terms: IPickerTerms; // Keeps hold of the selected terms
description: string;
}

View File

@ -1,5 +1,5 @@
{
"$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": "8909dae1-5562-4f0f-be6c-aa14eac34c66",
"alias": "PnPControlsWebPart",
"componentType": "WebPart",
@ -12,11 +12,12 @@
// 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": "8909dae1-5562-4f0f-be6c-aa14eac34c66",
"group": {
"default": "Under Development"
"default": "Other"
},
"title": {
"default": "PnPControls"

View File

@ -2,10 +2,9 @@ import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField
BaseClientSideWebPart
} from '@microsoft/sp-webpart-base';
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
import * as strings from 'PnPControlsWebPartStrings';
import PnPControls from './components/PnPControls';

View File

@ -1,11 +1,11 @@
import { ICheckedTerms } from '@pnp/spfx-property-controls/lib/PropertyFieldTermPicker';
import { IPickerTerms } 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;
terms: IPickerTerms;
}
export interface IPnpControlsState {

View File

@ -3,7 +3,7 @@ import * as moment from 'moment';
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 { ListView, SelectionMode } from '@pnp/spfx-controls-react/lib/ListView';
import { SPHttpClient } from '@microsoft/sp-http';
import { IViewField } from '@pnp/spfx-controls-react/lib/controls/listView';
@ -148,7 +148,12 @@ export default class PnPControls extends React.Component<IPnPControlsProps, IPnp
) : (
<div>
<p className="ms-font-xl">{this.props.description}</p>
<ListView items={this.state.items} viewFields={this._viewFields} iconFieldName="File.ServerRelativeUrl" />
<ListView items={this.state.items}
viewFields={this._viewFields}
iconFieldName="File.ServerRelativeUrl"
selectionMode={SelectionMode.multiple}
selection={this._getSelection}
/>
</div>
)
)
@ -156,5 +161,8 @@ export default class PnPControls extends React.Component<IPnPControlsProps, IPnp
</div>
);
}
private _getSelection(items: any[]) {
console.log('Selected items:', items);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

View File

@ -1,8 +1,9 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"module": "esnext",
"jsx": "react",
"declaration": true,
"sourceMap": true,
@ -20,6 +21,19 @@
"es5",
"dom",
"es2015.collection"
]
}
],
"inlineSources": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"outDir": "lib",
"moduleResolution": "node"
},
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

@ -1,3 +1,30 @@
{
"rulesDirectory": "./config"
"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
}
}

View File

@ -0,0 +1,75 @@
# Edit Application Customizers
## Summary
This web part will allow users to view/update application customizers properties across any web where the current user has access to. This web part can be helpful when we require to update the properties for application customizer without using any PowerShell script or cli tool.
![Web part in action](assets/react-all-applicationcustomizers.gif?raw=true "Webpart in action")
## Idea behind this web part
- SPFx Application customizer can be used to add scripts, and add custom html to well known placeholder(header and footer)
- We can use properties to pass data to Application customizers to make solution customizable.
- To update properties of application customizer there is no UI based solution.
- To update the title, details and other information of application customizer we use either PowerShell script or cli tool.
- This webpart can be used at a central location where all the users have access and if they require to update title, description and properties.
## Features
- Webpart to view/update Application Customizers registered for a selected web
- Provides two different UI Accordion or List based(configurable)
- Provides a dropdown to select the web from where we would require to fetch application customizers
- Allows to update application customizer properties which makes it easy to make re-useable application customizers
## Used SharePoint Framework Version
![SPFx 1.11](https://img.shields.io/badge/version-1.11-green.svg)
## Applies to
- [SharePoint Framework](https://aka.ms/spfx)
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
## Solution
Solution|Author(s)
--------|---------
react-edit-applicationcustomizers | [Kunj Sangani](https://www.linkedin.com/in/kunj-sangani/) and [Siddharth Vaghasia](https://www.linkedin.com/in/siddharthvaghasia)
## Version history
Version|Date|Comments
-------|----|--------
1.0|October 16, 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.**
---
## Minimal Path to Awesome
- Clone this repository
- Ensure that you are at the solution folder
- in the command-line run:
- **npm install**
- **gulp serve**
For any issue or help, Buzz us on twitter:([sanganikunj](https://twitter.com/sanganikunj)) or ([siddh_me](https://twitter.com/siddh_me/))
> Sharing is caring!
## References
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-edit-applicationcustomizers" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 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": {
"application-customizers-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/applicationCustomizers/ApplicationCustomizersWebPart.js",
"manifest": "./src/webparts/applicationCustomizers/ApplicationCustomizersWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"ApplicationCustomizersWebPartStrings": "lib/webparts/applicationCustomizers/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-all-application-customizers",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,20 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "react-all-application-customizers-client-side-solution",
"id": "f560c809-b5a8-4320-abef-224f27d2d0f0",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false,
"developer": {
"name": "",
"websiteUrl": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"mpnId": ""
}
},
"paths": {
"zippedPackage": "solution/react-all-application-customizers.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'));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
{
"name": "react-all-application-customizers",
"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": {
"@material-ui/core": "^4.11.0",
"@microsoft/sp-core-library": "1.11.0",
"@microsoft/sp-lodash-subset": "1.11.0",
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
"@microsoft/sp-property-pane": "1.11.0",
"@microsoft/sp-webpart-base": "1.11.0",
"@pnp/sp": "^2.0.10",
"ace-builds": "^1.4.12",
"office-ui-fabric-react": "6.214.0",
"react": "16.8.5",
"react-ace": "^9.1.3",
"react-dom": "16.8.5"
},
"devDependencies": {
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@microsoft/sp-build-web": "1.11.0",
"@microsoft/sp-tslint-rules": "1.11.0",
"@microsoft/sp-module-interfaces": "1.11.0",
"@microsoft/sp-webpart-workbench": "1.11.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",
"@types/webpack-env": "1.13.1",
"@types/es6-promise": "0.0.33"
}
}

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,35 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "05567ead-69c5-4c36-958c-613a21cce18c",
"alias": "ApplicationCustomizersWebPart",
"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": "ApplicationCustomizers"
},
"description": {
"default": "ApplicationCustomizers description"
},
"officeFabricIconFontName": "CustomizeToolbar",
"properties": {
"description": "ApplicationCustomizers",
"designType": "List"
}
}
]
}

View File

@ -0,0 +1,85 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneChoiceGroup
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import * as strings from 'ApplicationCustomizersWebPartStrings';
import ApplicationCustomizers from './components/ApplicationCustomizers';
import { IApplicationCustomizersProps } from './components/IApplicationCustomizersProps';
import { sp } from "@pnp/sp/presets/all";
export interface IApplicationCustomizersWebPartProps {
description: string;
designType: string;
}
export default class ApplicationCustomizersWebPart extends BaseClientSideWebPart<IApplicationCustomizersWebPartProps> {
protected onInit(): Promise<void> {
return super.onInit().then(_ => {
// other init code may be present
sp.setup({
spfxContext: this.context
});
});
}
public render(): void {
const element: React.ReactElement<IApplicationCustomizersProps> = React.createElement(
ApplicationCustomizers,
{
description: this.properties.description,
context: this.context,
designType: this.properties.designType
}
);
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
}),
PropertyPaneChoiceGroup('designType', {
label: strings.DesignFieldLabel,
options: [
{ key: 'Accordion', checked: true, text: 'Accordion', iconProps: { officeFabricIconFontName: 'AutoFillTemplate' } },
{ key: 'List', text: 'List', iconProps: { officeFabricIconFontName: 'GroupedList' } }
]
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,84 @@
@import '~office-ui-fabric-react/dist/sass/References.scss';
.applicationCustomizers {
.container {
max-width: 1200px;
margin: 0px auto;
}
.row {
@include ms-Grid-row;
padding: 20px;
}
.column2 {
@include ms-Grid-col;
@include ms-lg2;
@include ms-xl2;
margin-top: 5px;
padding: 10px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl10;
margin-top: 5px;
padding: 10px;
}
.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;
margin-top: 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{
#workbenchPageContent{
max-width: 1200px;
}
}

View File

@ -0,0 +1,446 @@
import * as React from 'react';
import styles from './ApplicationCustomizers.module.scss';
import { IApplicationCustomizersProps } from './IApplicationCustomizersProps';
import { assign } from '@microsoft/sp-lodash-subset';
import ApplicationCustomizersService from "../service/ApplicationCustomizersService";
import { Dropdown, DropdownMenuItemType, IDropdownOption, IDropdownStyles } from 'office-ui-fabric-react/lib/Dropdown';
import MuiAccordion from '@material-ui/core/Accordion';
import MuiAccordionSummary from '@material-ui/core/AccordionSummary';
import MuiAccordionDetails from '@material-ui/core/AccordionDetails';
import { withStyles } from '@material-ui/core/styles';
import { DefaultButton, TextField, thProperties, Dialog, DialogFooter, DialogType, List, mergeStyleSets, getFocusStyle, ITheme, getTheme, IconButton, Panel, PanelType } from 'office-ui-fabric-react';
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-github";
const Accordion = withStyles({
root: {
border: '1px solid rgba(0, 0, 0, .125)',
boxShadow: 'none',
'&:not(:last-child)': {
borderBottom: 0,
},
'&:before': {
display: 'none',
},
'&$expanded': {
margin: 'auto',
},
},
expanded: {},
})(MuiAccordion);
const AccordionSummary = withStyles({
root: {
backgroundColor: 'rgba(0, 0, 0, .03)',
borderBottom: '1px solid rgba(0, 0, 0, .125)',
marginBottom: -1,
minHeight: 56,
'&$expanded': {
minHeight: 56,
},
},
content: {
'&$expanded': {
margin: '12px 0',
},
},
expanded: {},
})(MuiAccordionSummary);
const AccordionDetails = withStyles((themes) => ({
root: {
padding: themes.spacing(2),
display: 'block'
},
}))(MuiAccordionDetails);
const theme: ITheme = getTheme();
const { palette, semanticColors, fonts } = theme;
const classNames = mergeStyleSets({
container: {
overflow: 'auto',
maxHeight: 500,
},
itemCell: [
getFocusStyle(theme, { inset: -1 }),
{
minHeight: 54,
padding: 10,
boxSizing: 'border-box',
borderBottom: `1px solid ${semanticColors.bodyDivider}`,
display: 'flex',
selectors: {
'&:hover': { background: palette.neutralLight },
},
},
],
itemImage: {
flexShrink: 0,
},
itemContent: {
marginLeft: 10,
overflow: 'hidden',
flexGrow: 1,
},
itemName: [
fonts.xLarge,
{
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
color: 'black'
},
],
itemIndex: {
fontSize: fonts.small.fontSize,
marginBottom: 10,
color: 'black'
},
chevron: {
alignSelf: 'center',
marginLeft: 10,
color: palette.neutralTertiary,
fontSize: fonts.large.fontSize,
flexShrink: 0,
},
});
const applicationCustomizersService = new ApplicationCustomizersService();
export interface IApplicationCustomizersState {
selectedItem: IDropdownOption;
dropdownSites: IDropdownOption[];
expanded: string | false;
allCustomizers: any;
previousEditIndex?: number;
editJSON?: { Title: string; Description: string; ClientSideComponentProperties: any };
hideDialog: boolean;
dialogContentProps?: any;
isPanelOpen: boolean;
itemInEdit?: number;
isViewPanelOpen: boolean;
viewJSON?: {
Title: string; Description: string; ClientSideComponentId: any;
ClientSideComponentProperties: any; Id: any;
};
}
export default class ApplicationCustomizers extends React.Component<IApplicationCustomizersProps, IApplicationCustomizersState> {
constructor(props: IApplicationCustomizersProps) {
super(props);
this.state = {
selectedItem: undefined,
dropdownSites: undefined,
expanded: 'panel1',
allCustomizers: [],
previousEditIndex: undefined,
hideDialog: true,
isPanelOpen: false,
isViewPanelOpen: false
};
}
public componentDidMount() {
applicationCustomizersService.fetchAllApplictionCustomizers(this.props.context.pageContext.web.absoluteUrl)
.then((allCustomizers) => {
allCustomizers = allCustomizers.map((cus) => { return assign(cus, { inEdit: false }); });
this.setState({ allCustomizers: allCustomizers });
}).catch((err) => {
console.log(err);
});
applicationCustomizersService.getAllSiteCollection()
.then((allSites) => {
let dropdownSites = allSites.PrimarySearchResults.map((val) => {
val['key'] = val['SPSiteUrl'];
val['text'] = `${val['Title']} - ${val['SPSiteUrl']}`;
return val;
});
this.setState({ dropdownSites: dropdownSites });
});
}
private onChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
this.setState({ selectedItem: item });
applicationCustomizersService.fetchAllApplictionCustomizers(item.key as string)
.then((allCustomizers) => {
allCustomizers = allCustomizers.map((cus) => { return assign(cus, { inEdit: false }); });
this.setState({ allCustomizers: allCustomizers });
}).catch((err) => {
console.log(err);
});
}
public handleChange = (panel: string) => (event: React.ChangeEvent<{}>, newExpanded: boolean) => {
this.setState({ expanded: newExpanded ? panel : false });
}
public editCustomApplication = (index: number, inEdit: boolean) => {
let allCustomizers = this.state.allCustomizers;
allCustomizers[index].inEdit = inEdit;
if (this.state.previousEditIndex !== undefined && inEdit) {
allCustomizers[this.state.previousEditIndex].inEdit = false;
}
if (inEdit) {
this.setState({
isPanelOpen: this.props.designType === "List" ? true : false,
itemInEdit: index,
editJSON: {
Title: allCustomizers[index].Title,
Description: allCustomizers[index].Description,
ClientSideComponentProperties: allCustomizers[index].ClientSideComponentProperties
}
});
}
if (!inEdit) {
this.setState({ isPanelOpen: false });
}
this.setState({ allCustomizers: allCustomizers, previousEditIndex: index });
}
public onChangeJSON = (obj: string, newValue: string) => {
let { editJSON } = this.state;
editJSON[obj] = newValue;
this.setState({ editJSON });
}
public updateCustomizer = (index: number) => {
let webURL = this.state.selectedItem ? this.state.selectedItem.key : this.props.context.pageContext.web.absoluteUrl;
let { allCustomizers } = this.state;
applicationCustomizersService.updateApplicationCustomizer(webURL, this.state.allCustomizers[index].Id, this.state.editJSON)
.then(() => {
allCustomizers[index].inEdit = false;
this.setState({
allCustomizers: allCustomizers,
hideDialog: false,
isPanelOpen: false,
dialogContentProps: {
type: DialogType.normal,
title: 'Updated Successfully',
closeButtonAriaLabel: 'Close',
subText: 'Your Customizer is updated. Please refresh the page to look at the changes?'
}
});
}).catch((err) => {
this.setState({
hideDialog: false,
dialogContentProps: {
type: DialogType.normal,
title: 'Updat Error',
closeButtonAriaLabel: 'Close',
subText: 'There was some error while updating you customizer. Please try again'
}
});
});
}
private toggleHideDialog = () => {
applicationCustomizersService.fetchAllApplictionCustomizers(this.state.selectedItem ?
this.state.selectedItem.key as string : this.props.context.pageContext.web.absoluteUrl)
.then((allCustomizers) => {
allCustomizers = allCustomizers.map((cus) => { return assign(cus, { inEdit: false }); });
this.setState({ allCustomizers: allCustomizers, hideDialog: true });
}).catch((err) => {
console.log(err);
});
}
private viewCustomApplication = (index: number) => {
let { allCustomizers } = this.state;
this.setState({
isViewPanelOpen: true,
viewJSON: {
Title: allCustomizers[index].Title,
ClientSideComponentId: allCustomizers[index].ClientSideComponentId,
ClientSideComponentProperties: allCustomizers[index].ClientSideComponentProperties,
Description: allCustomizers[index].Description,
Id: allCustomizers[index].Id
}
});
}
private onRenderCell = (item: any, index: number, isScrolling: boolean): JSX.Element => {
return (
<div className={classNames.itemCell} data-is-focusable={true}>
<div className={classNames.itemContent}>
<div className={classNames.itemName}>{item.Title}</div>
<div className={classNames.itemIndex}>{item.Description}</div>
</div>
<IconButton iconProps={{ iconName: 'View' }} onClick={() => { this.viewCustomApplication(index); }} title="View" ariaLabel="View"></IconButton>
<IconButton iconProps={{ iconName: 'Edit' }} onClick={() => { this.editCustomApplication(index, true); }} title="Edit" ariaLabel="Edit"></IconButton>
</div>
);
}
public render(): React.ReactElement<IApplicationCustomizersProps> {
return (
<div className={styles.applicationCustomizers}>
<div className={styles.container}>
<div className={styles.row}>
<h1>{this.props.description}</h1>
</div>
<div className={styles.row}>
<Dropdown
label="Select Web"
selectedKey={this.state.selectedItem ? this.state.selectedItem.key : undefined}
onChange={this.onChange}
placeholder="Select an option"
options={this.state.dropdownSites}
/>
</div>
{this.props.designType === "Accordion" && this.state.allCustomizers.length !== 0 &&
<div className={styles.row}>
{this.state.allCustomizers.map((customizer, index) => {
return (
<Accordion square expanded={this.state.expanded === `panel${index + 1}`} onChange={this.handleChange(`panel${index + 1}`)}>
<AccordionSummary aria-controls="panel1d-content" id="panel1d-header">
<div>{customizer.Title}{customizer.Description && ` - ${customizer.Description}`}</div>
</AccordionSummary>
<AccordionDetails>
{!customizer.inEdit ?
<div>
<div className={styles.column2}>Component ID</div>
<div className={styles.column}>{customizer.ClientSideComponentId}</div>
<div className={styles.column2}>ID</div>
<div className={styles.column}>{customizer.Id}</div>
<div className={styles.column2}>Properties</div>
<div className={styles.column}>{customizer.ClientSideComponentProperties}</div>
</div> :
<div>
<div className={styles.column2}>Title</div>
<div className={styles.column}><TextField value={this.state.editJSON.Title}
onChange={(ev, newVal) => {
this.onChangeJSON("Title", newVal);
}} />
</div>
<div className={styles.column2}>Description</div>
<div className={styles.column}><TextField value={this.state.editJSON.Description} multiline rows={3}
onChange={(ev, newVal) => {
this.onChangeJSON("Description", newVal);
}} /></div>
<div className={styles.column2}>Properties</div>
<div className={styles.column}>
<AceEditor
placeholder="Placeholder Text"
mode="json"
theme="github"
onChange={(val) => { this.onChangeJSON("ClientSideComponentProperties", val); }}
fontSize={14}
style={{ height: 200, width: 790 }}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={false}
value={this.state.editJSON.ClientSideComponentProperties}
setOptions={{
enableBasicAutocompletion: true,
enableLiveAutocompletion: false,
enableSnippets: false,
showLineNumbers: true,
tabSize: 2,
}} />
</div>
</div>
}
{!customizer.inEdit ?
<DefaultButton className={styles.button} text="Edit" onClick={() => { this.editCustomApplication(index, true); }} /> :
[<DefaultButton className={styles.button} text="Update" onClick={() => { this.updateCustomizer(index); }} />,
<DefaultButton style={{ marginLeft: 10, marginTop: 10 }} text="Cancel" onClick={() => { this.editCustomApplication(index, false); }} />]
}
</AccordionDetails>
</Accordion>
);
})}
</div>
}
{this.props.designType === "List" && this.state.allCustomizers.length !== 0 &&
<div className={styles.row}>
<List items={this.state.allCustomizers} onRenderCell={this.onRenderCell} />
</div>
}
{this.state.allCustomizers.length === 0 &&
<div className={styles.row}>We did not find any Application Customizers for the selected web</div>
}
<Dialog
hidden={this.state.hideDialog}
onDismiss={() => this.toggleHideDialog()}
dialogContentProps={this.state.dialogContentProps}
>
<DialogFooter>
<DefaultButton onClick={() => this.toggleHideDialog()} text="Cancel" />
</DialogFooter>
</Dialog>
<Panel
headerText="Edit Application Customizer"
isOpen={this.state.isPanelOpen}
onDismiss={() => this.setState({ isPanelOpen: false })}
closeButtonAriaLabel="Close"
type={PanelType.large}
>
{this.state.editJSON &&
<div className={styles.applicationCustomizers}>
<div className={styles.column2}>Title</div>
<div className={styles.column}><TextField value={this.state.editJSON.Title}
onChange={(ev, newVal) => {
this.onChangeJSON("Title", newVal);
}} />
</div>
<div className={styles.column2}>Description</div>
<div className={styles.column}><TextField value={this.state.editJSON.Description} multiline rows={3}
onChange={(ev, newVal) => {
this.onChangeJSON("Description", newVal);
}} /></div>
<div className={styles.column2}>Properties</div>
<div className={styles.column}>
<AceEditor
placeholder="Placeholder Text"
mode="json"
theme="github"
onChange={(val) => { this.onChangeJSON("ClientSideComponentProperties", val); }}
fontSize={14}
style={{ height: 200, width: 800 }}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={false}
value={this.state.editJSON.ClientSideComponentProperties}
setOptions={{
enableBasicAutocompletion: true,
enableLiveAutocompletion: false,
enableSnippets: false,
showLineNumbers: true,
tabSize: 2,
}} />
</div>
<DefaultButton style={{ marginLeft: 10, marginTop: 10 }} className={styles.button} text="Update" onClick={() => { this.updateCustomizer(this.state.itemInEdit); }} />
<DefaultButton style={{ marginLeft: 10, marginTop: 10 }} text="Cancel" onClick={() => { this.editCustomApplication(this.state.itemInEdit, false); }} />
</div>}
</Panel>
<Panel
headerText="View Application Customizer"
isOpen={this.state.isViewPanelOpen}
onDismiss={() => this.setState({ isViewPanelOpen: false })}
closeButtonAriaLabel="Close"
type={PanelType.medium}
>{this.state.viewJSON &&
<div className={styles.applicationCustomizers}>
<div className={styles.column2}>Title</div>
<div className={styles.column}>{this.state.viewJSON.Title}</div>
<div className={styles.column2}>Description</div>
<div className={styles.column}>{this.state.viewJSON.Description ? this.state.viewJSON.Description : 'null'}</div>
<div className={styles.column2}>ComponentID</div>
<div className={styles.column}>{this.state.viewJSON.ClientSideComponentId}</div>
<div className={styles.column2}>ID</div>
<div className={styles.column}>{this.state.viewJSON.Id}</div>
<div className={styles.column2}>Properties</div>
<div className={styles.column}>{this.state.viewJSON.ClientSideComponentProperties}</div>
</div>}</Panel>
</div>
</div>
);
}
}

View File

@ -0,0 +1,7 @@
import { WebPartContext } from "@microsoft/sp-webpart-base";
export interface IApplicationCustomizersProps {
description: string;
context: WebPartContext;
designType: string;
}

View File

@ -0,0 +1,8 @@
define([], function () {
return {
"PropertyPaneDescription": "",
"BasicGroupName": "",
"DescriptionFieldLabel": "Title",
"DesignFieldLabel": "Choose design"
}
});

View File

@ -0,0 +1,11 @@
declare interface IApplicationCustomizersWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
DesignFieldLabel: string;
}
declare module 'ApplicationCustomizersWebPartStrings' {
const strings: IApplicationCustomizersWebPartStrings;
export = strings;
}

View File

@ -0,0 +1,61 @@
import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/user-custom-actions";
import { ISearchQuery } from "@pnp/sp/search";
import { Web } from "@pnp/sp/webs";
export default class ApplicationCustomizersService {
/**
* fetchAllApplictionCustomizers
*/
public fetchAllApplictionCustomizers = async (webURL: string) => {
let web = Web(webURL);
let response;
try {
response = await web.userCustomActions();
console.log(response);
//let temp = await sp.site.userCustomActions();
//console.log(temp);
} catch (error) {
console.log(error);
response = error;
}
return response;
}
/**
* getAllSiteCollection
*/
public getAllSiteCollection = async () => {
let response;
try {
response = await sp.search(<ISearchQuery>{
Querytext: "contentclass:STS_Site",
SelectProperties: ["Title", "SPSiteUrl", "WebTemplate"],
RowLimit: 1000,
TrimDuplicates: true
});
console.log(response.PrimarySearchResults);
} catch (error) {
console.log(error);
response = error;
}
return response;
}
/**
* updateApplicationCustomizer
*/
public updateApplicationCustomizer = async (webURL: string | number, selectedID: string, updateJSON: any) => {
let web = Web(webURL as string);
let response;
try {
response = await web.userCustomActions.getById(selectedID).update(updateJSON);
} catch (error) {
console.log(error);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

View File

@ -0,0 +1,39 @@
{
"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",
"src/**/*.tsx"
],
"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
}
}

View File

@ -0,0 +1,78 @@
# Dynamic Accordion - FAQ Builder
## Summary
- This sample is based on [Erik Benke] and [Mike Zimmerman] (Accordion Section FAQ Builder web part. I has extended it support single FAQs list based on Category and dynamic properties selection.
- Adds a collapsible accordion section to an Office 365 SharePoint page or Teams Tab.
- Ideal for displaying FAQs.
- When adding the web part, you'll be prompted to select a list from a property panel dropdown (target list must be created with FAQ type Question and Answer.).
- The web part expects a column called **Category** of type choice that will be used as the category.
- The web part will automatically load all the properties in two dropdowns. One for Accordion Title and One for Accordion Content that must be html type.
- This will generate an accordion with one section for each item in the list.
- Modifications/deletions/additions to the list items in the target list of an added web part are automatically reflected on the page.
- To deploy to a Teams tab see current [Microsoft documentation](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-web-part-as-ms-teams-tab).
![Web Part in Action](./assets/react-accordion-section.gif)
### Usage
**1) Create or use a list for FAQs. It can have the FAQ format e.g. Title and a Content columns. You can also used the attached STP file if needed.:**
- The value in the Accordion Title property for each item will appear in the heading bars of the Accordion.
- The value in the Accordion Content property for each item will appear in the collapsible content section of the Accordion
- When creating the columns, select "Multiple lines of text". Rich text is now supported within the Content column.
![Create list for use with the Accordion](./assets/FAQsList.png)
[FAQ list Template for use with the Accordion](./assets/FAQsList.stp)
[FAQ Site Script use with the Accordion](./assets/FAQsList.json)
**2) Add the Dynamic Accordion Section web part to your page & select your list, category, title and content columns. Click Apply and Publish:**
![Select list and other properties from property panel for use with the Accordion](./assets/AccordionSettings1.png)
![Completed properties.](./assets/AccordionSettings2.png)
## Used SharePoint Framework Version
![1.10.0](https://img.shields.io/badge/version-1.10.0-green.svg)
## Applies to
- [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
- [Office 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
## Prerequisites
Please create the list as described above
## Solution
| Solution | Author(s) |
| ------------------------------------------ | ---------------------------------------------------------------------------------------- |
| SPFx Collapsible Accordion Section | [Erik Benke](https://github.com/ejbenke) ([@erikjbenke](https://twitter.com/erikjbenke)) |
| SPFx Collapsible Accordion Section | [Mike Zimmerman](https://github.com/mikezimm) |
| Dynamic SPFx Collapsible Accordion Section | [Jerry Yasir](https://github.com/jyasir) |
## Version history
| Version | Date | Comments |
| ------- | ------------------ | --------------------------------------------------------------------------------------------------- |
| 1.0 | September 20, 2020 | Reused [Erik Benke] and [Mike Zimmerman] web part |
| 1.1 | September 20, 2020 | Added Support for Dynamic Column selection for reuseability, Dynamic Property Selection for Columns |
## 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
- Clone or download this repository
- Run in command line:
- `npm install` to install the npm dependencies
- `gulp serve` to display in Developer Workbench (recommend using your tenant workbench so you can test with real lists within your site)
- To package and deploy:
- Use `gulp bundle --ship` & `gulp package-solution --ship`
- Add the `.sppkg` to your SharePoint App Catalog
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-accordion-dynamic-section" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -0,0 +1,20 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"react-accordion-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/reactAccordion/ReactAccordionWebPart.js",
"manifest": "./src/webparts/reactAccordion/ReactAccordionWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"ReactAccordionWebPartStrings": "lib/webparts/reactAccordion/loc/{locale}.js",
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js",
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/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-accordion",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "Accordion Section FAQ Builder",
"id": "bf6fa974-fd40-45a3-80e9-e826abe025b9",
"version": "1.6.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true
},
"paths": {
"zippedPackage": "solution/DynamicFAQ-Accordion.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,134 @@
{
"id": "061da2cd-f680-4da5-ab30-40a8ba1aafd8",
"alias": "ReactAccordionWebPart",
"componentType": "WebPart",
"version": "1.6.0",
"manifestVersion": 2,
"requiresCustomScript": false,
"supportedHosts": [
"SharePointWebPart",
"TeamsTab"
],
"loadLegacyFabricCss": true,
"preconfiguredEntries": [
{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
"group": {
"default": "Other"
},
"title": {
"default": "Dynamic Accordion Section"
},
"description": {
"default": "Collapsible accordion section for displaying list data based on Category and Dynamic selection"
},
"officeFabricIconFontName": "MusicInCollectionFill",
"properties": {
"description": "Dynamic React Accordion",
"listId": "",
"columnTitle": "",
"selectedChoice": "",
"accordianTitleColumn": "",
"accordianContentColumn": "",
"allowZeroExpanded": true
}
}
],
"loaderConfig": {
"entryModuleId": "react-accordion-web-part",
"internalModuleBaseUrls": [
"https://localhost:4321/"
],
"scriptResources": {
"react-accordion-web-part": {
"type": "path",
"path": "dist/react-accordion-web-part.js"
},
"ReactAccordionWebPartStrings": {
"defaultPath": "lib/webparts/reactAccordion/loc/en-us.js",
"type": "localizedPath",
"paths": {}
},
"ControlStrings": {
"defaultPath": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"type": "localizedPath",
"paths": {
"de-DE": "node_modules/@pnp/spfx-controls-react/lib/loc/de-de.js",
"de": "node_modules/@pnp/spfx-controls-react/lib/loc/de-de.js",
"dsb": "node_modules/@pnp/spfx-controls-react/lib/loc/de-de.js",
"rm": "node_modules/@pnp/spfx-controls-react/lib/loc/de-de.js",
"hsb": "node_modules/@pnp/spfx-controls-react/lib/loc/de-de.js",
"en-US": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"bn": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"chr": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"dv": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"div": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"en": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"fil": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"haw": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"iu": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"lo": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"moh": "node_modules/@pnp/spfx-controls-react/lib/loc/en-us.js",
"fr-FR": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"gsw": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"br": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"tzm-Tfng": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"co": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"fr": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"ff": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"lb": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"mg": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"oc": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"zgh": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"wo": "node_modules/@pnp/spfx-controls-react/lib/loc/fr-fr.js",
"lt-LT": "node_modules/@pnp/spfx-controls-react/lib/loc/lt-lt.js",
"nl-NL": "node_modules/@pnp/spfx-controls-react/lib/loc/nl-nl.js",
"nl": "node_modules/@pnp/spfx-controls-react/lib/loc/nl-nl.js",
"fy": "node_modules/@pnp/spfx-controls-react/lib/loc/nl-nl.js",
"ru-RU": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"ru": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"ba": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"be": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"ky": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"mn": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"sah": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"tg": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"tt": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js",
"tk": "node_modules/@pnp/spfx-controls-react/lib/loc/ru-ru.js"
}
},
"@microsoft/sp-property-pane": {
"type": "component",
"version": "1.10.0",
"id": "f9e737b7-f0df-4597-ba8c-3060f82380db"
},
"@microsoft/sp-core-library": {
"type": "component",
"version": "1.10.0",
"id": "7263c7d0-1d6a-45ec-8d85-d4d1d234171b"
},
"@microsoft/sp-webpart-base": {
"type": "component",
"version": "1.10.0",
"id": "974a7777-0990-4136-8fa6-95d80114c2e0"
},
"react": {
"type": "component",
"version": "16.8.5",
"id": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
"failoverPath": "node_modules/react/dist/react.js"
},
"react-dom": {
"type": "component",
"version": "16.8.5",
"id": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
"failoverPath": "node_modules/react-dom/dist/react-dom.js"
},
"@microsoft/sp-http": {
"type": "component",
"version": "1.10.0",
"id": "c07208f0-ea3b-4c1a-9965-ac1b825211a6"
}
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
'use strict';
const gulp = require('gulp');
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(gulp);

View File

@ -0,0 +1 @@
//# sourceMappingURL=index.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}

View File

@ -0,0 +1,2 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wFAAwF"}

View File

@ -0,0 +1,35 @@
import { Version } from "@microsoft/sp-core-library";
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import { IPropertyPaneConfiguration } from "@microsoft/sp-property-pane";
import "core-js/es6/array";
import "es6-map/implement";
import "core-js/modules/es6.array.find";
export interface IReactAccordionWebPartProps {
listId: string;
accordionTitle: string;
columnTitle: string;
selectedChoice: string;
allowZeroExpanded: boolean;
allowMultipleExpanded: boolean;
accordianTitleColumn: string;
accordianContentColumn: string;
}
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
private listColumns;
private allListColumns;
private columnChoices;
private columnsDropdownDisabled;
private choicesDropdownDisabled;
onInit(): Promise<void>;
render(): void;
protected onDispose(): void;
protected readonly disableReactivePropertyChanges: boolean;
protected readonly dataVersion: Version;
private loadColumns;
private loadAllColumns;
private loadCateogryChoices;
protected onPropertyPaneConfigurationStart(): void;
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void;
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration;
}
//# sourceMappingURL=ReactAccordionWebPart.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"ReactAccordionWebPart.d.ts","sourceRoot":"","sources":["../../../src/webparts/reactAccordion/ReactAccordionWebPart.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACL,0BAA0B,EAK3B,MAAM,6BAA6B,CAAC;AAErC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,gCAAgC,CAAC;AAcxC,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,qBAAqB,CACtE,2BAA2B,CAC5B;IACC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,aAAa,CAAgC;IAErD,OAAO,CAAC,uBAAuB,CAAiB;IAChD,OAAO,CAAC,uBAAuB,CAAiB;IAEzC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQvB,MAAM,IAAI,IAAI;IAyBrB,SAAS,CAAC,SAAS,IAAI,IAAI;uBAIb,8BAA8B,EAAI,OAAO;uBAGzC,WAAW,EAAI,OAAO;IAIpC,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,mBAAmB;IA+B3B,SAAS,CAAC,gCAAgC,IAAI,IAAI;IA6ClD,SAAS,CAAC,0BAA0B,CAClC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,GAAG,GACZ,IAAI;IAoEP,SAAS,CAAC,4BAA4B,IAAI,0BAA0B;CA6DrE"}

View File

@ -0,0 +1,297 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import * as React from "react";
import * as ReactDom from "react-dom";
import { Version } from "@microsoft/sp-core-library";
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import { PropertyPaneToggle, PropertyPaneDropdown, } from "@microsoft/sp-property-pane";
import { sp } from "@pnp/sp/presets/all";
import "core-js/es6/array";
import "es6-map/implement";
import "core-js/modules/es6.array.find";
import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy, } from "@pnp/spfx-property-controls/lib/PropertyFieldListPicker";
import * as strings from "ReactAccordionWebPartStrings";
import ReactAccordion from "./components/ReactAccordion";
var ReactAccordionWebPart = /** @class */ (function (_super) {
__extends(ReactAccordionWebPart, _super);
function ReactAccordionWebPart() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.columnsDropdownDisabled = true;
_this.choicesDropdownDisabled = true;
return _this;
}
ReactAccordionWebPart.prototype.onInit = function () {
var _this = this;
return _super.prototype.onInit.call(this).then(function (_) {
sp.setup({
spfxContext: _this.context,
});
});
};
ReactAccordionWebPart.prototype.render = function () {
var _this = this;
var element = React.createElement(ReactAccordion, {
listId: this.properties.listId,
columnTitle: this.properties.columnTitle,
selectedChoice: this.properties.selectedChoice,
accordionTitle: this.properties.accordionTitle,
accordianTitleColumn: this.properties.accordianTitleColumn,
accordianContentColumn: this.properties.accordianContentColumn,
allowZeroExpanded: this.properties.allowZeroExpanded,
allowMultipleExpanded: this.properties.allowMultipleExpanded,
displayMode: this.displayMode,
updateProperty: function (value) {
_this.properties.accordionTitle = value;
},
onConfigure: function () {
_this.context.propertyPane.open();
},
});
ReactDom.render(element, this.domElement);
};
ReactAccordionWebPart.prototype.onDispose = function () {
ReactDom.unmountComponentAtNode(this.domElement);
};
Object.defineProperty(ReactAccordionWebPart.prototype, "disableReactivePropertyChanges", {
get: function () {
return true;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ReactAccordionWebPart.prototype, "dataVersion", {
get: function () {
return Version.parse("1.0");
},
enumerable: true,
configurable: true
});
ReactAccordionWebPart.prototype.loadColumns = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.properties.listId) {
console.log("No List Selected");
return null;
}
var spListColumns = sp.web.lists
.getById(_this.properties.listId)
.fields.filter("ReadOnlyField eq false and Hidden eq false and TypeAsString eq 'Choice'")
.get();
spListColumns.then(function (columnResult) {
var listColumns = [];
columnResult.forEach(function (column) {
listColumns.push({
key: column.Title,
text: column.Title,
});
});
resolve(listColumns);
});
});
};
ReactAccordionWebPart.prototype.loadAllColumns = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.properties.listId) {
console.log("No List Selected");
return null;
}
var spListColumns = sp.web.lists
.getById(_this.properties.listId)
.fields.filter("ReadOnlyField eq false and Hidden eq false")
.get();
spListColumns.then(function (columnResult) {
var listColumns = [];
columnResult.forEach(function (column) {
listColumns.push({
key: column.InternalName,
text: column.Title + " - [" + column.InternalName + "]",
});
});
resolve(listColumns);
});
});
};
ReactAccordionWebPart.prototype.loadCateogryChoices = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.properties.columnTitle) {
console.log("No Columns Selected");
return null;
}
var categoryField = sp.web.lists
.getById(_this.properties.listId)
.fields.getByInternalNameOrTitle(_this.properties.columnTitle);
var choices = categoryField.select("Choices")();
choices.then(function (result) {
//console.clear();
//console.log(result.Choices);
var columnChoices = [];
result.Choices.forEach(function (choice) {
columnChoices.push({
key: choice,
text: choice,
});
});
resolve(columnChoices);
});
});
};
ReactAccordionWebPart.prototype.onPropertyPaneConfigurationStart = function () {
var _this = this;
this.columnsDropdownDisabled = !this.properties.listId;
this.choicesDropdownDisabled = !this.properties.columnTitle;
//if (this.lists) {
// return;
//}
this.context.statusRenderer.displayLoadingIndicator(this.domElement, "lists, column and choices");
if (this.properties.listId) {
this.loadColumns().then(function (columnOptions) {
_this.listColumns = columnOptions;
_this.columnsDropdownDisabled = !_this.properties.listId;
_this.context.propertyPane.refresh();
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
_this.render();
});
this.loadAllColumns().then(function (allcolumnOptions) {
_this.allListColumns = allcolumnOptions;
_this.columnsDropdownDisabled = !_this.properties.listId;
_this.context.propertyPane.refresh();
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
_this.render();
});
}
if (this.properties.columnTitle) {
this.loadCateogryChoices().then(function (choiceOptions) {
_this.columnChoices = choiceOptions;
_this.choicesDropdownDisabled = !_this.properties.columnTitle;
_this.context.propertyPane.refresh();
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
_this.render();
});
}
};
ReactAccordionWebPart.prototype.onPropertyPaneFieldChanged = function (propertyPath, oldValue, newValue) {
// push new list value
var _this = this;
// communicate loading items
if (this.properties.listId) {
this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Columns");
this.loadColumns().then(function (columnOptions) {
// store items
_this.listColumns = columnOptions;
// enable item selector
_this.columnsDropdownDisabled = false;
// clear status indicator
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
// re-render the web part as clearing the loading indicator removes the web part body
_this.render();
// refresh the item selector control by repainting the property pane
_this.context.propertyPane.refresh();
});
this.loadAllColumns().then(function (allcolumnOptions) {
_this.allListColumns = allcolumnOptions;
_this.columnsDropdownDisabled = !_this.properties.listId;
_this.context.propertyPane.refresh();
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
_this.render();
});
}
if (this.properties.columnTitle) {
this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Choices");
this.loadCateogryChoices().then(function (choiceOption) {
// store items
_this.columnChoices = choiceOption;
// enable item selector
_this.choicesDropdownDisabled = false;
// clear status indicator
_this.context.statusRenderer.clearLoadingIndicator(_this.domElement);
// re-render the web part as clearing the loading indicator removes the web part body
_this.render();
// refresh the item selector control by repainting the property pane
_this.context.propertyPane.refresh();
});
}
if (this.properties.selectedChoice) {
this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Data");
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
this.render();
this.context.propertyPane.refresh();
}
};
ReactAccordionWebPart.prototype.getPropertyPaneConfiguration = function () {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription,
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyFieldListPicker("listId", {
label: "Select a list",
selectedList: this.properties.listId,
includeHidden: false,
orderBy: PropertyFieldListPickerOrderBy.Title,
disabled: false,
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
properties: this.properties,
context: this.context,
onGetErrorMessage: null,
deferredValidationTime: 0,
key: "listPickerFieldId",
}),
PropertyPaneDropdown("columnTitle", {
label: "Select the (Choice) Column for Categories.",
options: this.listColumns,
disabled: this.columnsDropdownDisabled,
}),
PropertyPaneDropdown("selectedChoice", {
label: "Select the Choice value for filter.",
options: this.columnChoices,
disabled: this.choicesDropdownDisabled,
}),
PropertyPaneDropdown("accordianTitleColumn", {
label: "Select the Column for Accordion Title Rows.",
options: this.allListColumns,
disabled: this.choicesDropdownDisabled,
}),
PropertyPaneDropdown("accordianContentColumn", {
label: "Select the Column for Accordion Content.",
options: this.allListColumns,
disabled: this.choicesDropdownDisabled,
}),
PropertyPaneToggle("allowZeroExpanded", {
label: "Allow zero expanded",
checked: this.properties.allowZeroExpanded,
key: "allowZeroExpanded",
}),
PropertyPaneToggle("allowMultipleExpanded", {
label: "Allow multi expand",
checked: this.properties.allowMultipleExpanded,
key: "allowMultipleExpanded",
}),
],
},
],
},
],
};
};
return ReactAccordionWebPart;
}(BaseClientSideWebPart));
export default ReactAccordionWebPart;
//# sourceMappingURL=ReactAccordionWebPart.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,40 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "061da2cd-f680-4da5-ab30-40a8ba1aafd8",
"alias": "ReactAccordionWebPart",
"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", "TeamsTab"],
"loadLegacyFabricCss": true,
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": {
"default": "Other"
},
"title": {
"default": "Dynamic Accordion Section"
},
"description": {
"default": "Collapsible accordion section for displaying list data based on Category and Dynamic selection"
},
"officeFabricIconFontName": "MusicInCollectionFill",
"properties": {
"description": "Dynamic React Accordion",
"listId": "",
"columnTitle": "",
"selectedChoice": "",
"accordianTitleColumn": "",
"accordianContentColumn": "",
"allowZeroExpanded": true
}
}]
}

View File

@ -0,0 +1,15 @@
import { DisplayMode } from "@microsoft/sp-core-library";
export interface IReactAccordionProps {
listId: string;
accordionTitle: string;
columnTitle: string;
selectedChoice: string;
accordianTitleColumn: string;
accordianContentColumn: string;
allowZeroExpanded: boolean;
allowMultipleExpanded: boolean;
displayMode: DisplayMode;
updateProperty: (value: string) => void;
onConfigure: () => void;
}
//# sourceMappingURL=IReactAccordionProps.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"IReactAccordionProps.d.ts","sourceRoot":"","sources":["../../../../src/webparts/reactAccordion/components/IReactAccordionProps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB"}

Some files were not shown because too many files have changed in this diff Show More