parent
a3c0fc3b33
commit
cd2c6f8feb
|
@ -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": {
|
||||
"version": "1.12.1",
|
||||
"libraryName": "hero-webpart",
|
||||
"libraryId": "5efc0426-3e59-4fc7-b638-73eb77aaf788",
|
||||
"environment": "spo",
|
||||
"packageManager": "npm",
|
||||
"isCreatingSolution": true,
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
# hero-webpart
|
||||
|
||||
## Summary
|
||||
|
||||
This solution creates a customisable Hero Webpart, it uses a stored collection from the PnP PropertyFieldCollectionData control
|
||||
|
||||
[picture of the solution in action, if possible]
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
|
||||
![version](https://img.shields.io/npm/v/@microsoft/sp-component-base/latest?color=green)
|
||||
|
||||
## Applies to
|
||||
|
||||
- [SharePoint Framework](https://aka.ms/spfx)
|
||||
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
hero-webpart | Omar El-Anis @ SP Bytes www.spbytes.com
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.1|March 10, 2021|Update comment
|
||||
1.0|January 29, 2021|Initial release
|
||||
|
||||
## Disclaimer
|
||||
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
---
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository
|
||||
- Ensure that you are at the solution folder
|
||||
- in the command-line run:
|
||||
- **npm install**
|
||||
- **gulp serve**
|
||||
|
||||
> Include any additional steps as needed.
|
||||
|
||||
## Features
|
||||
|
||||
Description of the extension that expands upon high-level summary above.
|
||||
|
||||
This extension illustrates the following concepts:
|
||||
|
||||
- Store data (images) in a collection from property panel using the file picker module
|
||||
- Load the data into a paginated list
|
||||
- Display the data in a Hero style format
|
||||
|
||||
> Notice that better pictures and documentation will increase the sample usage and the value you are providing for others. Thanks for your submissions advance.
|
||||
|
||||
> Share your web part with others through Microsoft 365 Patterns and Practices program to get visibility and exposure. More details on the community, open-source projects and other activities from http://aka.ms/m365pnp.
|
||||
|
||||
## References
|
||||
|
||||
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
|
||||
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
|
||||
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
||||
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
Binary file not shown.
After Width: | Height: | Size: 6.1 MiB |
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"hero-webpart-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/heroWebpart/HeroWebpartWebPart.js",
|
||||
"manifest": "./src/webparts/heroWebpart/HeroWebpartWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"HeroWebpartWebPartStrings": "lib/webparts/heroWebpart/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": "hero-webpart",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "hero-webpart-client-side-solution",
|
||||
"id": "5efc0426-3e59-4fc7-b638-73eb77aaf788",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "Omar El-Anis",
|
||||
"websiteUrl": "www.spbytes.com",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "6238832"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/hero-webpart.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -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'));
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "hero-webpart",
|
||||
"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/sp": "^2.6.0",
|
||||
"@pnp/spfx-controls-react": "^3.2.1",
|
||||
"@pnp/spfx-property-controls": "3.2.0",
|
||||
"node-sass": "^6.0.1",
|
||||
"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 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "71d58a4f-1896-46aa-94a5-dbef33d14166",
|
||||
"alias": "HeroWebpartWebPart",
|
||||
"componentType": "WebPart",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": ["SharePointWebPart"],
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "Hero Webpart" },
|
||||
"description": { "default": "Provides a customisable Hero webpart that displays 5 images in a standlone or carousel view" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "Hero Webpart"
|
||||
}
|
||||
}]
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 189 KiB |
|
@ -0,0 +1,68 @@
|
|||
import * as React from "react";
|
||||
import { IHeroLayoutProps } from "./IHeroLayoutProps";
|
||||
import styles from './HeroWebpart.module.scss';
|
||||
|
||||
// Used to render list grid
|
||||
import { List } from 'office-ui-fabric-react/lib/List';
|
||||
import { IRectangle, ISize } from 'office-ui-fabric-react/lib/Utilities';
|
||||
|
||||
|
||||
export default class Hero extends React.Component<IHeroLayoutProps> {
|
||||
|
||||
|
||||
public render(): React.ReactElement<IHeroLayoutProps> {
|
||||
const items = this.props.items;
|
||||
var arr = [];
|
||||
arr.push(items);
|
||||
|
||||
return (
|
||||
<div role="group">
|
||||
<List
|
||||
role="presentation"
|
||||
className={styles.heroItem}
|
||||
items={arr}
|
||||
getItemCountForPage={this._getItemCountForPage}
|
||||
onRenderCell={this._onRenderHeroItem}
|
||||
{...this.props.listProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
const firstItem = items.slice(0,1)[0];
|
||||
var firstItemUrl = firstItem.filePicker[0].Hyperlink ? firstItem.filePicker[0].Hyperlink : "#";
|
||||
var smalltemUrl;
|
||||
return(
|
||||
<div className={styles.heroItem}>
|
||||
<div className={styles["flexcontainer"]}>
|
||||
<div className={styles.focusItem}>
|
||||
<div className={styles["flexitems"]}>
|
||||
<a href={firstItemUrl}>
|
||||
<img src={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>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles["flexcontainer"]}>
|
||||
{secondItems.map((item) => (
|
||||
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"}/>
|
||||
<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>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.heroWebpart {
|
||||
.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;
|
||||
}
|
||||
|
||||
.titleHead {
|
||||
@include ms-font-xl;
|
||||
@include ms-fontColor-black;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.carouselContent{
|
||||
color:"[theme: themeSecondary, default: #0078d7]";
|
||||
min-height:600px;
|
||||
height:600px;
|
||||
}
|
||||
.carouselButtonsContainer{
|
||||
color:"[theme: themeSecondary, default: #0078d7]";
|
||||
}
|
||||
|
||||
.carouselContentOne, .carouselContentTwo, .carouselContentThree, .carouselContentFour{
|
||||
color:"[theme: themeSecondary, default: #0078d7]";
|
||||
min-height:530px;
|
||||
height:530px;
|
||||
}
|
||||
|
||||
.carouselContentOne{
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
width: 100%!important;
|
||||
padding:0%
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div) {
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
|
||||
.carouselContentTwo {
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
width: 46%!important;
|
||||
padding:2%
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div) {
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
|
||||
.carouselContentThree{
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
width: 29%!important;
|
||||
padding:2%
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div) {
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
|
||||
.carouselContentFour{
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
width: 24%!important;
|
||||
padding:1%
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div) {
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
|
||||
.heroTitle{
|
||||
@include ms-font-xl;
|
||||
padding-bottom: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.heroItem {
|
||||
flex: auto;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
|
||||
.flexcontainer .flexitems:hover .description {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.flexcontainer .flexitems .description{
|
||||
@include ms-fontColor-white;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
color: #f1f1f1;
|
||||
width: calc(100% - 40px);
|
||||
transition: .5s ease;
|
||||
opacity: 0;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
padding: 20px 0px;;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.flexcontainer .flexitems{
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.flexcontainer:nth-child(1){
|
||||
flex: auto;
|
||||
flex-basis: 40%;
|
||||
flex-shrink: 1;
|
||||
padding-right:5px;
|
||||
padding-bottom: 7px;
|
||||
|
||||
*{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.description {
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.focusItem {
|
||||
overflow: hidden;
|
||||
.flexitems {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: auto;
|
||||
align-self: auto;
|
||||
order: 0;
|
||||
position: relative;
|
||||
padding-bottom: 5px;
|
||||
|
||||
img{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flexcontainer:nth-child(2) {
|
||||
flex: auto;
|
||||
flex-basis: 60%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
img{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
.description {
|
||||
width: calc(100% - 5px);
|
||||
}
|
||||
|
||||
.flexitems{
|
||||
padding-right:5px;
|
||||
flex-basis: calc(50% - 5px);
|
||||
flex-shrink: 1;
|
||||
align-self: auto;
|
||||
position: relative;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
.heroItem {
|
||||
flex-direction: column;
|
||||
.flexcontainer:nth-child(1){
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.flexcontainer:nth-child(2) {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.carouselContentOne, .carouselContentTwo, .carouselContentThree, .carouselContentFour{
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
width: 100%!important;
|
||||
height: 160px;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell img){
|
||||
width: 100%!important;
|
||||
height: 100px!important;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell .ms-Image){
|
||||
width: 100%!important;
|
||||
height: 100px!important;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div){
|
||||
max-height: 100px;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell div){
|
||||
max-height: 100px;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell .ms-DocumentCardLocation){
|
||||
display:none;
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
.subGroup{
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
.subGroup ~ .subGroup{
|
||||
display:inline-block;
|
||||
}
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
.subGroup ~ .subGroup a{
|
||||
display:inline-block;
|
||||
width: 48%!important;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell){
|
||||
.subGroup ~ .subGroup a *{
|
||||
font-size:8px
|
||||
}
|
||||
}
|
||||
:global(.ms-List-page .ms-List-cell .ms-DocumentCardDetails .ms-DocumentCardTitle:nth-child(2)){
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
import * as React from 'react';
|
||||
import styles from './HeroWebpart.module.scss';
|
||||
import { IHeroWebpartProps } from './IHeroWebpartProps';
|
||||
import {IHeroState} from './IHeroWebpartState';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
|
||||
import { PnPClientStorage } from "@pnp/common";
|
||||
import { IHeroLayoutProps } from './IHeroLayoutProps';
|
||||
import Hero from './HeroLayout';
|
||||
import { sp } from '@pnp/sp';
|
||||
import { Stack, IStackProps, IStackTokens } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { Label } from 'office-ui-fabric-react/lib/Label';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
|
||||
const stackTokens: IStackTokens = { childrenGap: 20 };
|
||||
|
||||
const rowProps: IStackProps = { horizontal: true, verticalAlign: 'center' };
|
||||
|
||||
const tokens = {
|
||||
sectionStack: {
|
||||
childrenGap: 10,
|
||||
},
|
||||
spinnerStack: {
|
||||
childrenGap: 20,
|
||||
},
|
||||
};
|
||||
|
||||
const storage = new PnPClientStorage();
|
||||
|
||||
export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHeroState> {
|
||||
|
||||
constructor(props: IHeroWebpartProps) {
|
||||
super(props);
|
||||
sp.setup({
|
||||
spfxContext: this.props.spfxContext
|
||||
});
|
||||
this.state = {
|
||||
items: this.props.items || [],
|
||||
itemsPaginated: this.props.items.slice(0,5) || [],
|
||||
currentPage: 1,
|
||||
totalPages: Math.ceil(this.props.items.length / 5),
|
||||
pageLimit: 5
|
||||
};
|
||||
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)});
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private emptyCourse(){
|
||||
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: "",
|
||||
description: "We don't have anything here yet, we're always open to suggestions!",
|
||||
enrollment: "",
|
||||
SPurl: ""
|
||||
});
|
||||
}
|
||||
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();
|
||||
return(
|
||||
<Stack {...rowProps} tokens={tokens.spinnerStack}>
|
||||
<Label>Loading</Label>
|
||||
<Spinner size={SpinnerSize.large} />
|
||||
</Stack>
|
||||
);
|
||||
}else{
|
||||
var itemList:any[];
|
||||
this.props.showAllHero ? itemList = this.state.itemsPaginated : itemList = this.state.items;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.heroWebpart}>
|
||||
<div className={styles.titleHead}>
|
||||
{this.props.title}
|
||||
</div>
|
||||
<Hero items={this.props.showAllHero ? this.state.itemsPaginated : this.state.items.slice(0, 5)}/>
|
||||
{this.props.showAllHero ?
|
||||
<Pagination
|
||||
currentPage={this.state.currentPage}
|
||||
totalPages={this.state.totalPages}
|
||||
onChange={(page) => this._getPage(page)}
|
||||
limiter={5} // Optional - default value 3
|
||||
hideFirstPageJump={this.props.hideFirstPageJump} // Optional
|
||||
hideLastPageJump={this.props.hideLastPageJump} // Optional
|
||||
limiterIcon={"Emoji12"} // Optional
|
||||
/> : "" }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { IListProps } from 'office-ui-fabric-react/lib/List';
|
||||
|
||||
|
||||
export interface IHeroLayoutProps {
|
||||
items:any[];
|
||||
listProps?: Partial<IListProps>;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
|
||||
export interface IHeroWebpartProps {
|
||||
title: string;
|
||||
spfxContext: WebPartContext;
|
||||
isPaginated: boolean;
|
||||
pageLimit: number;
|
||||
hideFirstPageJump: boolean;
|
||||
hideLastPageJump: boolean;
|
||||
showAllHero: boolean;
|
||||
items:any[];
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export interface IHeroState {
|
||||
items: any[];
|
||||
itemsPaginated: any[];
|
||||
currentPage: number;
|
||||
totalPages: number;
|
||||
pageLimit: number;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Set the images, links and details of the Hero items",
|
||||
"BasicGroupName": "Hero Settings",
|
||||
"TitleFieldLabel": "Webpart Title"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
declare interface IHeroWebpartWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
TitleFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'HeroWebpartWebPartStrings' {
|
||||
const strings: IHeroWebpartWebPartStrings;
|
||||
export = strings;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue