Merge pull request #2060 from fthorild/fthorild/issue2056

Added sorting fixing #2056
This commit is contained in:
Hugo Bernier 2021-10-30 00:40:44 -04:00 committed by GitHub
commit 4cae8f5e6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 34 deletions

View File

@ -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)
## 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
@ -46,11 +51,7 @@ Version|Date|Comments
2.0|January 19, 2020|Upgrade to SPFx 1.10
2.1|June 22, 2020|Added pagination (Abhishek Garg)
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
## 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.**
---
2.3|September 30, 2021 | Added sorting (@fthorild)
## 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
## 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" />

View File

@ -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."
],
"creationDateTime": "2020-06-22",
"updateDateTime": "2020-06-22",
"updateDateTime": "2021-09-30",
"products": [
"SharePoint",
"Office"

View File

@ -3,7 +3,7 @@
"solution": {
"name": "react-accordion-client-side-solution",
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
"version": "2.2.0.0",
"version": "2.3.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false
},

View File

@ -1,6 +1,6 @@
{
"name": "react-accordion",
"version": "2.2.0",
"version": "2.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "react-accordion",
"version": "2.2.0",
"version": "2.3.0",
"private": true,
"main": "lib/index.js",
"engines": {

View File

@ -29,10 +29,13 @@
"properties": {
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
"listName": "FAQ",
"totalItems":20,
"totalItems": 20,
"maxItemsPerPage": 5,
"allowPaging":true
"allowPaging": true,
"customSortField": "",
"sortById": false,
"sortByModified": false
}
}
]
}
}

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version, DisplayMode } from '@microsoft/sp-core-library';
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 ReactAccordion from './components/ReactAccordion';
@ -13,16 +13,19 @@ export interface IReactAccordionWebPartProps {
choice: string;
title: string;
displayMode: DisplayMode;
totalItems:number;
totalItems: number;
maxItemsPerPage: number;
enablePaging:boolean;
enablePaging: boolean;
customSortField: string;
sortById: boolean;
sortByModified: boolean;
updateProperty: (value: string) => void;
}
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
public render(): void {
const element: React.ReactElement<IReactAccordionProps> = React.createElement(
ReactAccordion,
{
@ -31,9 +34,12 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
siteUrl: this.context.pageContext.web.absoluteUrl,
title: this.properties.title,
displayMode: this.displayMode,
totalItems:this.properties.totalItems,
totalItems: this.properties.totalItems,
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) => {
this.properties.title = value;
}
@ -53,10 +59,10 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
//set maxitems to top
if(!this.properties.enablePaging){
if (!this.properties.enablePaging) {
this.properties.maxItemsPerPage = this.properties.totalItems;
}
return {
pages: [
{
@ -83,7 +89,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
label: strings.EnablePagingLabel
}),
PropertyPaneSlider('maxItemsPerPage', {
disabled:!this.properties.enablePaging,
disabled: !this.properties.enablePaging,
label: strings.MaxItemsPerPageLabel,
ariaLabel: strings.MaxItemsPerPageLabel,
min: 3,
@ -91,6 +97,14 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
value: 5,
showValue: true,
step: 1
}),
PropertyPaneTextField('customSortField', {
label: strings.CustomSortOrder
}),
PropertyPaneToggle('sortById', {
label: strings.SortById
}),PropertyPaneToggle('sortByModified', {
label: strings.SortByModified
})
]
}

View File

@ -10,5 +10,8 @@ export interface IReactAccordionProps {
maxItemsPerPage: number;
enablePaging:boolean;
totalItems:number;
customSortField:string;
sortById:boolean;
sortByModified:boolean;
updateProperty: (value: string) => void;
}
}

View File

@ -7,4 +7,5 @@ export interface IReactAccordionState {
listItems: IAccordionListItem[];
isLoading: boolean;
loaderMessage: string;
}
error: string;
}

View File

@ -30,7 +30,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
items: [],
listItems: [],
isLoading: false,
loaderMessage: ''
loaderMessage: '',
error: ''
};
if (!this.listNotConfigured(this.props)) {
@ -73,8 +74,24 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
}
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, {
headers: {
@ -86,6 +103,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
return response.json();
})
.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];
@ -95,14 +117,16 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
items: response.value,
listItems: response.value,
isLoading: false,
loaderMessage: ""
loaderMessage: '',
error: ''
});
}, (error: any): void => {
this.setState({
status: 'Loading all items failed with error: ' + error,
pagedItems: [],
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> {
let displayLoader;
let errorMessage;
let faqTitle;
let { items } = this.state;
let pageCountDivisor: number = this.props.maxItemsPerPage;
@ -149,7 +174,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
displayLoader = (null);
}
if(this.props.enablePaging){
if (this.props.enablePaging) {
if (items.length > 0) {
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>);
}
}
if (this.state.error) {
errorMessage = <div>{this.state.error}</div>;
}
return (
<div className={styles.reactAccordion}>
<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-col ms-u-lg12'>
{this.state.status}
<Accordion accordion={false}>
<Accordion>
{pagedItems}
</Accordion>
</div>
@ -186,7 +216,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
</div>
</div>
</div>
{errorMessage}
</div>
);
}
}
}

View File

@ -5,6 +5,9 @@ define([], function () {
"ListNameLabel": "List Name",
"MaxItemsPerPageLabel": "Max number of items per page",
"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"
}
});

View File

@ -5,6 +5,9 @@ declare interface IReactAccordionWebPartStrings {
MaxItemsPerPageLabel: string;
EnablePagingLabel: string;
TotalItemsLabel:string;
CustomSortOrder:string;
SortById:string;
SortByModified:string;
}
declare module 'ReactAccordionWebPartStrings' {