Merge branch 'main' into fix-bug-#1719-ListMenu-Items
|
@ -0,0 +1,27 @@
|
||||||
|
> By submitting this pull request, you agree to the [contribution guidelines](https://github.com/pnp/sp-dev-fx-webparts/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
> If you aren't familiar with how to contribute to open-source repositories using GitHub, or if you find the instructions on this page confusing, [sign up](https://forms.office.com/Pages/ResponsePage.aspx?id=KtIy2vgLW0SOgZbwvQuRaXDXyCl9DkBHq4A2OG7uLpdUREZVRDVYUUJLT1VNRDM4SjhGMlpUNzBORy4u) for one of our [Sharing is Caring](https://pnp.github.io/sharing-is-caring/#pnp-sic-events) events. It's completely free, and we'll guide you through the process.
|
||||||
|
|
||||||
|
| Q | A |
|
||||||
|
| --------------- | --------------------------------------- |
|
||||||
|
| Bug fix? | yes |
|
||||||
|
| Related issues? | fixes #X, partially #Y, mentioned in #Z |
|
||||||
|
|
||||||
|
## What's in this Pull Request?
|
||||||
|
|
||||||
|
> Please describe the changes in this PR. Sample description or details around bugs which are being fixed.
|
||||||
|
>
|
||||||
|
> _(DELETE THIS PARAGRAPH AFTER READING)_
|
||||||
|
|
||||||
|
## Submitter Guidance (DELETE AFTER READING)
|
||||||
|
>
|
||||||
|
> *Please update this PR information accordingly. We'll use this as part of our release notes in monthly communications.*
|
||||||
|
>
|
||||||
|
> *Pull requests that do not follow this template will be automatically rejected.*
|
||||||
|
>
|
||||||
|
> *Please target your PR to `main` branch.*
|
||||||
|
>
|
||||||
|
> *Remember that this repository is maintained by community members who volunteer their time to help. Be courteous and patient.*
|
||||||
|
> _(DELETE THIS SECTION AFTER READING)_
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,20 @@ Short summary on functionality and used technologies.
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
![SPFx 1.13.0](https://img.shields.io/badge/SPFx-1.13.0-green.svg)
|
||||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
> Don't worry if you're unsure about the compatibility matrix above. We'll verify it when we approve the PR.
|
> Don't worry if you're unsure about the compatibility matrix above. We'll verify it when we approve the PR.
|
||||||
>
|
>
|
||||||
|
> If using SPFx 1.12.1, update the SPFx and Node.js tags accordingly:
|
||||||
|
> ![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
|
> ![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
|
>
|
||||||
> If using an older version of SPFx, update the SPFx and Node.js compatibility tag accordingly:
|
> If using an older version of SPFx, update the SPFx and Node.js compatibility tag accordingly:
|
||||||
> SPFx 1.11
|
> SPFx 1.11
|
||||||
> ![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
> ![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
||||||
|
@ -42,10 +48,12 @@ Short summary on functionality and used technologies.
|
||||||
> ![Node.js LTS 6.x | LTS 8.x](https://img.shields.io/badge/Node.js-LTS%206.x%20%7C%20LTS%208.x-green.svg)
|
> ![Node.js LTS 6.x | LTS 8.x](https://img.shields.io/badge/Node.js-LTS%206.x%20%7C%20LTS%208.x-green.svg)
|
||||||
>
|
>
|
||||||
> If you built this sample specifically for SharePoint 2016, or SharePoint 2019 support, update the SharePoint compatibility tag accordingly:
|
> If you built this sample specifically for SharePoint 2016, or SharePoint 2019 support, update the SharePoint compatibility tag accordingly:
|
||||||
> ![SharePoint 2019 | Online](https://img.shields.io/badge/SharePoint-2019%20%7C%20Online-yellow.svg)
|
> ![Works with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Compatible-green.svg)
|
||||||
> ![SharePoint 2016 | 2019 | Online](https://img.shields.io/badge/SharePoint-2016%20%7C%202019%20%7C%20Online-green.svg)
|
> ![Work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Compatible-green.svg)
|
||||||
> If you know your web part only works on the hosted workbench, you can use this for the workbench compatibility tag:
|
> If you know your web part only works on the hosted workbench, you can use this for the workbench compatibility tag:
|
||||||
> ![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
> ![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to XXX")
|
||||||
|
> ![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
>
|
||||||
>
|
>
|
||||||
> If you specifically built and tested this web part to work with Teams, use this for the Teams compatibility tag:
|
> If you specifically built and tested this web part to work with Teams, use this for the Teams compatibility tag:
|
||||||
> ![Teams Yes: Designed for Microsoft Teams](https://img.shields.io/badge/Teams-Yes-green.svg "Designed for Microsoft Teams")
|
> ![Teams Yes: Designed for Microsoft Teams](https://img.shields.io/badge/Teams-Yes-green.svg "Designed for Microsoft Teams")
|
||||||
|
@ -79,8 +87,8 @@ folder name | [Author Name](LinkToYourGitHubProfile) ([@yourtwitterhandle](https
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.1|September 2, 2021|Update comment
|
1.1|November 1, 2021|Update comment
|
||||||
1.0|August 29, 2021|Initial release
|
1.0|October 29, 2021|Initial release
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,14 @@ This simplistic sample web part demonstrates the use of JavaScript in a SharePoi
|
||||||
|
|
||||||
> Does only show data when hosted in SharePoint. No mock data at this point for local testing the rendering.
|
> Does only show data when hosted in SharePoint. No mock data at this point for local testing the rendering.
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
|
|
||||||
![SPFx 1.11.0](https://img.shields.io/badge/drop-1.11.0-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-yellow.svg)
|
||||||
|
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams") ![Local Workbench (Partially)](https://img.shields.io/badge/Local%20Workbench-Partially-yellow.svg "Only basic functionality works on local workbench") ![Hosted Workbench](https://img.shields.io/badge/Hosted%20Workbench-Fully-green.svg "Hosted workbench fully supported")
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -49,13 +54,6 @@ Version|Date|Comments
|
||||||
1.1|May 15, 2017|Updated to GA Version
|
1.1|May 15, 2017|Updated to GA Version
|
||||||
2.0|August 29, 2020|Upgraded to SPFx 1.11.0
|
2.0|August 29, 2020|Upgraded to SPFx 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.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
|
@ -63,7 +61,7 @@ Version|Date|Comments
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `tsd install`
|
- `tsd install`
|
||||||
- `gulp serve`
|
- `gulp serve`
|
||||||
- `Open the *workbench* on your Office 365 Developer tenant`
|
- Open the *workbench* on your Office 365 Developer tenant
|
||||||
- Basic functionality can be tested locally, data is only shown when used in context of SharePoint
|
- Basic functionality can be tested locally, data is only shown when used in context of SharePoint
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
@ -77,4 +75,20 @@ This Web Part illustrates the following concepts on top of the SharePoint Framew
|
||||||
* Logging
|
* Logging
|
||||||
* Rendering error messages.
|
* Rendering error messages.
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=js-display-list&authors=@VelinGeorgiev%20@sharepointknight&title=js-display-list%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=js-display-list&authors=@VelinGeorgiev%20@sharepointknight&title=js-display-list%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=js-display-list&authors=@VelinGeorgiev%20@sharepointknight&title=js-display-list%20-%20).
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-display-list" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-display-list" />
|
||||||
|
|
|
@ -22,11 +22,22 @@ Alternatively, you can add the output files for the web part to a custom SPFx pr
|
||||||
* Copy all files from `js-workbench-customizer\dist` to the `dist` folder of your custom solution
|
* Copy all files from `js-workbench-customizer\dist` to the `dist` folder of your custom solution
|
||||||
* Copy the `workbenchCustomizer` folder from `js-workbench-customizer\lib\webparts` to the corresponding webparts folder of your custom solution
|
* Copy the `workbenchCustomizer` folder from `js-workbench-customizer\lib\webparts` to the corresponding webparts folder of your custom solution
|
||||||
|
|
||||||
Note: This approach will not "pollute" your solution with additional resources or dependencies as the SPFx toolchain will ignore those additional files by default when you package your solution. You can also clean everything by running `gulp clean` as both the lib and dist folders are deleted and recreated again. Git will also ignore dist and lib folders by default, so the files will never be added to source control.
|
> **Note:** This approach will not "pollute" your solution with additional resources or dependencies as the SPFx toolchain will ignore those additional files by default when you package your solution. You can also clean everything by running `gulp clean` as both the lib and dist folders are deleted and recreated again. Git will also ignore dist and lib folders by default, so the files will never be added to source control.
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![1.11.0](https://img.shields.io/badge/drop-1.11.0-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)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%202019-Not%20compatible-red.svg)
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%202016%20(Feature%20Pack%202)-Not%20compatible-red.svg)
|
||||||
|
![Local Workbench Compatible](https://img.shields.io/badge/Local%20Workbench-Compatible-green.svg)
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -54,12 +65,6 @@ Version|Date|Comments
|
||||||
1.4|July 28, 2020|Update styles to minimise toolbar overlap
|
1.4|July 28, 2020|Update styles to minimise toolbar overlap
|
||||||
1.5|July 30, 2020|Update styles to improve full-width mode
|
1.5|July 30, 2020|Update styles to improve full-width mode
|
||||||
|
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
* Clone this repository
|
* Clone this repository
|
||||||
|
@ -67,4 +72,20 @@ Version|Date|Comments
|
||||||
* `npm install`
|
* `npm install`
|
||||||
* `gulp serve`
|
* `gulp serve`
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=js-workbench-customizer&authors=@joelfmrodrigues&title=js-workbench-customizer%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=js-workbench-customizer&authors=@joelfmrodrigues&title=js-workbench-customizer%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=js-workbench-customizer&authors=@joelfmrodrigues&title=js-workbench-customizer%20-%20).
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-workbench-customizer" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-workbench-customizer" />
|
||||||
|
|
|
@ -22,9 +22,14 @@ This is a sample web Part that illustrates the use of React Accessible Accordion
|
||||||
|
|
||||||
![Sample Web Part built using SPFx with React Framework showing list data in accordion format](./assets/AccordionPreview.png)
|
![Sample Web Part built using SPFx with React Framework showing list data in accordion format](./assets/AccordionPreview.png)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
|
|
||||||
![1.10.0](https://img.shields.io/badge/drop-1.10.0-green.svg)
|
## Compatibility
|
||||||
|
|
||||||
|
![SPFx 1.10](https://img.shields.io/badge/SPFx-1.10.0-green.svg)
|
||||||
|
![Node.js LTS 10.x | LTS 8.x](https://img.shields.io/badge/Node.js-LTS%2010.x%7C%20LTS%208.x-green.svg) ![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||||
|
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||||
|
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -46,11 +51,7 @@ Version|Date|Comments
|
||||||
2.0|January 19, 2020|Upgrade to SPFx 1.10
|
2.0|January 19, 2020|Upgrade to SPFx 1.10
|
||||||
2.1|June 22, 2020|Added pagination (Abhishek Garg)
|
2.1|June 22, 2020|Added pagination (Abhishek Garg)
|
||||||
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
|
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
|
||||||
|
2.3|September 30, 2021 | Added sorting (@fthorild)
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
@ -94,4 +95,19 @@ This sample illustrates the following concepts on top of the SharePoint Framewor
|
||||||
- searching in the fetched data by making use of Search Box from Office Fabric UI
|
- searching in the fetched data by making use of Search Box from Office Fabric UI
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-accordion" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-accordion" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This is a sample web Part that illustrates the use of React Accessible Accordion plugin for building SharePoint Framework client-side web parts to show SharePoint list data in Accordion format."
|
"This is a sample web Part that illustrates the use of React Accessible Accordion plugin for building SharePoint Framework client-side web parts to show SharePoint list data in Accordion format."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2020-06-22",
|
"creationDateTime": "2020-06-22",
|
||||||
"updateDateTime": "2020-06-22",
|
"updateDateTime": "2021-09-30",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-accordion-client-side-solution",
|
"name": "react-accordion-client-side-solution",
|
||||||
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
|
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
|
||||||
"version": "2.2.0.0",
|
"version": "2.3.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-accordion",
|
"name": "react-accordion",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-accordion",
|
"name": "react-accordion",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -29,9 +29,12 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
|
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
|
||||||
"listName": "FAQ",
|
"listName": "FAQ",
|
||||||
"totalItems":20,
|
"totalItems": 20,
|
||||||
"maxItemsPerPage": 5,
|
"maxItemsPerPage": 5,
|
||||||
"allowPaging":true
|
"allowPaging": true,
|
||||||
|
"customSortField": "",
|
||||||
|
"sortById": false,
|
||||||
|
"sortByModified": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { Version, DisplayMode } from '@microsoft/sp-core-library';
|
import { Version, DisplayMode } from '@microsoft/sp-core-library';
|
||||||
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
import { IPropertyPaneConfiguration, PropertyPaneSlider, PropertyPaneTextField,PropertyPaneToggle } from "@microsoft/sp-property-pane";
|
import { IPropertyPaneConfiguration, PropertyPaneSlider, PropertyPaneTextField, PropertyPaneToggle } from "@microsoft/sp-property-pane";
|
||||||
|
|
||||||
import * as strings from 'ReactAccordionWebPartStrings';
|
import * as strings from 'ReactAccordionWebPartStrings';
|
||||||
import ReactAccordion from './components/ReactAccordion';
|
import ReactAccordion from './components/ReactAccordion';
|
||||||
|
@ -13,9 +13,12 @@ export interface IReactAccordionWebPartProps {
|
||||||
choice: string;
|
choice: string;
|
||||||
title: string;
|
title: string;
|
||||||
displayMode: DisplayMode;
|
displayMode: DisplayMode;
|
||||||
totalItems:number;
|
totalItems: number;
|
||||||
maxItemsPerPage: number;
|
maxItemsPerPage: number;
|
||||||
enablePaging:boolean;
|
enablePaging: boolean;
|
||||||
|
customSortField: string;
|
||||||
|
sortById: boolean;
|
||||||
|
sortByModified: boolean;
|
||||||
updateProperty: (value: string) => void;
|
updateProperty: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +34,12 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
siteUrl: this.context.pageContext.web.absoluteUrl,
|
siteUrl: this.context.pageContext.web.absoluteUrl,
|
||||||
title: this.properties.title,
|
title: this.properties.title,
|
||||||
displayMode: this.displayMode,
|
displayMode: this.displayMode,
|
||||||
totalItems:this.properties.totalItems,
|
totalItems: this.properties.totalItems,
|
||||||
maxItemsPerPage: this.properties.maxItemsPerPage,
|
maxItemsPerPage: this.properties.maxItemsPerPage,
|
||||||
enablePaging:this.properties.enablePaging,
|
enablePaging: this.properties.enablePaging,
|
||||||
|
customSortField: this.properties.customSortField,
|
||||||
|
sortById: this.properties.sortById,
|
||||||
|
sortByModified: this.properties.sortByModified,
|
||||||
updateProperty: (value: string) => {
|
updateProperty: (value: string) => {
|
||||||
this.properties.title = value;
|
this.properties.title = value;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +59,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
|
|
||||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
//set maxitems to top
|
//set maxitems to top
|
||||||
if(!this.properties.enablePaging){
|
if (!this.properties.enablePaging) {
|
||||||
this.properties.maxItemsPerPage = this.properties.totalItems;
|
this.properties.maxItemsPerPage = this.properties.totalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +89,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
label: strings.EnablePagingLabel
|
label: strings.EnablePagingLabel
|
||||||
}),
|
}),
|
||||||
PropertyPaneSlider('maxItemsPerPage', {
|
PropertyPaneSlider('maxItemsPerPage', {
|
||||||
disabled:!this.properties.enablePaging,
|
disabled: !this.properties.enablePaging,
|
||||||
label: strings.MaxItemsPerPageLabel,
|
label: strings.MaxItemsPerPageLabel,
|
||||||
ariaLabel: strings.MaxItemsPerPageLabel,
|
ariaLabel: strings.MaxItemsPerPageLabel,
|
||||||
min: 3,
|
min: 3,
|
||||||
|
@ -91,6 +97,14 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
value: 5,
|
value: 5,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
step: 1
|
step: 1
|
||||||
|
}),
|
||||||
|
PropertyPaneTextField('customSortField', {
|
||||||
|
label: strings.CustomSortOrder
|
||||||
|
}),
|
||||||
|
PropertyPaneToggle('sortById', {
|
||||||
|
label: strings.SortById
|
||||||
|
}),PropertyPaneToggle('sortByModified', {
|
||||||
|
label: strings.SortByModified
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,8 @@ export interface IReactAccordionProps {
|
||||||
maxItemsPerPage: number;
|
maxItemsPerPage: number;
|
||||||
enablePaging:boolean;
|
enablePaging:boolean;
|
||||||
totalItems:number;
|
totalItems:number;
|
||||||
|
customSortField:string;
|
||||||
|
sortById:boolean;
|
||||||
|
sortByModified:boolean;
|
||||||
updateProperty: (value: string) => void;
|
updateProperty: (value: string) => void;
|
||||||
}
|
}
|
|
@ -7,4 +7,5 @@ export interface IReactAccordionState {
|
||||||
listItems: IAccordionListItem[];
|
listItems: IAccordionListItem[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
loaderMessage: string;
|
loaderMessage: string;
|
||||||
|
error: string;
|
||||||
}
|
}
|
|
@ -30,7 +30,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
items: [],
|
items: [],
|
||||||
listItems: [],
|
listItems: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ''
|
loaderMessage: '',
|
||||||
|
error: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.listNotConfigured(this.props)) {
|
if (!this.listNotConfigured(this.props)) {
|
||||||
|
@ -74,7 +75,23 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
|
|
||||||
private readItems(): void {
|
private readItems(): void {
|
||||||
|
|
||||||
let restAPI = this.props.siteUrl + `/_api/web/Lists/GetByTitle('${this.props.listName}')/items?$select=Title,Description&$top=${this.props.totalItems}`;
|
const orders = [];
|
||||||
|
if (this.props.customSortField) {
|
||||||
|
orders.push(this.props.customSortField);
|
||||||
|
}
|
||||||
|
if (this.props.sortById) {
|
||||||
|
orders.push('ID');
|
||||||
|
}
|
||||||
|
if (this.props.sortByModified) {
|
||||||
|
orders.push('Modified');
|
||||||
|
}
|
||||||
|
|
||||||
|
const selects = `select=Title,Description${this.props.customSortField ? `,${this.props.customSortField}` : ''}`;
|
||||||
|
|
||||||
|
const restAPI = this.props.siteUrl + `/_api/web/Lists/GetByTitle('${this.props.listName}')/items?` +
|
||||||
|
`$${selects}` +
|
||||||
|
`${orders.length > 0 ? '&$orderby=' + orders.join(',') : ''}` +
|
||||||
|
`&$top=${this.props.totalItems}`;
|
||||||
|
|
||||||
this.props.spHttpClient.get(restAPI, SPHttpClient.configurations.v1, {
|
this.props.spHttpClient.get(restAPI, SPHttpClient.configurations.v1, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -86,6 +103,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((response: { value: IAccordionListItem[] }): void => {
|
.then((response: { value: IAccordionListItem[] }): void => {
|
||||||
|
if (!response.value) {
|
||||||
|
this.setState({
|
||||||
|
error: `No items were found, check the list Title and/or custom sort order field internal name`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let listItemsCollection = [...response.value];
|
let listItemsCollection = [...response.value];
|
||||||
|
|
||||||
|
@ -95,14 +117,16 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
items: response.value,
|
items: response.value,
|
||||||
listItems: response.value,
|
listItems: response.value,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ""
|
loaderMessage: '',
|
||||||
|
error: ''
|
||||||
});
|
});
|
||||||
}, (error: any): void => {
|
}, (error: any): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
status: 'Loading all items failed with error: ' + error,
|
status: 'Loading all items failed with error: ' + error,
|
||||||
pagedItems: [],
|
pagedItems: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ""
|
loaderMessage: "",
|
||||||
|
error: `Loading failed. Validate that you have entered a valid List Title and/or internal field name for the custom sort order ${error}`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,6 +134,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
|
|
||||||
public render(): React.ReactElement<IReactAccordionProps> {
|
public render(): React.ReactElement<IReactAccordionProps> {
|
||||||
let displayLoader;
|
let displayLoader;
|
||||||
|
let errorMessage;
|
||||||
let faqTitle;
|
let faqTitle;
|
||||||
let { items } = this.state;
|
let { items } = this.state;
|
||||||
let pageCountDivisor: number = this.props.maxItemsPerPage;
|
let pageCountDivisor: number = this.props.maxItemsPerPage;
|
||||||
|
@ -149,7 +174,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
displayLoader = (null);
|
displayLoader = (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.props.enablePaging){
|
if (this.props.enablePaging) {
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
pageCount = Math.ceil(items.length / pageCountDivisor);
|
pageCount = Math.ceil(items.length / pageCountDivisor);
|
||||||
}
|
}
|
||||||
|
@ -157,6 +182,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
pageButtons.push(<PrimaryButton onClick={() => { _pagedButtonClick(i + 1, items); }}> {i + 1} </PrimaryButton>);
|
pageButtons.push(<PrimaryButton onClick={() => { _pagedButtonClick(i + 1, items); }}> {i + 1} </PrimaryButton>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.state.error) {
|
||||||
|
errorMessage = <div>{this.state.error}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.reactAccordion}>
|
<div className={styles.reactAccordion}>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
@ -175,7 +205,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
<div className={`ms-Grid-row`}>
|
<div className={`ms-Grid-row`}>
|
||||||
<div className='ms-Grid-col ms-u-lg12'>
|
<div className='ms-Grid-col ms-u-lg12'>
|
||||||
{this.state.status}
|
{this.state.status}
|
||||||
<Accordion accordion={false}>
|
<Accordion>
|
||||||
{pagedItems}
|
{pagedItems}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,6 +216,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{errorMessage}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ define([], function () {
|
||||||
"ListNameLabel": "List Name",
|
"ListNameLabel": "List Name",
|
||||||
"MaxItemsPerPageLabel": "Max number of items per page",
|
"MaxItemsPerPageLabel": "Max number of items per page",
|
||||||
"EnablePagingLabel":"Enable Paging",
|
"EnablePagingLabel":"Enable Paging",
|
||||||
"TotalItemsLabel":"Maximum items to retrieve"
|
"TotalItemsLabel":"Maximum items to retrieve",
|
||||||
|
"CustomSortOrder":"Custom sort order",
|
||||||
|
"SortById":"Sort by ID",
|
||||||
|
"SortByModified":"Sort by modified date"
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -5,6 +5,9 @@ declare interface IReactAccordionWebPartStrings {
|
||||||
MaxItemsPerPageLabel: string;
|
MaxItemsPerPageLabel: string;
|
||||||
EnablePagingLabel: string;
|
EnablePagingLabel: string;
|
||||||
TotalItemsLabel:string;
|
TotalItemsLabel:string;
|
||||||
|
CustomSortOrder:string;
|
||||||
|
SortById:string;
|
||||||
|
SortByModified:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'ReactAccordionWebPartStrings' {
|
declare module 'ReactAccordionWebPartStrings' {
|
||||||
|
|
|
@ -6,9 +6,14 @@ A version of [react-adaptivecards](https://github.com/pnp/sp-dev-fx-webparts/tre
|
||||||
|
|
||||||
![Adaptive Cards in SharePoint](assets/preview.png)
|
![Adaptive Cards in SharePoint](assets/preview.png)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
|
|
||||||
![1.11.0](https://img.shields.io/badge/version-1.11.0-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-yellow.svg)
|
||||||
|
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||||
|
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -29,12 +34,6 @@ Version|Date|Comments
|
||||||
1.0|April 27, 2020|Initial release
|
1.0|April 27, 2020|Initial release
|
||||||
2.0|August 25, 2020|Upgraded to SPFx 1.11 and added support for May 2020 changes to Adaptive Cards
|
2.0|August 25, 2020|Upgraded to SPFx 1.11 and added support for May 2020 changes to Adaptive Cards
|
||||||
|
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
* Clone this repository
|
* Clone this repository
|
||||||
|
@ -55,5 +54,20 @@ Version|Date|Comments
|
||||||
| AdaptiveCardHost.tsx | React Function component | Renders placeholder if template/data are missing. Handles card actions. |
|
| AdaptiveCardHost.tsx | React Function component | Renders placeholder if template/data are missing. Handles card actions. |
|
||||||
| AdaptiveCard.tsx | React Class component | Responsible for rendering adaptive card and expanding card with data |
|
| AdaptiveCard.tsx | React Class component | Responsible for rendering adaptive card and expanding card with data |
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-adaptivecards-hooks&authors=@pschaeflein&title=react-adaptivecards-hooks%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-adaptivecards-hooks&authors=@pschaeflein&title=react-adaptivecards-hooks%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-adaptivecards-hooks&authors=@pschaeflein&title=react-adaptivecards-hooks%20-%20).
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-adaptivecards-hooks" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-adaptivecards-hooks" />
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,12 @@ Attempts to replicate the functionality of Page Properties with the following im
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
![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)
|
![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-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "This solution requires access to information about the hosting page")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-yellow.svg "Works better when placed on a modern site page.")
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# react-at-a-glance
|
# At a glance
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ This sample shows a web part to show the first few sentences of an article in a
|
||||||
The idea is based of the *At a glance* section of a news in the BBC news app (beta).
|
The idea is based of the *At a glance* section of a news in the BBC news app (beta).
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
- Usage of `SPHttpClient` or `PnP JS`
|
- Usage of `SPHttpClient` or `PnPjs`
|
||||||
- Conditional property enabling
|
- Conditional property enabling
|
||||||
- Usage of regex to get the sentences from article content
|
- Usage of regex to get the sentences from article content
|
||||||
- Usage of Carousel for mobile view
|
- Usage of Carousel for mobile view
|
||||||
|
@ -31,14 +31,16 @@ The idea is based of the *At a glance* section of a news in the BBC news app (be
|
||||||
|
|
||||||
![article-content-desktop](./assets/article-content-desktop.png)
|
![article-content-desktop](./assets/article-content-desktop.png)
|
||||||
|
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to a news page to work")
|
||||||
|
![Hosted Workbench Partially](https://img.shields.io/badge/Hosted%20Workbench-Partially-yellow.svg "The solution needs to run on a news page to work")
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -62,17 +64,18 @@ react-at-a-glance | [Anoop Tatti](https://github.com/anoopt) ([https://linktr.ee
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|September 07, 2021|Initial release
|
1.0|September 07, 2021|Initial release
|
||||||
|
1.1|October 20, 2021|Minor CSS changes
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
- Ensure that you are at the solution folder
|
- Ensure that you are at the solution folder
|
||||||
- in the command-line run:
|
- in the command-line run:
|
||||||
- **npm install**
|
- `npm install`
|
||||||
- **gulp serve**
|
- `gulp serve`
|
||||||
- Open a news article
|
- Open a news article
|
||||||
- Add `?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js` to the URL
|
- Add `?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js` to the URL
|
||||||
- Add the `At a glance` web part to the page
|
- Add the **At a glance** web part to the page
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"The idea is based of the At a glance section of a news in the BBC news app."
|
"The idea is based of the At a glance section of a news in the BBC news app."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2021-09-07",
|
"creationDateTime": "2021-09-07",
|
||||||
"updateDateTime": "2021-09-07",
|
"updateDateTime": "2021-10-20",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -77,6 +77,10 @@ export default class NewsGlanceWebPart extends BaseClientSideWebPart<INewsGlance
|
||||||
let element: any;
|
let element: any;
|
||||||
|
|
||||||
if (this.width < 400) {
|
if (this.width < 400) {
|
||||||
|
this.sentences = this.sentences.map(sentence => {
|
||||||
|
return sentence.length > 100 ? `${sentence.slice(0, 100)}...` : sentence;
|
||||||
|
});
|
||||||
|
|
||||||
element = React.createElement(
|
element = React.createElement(
|
||||||
NewsGlanceSmall,
|
NewsGlanceSmall,
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,13 +25,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftItem {
|
.leftItem {
|
||||||
max-width: 150px;
|
max-width: 200px;
|
||||||
object-fit: contain;
|
flex: 1;
|
||||||
align-self: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rightItem {
|
.rightItem {
|
||||||
flex: 1 1 auto;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.articleImage {
|
.articleImage {
|
||||||
|
|
|
@ -8,10 +8,8 @@
|
||||||
|
|
||||||
.carouselItem {
|
.carouselItem {
|
||||||
background-color: $ms-color-themeDark;
|
background-color: $ms-color-themeDark;
|
||||||
// display: flex;
|
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
height: 98%;
|
height: 98%;
|
||||||
// justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carouselDotList {
|
.carouselDotList {
|
||||||
|
|
|
@ -119,7 +119,7 @@ Calendar Web Part|[Eli H. Schei](https://github.com/Eli-Schei)
|
||||||
Calendar Web Part|[Hugo Bernier](https://github.com/hugoabernier) ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/))
|
Calendar Web Part|[Hugo Bernier](https://github.com/hugoabernier) ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/))
|
||||||
Calendar Web Part|[João Mendes](https://github.com/joaojmendes)
|
Calendar Web Part|[João Mendes](https://github.com/joaojmendes)
|
||||||
Calendar Web Part|[Mohamed Derhalli](https://github.com/derhallim)
|
Calendar Web Part|[Mohamed Derhalli](https://github.com/derhallim)
|
||||||
Calendar Web PArt|[Mohammed Amer](https://www.linkedin.com/in/mohammad3mer/) ([@Mohammad3mer](https://twitter.com/Mohammad3mer))
|
Calendar Web PArt|[Mohammed Amer](https://github.com/mohammadamer) ([@Mohammad3mer](https://twitter.com/Mohammad3mer), https://www.linkedin.com/in/mohammad3mer/)
|
||||||
Calendar Web Part|[Nanddeep Nachan](https://github.com/nanddeepn) ([@NanddeepNachan](https://twitter.com/NanddeepNachan))
|
Calendar Web Part|[Nanddeep Nachan](https://github.com/nanddeepn) ([@NanddeepNachan](https://twitter.com/NanddeepNachan))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
@ -139,6 +139,8 @@ Version|Date|Comments
|
||||||
1.0.10|March 27, 2021|Updated prompt message when deleting single v/s multi-event.
|
1.0.10|March 27, 2021|Updated prompt message when deleting single v/s multi-event.
|
||||||
1.0.11|May 10, 2021|Optimized page refresh using local storage
|
1.0.11|May 10, 2021|Optimized page refresh using local storage
|
||||||
1.0.12|June 21, 2021|Fixes overlap with Year-view and the comment section by adding a vertical scrollbar.
|
1.0.12|June 21, 2021|Fixes overlap with Year-view and the comment section by adding a vertical scrollbar.
|
||||||
|
1.0.13|October 2, 2021|Fix to make sure Today is always visible and highlighted.
|
||||||
|
1.0.14|October 16, 2021|Resolve unhandled exception that happens clicking on recurrent events
|
||||||
|
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
@ -160,11 +162,11 @@ Version|Date|Comments
|
||||||
|
|
||||||
We do not support samples, but we do use GitHub to track issues and constantly want to improve these samples.
|
We do not support samples, but we do use GitHub to track issues and constantly want to improve these samples.
|
||||||
|
|
||||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@mohammadamer,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
||||||
|
|
||||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@mohammadamer,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
||||||
|
|
||||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@mohammadamer,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This Web Part allows you to manage events in a calendar. Uses a list of existing calendars on any website. The location and name of the list and the dates of the events to be displayed are defined in the properties of the web part."
|
"This Web Part allows you to manage events in a calendar. Uses a list of existing calendars on any website. The location and name of the list and the dates of the events to be displayed are defined in the properties of the web part."
|
||||||
],
|
],
|
||||||
"created": "2020-12-04",
|
"created": "2020-12-04",
|
||||||
"modified": "2021-07-14",
|
"modified": "2021-10-16",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -369,6 +369,8 @@ export default class parseRecurrentEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.fRecurrence === "1" && e.MasterSeriesItemID !== "") {
|
if (e.fRecurrence === "1" && e.MasterSeriesItemID !== "") {
|
||||||
|
e.EventDate = new Date(this.parseDate(e.EventDate, e.fAllDayEvent));
|
||||||
|
e.EndDate = new Date(this.parseDate(e.EndDate, e.fAllDayEvent));
|
||||||
const ni = this.cloneObj(e);
|
const ni = this.cloneObj(e);
|
||||||
er.push(ni);
|
er.push(ni);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,50 +4,52 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.month {
|
.month {
|
||||||
margin: 5px 10px 15px 10px;
|
margin: 5px 10px 15px 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.monthName {
|
.monthName {
|
||||||
color: $ms-color-themeDark;
|
color: $ms-color-themePrimary;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day {
|
.day {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
border: dotted 1px;
|
border: dotted 1px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
transform: scale(0.9, 0.9);
|
transform: scale(0.9, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.date {
|
.date {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background: white;
|
border-radius: 50px;
|
||||||
border-radius: 50px;
|
border: none;
|
||||||
border: none;
|
outline: none;
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date.inMonth:hover {
|
&.inMonth {
|
||||||
cursor: pointer;
|
&:hover {
|
||||||
background: $ms-color-themeDark;
|
cursor: pointer;
|
||||||
color: white;
|
background: $ms-color-themePrimary;
|
||||||
font-weight: bold;
|
color: white;
|
||||||
}
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.today {
|
&.today {
|
||||||
background: $ms-color-themeDark;
|
background: $ms-color-themePrimary;
|
||||||
}
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.date.prevMonth,
|
.date.prevMonth,
|
||||||
.date.nextMonth {
|
.date.nextMonth {
|
||||||
color: grey;
|
color: grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ function CalendarDate(props) {
|
||||||
const { dateToRender, dateOfMonth } = props;
|
const { dateToRender, dateOfMonth } = props;
|
||||||
const today =
|
const today =
|
||||||
dateToRender.format('YYYY-MM-DD') === moment().format('YYYY-MM-DD')
|
dateToRender.format('YYYY-MM-DD') === moment().format('YYYY-MM-DD')
|
||||||
? 'today'
|
? styles.today
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
if (dateToRender.month() < dateOfMonth.month()) {
|
if (dateToRender.month() < dateOfMonth.month()) {
|
||||||
|
|
|
@ -170,7 +170,14 @@ This sample shows how to use X and Y coordinate data elements in a scatter chart
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11-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 | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
![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)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to SharePoint content")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
Search People from Organization Directory and show live persona card on hover.
|
Search People from Organization Directory and show live persona card on hover.
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
![directory](/samples/react-directory/assets/react-directory7.png)
|
![directory](/samples/react-directory/assets/react-directory7.png)
|
||||||
|
@ -34,10 +33,12 @@
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
![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)
|
![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-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to your organization directory")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -77,13 +78,6 @@ Version|Date|Comments
|
||||||
3.0.0|Oct 17 2020|Minor fixes and add the additional web part property.
|
3.0.0|Oct 17 2020|Minor fixes and add the additional web part property.
|
||||||
3.0.1|March 4 2021|Bugfix 'Sort People by'
|
3.0.1|March 4 2021|Bugfix 'Sort People by'
|
||||||
|
|
||||||
|
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
|
@ -92,6 +86,20 @@ Version|Date|Comments
|
||||||
- `gulp build`
|
- `gulp build`
|
||||||
- `gulp bundle --ship`
|
- `gulp bundle --ship`
|
||||||
- `gulp package-solution --ship`
|
- `gulp package-solution --ship`
|
||||||
- `Add to AppCatalog and deploy`
|
- Add to AppCatalog and deploy
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-directory&authors=@joaojmendes%20@petkir%20@sudharsank%20@Abderahman88&title=react-directory%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-directory&authors=@joaojmendes%20@petkir%20@sudharsank%20@Abderahman88&title=react-directory%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-directory&authors=@joaojmendes%20@petkir%20@sudharsank%20@Abderahman88&title=react-directory%20-%20).
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-directory" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-directory" />
|
||||||
|
|
|
@ -29,9 +29,16 @@ Below NPM packages are used to develop this sample.
|
||||||
2. react-orgchart (https://www.npmjs.com/package/react-orgchart)
|
2. react-orgchart (https://www.npmjs.com/package/react-orgchart)
|
||||||
3. array-to-tree (https://www.npmjs.com/package/array-to-tree)
|
3. array-to-tree (https://www.npmjs.com/package/array-to-tree)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/version-1.11.0-green.svg)
|
![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)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to SharePoint content")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -52,12 +59,6 @@ Version|Date|Comments
|
||||||
2.0.0|November 21, 2020|Upgraded to SPFx v1.11.0 (Nanddeep Nachan)
|
2.0.0|November 21, 2020|Upgraded to SPFx v1.11.0 (Nanddeep Nachan)
|
||||||
1.0.0|October 15, 2018|Initial release
|
1.0.0|October 15, 2018|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
|
## Prerequisites
|
||||||
|
|
||||||
- SharePoint Online tenant
|
- SharePoint Online tenant
|
||||||
|
@ -93,4 +94,18 @@ This sample web part shows how data stored in SharePoint list can be transformed
|
||||||
[figure5]: ./assets/list-sample-data.png
|
[figure5]: ./assets/list-sample-data.png
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-display-hierarchy&authors=@nanddeepn%20@ravi16a87&title=react-display-hierarchy%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-display-hierarchy&authors=@nanddeepn%20@ravi16a87&title=react-display-hierarchy%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-display-hierarchy&authors=@nanddeepn%20@ravi16a87&title=react-display-hierarchy%20-%20).
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-display-hierarchy" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-display-hierarchy" />
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
release
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.12.1",
|
||||||
|
"libraryName": "react-menu-accordion",
|
||||||
|
"libraryId": "f7134ff1-6e97-430c-9a73-5dc4902c75e3",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
# Documents Links Accordion
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This web part allows user create a accordion with documents links grouped by any column of document library.
|
||||||
|
When the user clicks on the header it dynamically load documents.
|
||||||
|
|
||||||
|
![documentsLinksAccordion](./assets/documentsLinksAccordion.gif)
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
![documentsLinksAccordion](./assets/documentsLinksAccordion1.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg)
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-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)
|
||||||
|
|
||||||
|
## Web Part Properties
|
||||||
|
|
||||||
|
Property |Type|Required| comments
|
||||||
|
--------------------|----|--------|----------
|
||||||
|
Web part Title| Text| no|
|
||||||
|
Select Document Library| dropdown|yes
|
||||||
|
Select Field to Group By | dropdown|yes
|
||||||
|
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
The web part Use PnPjs library, Fluent-Ui-react components
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
React Documents Links Accordion |[João Mendes](https://github.com/joaojmendes) ([@joaojmendes](https://twitter.com/joaojmendes))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0.0|October 10, 2021|Initial release
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
- Clone this repository
|
||||||
|
- Move to sample folder
|
||||||
|
- in the command line run:
|
||||||
|
- `npm install`
|
||||||
|
- `gulp build`
|
||||||
|
- `gulp bundle --ship`
|
||||||
|
- `gulp package-solution --ship`
|
||||||
|
- Add to AppCatalog and deploy
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-list-items-menu&authors=@joaojmendes%20@Ravikadri&title=react-list-items-menu%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-list-items-menu&authors=@joaojmendes%20@Ravikadri&title=react-list-items-menu%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-list-items-menu&authors=@joaojmendes%20@Ravikadri&title=react-list-items-menu%20-%20).
|
||||||
|
|
||||||
|
|
||||||
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-documents-links-accordion" />
|
After Width: | Height: | Size: 3.1 MiB |
After Width: | Height: | Size: 460 KiB |
|
@ -0,0 +1,89 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "pnp-sp-dev-spfx-web-parts-react-document-links-accordion",
|
||||||
|
"source": "pnp",
|
||||||
|
"title": "Documents Links Accordion",
|
||||||
|
"shortDescription": "This web part allows user create a accordion with documents links grouped by any column of document library.",
|
||||||
|
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-document-links-accordion",
|
||||||
|
"longDescription": [
|
||||||
|
"This web part allows user create a accordion with documents links grouped by any column of document library.",
|
||||||
|
"When the user clicks on the header it dynamically load documents."
|
||||||
|
],
|
||||||
|
"creationDateTime": "2021-10-10",
|
||||||
|
"updateDateTime": "2021-10-10",
|
||||||
|
"products": [
|
||||||
|
"SharePoint",
|
||||||
|
"Office"
|
||||||
|
],
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"key": "CLIENT-SIDE-DEV",
|
||||||
|
"value": "React"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SPFX-VERSION",
|
||||||
|
"value": "1.12.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SPFX-FULLPAGEAPP",
|
||||||
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SPFX-TEAMSTAB",
|
||||||
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SPFX-TEAMSPERSONALAPP",
|
||||||
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "REACT-HOOKS",
|
||||||
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "PNPCONTROLS",
|
||||||
|
"value": "PropertyFieldListPicker, PropertyFieldMessage, PropertyFieldSpinner, Placeholder, AccessibleAccordion"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"order": 100,
|
||||||
|
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-document-links-accordion/assets/documentsLinksAccordion.gif",
|
||||||
|
"alt": "Web part in action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"order": 101,
|
||||||
|
"url": "https://github.com/pnp/sp-dev-fx-webparts/blob/main/samples/react-document-links-accordion/assets/documentsLinksAccordion1.png",
|
||||||
|
"alt": "Screen shot of web part"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"gitHubAccount": "joaojmendes",
|
||||||
|
"company": "Storm Technology Ltd",
|
||||||
|
"pictureUrl": "https://github.com/joaojmendes.png",
|
||||||
|
"name": "Jo\u00E3o Mendes",
|
||||||
|
"twitter": "joaojmendes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Build your first SharePoint client-side web part",
|
||||||
|
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
|
||||||
|
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Supporting section backgrounds",
|
||||||
|
"description": "Starting with SharePoint Framework v1.8, web parts can be made aware of any section backgrounds and use these colors to improve the appearance of a web part when hosted in a section with a different background.",
|
||||||
|
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/supporting-section-backgrounds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Building Microsoft Teams Tabs using SharePoint Framework",
|
||||||
|
"description": "Starting with SharePoint Framework v1.8, you can build tabs for Microsoft Teams with the SharePoint Framework tooling and use SharePoint as a host for your solutions. As part of the SharePoint Framework v1.10 you can also publish your solution as Microsoft Teams personal app.",
|
||||||
|
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/integrate-with-teams-introduction"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
|
"version": "2.0",
|
||||||
|
"bundles": {
|
||||||
|
"documentslinksaccordion-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/DocumentsLinksAccordion/DocumentsLinksAccordionWebPart.js",
|
||||||
|
"manifest": "./src/webparts/DocumentsLinksAccordion/DocumentsLinksAccordionWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externals": {},
|
||||||
|
"localizedResources": {
|
||||||
|
"DocumentsLinksAccordionWebPartStrings": "lib/webparts/DocumentsLinksAccordion/loc/{locale}.js",
|
||||||
|
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
|
||||||
|
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||||
|
"deployCdnPath": "./release/assets/"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
|
"workingDir": "./release/assets/",
|
||||||
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
|
"container": "react-menu-accordion",
|
||||||
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
|
"solution": {
|
||||||
|
"name": "react-documentslinks-accordion",
|
||||||
|
"id": "f7134ff1-6e97-430c-9a73-5dc4902c75e3",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"includeClientSideAssets": true,
|
||||||
|
"skipFeatureDeployment": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"mpnId": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"zippedPackage": "solution/react-documentslinks-accordion.sppkg"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const build = require('@microsoft/sp-build-web');
|
||||||
|
|
||||||
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
|
var getTasks = build.rig.getTasks;
|
||||||
|
build.rig.getTasks = function () {
|
||||||
|
var result = getTasks.call(build.rig);
|
||||||
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
build.initialize(require('gulp'));
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "react-documentslinks-accordion",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp bundle",
|
||||||
|
"clean": "gulp clean",
|
||||||
|
"test": "gulp test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@microsoft/sp-core-library": "1.12.1",
|
||||||
|
"@microsoft/sp-lodash-subset": "1.12.1",
|
||||||
|
"@microsoft/sp-office-ui-fabric-core": "1.12.1",
|
||||||
|
"@microsoft/sp-property-pane": "1.12.1",
|
||||||
|
"@microsoft/sp-webpart-base": "1.12.1",
|
||||||
|
"@pnp/spfx-controls-react": "^3.3.0",
|
||||||
|
"@pnp/spfx-property-controls": "^3.2.0",
|
||||||
|
"@uifabric/file-type-icons": "^7.8.1",
|
||||||
|
"date-fns": "^2.25.0",
|
||||||
|
"office-ui-fabric-react": "7.156.0",
|
||||||
|
"react": "16.9.0",
|
||||||
|
"react-dom": "16.9.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "16.9.36",
|
||||||
|
"@types/react-dom": "16.9.8",
|
||||||
|
"@microsoft/sp-build-web": "1.12.1",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.12.1",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.12.1",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.12.1",
|
||||||
|
"@microsoft/rush-stack-compiler-3.7": "0.2.3",
|
||||||
|
"gulp": "~4.0.2",
|
||||||
|
"ajv": "~5.2.2",
|
||||||
|
"@types/webpack-env": "1.13.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
import { SPComponentLoader } from "@microsoft/sp-loader";
|
||||||
|
import { sp } from "@pnp/sp";
|
||||||
|
import "@pnp/sp/webs";
|
||||||
|
import "@pnp/sp/regional-settings/web";
|
||||||
|
import { IRegionalSettingsInfo } from "@pnp/sp/regional-settings";
|
||||||
|
|
||||||
|
// get all the web's regional settings
|
||||||
|
|
||||||
|
const DEFAULT_PERSONA_IMG_HASH: string = "7ad602295f8386b7615b582d87bcc294";
|
||||||
|
const DEFAULT_IMAGE_PLACEHOLDER_HASH: string = "4a48f26592f4e1498d7a478a4c48609c";
|
||||||
|
const MD5_MODULE_ID: string = "8494e7d7-6b99-47b2-a741-59873e42f16f";
|
||||||
|
const PROFILE_IMAGE_URL: string = "/_layouts/15/userphoto.aspx?size=M&accountname=";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets user photo
|
||||||
|
* @param userId
|
||||||
|
* @returns user photo
|
||||||
|
*/
|
||||||
|
export const getUserPhoto = async (userId): Promise<string> => {
|
||||||
|
const personaImgUrl = PROFILE_IMAGE_URL + userId;
|
||||||
|
console.log(personaImgUrl);
|
||||||
|
// tslint:disable-next-line: no-use-before-declare
|
||||||
|
const url: string = await getImageBase64(personaImgUrl);
|
||||||
|
// tslint:disable-next-line: no-use-before-declare
|
||||||
|
const newHash = await getMd5HashForUrl(url);
|
||||||
|
|
||||||
|
if (newHash !== DEFAULT_PERSONA_IMG_HASH && newHash !== DEFAULT_IMAGE_PLACEHOLDER_HASH) {
|
||||||
|
return "data:image/png;base64," + url;
|
||||||
|
} else {
|
||||||
|
return "undefined";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get MD5Hash for the image url to verify whether user has default image or custom image
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
export const getMd5HashForUrl = async (url: string) => {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
// tslint:disable-next-line: no-use-before-declare
|
||||||
|
const library: any = await loadSPComponentById(MD5_MODULE_ID);
|
||||||
|
try {
|
||||||
|
const md5Hash = library.Md5Hash;
|
||||||
|
if (md5Hash) {
|
||||||
|
const convertedHash = md5Hash(url);
|
||||||
|
resolve(convertedHash);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
resolve(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load SPFx component by id, SPComponentLoader is used to load the SPFx components
|
||||||
|
* @param componentId - componentId, guid of the component library
|
||||||
|
*/
|
||||||
|
export const loadSPComponentById = async (componentId: string) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
SPComponentLoader.loadComponentById(componentId)
|
||||||
|
.then((component: any) => {
|
||||||
|
resolve(component);
|
||||||
|
})
|
||||||
|
.catch((error) => {});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Gets image base64
|
||||||
|
* @param pictureUrl
|
||||||
|
* @returns image base64
|
||||||
|
*/
|
||||||
|
export const getImageBase64 = async (pictureUrl: string): Promise<string> => {
|
||||||
|
console.log(pictureUrl);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let image = new Image();
|
||||||
|
image.addEventListener("load", () => {
|
||||||
|
let tempCanvas = document.createElement("canvas");
|
||||||
|
(tempCanvas.width = image.width),
|
||||||
|
(tempCanvas.height = image.height),
|
||||||
|
tempCanvas.getContext("2d").drawImage(image, 0, 0);
|
||||||
|
let base64Str;
|
||||||
|
try {
|
||||||
|
base64Str = tempCanvas.toDataURL("image/png");
|
||||||
|
} catch (e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
base64Str = base64Str.replace(/^data:image\/png;base64,/, "");
|
||||||
|
resolve(base64Str);
|
||||||
|
});
|
||||||
|
image.src = pictureUrl;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const zeroPad = (num, places) => {
|
||||||
|
var zero = places - num.toString().length + 1;
|
||||||
|
return Array(+(zero > 0 && zero)).join("0") + num;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSiteRegionalSettings = async (): Promise<IRegionalSettingsInfo> => {
|
||||||
|
try {
|
||||||
|
const s = await sp.web.regionalSettings();
|
||||||
|
return s;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
Promise.reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertTimeTo12H = (
|
||||||
|
_hour: number
|
||||||
|
): Promise<{ hourInTimeFormat: string; current12HTimeFormat: string }> => {
|
||||||
|
console.log("prm", _hour);
|
||||||
|
return new Promise((resolve, rejected) => {
|
||||||
|
let hourInTimeFormat: string = "";
|
||||||
|
let current12HTimeFormat: string = "AM";
|
||||||
|
if (_hour >= 0 && _hour <= 11) {
|
||||||
|
if (_hour === 0) {
|
||||||
|
hourInTimeFormat = "12";
|
||||||
|
} else {
|
||||||
|
hourInTimeFormat = _hour.toString();
|
||||||
|
}
|
||||||
|
current12HTimeFormat = "AM";
|
||||||
|
} else {
|
||||||
|
const _hour12h = _hour - 12;
|
||||||
|
hourInTimeFormat = _hour12h === 0 ? "12" : _hour12h.toString();
|
||||||
|
current12HTimeFormat = "PM";
|
||||||
|
}
|
||||||
|
resolve({ hourInTimeFormat, current12HTimeFormat });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertTimeTo24h = (hour: number, current12HTimeFormat: string): Promise<string> => {
|
||||||
|
return new Promise((resolve, rejected) => {
|
||||||
|
let hourInTimeFormat: string = "";
|
||||||
|
if (current12HTimeFormat === "PM") {
|
||||||
|
if (hour >= 1 && hour <= 11) {
|
||||||
|
if (hour === 12) {
|
||||||
|
hourInTimeFormat = "12";
|
||||||
|
}
|
||||||
|
const _hour24h = hour + 12;
|
||||||
|
hourInTimeFormat = _hour24h.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hour === 12) {
|
||||||
|
hourInTimeFormat = "00";
|
||||||
|
} else {
|
||||||
|
hourInTimeFormat = hour.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(hourInTimeFormat);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Check if string is valid date */
|
||||||
|
export const checkIfValidDate = (str:string):boolean => {
|
||||||
|
// Regular expression to check if string is valid date
|
||||||
|
const regexExp = /(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})/gi;
|
||||||
|
|
||||||
|
return regexExp.test(str);
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||||
|
import { MSGraphClient, AadTokenProvider } from "@microsoft/sp-http";
|
||||||
|
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||||
|
import { IRegionalSettingsInfo} from "@pnp/sp/regional-settings";
|
||||||
|
|
||||||
|
|
||||||
|
export interface IAppContextProps {
|
||||||
|
currentUser:string;
|
||||||
|
msGraphClient:MSGraphClient;
|
||||||
|
locale:string;
|
||||||
|
themeVariant: IReadonlyTheme | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppContext = React.createContext<IAppContextProps>(undefined);
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { IDatePickerStrings } from 'office-ui-fabric-react/lib/DatePicker';
|
||||||
|
export const DayPickerStrings: IDatePickerStrings = {
|
||||||
|
months: [
|
||||||
|
'January',
|
||||||
|
'February',
|
||||||
|
'March',
|
||||||
|
'April',
|
||||||
|
'May',
|
||||||
|
'June',
|
||||||
|
'July',
|
||||||
|
'August',
|
||||||
|
'September',
|
||||||
|
'October',
|
||||||
|
'November',
|
||||||
|
'December',
|
||||||
|
],
|
||||||
|
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||||
|
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||||
|
shortDays: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
|
||||||
|
goToToday: 'Go to today',
|
||||||
|
prevMonthAriaLabel: 'Go to previous month',
|
||||||
|
nextMonthAriaLabel: 'Go to next month',
|
||||||
|
prevYearAriaLabel: 'Go to previous year',
|
||||||
|
nextYearAriaLabel: 'Go to next year',
|
||||||
|
closeButtonAriaLabel: 'Close date picker',
|
||||||
|
monthPickerHeaderAriaLabel: '{0}, select to change the year',
|
||||||
|
yearPickerHeaderAriaLabel: '{0}, select to change the month',
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
$default-background: #f3f2f1;
|
||||||
|
$default-color: #252423;
|
||||||
|
$default-button-background: #6264a7;
|
||||||
|
$default-Button-color: #f3f2f1;
|
||||||
|
|
||||||
|
// dark theme
|
||||||
|
$dark-background: #2d2c2c;
|
||||||
|
$dark-color: #ffffff;
|
||||||
|
$dark-button-background: #6264a7;
|
||||||
|
$dark-button-color: #2d2c2c;
|
||||||
|
|
||||||
|
// contrast theme
|
||||||
|
$contrast-background: #000000;
|
||||||
|
$contrast-color: #ffffff;
|
||||||
|
$contrast-button-background: #b5c01c;
|
||||||
|
$contrast-Button-color: #000000;
|
|
@ -0,0 +1,74 @@
|
||||||
|
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||||
|
|
||||||
|
.DocumentsLinksAccordion {
|
||||||
|
.container {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 0px auto;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
background-color: $ms-color-themeDark;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
@include ms-Grid-col;
|
||||||
|
@include ms-lg10;
|
||||||
|
@include ms-xl8;
|
||||||
|
@include ms-xlPush2;
|
||||||
|
@include ms-lgPush1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include ms-font-xl;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subTitle {
|
||||||
|
@include ms-font-l;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@include ms-font-l;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
// Our button
|
||||||
|
text-decoration: none;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
// Primary Button
|
||||||
|
min-width: 80px;
|
||||||
|
background-color: $ms-color-themePrimary;
|
||||||
|
border-color: $ms-color-themePrimary;
|
||||||
|
color: $ms-color-white;
|
||||||
|
|
||||||
|
// Basic Button
|
||||||
|
outline: transparent;
|
||||||
|
position: relative;
|
||||||
|
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: $ms-font-size-m;
|
||||||
|
font-weight: $ms-font-weight-regular;
|
||||||
|
border-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 16px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: $ms-font-weight-semibold;
|
||||||
|
font-size: $ms-font-size-m;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
margin: 0 4px;
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,356 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import * as strings from "DocumentsLinksAccordionWebPartStrings";
|
||||||
|
import { filter, findIndex, uniqBy } from "lodash";
|
||||||
|
import {
|
||||||
|
Customizer,
|
||||||
|
INavLink,
|
||||||
|
INavLinkGroup,
|
||||||
|
Label,
|
||||||
|
Link,
|
||||||
|
mergeStyleSets,
|
||||||
|
MessageBar,
|
||||||
|
MessageBarType,
|
||||||
|
Spinner,
|
||||||
|
SpinnerSize,
|
||||||
|
Stack,
|
||||||
|
FontIcon,
|
||||||
|
Text,
|
||||||
|
DetailsList,
|
||||||
|
DetailsListLayoutMode,
|
||||||
|
IColumn,
|
||||||
|
SelectionMode,
|
||||||
|
IDetailsListProps,
|
||||||
|
IStackStyles,
|
||||||
|
IStyle,
|
||||||
|
IDetailsListStyles,
|
||||||
|
} from "office-ui-fabric-react";
|
||||||
|
|
||||||
|
import { getFileTypeIconProps } from "@uifabric/file-type-icons";
|
||||||
|
import { useList } from "../../hooks/useList";
|
||||||
|
import { IDocumentsLinksAccordionState } from "./IDocumentsLinksAccordionState";
|
||||||
|
import { IDocumentsLinksAccordionProps } from "./IDocumentsLinksAccordionProps";
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionItemHeading,
|
||||||
|
AccordionItemButton,
|
||||||
|
AccordionItemPanel,
|
||||||
|
} from "@pnp/spfx-controls-react/lib/AccessibleAccordion";
|
||||||
|
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
|
||||||
|
|
||||||
|
const { getGroupItems, getGroupHeaders, getField } = useList();
|
||||||
|
export const DocumentsLinksAccordion: React.FunctionComponent<IDocumentsLinksAccordionProps> = (
|
||||||
|
props: IDocumentsLinksAccordionProps
|
||||||
|
) => {
|
||||||
|
const [state, setState] = React.useState<IDocumentsLinksAccordionState>({
|
||||||
|
navLinkGroups: [],
|
||||||
|
isLoading: false,
|
||||||
|
hasError: false,
|
||||||
|
errorMessage: "",
|
||||||
|
listName: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const stackItemStyles: Partial<IStackStyles> = React.useMemo(() => {
|
||||||
|
return {
|
||||||
|
root: {
|
||||||
|
padding: 7,
|
||||||
|
} as IStyle,
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const listViewStyles: Partial<IDetailsListStyles> = React.useMemo(() => {
|
||||||
|
return {
|
||||||
|
focusZone: {
|
||||||
|
width: "auto",
|
||||||
|
maxHeight: 450,
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
|
"&::-webkit-scrollbar-thumb": {
|
||||||
|
backgroundColor: props.themeVariant?.palette?.neutralLighter,
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
width: "7.5px",
|
||||||
|
},
|
||||||
|
"scrollbar-color": props.themeVariant?.palette?.neutralLighter,
|
||||||
|
"scrollbar-width": "thin",
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
"&::-webkit-scrollbar-thumb": {
|
||||||
|
backgroundColor: props.themeVariant?.palette?.neutralLighter,
|
||||||
|
},
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
height: "7.5px",
|
||||||
|
},
|
||||||
|
"scrollbar-color": props.themeVariant?.palette?.neutralLighter,
|
||||||
|
"scrollbar-width": "thin",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const classComponent = React.useMemo(() => {
|
||||||
|
return mergeStyleSets({
|
||||||
|
webPartTitle: {
|
||||||
|
fontWeight: 600,
|
||||||
|
overflowX: "hidden",
|
||||||
|
textOverflow: "Ellipsis",
|
||||||
|
fontSize: props.themeVariant.fonts.large.fontSize,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [props.themeVariant]);
|
||||||
|
|
||||||
|
const stateRef = React.useRef(state); // Use to access state on eventListenners
|
||||||
|
|
||||||
|
const columns: IColumn[] = React.useMemo(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: "documentRenderLink",
|
||||||
|
name: "Document",
|
||||||
|
fieldName: "name",
|
||||||
|
minWidth: 400,
|
||||||
|
maxWidth: 800,
|
||||||
|
isResizable: false,
|
||||||
|
data: "string",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onRenderRow: IDetailsListProps["onRenderRow"] = (propsItem) => {
|
||||||
|
if (propsItem.item) {
|
||||||
|
const item = propsItem.item as INavLink;
|
||||||
|
return (
|
||||||
|
<Stack horizontal horizontalAlign="start" tokens={{ childrenGap: 10 }} styles={stackItemStyles}>
|
||||||
|
<FontIcon iconName={item.iconProps.iconName} />
|
||||||
|
<Link href={item.url} target="_blank">
|
||||||
|
<Text variant={"medium"}>{item.name}</Text>
|
||||||
|
</Link>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
React.useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
if (!props.listId || !props.fieldName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let _navLinksGroups: INavLinkGroup[] = [];
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
isLoading: true,
|
||||||
|
navLinkGroups: _navLinksGroups,
|
||||||
|
};
|
||||||
|
setState(stateRef.current);
|
||||||
|
const _groupHeaders = await getGroupHeaders(props.listId, props.fieldName, props.listBaseTemplate);
|
||||||
|
const { fieldName } = props;
|
||||||
|
const _field: any = await getField(props.listId, props.fieldName);
|
||||||
|
|
||||||
|
for (const groupHeader of _groupHeaders) {
|
||||||
|
let _name: any;
|
||||||
|
switch (_field.fieldType) {
|
||||||
|
case "TaxonomyFieldType":
|
||||||
|
_name = groupHeader[fieldName]?.Label ?? "Unassigned";
|
||||||
|
break;
|
||||||
|
case "TaxonomyFieldTypeMulti":
|
||||||
|
_name = groupHeader[fieldName][0]?.Label ?? "Unassigned";
|
||||||
|
break;
|
||||||
|
case "User":
|
||||||
|
if (_name != "Unassigned") {
|
||||||
|
_name = groupHeader[fieldName][0]?.title;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Lookup":
|
||||||
|
_name =
|
||||||
|
groupHeader[props.fieldName] !== "" &&
|
||||||
|
groupHeader[props.fieldName] !== undefined &&
|
||||||
|
groupHeader[props.fieldName][0].lookupValue !== ""
|
||||||
|
? groupHeader[props.fieldName][0]?.lookupValue
|
||||||
|
: "Unassigned";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_name =
|
||||||
|
groupHeader[props.fieldName] !== "" && groupHeader[props.fieldName] !== undefined
|
||||||
|
? groupHeader[props.fieldName]
|
||||||
|
: "Unassigned";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_navLinksGroups.push({
|
||||||
|
name: _name,
|
||||||
|
groupData: _name,
|
||||||
|
collapseByDefault: true,
|
||||||
|
links: [],
|
||||||
|
});
|
||||||
|
// Ensure the groups name are unique!
|
||||||
|
_navLinksGroups = uniqBy(_navLinksGroups, "name");
|
||||||
|
}
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
hasError: false,
|
||||||
|
errorMessage: "",
|
||||||
|
isLoading: false,
|
||||||
|
listName: _field.fieldScope,
|
||||||
|
navLinkGroups: _navLinksGroups,
|
||||||
|
};
|
||||||
|
|
||||||
|
setState(stateRef.current);
|
||||||
|
} catch (error) {
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
hasError: true,
|
||||||
|
errorMessage: error.message,
|
||||||
|
};
|
||||||
|
setState(stateRef.current);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, [props.listId, props.fieldName]);
|
||||||
|
|
||||||
|
// On Header click get Items for the header
|
||||||
|
const onGroupHeaderClick = React.useCallback(
|
||||||
|
async (ev: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||||
|
try {
|
||||||
|
const _groupName = ev.currentTarget.innerText;
|
||||||
|
const { navLinkGroups } = stateRef.current;
|
||||||
|
|
||||||
|
setState(stateRef.current);
|
||||||
|
const _navGroup = filter(navLinkGroups, { name: _groupName });
|
||||||
|
if (_navGroup?.length && _navGroup[0]?.links?.length === 0) {
|
||||||
|
const _navlinks: INavLink[] = [];
|
||||||
|
const _groupHeaderItems: any[] = await getGroupItems(
|
||||||
|
props.listId,
|
||||||
|
props.fieldName,
|
||||||
|
_groupName,
|
||||||
|
props.listBaseTemplate
|
||||||
|
);
|
||||||
|
if (_groupHeaderItems?.length) {
|
||||||
|
for (const _groupHeaderItem of _groupHeaderItems) {
|
||||||
|
if (props.listBaseTemplate === 0) {
|
||||||
|
// List
|
||||||
|
_navlinks.push({
|
||||||
|
name: _groupHeaderItem.Title,
|
||||||
|
url: `${_groupHeaderItem.FileDirRef}/dispform.aspx?ID=${_groupHeaderItem.Id}`,
|
||||||
|
iconProps: {
|
||||||
|
iconName: "TaskManager",
|
||||||
|
},
|
||||||
|
key: _groupHeaderItem.Id,
|
||||||
|
target: "_blank",
|
||||||
|
isExpanded: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.listBaseTemplate === 1) {
|
||||||
|
// Document Library
|
||||||
|
_navlinks.push({
|
||||||
|
name: _groupHeaderItem.FileLeafRef,
|
||||||
|
url: _groupHeaderItem.FileRef,
|
||||||
|
iconProps: {
|
||||||
|
...getFileTypeIconProps({
|
||||||
|
extension: _groupHeaderItem.DocIcon,
|
||||||
|
size: 16,
|
||||||
|
imageFileType: "svg",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
key: _groupHeaderItem.title,
|
||||||
|
target: "_blank",
|
||||||
|
isExpanded: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update Navigation with Items of Group
|
||||||
|
|
||||||
|
_navGroup[0].links = _navlinks;
|
||||||
|
}
|
||||||
|
const _index = findIndex(navLinkGroups, { name: _groupName });
|
||||||
|
_navGroup[0].collapseByDefault = true;
|
||||||
|
navLinkGroups[_index] = _navGroup[0];
|
||||||
|
|
||||||
|
stateRef.current = { ...stateRef.current, navLinkGroups: navLinkGroups };
|
||||||
|
setState(stateRef.current);
|
||||||
|
} catch (error) {}
|
||||||
|
},
|
||||||
|
[props]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show Error if Exists
|
||||||
|
if (state.hasError) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MessageBar messageBarType={MessageBarType.error} isMultiline>
|
||||||
|
{state.errorMessage}
|
||||||
|
</MessageBar>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// render component
|
||||||
|
if (!props.listId || !props.fieldName) {
|
||||||
|
return (
|
||||||
|
<Placeholder
|
||||||
|
iconName="Edit"
|
||||||
|
iconText={strings.PlaceHolderIconText}
|
||||||
|
description={strings.PlaceHolderDescription}
|
||||||
|
buttonLabel={strings.PlaceHolderButtonLable}
|
||||||
|
onConfigure={props.onConfigure}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Customizer settings={{ theme: props.themeVariant }}>
|
||||||
|
{state.isLoading ? (
|
||||||
|
<Stack horizontal horizontalAlign="center">
|
||||||
|
<Spinner size={SpinnerSize.medium}></Spinner>
|
||||||
|
</Stack>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Stack horizontalAlign="space-between" horizontal tokens={{ childrenGap: 10 }} style={{ width: "100%" }}>
|
||||||
|
<div className={classComponent.webPartTitle}>{props.title}</div>
|
||||||
|
<Link href={state.listName}>{strings.ViewAllLabel}</Link>
|
||||||
|
</Stack>
|
||||||
|
{state.navLinkGroups?.length === 0 ? (
|
||||||
|
<Label
|
||||||
|
style={{
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: props.themeVariant.fonts.small.fontSize,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{strings.NodocumentsLabel}
|
||||||
|
</Label>
|
||||||
|
) : (
|
||||||
|
<Accordion allowZeroExpanded allowMultipleExpanded>
|
||||||
|
{state.navLinkGroups.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionItemHeading
|
||||||
|
onClick={async (ev) => {
|
||||||
|
await onGroupHeaderClick(ev);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AccordionItemButton>{item.name}</AccordionItemButton>
|
||||||
|
</AccordionItemHeading>
|
||||||
|
<AccordionItemPanel>
|
||||||
|
<Stack>
|
||||||
|
<DetailsList
|
||||||
|
items={item.links}
|
||||||
|
columns={columns}
|
||||||
|
styles={listViewStyles}
|
||||||
|
compact={true}
|
||||||
|
selectionMode={SelectionMode.none}
|
||||||
|
setKey="none"
|
||||||
|
layoutMode={DetailsListLayoutMode.justified}
|
||||||
|
isHeaderVisible={false}
|
||||||
|
onRenderRow={onRenderRow}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</AccordionItemPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Accordion>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Customizer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
import { IReadonlyTheme } from "@microsoft/sp-component-base";
|
||||||
|
import { DisplayMode } from "@microsoft/sp-core-library";
|
||||||
|
|
||||||
|
export interface IDocumentsLinksAccordionProps {
|
||||||
|
title: string;
|
||||||
|
listId:string;
|
||||||
|
listBaseTemplate:number;
|
||||||
|
fieldName:string;
|
||||||
|
locale:string;
|
||||||
|
themeVariant: IReadonlyTheme | undefined;
|
||||||
|
onConfigure: () => void;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Nav, INavStyles, INavLinkGroup } from 'office-ui-fabric-react/lib/Nav';
|
||||||
|
export interface IDocumentsLinksAccordionState {
|
||||||
|
navLinkGroups: INavLinkGroup[];
|
||||||
|
isLoading: boolean;
|
||||||
|
hasError:boolean;
|
||||||
|
errorMessage:string;
|
||||||
|
listName:string;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
export interface IListItemsMenu {
|
||||||
|
groupBy:string;
|
||||||
|
id:string;
|
||||||
|
title:string;
|
||||||
|
url:string;
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
import "@pnp/sp/fields";
|
||||||
|
import "@pnp/sp/items";
|
||||||
|
import "@pnp/sp/lists";
|
||||||
|
import "@pnp/sp/webs";
|
||||||
|
|
||||||
|
import { sortBy, uniqBy } from "lodash";
|
||||||
|
|
||||||
|
import { sp } from "@pnp/sp";
|
||||||
|
import { IFieldInfo } from "@pnp/sp/fields";
|
||||||
|
import { IListInfo } from "@pnp/sp/lists";
|
||||||
|
import * as moment from "moment";
|
||||||
|
import { format, parse, parseISO } from "date-fns";
|
||||||
|
import { checkIfValidDate } from "../Utils/Utils";
|
||||||
|
|
||||||
|
export const useList = () => {
|
||||||
|
// Run on useList hook
|
||||||
|
(async () => {})();
|
||||||
|
|
||||||
|
// Get List Columns
|
||||||
|
const getListColumns = async (listId: string): Promise<IFieldInfo[]> => {
|
||||||
|
const _listColumnsResults: IFieldInfo[] = await sp.web.lists.getById(listId).fields.filter("Hidden eq false").get();
|
||||||
|
|
||||||
|
const _wColumns: IFieldInfo[] = uniqBy(sortBy(_listColumnsResults, "Title"), "Title");
|
||||||
|
return _wColumns;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getField = async (listId: string, field: string): Promise<any> => {
|
||||||
|
const _field: IFieldInfo = await sp.web.lists.getById(listId).fields.getByInternalNameOrTitle(field).get();
|
||||||
|
|
||||||
|
const fieldType = _field.TypeAsString;
|
||||||
|
const fieldScope = _field.Scope;
|
||||||
|
return { fieldType, fieldScope };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGroupHeaders = async (listId: string, groupByField: string, baseTemplate: number): Promise<any[]> => {
|
||||||
|
let _viewXml = `<View Scope='Recursive'>
|
||||||
|
<Query>
|
||||||
|
<GroupBy Collapse="TRUE">
|
||||||
|
<FieldRef Name="${groupByField}"/>
|
||||||
|
</GroupBy>
|
||||||
|
</Query>
|
||||||
|
<RowLimit>1000</RowLimit>
|
||||||
|
</View>`;
|
||||||
|
|
||||||
|
const _groupHeadersResults = await sp.web.lists.getById(listId).renderListDataAsStream({ ViewXml: _viewXml });
|
||||||
|
return uniqBy(_groupHeadersResults.Row, groupByField);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGroupItems = async (
|
||||||
|
listId: string,
|
||||||
|
groupByField: string,
|
||||||
|
groupFieldValue: string,
|
||||||
|
baseTemplate: number
|
||||||
|
): Promise<any[]> => {
|
||||||
|
const _field: any = await getField(listId, groupByField);
|
||||||
|
|
||||||
|
if (checkIfValidDate(groupFieldValue)) {
|
||||||
|
groupFieldValue = format(new Date(groupFieldValue), "yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_field.fieldType) {
|
||||||
|
case "DateTime":
|
||||||
|
groupFieldValue =
|
||||||
|
groupFieldValue != "Unassigned" ? format(parseISO(groupFieldValue), "yyyy-MM-dd") : "Unassigned";
|
||||||
|
break;
|
||||||
|
case "AllDayEvent":
|
||||||
|
groupFieldValue = groupFieldValue === "No" ? "0" : "1";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _viewXml = `<View Scope='Recursive'>
|
||||||
|
<Query>
|
||||||
|
<OrderBy>
|
||||||
|
<FieldRef Name="${groupByField}" Ascending="FALSE"></FieldRef>
|
||||||
|
</OrderBy>
|
||||||
|
</Query>
|
||||||
|
</View>`;
|
||||||
|
|
||||||
|
if (groupFieldValue != "Unassigned") {
|
||||||
|
_viewXml = `<View Scope='Recursive'>
|
||||||
|
<Query>
|
||||||
|
<OrderBy>
|
||||||
|
<FieldRef Name="${groupByField}" Ascending="FALSE"></FieldRef>
|
||||||
|
</OrderBy>
|
||||||
|
<Where>
|
||||||
|
<Eq>
|
||||||
|
<FieldRef Name="${groupByField}"></FieldRef>
|
||||||
|
<Value Type="${_field.fieldType}" IncludeTimeValue="FALSE">${groupFieldValue}</Value>
|
||||||
|
</Eq>
|
||||||
|
</Where>
|
||||||
|
</Query>
|
||||||
|
</View>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupFieldValue === "Unassigned") {
|
||||||
|
_viewXml = `<View Scope='Recursive'>
|
||||||
|
<Query>
|
||||||
|
<OrderBy>
|
||||||
|
<FieldRef Name="${groupByField}" Ascending="FALSE"></FieldRef>
|
||||||
|
</OrderBy>
|
||||||
|
<Where>
|
||||||
|
<IsNull>
|
||||||
|
<FieldRef Name="${groupByField}"></FieldRef>
|
||||||
|
</IsNull>
|
||||||
|
</Where>
|
||||||
|
</Query>
|
||||||
|
</View>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _groupItemsResults = await sp.web.lists.getById(listId).renderListDataAsStream({ ViewXml: _viewXml });
|
||||||
|
|
||||||
|
return _groupItemsResults.Row;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get Lists
|
||||||
|
const getLists = async (baseTemplate: number): Promise<IListInfo[]> => {
|
||||||
|
let _filter: string = "Hidden eq false and ";
|
||||||
|
if (baseTemplate === 0) {
|
||||||
|
_filter = _filter + " BaseType ne 1";
|
||||||
|
} else {
|
||||||
|
_filter = _filter + " BaseType eq 1";
|
||||||
|
}
|
||||||
|
const _lists: IListInfo[] = await sp.web.lists.filter(_filter).get();
|
||||||
|
return _lists;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return functions
|
||||||
|
return {
|
||||||
|
getListColumns,
|
||||||
|
getLists,
|
||||||
|
getGroupItems,
|
||||||
|
getGroupHeaders,
|
||||||
|
getField,
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
"id": "a0215264-a8cd-4952-aecd-4e80719de202",
|
||||||
|
"alias": "DocumentsLinksAccordionWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
"supportsFullBleed": true,
|
||||||
|
// 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", "SharePointFullPage", "TeamsPersonalApp","TeamsTab"],
|
||||||
|
|
||||||
|
"preconfiguredEntries": [{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
|
||||||
|
"group": { "default": "SPFx Custom Web Parts" },
|
||||||
|
"title": { "default": "Documents Links Accordion" },
|
||||||
|
"description": { "default": "Documents" },
|
||||||
|
"officeFabricIconFontName": "GroupedList",
|
||||||
|
"properties": {
|
||||||
|
"title": "Documents",
|
||||||
|
"listId": "",
|
||||||
|
"fieldName": "",
|
||||||
|
"listBasetemplate": 1
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,302 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import * as ReactDom from "react-dom";
|
||||||
|
|
||||||
|
import {
|
||||||
|
loadTheme,
|
||||||
|
MessageBarType,
|
||||||
|
SpinnerSize
|
||||||
|
} from "office-ui-fabric-react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
IReadonlyTheme,
|
||||||
|
ThemeChangedEventArgs,
|
||||||
|
ThemeProvider
|
||||||
|
} from "@microsoft/sp-component-base";
|
||||||
|
import { MSGraphClient } from "@microsoft/sp-http";
|
||||||
|
import {
|
||||||
|
IPropertyPaneConfiguration,
|
||||||
|
IPropertyPaneDropdownOption,
|
||||||
|
IPropertyPaneField,
|
||||||
|
IPropertyPaneGroup,
|
||||||
|
IPropertyPanePage,
|
||||||
|
PropertyPaneDropdown,
|
||||||
|
PropertyPaneTextField
|
||||||
|
} from "@microsoft/sp-property-pane";
|
||||||
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
|
import { sp } from "@pnp/sp";
|
||||||
|
import {
|
||||||
|
PropertyFieldListPicker,
|
||||||
|
PropertyFieldListPickerOrderBy
|
||||||
|
} from "@pnp/spfx-property-controls/lib/PropertyFieldListPicker";
|
||||||
|
import {
|
||||||
|
PropertyFieldMessage
|
||||||
|
} from "@pnp/spfx-property-controls/lib/PropertyFieldMessage";
|
||||||
|
import {
|
||||||
|
PropertyFieldSpinner
|
||||||
|
} from "@pnp/spfx-property-controls/lib/PropertyFieldSpinner";
|
||||||
|
|
||||||
|
|
||||||
|
import { useList } from "../../hooks/useList";
|
||||||
|
|
||||||
|
export interface IListItemsMenuWebPartProps {
|
||||||
|
title: string;
|
||||||
|
listId: string;
|
||||||
|
fieldName: string;
|
||||||
|
listBasetemplate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json");
|
||||||
|
const teamsDarkTheme = require("../../common/TeamsDarkTheme.json");
|
||||||
|
const teamsContrastTheme = require("../../common/TeamsContrastTheme.json");
|
||||||
|
|
||||||
|
const { getListColumns, getLists } = useList() ;
|
||||||
|
|
||||||
|
import * as strings from 'DocumentsLinksAccordionWebPartStrings';
|
||||||
|
import { IDocumentsLinksAccordionProps } from "../../components/DocumentsLinksAccordion/IDocumentsLinksAccordionProps";
|
||||||
|
import {DocumentsLinksAccordion} from "../../components/DocumentsLinksAccordion/DocumentsLinksAccordion";
|
||||||
|
import { Version } from "@microsoft/sp-core-library";
|
||||||
|
export interface IDocumentsLinksAccordionWebPartProps {
|
||||||
|
title: string;
|
||||||
|
listId: string;
|
||||||
|
fieldName: string;
|
||||||
|
listBasetemplate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class DocumentsLinksAccordionWebPart extends BaseClientSideWebPart<IDocumentsLinksAccordionWebPartProps> {
|
||||||
|
|
||||||
|
private columns: IPropertyPaneDropdownOption[] = [];
|
||||||
|
private lists: IPropertyPaneDropdownOption[] = [];
|
||||||
|
private _themeProvider: ThemeProvider;
|
||||||
|
private _themeVariant: IReadonlyTheme | undefined;
|
||||||
|
private _msgGraphclient: MSGraphClient;
|
||||||
|
private _hasError: boolean = false;
|
||||||
|
private _messageError: string = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
protected async onInit(): Promise<void> {
|
||||||
|
|
||||||
|
sp.setup({
|
||||||
|
spfxContext: this.context,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._msgGraphclient = await this.context.msGraphClientFactory.getClient();
|
||||||
|
|
||||||
|
this._themeProvider = this.context.serviceScope.consume(
|
||||||
|
ThemeProvider.serviceKey
|
||||||
|
);
|
||||||
|
// If it exists, get the theme variant
|
||||||
|
this._themeVariant = this._themeProvider.tryGetTheme();
|
||||||
|
// Register a handler to be notified if the theme variant changes
|
||||||
|
this._themeProvider.themeChangedEvent.add(
|
||||||
|
this,
|
||||||
|
this._handleThemeChangedEvent
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.context.sdks.microsoftTeams) {
|
||||||
|
// in teams ?
|
||||||
|
const context = this.context.sdks.microsoftTeams!.context;
|
||||||
|
this._applyTheme(context.theme || "default");
|
||||||
|
this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(
|
||||||
|
this._applyTheme
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the current theme variant reference and re-render.
|
||||||
|
*
|
||||||
|
* @param args The new theme
|
||||||
|
*/
|
||||||
|
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
|
||||||
|
this._themeVariant = args.theme;
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply theme id in Teams
|
||||||
|
private _applyTheme = (theme: string): void => {
|
||||||
|
this.context.domElement.setAttribute("data-theme", theme);
|
||||||
|
document.body.setAttribute("data-theme", theme);
|
||||||
|
|
||||||
|
if (theme == "dark") {
|
||||||
|
loadTheme({
|
||||||
|
palette: teamsDarkTheme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme == "default") {
|
||||||
|
loadTheme({
|
||||||
|
palette: teamsDefaultTheme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme == "contrast") {
|
||||||
|
loadTheme({
|
||||||
|
palette: teamsContrastTheme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): void {
|
||||||
|
|
||||||
|
const element: React.ReactElement<IDocumentsLinksAccordionProps> = React.createElement(
|
||||||
|
DocumentsLinksAccordion,
|
||||||
|
{
|
||||||
|
title: this.properties.title,
|
||||||
|
listId: this.properties.listId,
|
||||||
|
fieldName: this.properties.fieldName,
|
||||||
|
themeVariant: this._themeVariant,
|
||||||
|
locale: this.context.pageContext.cultureInfo.currentUICultureName,
|
||||||
|
listBaseTemplate: this.properties.listBasetemplate ?? 1,
|
||||||
|
onConfigure: () =>{ this.context.propertyPane.open(); },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ReactDom.render(element, this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onDispose(): void {
|
||||||
|
ReactDom.unmountComponentAtNode(this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get disableReactivePropertyChanges() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onPropertyPaneConfigurationStart() {
|
||||||
|
if (
|
||||||
|
this.properties.fieldName &&
|
||||||
|
this.properties.listId &&
|
||||||
|
this.columns.length === 0
|
||||||
|
) {
|
||||||
|
await this.addListColumns(this.properties.listId);
|
||||||
|
this.context.propertyPane.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.properties.listId && this.lists.length === 0){
|
||||||
|
await this.addLists('1');
|
||||||
|
this.context.propertyPane.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onPropertyPaneFieldChanged(
|
||||||
|
propertyPath: string,
|
||||||
|
oldValue: any,
|
||||||
|
newValue: any
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (propertyPath === "listId" && newValue != oldValue) {
|
||||||
|
this.columns = [];
|
||||||
|
|
||||||
|
this.context.propertyPane.refresh();
|
||||||
|
await this.addListColumns(newValue);
|
||||||
|
this.context.propertyPane.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async addLists(newValue: any) {
|
||||||
|
try {
|
||||||
|
this.lists = [];
|
||||||
|
const _lists = await getLists(newValue);
|
||||||
|
for (const _list of _lists) {
|
||||||
|
this.lists.push({ key: _list.Id, text: _list.Title });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this._hasError = true;
|
||||||
|
this._messageError =error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async addListColumns(newValue: any) {
|
||||||
|
try {
|
||||||
|
this.columns = [];
|
||||||
|
const _listColumns = await getListColumns(newValue);
|
||||||
|
for (const _column of _listColumns) {
|
||||||
|
this.columns.push({ key: _column.InternalName, text: _column.Title });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this._hasError = true;
|
||||||
|
this._messageError = error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
const _pages: IPropertyPanePage[] = [
|
||||||
|
{
|
||||||
|
header: {
|
||||||
|
description: strings.PropertyPaneDescription,
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
groupName: strings.BasicGroupName,
|
||||||
|
groupFields: [
|
||||||
|
PropertyPaneTextField("title", {
|
||||||
|
label: strings.DescriptionFieldLabel,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let groups: IPropertyPaneGroup = _pages[0].groups[0] as IPropertyPaneGroup;
|
||||||
|
let groupFields: IPropertyPaneField<any>[] = groups.groupFields;
|
||||||
|
groupFields.push(
|
||||||
|
PropertyFieldListPicker("listId", {
|
||||||
|
label: "Select Document Library",
|
||||||
|
selectedList: this.properties.listId ,
|
||||||
|
includeHidden: false,
|
||||||
|
baseTemplate: 101,
|
||||||
|
orderBy: PropertyFieldListPickerOrderBy.Title,
|
||||||
|
disabled: false,
|
||||||
|
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
|
||||||
|
properties: this.properties,
|
||||||
|
context: this.context,
|
||||||
|
onGetErrorMessage: null,
|
||||||
|
deferredValidationTime: 0,
|
||||||
|
key: "listPickerFieldId",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (this.properties.listId) {
|
||||||
|
groupFields.push(
|
||||||
|
PropertyFieldSpinner("", {
|
||||||
|
key: "sp1",
|
||||||
|
size: SpinnerSize.medium,
|
||||||
|
isVisible: (this.columns.length || this._hasError) ? false : true,
|
||||||
|
label: "Loading ...",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Columns
|
||||||
|
if (this.columns.length > 0) {
|
||||||
|
groupFields.push(
|
||||||
|
PropertyPaneDropdown("fieldName", {
|
||||||
|
label: "Select field to group by documents",
|
||||||
|
options: this.columns,
|
||||||
|
selectedKey: this.properties.fieldName,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Error
|
||||||
|
if (this._hasError) {
|
||||||
|
groupFields.push(
|
||||||
|
PropertyFieldMessage("", {
|
||||||
|
key: "msgError",
|
||||||
|
messageType: MessageBarType.error,
|
||||||
|
multiline: true,
|
||||||
|
text: this._messageError,
|
||||||
|
isVisible: this._hasError,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _panelConfiguration: IPropertyPaneConfiguration = { pages: _pages };
|
||||||
|
return _panelConfiguration;
|
||||||
|
}
|
||||||
|
}
|
12
samples/react-document-links-accordion/src/webparts/DocumentsLinksAccordion/loc/en-us.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
PlaceHolderButtonLable: "Configure",
|
||||||
|
PlaceHolderDescription: "Please configure the web part.",
|
||||||
|
PlaceHolderIconText: "Configure Documents Links Accordion Web Part",
|
||||||
|
"PropertyPaneDescription": "Show documents grouped by field",
|
||||||
|
"BasicGroupName": "Properties",
|
||||||
|
"DescriptionFieldLabel": "Title",
|
||||||
|
"NodocumentsLabel":"No documents found in library",
|
||||||
|
"ViewAllLabel": "View All"
|
||||||
|
}
|
||||||
|
});
|
15
samples/react-document-links-accordion/src/webparts/DocumentsLinksAccordion/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
declare interface IDocumentsLinksAccordionWebPartStrings {
|
||||||
|
PropertyPaneDescription: string;
|
||||||
|
BasicGroupName: string;
|
||||||
|
DescriptionFieldLabel: string;
|
||||||
|
ViewAllLabel:string;
|
||||||
|
NodocumentsLabel:string;
|
||||||
|
PlaceHolderButtonLable: string;
|
||||||
|
PlaceHolderDescription: string;
|
||||||
|
PlaceHolderIconText: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'DocumentsLinksAccordionWebPartStrings' {
|
||||||
|
const strings: IDocumentsLinksAccordionWebPartStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 383 B |
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.7/includes/tsconfig-web.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react",
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@microsoft"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"webpack-env"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es5",
|
||||||
|
"dom",
|
||||||
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"class-name": false,
|
||||||
|
"export-name": false,
|
||||||
|
"forin": false,
|
||||||
|
"label-position": false,
|
||||||
|
"member-access": true,
|
||||||
|
"no-arg": false,
|
||||||
|
"no-console": false,
|
||||||
|
"no-construct": false,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-eval": false,
|
||||||
|
"no-function-expression": true,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-unnecessary-semicolons": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-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
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,9 +22,18 @@ This web part will allow users to view/update application customizers properties
|
||||||
- Allows to update application customizer properties which makes it easy to make re-useable 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)
|
## 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)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "This solution requires access to list the application customizers on a hosted site collection")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -45,12 +54,6 @@ Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|October 16, 2020|Initial release
|
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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
|
@ -62,8 +65,6 @@ Version|Date|Comments
|
||||||
|
|
||||||
For any issue or help, Buzz us on twitter:([sanganikunj](https://twitter.com/sanganikunj)) or ([siddh_me](https://twitter.com/siddh_me/))
|
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
|
## References
|
||||||
|
|
||||||
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
@ -72,4 +73,21 @@ For any issue or help, Buzz us on twitter:([sanganikunj](https://twitter.com/san
|
||||||
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
- [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
|
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-edit-applicationcustomizers&authors=@kunj-sangani%20@siddharth-vaghasia&title=react-edit-applicationcustomizers%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-edit-applicationcustomizers&authors=@kunj-sangani%20@siddharth-vaghasia&title=react-edit-applicationcustomizers%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-edit-applicationcustomizers&authors=@kunj-sangani%20@siddharth-vaghasia&title=react-edit-applicationcustomizers%20-%20).
|
||||||
|
|
||||||
|
|
||||||
|
> Sharing is caring!
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-edit-applicationcustomizers" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-edit-applicationcustomizers" />
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
|
@ -0,0 +1 @@
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 383 B |
|
@ -0,0 +1,33 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
release
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.12.1",
|
||||||
|
"libraryName": "react-emoji-reaction-rating",
|
||||||
|
"libraryId": "fe292bb9-a5c2-40b4-b90b-61e8510c3c09",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
# Emoji Ratings
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This is sample web part which can be used to take emoji based reaction or feedback for particular news/article/posts.
|
||||||
|
We all know every organizations would be using SharePoint news features for company's internal communications from HR to IT updates and some time annoucements. News created in SharePoint are created as Pages in library. Idea behind this web part is to take employee/user's feedback as emoji reactions on particular news. This web part can also be used on wiki articles or blog posts to take similar reactions. Web part uses concept of 1 to 5 star based rating system(configurable), you can decide low to high based on your preference.
|
||||||
|
|
||||||
|
Ideally, we can do some automation using PnP Powershell and PowerAutomate (trigger when item is created ) to add this web part to any every news that is published.
|
||||||
|
|
||||||
|
If you wish to directly use the package in your tenant here is [link](https://github.com/siddharth-vaghasia/public-docs/blob/master/react-emoji-reaction-rating.sppkg) to download.
|
||||||
|
|
||||||
|
|
||||||
|
![Web part in Action](./assets/EmojiWPinAction.gif)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Configurable header text, rating text, and images
|
||||||
|
* We can choose to show from minimum one rating to max 5 rating images and text
|
||||||
|
* Option to show total count of particular rating count as badge
|
||||||
|
* Option to show and capture comments from user when submitting feedback
|
||||||
|
* Display current user's rating selection with highlighted background
|
||||||
|
* Allow user to change rating(update rating)
|
||||||
|
* Stores ratings in SharePoint List
|
||||||
|
* Option to create list on the fly and choose list to store the ratings
|
||||||
|
* Option for admin to choose background color
|
||||||
|
|
||||||
|
## Technical Notes
|
||||||
|
|
||||||
|
* User's rating data would be stored in SP List, below are list of columns and its relevance
|
||||||
|
|
||||||
|
1. `Title`: To store user's display name (not required though)
|
||||||
|
2. `Page Name`: To store page on which rating is given by particular user, this will have absolute url of page
|
||||||
|
3. `User`: To store user who has given feedback for particular page/news where web part is added
|
||||||
|
4. `Comment`: To store comment provided by user while submitting reaction.
|
||||||
|
5. Then there are 5 columns `Rating1`, `Rating2`, `Rating3`, `Rating4`, `Rating5` which will store the rating text configured by admin in web part... Only one of this 5 columns would be populated for single item in list, which is what user has selected as part of giving reaction
|
||||||
|
|
||||||
|
* Below is how you can configure emoji's text and its image url
|
||||||
|
![Web part in Action](./assets/EmojisConfigurations.png)
|
||||||
|
|
||||||
|
I have added default emoji's images which can be used and uploaded to SharePoint library in the assets folder of this solution.
|
||||||
|
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Teams Incompatible](https://img.shields.io/badge/Teams-Incompatible-lightgrey.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "This solution requires access to a SharePoint list")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
|
## Applies to
|
||||||
|
|
||||||
|
- [SharePoint Framework](https://aka.ms/spfx)
|
||||||
|
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
|
||||||
|
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
* SharePoint Online tenant
|
||||||
|
* Permission to deploy package to Tenant or SharePoint Site collection app catalog
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
react-emoji-ratings | [Siddharth Vaghasia](https://github.com/siddharth-vaghasia) ([@siddh_me](https://twitter.com/siddh_me))
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0|Sep 04, 2021|Initial release
|
||||||
|
|
||||||
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
- Clone this repository
|
||||||
|
- Ensure that you are at the solution folder
|
||||||
|
- in the command-line run:
|
||||||
|
- `npm install`
|
||||||
|
- `gulp serve`
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
- [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
|
||||||
|
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-emoji-ratings&authors=@siddharth-vaghasia&title=react-emoji-ratings%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-emoji-ratings&authors=@siddharth-vaghasia&title=react-emoji-ratings%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-emoji-ratings&authors=@siddharth-vaghasia&title=react-emoji-ratings%20-%20).
|
||||||
|
|
||||||
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-emoji-ratings" />
|
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 5.5 KiB |