Fixes for blank collection

Added fixes for when webpart is first added to page and no collection exists
This commit is contained in:
Omar 2021-07-08 23:24:32 +01:00
parent 339acc7568
commit 7197a95a05
7 changed files with 31 additions and 44 deletions

View File

@ -2,12 +2,10 @@
## Summary
This solution creates a customisable Hero style webpart that allows any number of images to be added, it will by default display just 5 but you can enable pagination which will allow all items to be loaded in a paged view. It uses a stored collection from the PnP PropertyFieldCollectionData control to store the images, Title, Description and URL fields.
You can customise this in a number of ways but it hopefully gives a baseline for re-creating some of the functionality of the OOB Hero Webpart.
![Hero](https://github.com/omarelanis/sp-dev-fx-webparts/blob/master/samples/hero-webpart/Sample/Hero-Webpart.gif)
This solution creates a customisable Hero Webpart, it uses a stored collection from the PnP PropertyFieldCollectionData control
[https://github.com/omarelanis/sp-dev-fx-webparts/blob/master/samples/hero-webpart/Sample/Hero-Webpart.gif]
## Used SharePoint Framework Version
![version](https://img.shields.io/npm/v/@microsoft/sp-component-base/latest?color=green)
@ -69,4 +67,4 @@ This extension illustrates the following concepts:
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development

View File

@ -1,7 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "hero-webpart-client-side-solution",
"name": "Hero Layout Webpart",
"id": "5efc0426-3e59-4fc7-b638-73eb77aaf788",
"version": "1.0.0.0",
"includeClientSideAssets": true,

View File

@ -17,11 +17,15 @@
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "Hero Webpart" },
"title": { "default": "Hero Layout Webpart" },
"description": { "default": "Provides a customisable Hero webpart that displays 5 images in a standlone or carousel view" },
"officeFabricIconFontName": "Page",
"properties": {
"description": "Hero Webpart"
"description": "Hero Layout Webpart",
"isPaginated":false,
"hideFirstPageJump":false,
"hideLastPageJump":false,
"showAllHero":false
}
}]
}

View File

@ -43,7 +43,7 @@ export default class HeroWebpartWebPart extends BaseClientSideWebPart<IHeroWebpa
spfxContext: this.context,
showAllHero: this.properties.showAllHero,
pageLimit:5,
items:this.properties.collectionData
items:this.properties.collectionData?this.properties.collectionData:[]
}
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View File

@ -32,7 +32,7 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
private _getItemCountForPage = (itemIndex: number, surfaceRect: IRectangle): number => {
return 1;
}
private _onRenderHeroItem = (items: any, index: number | undefined): JSX.Element => {
const thumbRend = "https://media.akamai.odsp.cdn.office.net/uksouth1-mediap.svc.ms/transform/thumbnail?provider=url&inputFormat=jpg&docid=";
const secondItems = items.slice(1,5);
@ -45,7 +45,7 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
<div className={styles.focusItem}>
<div className={styles["flexitems"]}>
<a href={firstItemUrl}>
<img src={thumbRend+firstItem.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
<img src={firstItem.filePicker[0].fileNameWithoutExtension=='blankEntry154873'?firstItem.filePicker[0].fileAbsoluteUrl:thumbRend+firstItem.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
<div className={styles.description}><div className={styles.heroTitle}>{firstItem.Title}</div>{firstItem.Description ? firstItem.Description.length>150 ? firstItem.Description.substring(0, 150)+".." : firstItem.Description : "Description coming soon"}</div>
</a>
</div>
@ -56,7 +56,7 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
smalltemUrl= item.filePicker[0].Hyperlink ? item.filePicker[0].Hyperlink : "#",
<div className={styles["flexitems"]}>
<a href={smalltemUrl}>
<img src={thumbRend+item.filePicker[0].fileAbsoluteUrl+"&w=640"}/>
<img src={item.filePicker[0].fileNameWithoutExtension=='blankEntry154873'?item.filePicker[0].fileAbsoluteUrl:thumbRend+item.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
<div className={styles.description}><div className={styles.heroTitle}>{item.Title}</div>{item.Description ? item.Description.length>150 ? item.Description.substring(0, 150)+".." : item.Description : "Description coming soon"}</div>
</a>
</div>

View File

@ -36,61 +36,46 @@ export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHer
});
this.state = {
items: this.props.items || [],
itemsPaginated: this.props.items.slice(0,5) || [],
itemsPaginated: this.props.items.length>0?this.props.items.slice(0,5):[],
currentPage: 1,
totalPages: Math.ceil(this.props.items.length / 5),
pageLimit: 5
totalPages: this.props.items.length>0?Math.ceil(this.props.items.length / 5):1,
pageLimit: this.props.pageLimit
};
this._getItems();
// Delete any expired cache items
// storage.local.deleteExpired();
// // Get items from cache if they exist
// const items = storage.local.get("c70a33331a1e4172bd87d46ee92af341");
// if (items===null || undefined===items[0]){
// this._getItems();
// }else{
// this.setState({items: items,itemsPaginated:items.slice(0,5),totalPages:Math.ceil(items.length / 5)});
// }
}
private _getItems(){
this.setState({itemsPaginated:this.state.items.slice(0,5),totalPages:Math.ceil(this.state.items.length / 5)});
let empty=[];
if(this.state.items.length>0){
this.setState({itemsPaginated:this.state.items.slice(0,5)}),this.setState({totalPages:Math.ceil(this.state.items.length / 5)});
}else{
empty=this.emptyHeroItem();this.setState({items:empty}),this.setState({itemsPaginated:empty});
}
}
private _getPage(page: number){
this.setState({currentPage: page});
var itemsSlice:any[], totalPages:number;
itemsSlice = this.state.items.slice((page - 1) * this.state.pageLimit, ((page - 1) * this.state.pageLimit) + this.state.pageLimit);
itemsSlice.length==0 ? this.setState({itemsPaginated: this.emptyCourse()}) : this.setState({itemsPaginated: itemsSlice},this.render);
itemsSlice.length==0 ? this.setState({itemsPaginated: this.emptyHeroItem()}) : this.setState({itemsPaginated: itemsSlice},this.render);
}
private emptyCourse(){
private emptyHeroItem(){
var b=[];
for (let i = 0; i < this.state.pageLimit; i++) {
b.push({
id:"",
thumbnail: require('../assets/blankEntry.jpg'),
title: "Coming soon!",
name: "",
profileImageSrc: "",
courseCode: "",
activity: "",
Title: "Coming soon!",
description: "We don't have anything here yet, we're always open to suggestions!",
enrollment: "",
SPurl: ""
Hyperlink:"",
filePicker:[{fileAbsoluteUrl:require('../assets/blankEntry154873.jpg'),fileName:'blankEntry154873.jpg',fileNameWithoutExtension:'blankEntry154873'}]
});
}
return b;
}
public render(): React.ReactElement<IHeroWebpartProps> {
// if(this.state.items!=this.props.items){
// this.setState({items :this.props.items});
// }
if(this.state.items.length<1){
//this._getItems();
if(this.state.items.length<=0){
this._getItems();
return(
<Stack {...rowProps} tokens={tokens.spinnerStack}>
<Label>Loading</Label>