Update SPFx
This commit is contained in:
parent
39ea25afc2
commit
c2a2ec7ffd
|
@ -9,6 +9,7 @@ node_modules
|
||||||
# Build generated files
|
# Build generated files
|
||||||
dist
|
dist
|
||||||
lib
|
lib
|
||||||
|
release
|
||||||
solution
|
solution
|
||||||
temp
|
temp
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
!dist
|
||||||
|
config
|
||||||
|
|
||||||
|
gulpfile.js
|
||||||
|
|
||||||
|
release
|
||||||
|
src
|
||||||
|
temp
|
||||||
|
|
||||||
|
tsconfig.json
|
||||||
|
tslint.json
|
||||||
|
|
||||||
|
*.log
|
||||||
|
|
||||||
|
.yo-rc.json
|
||||||
|
.vscode
|
|
@ -1,11 +1,16 @@
|
||||||
{
|
{
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"plusBeta": false,
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"environment": "spo",
|
"version": "1.14.0",
|
||||||
"version": "1.6.0",
|
|
||||||
"libraryName": "image-gallery",
|
"libraryName": "image-gallery",
|
||||||
"libraryId": "876cbbe8-6974-4676-9da3-5c190ac8164f",
|
"libraryId": "e55194cd-8581-401c-b4fc-06169480813f",
|
||||||
|
"environment": "spo",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
"solutionName": "image-gallery",
|
||||||
|
"solutionShortDescription": "image-gallery description",
|
||||||
|
"skipFeatureDeployment": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
"componentType": "webpart"
|
"componentType": "webpart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,37 @@
|
||||||
# Filterable Image Gallery
|
# Filterable Image Gallery
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
This sample describes an SPFx application which implements an image gallery with taxonomy base filtering and typed search. This application also implements pagination.
|
This sample describes an SPFx application which implements an image gallery with taxonomy base filtering and typed search. This application also implements pagination.
|
||||||
|
|
||||||
|
|
||||||
![Filterable Image Gallery web part built on the SharePoint Framework using React](./assets/image-gallery.gif)
|
![Filterable Image Gallery web part built on the SharePoint Framework using React](./assets/image-gallery.gif)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
![drop](https://img.shields.io/badge/version-1.6.0-green.svg)
|
## Compatibility
|
||||||
|
|
||||||
|
![SPFx 1.14](https://img.shields.io/badge/SPFx-1.14-green.svg)
|
||||||
|
![Node.js v14 | v12](https://img.shields.io/badge/Node.js-v14%20%7C%20v12-green.svg)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
* [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
|
* [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)
|
* [Microsoft 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-image-gallery | Ejaz Hussain
|
react-image-gallery | [Ejaz Hussain](https://github.com/ejazhussain) ([@EjazHussain_](https://twitter.com/EjazHussain_))
|
||||||
|
react-image-gallery | [Ari Gunawan](https://github.com/AriGunawan) ([@arigunawan3023](https://twitter.com/arigunawan3023))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|March 01, 2019|Initial release
|
1.0|March 01, 2019|Initial release
|
||||||
|
1.1|May 23, 2022|Update SPFx version, update README, and fix minor issues
|
||||||
## 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
|
||||||
|
|
||||||
|
@ -39,12 +41,13 @@ Version|Date|Comments
|
||||||
- `gulp serve`
|
- `gulp serve`
|
||||||
|
|
||||||
|
|
||||||
- Create a Department Term set with associated child terms, for example, HR, Information Services, Sales, Marketing
|
- Create a Departments Term set with associated child terms, for example, HR, Information Services, Sales, Marketing
|
||||||
- Create an Image Library and add some sample images
|
- Create an Image Library and add some sample images
|
||||||
- Tag each image with Department Metadata Column
|
- Tag each image with Department Metadata Column
|
||||||
- Also fill in Title field for each image, this is require for typed search functionality
|
- Also fill in Title field for each image, this is require for typed search functionality
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
Here are the main features for this application
|
Here are the main features for this application
|
||||||
|
|
||||||
- Taxonomy-based filtering
|
- Taxonomy-based filtering
|
||||||
|
@ -52,4 +55,30 @@ Here are the main features for this application
|
||||||
- Right-side popup panel
|
- Right-side popup panel
|
||||||
- Server-side pagination using REST API
|
- Server-side pagination using REST API
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but 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're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-image-gallery%22) to see if anybody else is having the same issues.
|
||||||
|
|
||||||
|
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-image-gallery) and see what the community is saying.
|
||||||
|
|
||||||
|
If you encounter any issues 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%2Csample%3A%20react-image-gallery&template=bug-report.yml&sample=react-image-gallery&authors=@arigunawan%20@ejazhussain&title=react-image-gallery%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%3Aquestion%2Csample%3A%20react-image-gallery&template=question.yml&sample=react-image-gallery&authors=@arigunawan%20@ejazhussain&title=react-image-gallery%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%3Aenhancement%2Csample%3A%20react-image-gallery&template=suggestion.yml&sample=react-image-gallery&authors=@arigunawan%20@ejazhussain&title=react-image-gallery%20-%20).
|
||||||
|
|
||||||
|
## 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.**
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-image-gallery" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-image-gallery" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
"workingDir": "./temp/deploy/",
|
"workingDir": "./release/assets/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "image-gallery",
|
"container": "image-gallery",
|
||||||
"accessKey": "<!-- ACCESS KEY -->"
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
|
|
@ -3,9 +3,36 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "image-gallery-client-side-solution",
|
"name": "image-gallery-client-side-solution",
|
||||||
"id": "876cbbe8-6974-4676-9da3-5c190ac8164f",
|
"id": "876cbbe8-6974-4676-9da3-5c190ac8164f",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true
|
"skipFeatureDeployment": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"mpnId": "Undefined-1.14.0"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"shortDescription": {
|
||||||
|
"default": "image-gallery description"
|
||||||
|
},
|
||||||
|
"longDescription": {
|
||||||
|
"default": "image-gallery description"
|
||||||
|
},
|
||||||
|
"screenshotPaths": [],
|
||||||
|
"videoUrl": "",
|
||||||
|
"categories": []
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"title": "image-gallery Feature",
|
||||||
|
"description": "The feature that activates elements of the image-gallery solution.",
|
||||||
|
"id": "afeca86e-a632-48ce-a9eb-b5a4a3e94d85",
|
||||||
|
"version": "1.0.0.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/image-gallery.sppkg"
|
"zippedPackage": "solution/image-gallery.sppkg"
|
||||||
|
|
|
@ -2,9 +2,5 @@
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||||
"port": 4321,
|
"port": 4321,
|
||||||
"https": true,
|
"https": true,
|
||||||
"initialPage": "https://localhost:5432/workbench",
|
"initialPage": "https://enter-your-SharePoint-site/_layouts/workbench.aspx"
|
||||||
"api": {
|
|
||||||
"port": 5432,
|
|
||||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const gulp = require('gulp');
|
|
||||||
const build = require('@microsoft/sp-build-web');
|
const build = require('@microsoft/sp-build-web');
|
||||||
|
|
||||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
build.initialize(gulp);
|
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
File diff suppressed because it is too large
Load Diff
|
@ -2,41 +2,33 @@
|
||||||
"name": "react-image-gallery",
|
"name": "react-image-gallery",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"main": "lib/index.js",
|
||||||
"node": ">=0.10.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp bundle",
|
"build": "gulp bundle",
|
||||||
"clean": "gulp clean",
|
"clean": "gulp clean",
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.6.0",
|
"@microsoft/sp-core-library": "1.14.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.6.0",
|
"@microsoft/sp-lodash-subset": "1.14.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.6.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.14.0",
|
||||||
"@microsoft/sp-webpart-base": "1.6.0",
|
"@microsoft/sp-property-pane": "1.14.0",
|
||||||
"@pnp/common": "^1.2.7",
|
"@microsoft/sp-webpart-base": "1.14.0",
|
||||||
"@pnp/graph": "^1.2.7",
|
"@pnp/spfx-controls-react": "^3.7.2",
|
||||||
"@pnp/logging": "^1.2.7",
|
"office-ui-fabric-react": "7.174.1",
|
||||||
"@pnp/odata": "^1.2.7",
|
"react": "16.13.1",
|
||||||
"@pnp/sp": "^1.2.7",
|
"react-dom": "16.13.1",
|
||||||
"@pnp/spfx-controls-react": "1.11.0",
|
"react-js-pagination": "^3.0.3"
|
||||||
"@types/es6-promise": "0.0.33",
|
|
||||||
"@types/react": "15.6.6",
|
|
||||||
"@types/react-dom": "15.5.6",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"react": "15.6.2",
|
|
||||||
"react-dom": "15.6.2",
|
|
||||||
"react-js-pagination": "^3.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "1.6.0",
|
"@types/react": "16.9.51",
|
||||||
"@microsoft/sp-module-interfaces": "1.6.0",
|
"@types/react-dom": "16.9.8",
|
||||||
"@microsoft/sp-webpart-workbench": "1.6.0",
|
"@microsoft/sp-build-web": "1.14.0",
|
||||||
"tslint-microsoft-contrib": "~5.0.0",
|
"@microsoft/sp-tslint-rules": "1.14.0",
|
||||||
"gulp": "~3.9.1",
|
"@microsoft/sp-module-interfaces": "1.14.0",
|
||||||
"@types/chai": "3.4.34",
|
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
|
||||||
"@types/mocha": "2.2.38",
|
"gulp": "~4.0.2",
|
||||||
"ajv": "~5.2.2"
|
"ajv": "~5.2.2",
|
||||||
|
"@types/webpack-env": "1.13.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,147 +1,94 @@
|
||||||
import { SPHttpClient, SPHttpClientResponse, ISPHttpClientOptions } from '@microsoft/sp-http';
|
import { SPHttpClient } from "@microsoft/sp-http";
|
||||||
import { reject } from 'lodash';
|
import { IListService } from "../Interfaces";
|
||||||
import { IListService, IImage } from '../Interfaces';
|
|
||||||
import { sp, spODataEntityArray, Item } from "@pnp/sp";
|
|
||||||
import Constants from '../Common/constants';
|
|
||||||
import { stringIsNullOrEmpty } from '@pnp/common';
|
|
||||||
|
|
||||||
|
|
||||||
export class ListService implements IListService {
|
export class ListService implements IListService {
|
||||||
|
private spHttpClient: SPHttpClient;
|
||||||
|
|
||||||
private spHttpClient: SPHttpClient;
|
constructor(spHttpClient?: SPHttpClient) {
|
||||||
|
this.spHttpClient = spHttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(spHttpClient?: SPHttpClient) {
|
public async readItems(url: string): Promise<any> {
|
||||||
this.spHttpClient = spHttpClient;
|
try {
|
||||||
|
const response = await this.spHttpClient.get(
|
||||||
|
url,
|
||||||
|
SPHttpClient.configurations.v1,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json;odata=nometadata",
|
||||||
|
"odata-version": "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const items: any = await response.json();
|
||||||
|
let result = {};
|
||||||
|
if (items.value.length) {
|
||||||
|
result = {
|
||||||
|
items: items.value,
|
||||||
|
nextLink: items["odata.nextLink"],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async readItems(url: string): Promise<any> {
|
// return new Promise<any>(async (resolve) => {
|
||||||
try {
|
|
||||||
|
|
||||||
const response = await this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
// this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
||||||
{
|
// {
|
||||||
headers: {
|
// headers: {
|
||||||
'Accept': 'application/json;odata=nometadata',
|
// 'Accept': 'application/json;odata=nometadata',
|
||||||
'odata-version': ''
|
// 'odata-version': ''
|
||||||
}
|
// }
|
||||||
});
|
// }).then((response: SPHttpClientResponse): Promise<{ value: number }> => {
|
||||||
|
// return response.json();
|
||||||
|
// }).then((response: { value: number }): void => {
|
||||||
|
|
||||||
const items: any = await response.json();
|
// resolve(response.value);
|
||||||
let result = {};
|
// });
|
||||||
if (items.value.length) {
|
|
||||||
|
|
||||||
result = {
|
// });
|
||||||
items: items.value,
|
}
|
||||||
nextLink: items["odata.nextLink"]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
|
public async getListItemsCount(url: string): Promise<any> {
|
||||||
|
try {
|
||||||
|
const response = await this.spHttpClient.get(
|
||||||
|
url,
|
||||||
|
SPHttpClient.configurations.v1,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json;odata=nometadata",
|
||||||
|
"odata-version": "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
catch (error) {
|
);
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const result: any = await response.json();
|
||||||
|
|
||||||
|
return result.value;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return new Promise<any>(async (resolve) => {
|
|
||||||
|
|
||||||
// this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
|
||||||
// {
|
|
||||||
// headers: {
|
|
||||||
// 'Accept': 'application/json;odata=nometadata',
|
|
||||||
// 'odata-version': ''
|
|
||||||
// }
|
|
||||||
// }).then((response: SPHttpClientResponse): Promise<{ value: number }> => {
|
|
||||||
// return response.json();
|
|
||||||
// }).then((response: { value: number }): void => {
|
|
||||||
|
|
||||||
// resolve(response.value);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getListItemsCount(url: string): Promise<any> {
|
// return new Promise<any>(async (resolve) => {
|
||||||
try {
|
|
||||||
|
|
||||||
const response = await this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json;odata=nometadata',
|
|
||||||
'odata-version': ''
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const result: any = await response.json();
|
|
||||||
|
|
||||||
return result.value;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return new Promise<any>(async (resolve) => {
|
|
||||||
|
|
||||||
// this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
|
||||||
// {
|
|
||||||
// headers: {
|
|
||||||
// 'Accept': 'application/json;odata=nometadata',
|
|
||||||
// 'odata-version': ''
|
|
||||||
// }
|
|
||||||
// }).then((response: SPHttpClientResponse): Promise<{ value: number }> => {
|
|
||||||
// return response.json();
|
|
||||||
// }).then((response: { value: number }): void => {
|
|
||||||
|
|
||||||
// resolve(response.value);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// this.spHttpClient.get(url, SPHttpClient.configurations.v1,
|
||||||
|
// {
|
||||||
|
// headers: {
|
||||||
|
// 'Accept': 'application/json;odata=nometadata',
|
||||||
|
// 'odata-version': ''
|
||||||
|
// }
|
||||||
|
// }).then((response: SPHttpClientResponse): Promise<{ value: number }> => {
|
||||||
|
// return response.json();
|
||||||
|
// }).then((response: { value: number }): void => {
|
||||||
|
|
||||||
|
// resolve(response.value);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,18 @@
|
||||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
// 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
|
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||||
"requiresCustomScript": false,
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": ["SharePointWebPart", "TeamsPersonalApp", "TeamsTab", "SharePointFullPage"],
|
||||||
|
"supportsThemeVariants": true,
|
||||||
|
|
||||||
"preconfiguredEntries": [{
|
"preconfiguredEntries": [{
|
||||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
"group": { "default": "Other" },
|
"group": { "default": "Other" },
|
||||||
"title": { "default": "imageGallery" },
|
"title": { "default": "React Image Gallery" },
|
||||||
"description": { "default": "imageGallery description" },
|
"description": { "default": "React component that shows image gallery from a list" },
|
||||||
"officeFabricIconFontName": "Page",
|
"officeFabricIconFontName": "PhotoCollection",
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": "imageGallery"
|
"description": "imageGallery",
|
||||||
|
"pageSize": 5
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,16 @@ import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { Version } from '@microsoft/sp-core-library';
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
import {
|
import {
|
||||||
BaseClientSideWebPart,
|
|
||||||
IPropertyPaneConfiguration,
|
IPropertyPaneConfiguration,
|
||||||
PropertyPaneTextField,
|
PropertyPaneTextField,
|
||||||
PropertyPaneSlider
|
PropertyPaneSlider
|
||||||
} from '@microsoft/sp-webpart-base';
|
} from '@microsoft/sp-property-pane';
|
||||||
|
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||||
|
|
||||||
import * as strings from 'ImageGalleryWebPartStrings';
|
import * as strings from 'ImageGalleryWebPartStrings';
|
||||||
import ImageGallery from './components/ImageGallery';
|
import ImageGallery from './components/ImageGallery';
|
||||||
import { IImageGalleryProps } from './components/IImageGalleryProps';
|
import { IImageGalleryProps } from './components/IImageGalleryProps';
|
||||||
import ConfigureWebPart from './components/ConfigureWebPart/ConfigureWebPart';
|
import ConfigureWebPart from './components/ConfigureWebPart/ConfigureWebPart';
|
||||||
import { sp } from '@pnp/sp';
|
|
||||||
import { ListService } from '../../Services/ListService';
|
import { ListService } from '../../Services/ListService';
|
||||||
|
|
||||||
export interface IImageGalleryWebPartProps {
|
export interface IImageGalleryWebPartProps {
|
||||||
|
@ -22,17 +21,12 @@ export interface IImageGalleryWebPartProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGalleryWebPartProps> {
|
export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGalleryWebPartProps> {
|
||||||
private listService: ListService
|
private listService: ListService;
|
||||||
|
|
||||||
|
|
||||||
protected async onInit(): Promise<void> {
|
protected async onInit(): Promise<void> {
|
||||||
const _ = await super.onInit();
|
const _ = await super.onInit();
|
||||||
|
|
||||||
this.listService = new ListService(this.context.spHttpClient);
|
this.listService = new ListService(this.context.spHttpClient);
|
||||||
|
|
||||||
sp.setup({
|
|
||||||
spfxContext: this.context
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
@ -43,17 +37,15 @@ export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGal
|
||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
|
||||||
let element: any;
|
let element: any;
|
||||||
|
|
||||||
if (this.properties.imageLibrary && this.properties.pageSize) {
|
if (this.properties.imageLibrary && this.properties.pageSize) {
|
||||||
|
|
||||||
element = React.createElement<IImageGalleryProps>(
|
element = React.createElement<IImageGalleryProps>(
|
||||||
ImageGallery,
|
ImageGallery,
|
||||||
{
|
{
|
||||||
listName: this.properties.imageLibrary,
|
listName: this.properties.imageLibrary,
|
||||||
context: this.context,
|
context: this.context,
|
||||||
siteUrl: this.context.pageContext.site.absoluteUrl,
|
siteUrl: this.context.pageContext.web.absoluteUrl,
|
||||||
pageSize: this.properties.pageSize
|
pageSize: this.properties.pageSize
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,7 +64,6 @@ export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGal
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReactDom.render(element, this.domElement);
|
ReactDom.render(element, this.domElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +74,7 @@ export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGal
|
||||||
protected get dataVersion(): Version {
|
protected get dataVersion(): Version {
|
||||||
return Version.parse('1.0');
|
return Version.parse('1.0');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get disableReactivePropertyChanges(): boolean {
|
protected get disableReactivePropertyChanges(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +83,6 @@ export default class ImageGalleryWebPart extends BaseClientSideWebPart<IImageGal
|
||||||
return {
|
return {
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
|
|
||||||
groups: [
|
groups: [
|
||||||
{
|
{
|
||||||
groupName: strings.BasicGroupName,
|
groupName: strings.BasicGroupName,
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -1,21 +1,17 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { IWebPartContext } from '@microsoft/sp-webpart-base';
|
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||||
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
|
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
|
||||||
import styles from './ConfigureWebPart.module.scss';
|
import styles from './ConfigureWebPart.module.scss';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface IConfigureWebPartProps {
|
export interface IConfigureWebPartProps {
|
||||||
webPartContext: IWebPartContext;
|
webPartContext: WebPartContext;
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
buttonText?: string;
|
buttonText?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ConfigureWebPart: React.FunctionComponent<IConfigureWebPartProps> = (props) => {
|
||||||
const ConfigureWebPart: React.SFC<IConfigureWebPartProps> = (props) => {
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
webPartContext,
|
webPartContext,
|
||||||
title,
|
title,
|
||||||
|
|
|
@ -4,10 +4,10 @@ export interface IImageGalleryState {
|
||||||
showPanel: boolean;
|
showPanel: boolean;
|
||||||
selectedImage?: IImage;
|
selectedImage?: IImage;
|
||||||
showLoader: boolean;
|
showLoader: boolean;
|
||||||
itemsNotFoundMessage?: string,
|
itemsNotFoundMessage?: string;
|
||||||
sQuery?: string,
|
sQuery?: string;
|
||||||
dQuery?: string
|
dQuery?: string;
|
||||||
itemsNotFound?: boolean,
|
itemsNotFound?: boolean;
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
currentPage?: number;
|
currentPage?: number;
|
||||||
|
|
|
@ -179,4 +179,9 @@
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid rgba(0, 0, 0, .125);
|
border: 1px solid rgba(0, 0, 0, .125);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
|
@ -1,26 +1,19 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styles from './ImageGallery.module.scss';
|
import styles from './ImageGallery.module.scss';
|
||||||
import { IImageGalleryProps } from './IImageGalleryProps';
|
import { IImageGalleryProps } from './IImageGalleryProps';
|
||||||
import { escape } from '@microsoft/sp-lodash-subset';
|
import { css } from '@uifabric/utilities/lib';
|
||||||
import { css, classNamesFunction, IStyleFunction } from '@uifabric/utilities/lib';
|
|
||||||
import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";
|
import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";
|
||||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||||
import { IListService, IImage } from '../../../Interfaces';
|
import { IListService, IImage } from '../../../Interfaces';
|
||||||
import { ListService } from '../../../Services/ListService';
|
import { ListService } from '../../../Services/ListService';
|
||||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||||
import { objectDefinedNotNull, stringIsNullOrEmpty } from '@pnp/common';
|
|
||||||
import { Label } from 'office-ui-fabric-react/lib/Label';
|
|
||||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||||
import { Icon } from 'office-ui-fabric-react/lib/Icon';
|
import { Icon } from 'office-ui-fabric-react/lib/Icon';
|
||||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||||
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
|
||||||
import { Button } from 'office-ui-fabric-react/lib/Button';
|
|
||||||
import { IImageGalleryState } from './IImageGalleryState';
|
import { IImageGalleryState } from './IImageGalleryState';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default class ImageGallery extends React.Component<IImageGalleryProps, IImageGalleryState> {
|
export default class ImageGallery extends React.Component<IImageGalleryProps, IImageGalleryState> {
|
||||||
|
|
||||||
private _spService: IListService;
|
private _spService: IListService;
|
||||||
private selectQuery: string[] = [];
|
private selectQuery: string[] = [];
|
||||||
private expandQuery: string[] = [];
|
private expandQuery: string[] = [];
|
||||||
|
@ -41,10 +34,7 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
pageSize: this.props.pageSize,
|
pageSize: this.props.pageSize,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
nextLink: "",
|
nextLink: "",
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this._onTaxPickerChange = this._onTaxPickerChange.bind(this);
|
this._onTaxPickerChange = this._onTaxPickerChange.bind(this);
|
||||||
this._onClickNext = this._onClickNext.bind(this);
|
this._onClickNext = this._onClickNext.bind(this);
|
||||||
|
@ -52,17 +42,12 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
this._onImageClick = this._onImageClick.bind(this);
|
this._onImageClick = this._onImageClick.bind(this);
|
||||||
this._onSearchChange = this._onSearchChange.bind(this);
|
this._onSearchChange = this._onSearchChange.bind(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this._spService = new ListService(this.props.context.spHttpClient);
|
this._spService = new ListService(this.props.context.spHttpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
//Get Images from the library
|
//Get Images from the library
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let value = await this._spService.getListItemsCount(`${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/ItemCount`);
|
let value = await this._spService.getListItemsCount(`${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/ItemCount`);
|
||||||
this.setState({
|
this.setState({
|
||||||
itemCount: value
|
itemCount: value
|
||||||
|
@ -83,17 +68,16 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
});
|
});
|
||||||
let response = await this._spService.readItems(url);
|
let response = await this._spService.readItems(url);
|
||||||
|
|
||||||
if (objectDefinedNotNull(response)) {
|
if (response) {
|
||||||
|
if (response.nextLink) {
|
||||||
if (objectDefinedNotNull(response.nextLink)) {
|
|
||||||
this.urlCollection.push(response.nextLink);
|
this.urlCollection.push(response.nextLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
showLoader: false,
|
showLoader: false,
|
||||||
items: response.items,
|
items: response.items,
|
||||||
status: `Showing items ${(this.state.currentPage - 1) * this.props.pageSize + 1} - ${((this.state.currentPage - 1) * this.props.pageSize) + response.items.length} of ${this.state.itemCount}`
|
status: `Showing items ${(this.state.currentPage - 1) * this.props.pageSize + 1} - ${((this.state.currentPage - 1) * this.props.pageSize) + response.items.length} of ${this.state.itemCount}`
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -102,12 +86,10 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
status: "",
|
status: "",
|
||||||
itemsNotFound: true
|
itemsNotFound: true
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _onClickNext() {
|
private async _onClickNext() {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
currentPage: this.state.currentPage + 1,
|
currentPage: this.state.currentPage + 1,
|
||||||
showLoader: true
|
showLoader: true
|
||||||
|
@ -115,12 +97,13 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
let url = this.urlCollection[this.urlCollection.length - 1];
|
let url = this.urlCollection[this.urlCollection.length - 1];
|
||||||
this._readItems(url);
|
this._readItems(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _onClickPrevious() {
|
private async _onClickPrevious() {
|
||||||
let url = "";
|
let url = "";
|
||||||
if (this.urlCollection.length > 1) {
|
if (this.urlCollection.length > 1) {
|
||||||
this.setState({
|
this.setState({
|
||||||
currentPage: this.state.currentPage - 1
|
currentPage: this.state.currentPage - 1
|
||||||
})
|
});
|
||||||
|
|
||||||
this.urlCollection.pop();
|
this.urlCollection.pop();
|
||||||
url = this.urlCollection[this.urlCollection.length - 1];
|
url = this.urlCollection[this.urlCollection.length - 1];
|
||||||
|
@ -143,8 +126,6 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private buildQueryParams(taxQuery?: string, searchQuery?: string): string {
|
private buildQueryParams(taxQuery?: string, searchQuery?: string): string {
|
||||||
this.selectQuery = [];
|
this.selectQuery = [];
|
||||||
this.expandQuery = [];
|
this.expandQuery = [];
|
||||||
|
@ -179,33 +160,30 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
return queryParam + selectColumns + filterColumns;
|
return queryParam + selectColumns + filterColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private buildFilterQuery(taxQuery: string, searchQuery: string) {
|
private buildFilterQuery(taxQuery: string, searchQuery: string) {
|
||||||
let result: string = "";
|
let result: string = "";
|
||||||
|
|
||||||
if (!stringIsNullOrEmpty(taxQuery) && stringIsNullOrEmpty(searchQuery)) {
|
if (!taxQuery && searchQuery) {
|
||||||
result = `TaxCatchAll/Term eq '${taxQuery}'`;
|
result = `TaxCatchAll/Term eq '${taxQuery}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringIsNullOrEmpty(taxQuery) && !stringIsNullOrEmpty(searchQuery)) {
|
if (taxQuery && !searchQuery) {
|
||||||
result = `startswith(Title,'${searchQuery}')`;
|
result = `startswith(Title,'${searchQuery}')`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stringIsNullOrEmpty(taxQuery) && !stringIsNullOrEmpty(searchQuery)) {
|
if (!taxQuery && !searchQuery) {
|
||||||
result = `(TaxCatchAll/Term eq '${taxQuery}') and (startswith(Title,'${searchQuery}'))`;
|
result = `(TaxCatchAll/Term eq '${taxQuery}') and (startswith(Title,'${searchQuery}'))`;
|
||||||
}
|
}
|
||||||
if (stringIsNullOrEmpty(taxQuery) && stringIsNullOrEmpty(searchQuery)) {
|
|
||||||
|
if (taxQuery && searchQuery) {
|
||||||
result = "";
|
result = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
private async _onTaxPickerChange(terms: IPickerTerms) {
|
|
||||||
|
|
||||||
|
private async _onTaxPickerChange(terms: IPickerTerms) {
|
||||||
this.urlCollection = [];
|
this.urlCollection = [];
|
||||||
let query = "";
|
let query = "";
|
||||||
|
|
||||||
|
@ -225,9 +203,9 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
let url = `${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`;
|
let url = `${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`;
|
||||||
this.urlCollection.push(url);
|
this.urlCollection.push(url);
|
||||||
this._readItems(url);
|
this._readItems(url);
|
||||||
|
|
||||||
}
|
}
|
||||||
private async _onSearchChange(query: any) {
|
|
||||||
|
private async _onSearchChange(event: any, query: any) {
|
||||||
this.urlCollection = [];
|
this.urlCollection = [];
|
||||||
this.setState({
|
this.setState({
|
||||||
sQuery: query
|
sQuery: query
|
||||||
|
@ -235,12 +213,10 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
|
|
||||||
let queryParam = this.buildQueryParamsTotalFilteredItems(this.state.dQuery, query);
|
let queryParam = this.buildQueryParamsTotalFilteredItems(this.state.dQuery, query);
|
||||||
let response = await this._spService.readItems(`${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`);
|
let response = await this._spService.readItems(`${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`);
|
||||||
if (objectDefinedNotNull(response)) {
|
if (response) {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
itemCount: response.items.length
|
itemCount: response.items.length
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -248,12 +224,12 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
queryParam = this.buildQueryParams(this.state.dQuery, query);
|
queryParam = this.buildQueryParams(this.state.dQuery, query);
|
||||||
let url = `${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`;
|
let url = `${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.props.listName}')/items/${queryParam}`;
|
||||||
this.urlCollection.push(url);
|
this.urlCollection.push(url);
|
||||||
this._readItems(url);
|
this._readItems(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onImageClick(selectedImage: any): void {
|
private _onImageClick(selectedImage: any): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedImage,
|
selectedImage,
|
||||||
|
@ -263,7 +239,6 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): React.ReactElement<IImageGalleryProps> {
|
public render(): React.ReactElement<IImageGalleryProps> {
|
||||||
|
|
||||||
const spinnerStyles = props => ({
|
const spinnerStyles = props => ({
|
||||||
circle: [
|
circle: [
|
||||||
{
|
{
|
||||||
|
@ -279,13 +254,11 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
let tagList;
|
let tagList;
|
||||||
|
|
||||||
if (this.state.items.length) {
|
if (this.state.items.length) {
|
||||||
|
|
||||||
result = this.state.items.map((item, index) => {
|
result = this.state.items.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index} className={css(styles.column, styles.mslg3)} onClick={() => this._onImageClick(item)}>
|
<div key={index} className={css(styles.column, styles.mslg3)} onClick={() => this._onImageClick(item)}>
|
||||||
|
@ -295,27 +268,27 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
<figcaption>{item.Title}</figcaption>
|
<figcaption>{item.Title}</figcaption>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectDefinedNotNull(this.state.selectedImage.Department)) {
|
if (this.state.selectedImage.Department) {
|
||||||
tagList = this.state.selectedImage.Department.map((tag: any, index) => {
|
tagList = this.state.selectedImage.Department.map((tag: any, index) => {
|
||||||
return <li className={styles.listGroupItem} key={index}> <Icon iconName="Tag" className={styles.msIconTag} /> {tag.Label}</li>;
|
return <li className={styles.listGroupItem} key={index}> <Icon iconName="Tag" className={styles.msIconTag} /> {tag.Label}</li>;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.imageGallery}>
|
<div className={styles.imageGallery}>
|
||||||
<div className={styles.container} dir="ltr">
|
<div className={styles.container} dir="ltr">
|
||||||
<div className={css(styles.row, styles.header)}>
|
<div className={css(styles.row, styles.header)}>
|
||||||
<div className={css(styles.column, styles.mslg12, styles.pageTitle)}>
|
<div className={css(styles.column, styles.mslg12, styles.pageTitle)}>
|
||||||
<h1>Image Gallery <small> Filterable</small></h1></div>
|
<h1>Image Gallery <small> Filterable</small></h1></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className={css(styles.row, styles.filters)}>
|
<div className={css(styles.row, styles.filters)}>
|
||||||
<div className={css(styles.column, styles.mslg12, styles.panel)}>
|
<div className={css(styles.column, styles.mslg12, styles.panel)}>
|
||||||
<div className={styles.panelBody}>
|
<div className={styles.filterContainer}>
|
||||||
<div className={css(styles.column, styles.mslg3, styles.filter)}>
|
<div>
|
||||||
<TaxonomyPicker
|
<TaxonomyPicker
|
||||||
allowMultipleSelections={false}
|
allowMultipleSelections={false}
|
||||||
termsetNameOrID="Departments"
|
termsetNameOrID="Departments"
|
||||||
|
@ -325,10 +298,9 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
onChange={this._onTaxPickerChange}
|
onChange={this._onTaxPickerChange}
|
||||||
isTermSetSelectable={false}
|
isTermSetSelectable={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className={css(styles.column, styles.mslg3, "ms-u-lgPush6", styles.searchBox)}>
|
<div>
|
||||||
<TextField label="Search" className={styles.searchBoxInputField} placeholder="Enter search term" onChanged={this._onSearchChange} />
|
<TextField label="Search" className={styles.searchBoxInputField} placeholder="Enter search term" onChange={this._onSearchChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -336,15 +308,12 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
<div className={css(styles.row)}>
|
<div className={css(styles.row)}>
|
||||||
<div className={css(styles.column, styles.mslg12, styles.panel)}>
|
<div className={css(styles.column, styles.mslg12, styles.panel)}>
|
||||||
<div className={styles.panelBody}>
|
<div className={styles.panelBody}>
|
||||||
|
|
||||||
{
|
{
|
||||||
this.state.showLoader
|
this.state.showLoader
|
||||||
? <Spinner size={SpinnerSize.large} label="loading..." className={css(styles.loader)} getStyles={spinnerStyles} />
|
? <Spinner size={SpinnerSize.large} label="loading..." className={css(styles.loader)} styles={spinnerStyles} />
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className={css(styles.row, styles.mainContent)}>
|
<div className={css(styles.row, styles.mainContent)}>
|
||||||
|
|
||||||
{result.length > 0 ? result : ""}
|
{result.length > 0 ? result : ""}
|
||||||
{!result.length && this.state.itemsNotFound ? <MessageBar
|
{!result.length && this.state.itemsNotFound ? <MessageBar
|
||||||
messageBarType={MessageBarType.warning}
|
messageBarType={MessageBarType.warning}
|
||||||
|
@ -375,7 +344,6 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -386,10 +354,10 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
<div className={styles.status}>{this.state.status}</div>
|
<div className={styles.status}>{this.state.status}</div>
|
||||||
<ul className={styles.pager}>
|
<ul className={styles.pager}>
|
||||||
<li>
|
<li>
|
||||||
<Button disabled={((this.state.currentPage - 1) * this.props.pageSize + 1) <= 1} onClick={this._onClickPrevious}>Previous</Button>
|
<PrimaryButton disabled={((this.state.currentPage - 1) * this.props.pageSize + 1) <= 1} onClick={this._onClickPrevious}>Previous</PrimaryButton>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Button disabled={((this.state.currentPage - 1) * this.props.pageSize) + this.state.items.length >= this.state.itemCount} onClick={this._onClickNext}>Next</Button>
|
<PrimaryButton disabled={((this.state.currentPage - 1) * this.props.pageSize) + this.state.items.length >= this.state.itemCount} onClick={this._onClickNext}>Next</PrimaryButton>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -399,5 +367,4 @@ export default class ImageGallery extends React.Component<IImageGalleryProps, II
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
After Width: | Height: | Size: 542 B |
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.9/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
@ -10,25 +11,25 @@
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types",
|
"./node_modules/@types",
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"es6-promise",
|
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es5",
|
"es5",
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts",
|
||||||
],
|
"src/**/*.tsx"
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"lib"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
"rulesDirectory": [
|
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
"tslint-microsoft-contrib"
|
|
||||||
],
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"class-name": false,
|
"class-name": false,
|
||||||
"export-name": false,
|
"export-name": false,
|
||||||
|
@ -19,7 +17,6 @@
|
||||||
"no-switch-case-fall-through": true,
|
"no-switch-case-fall-through": true,
|
||||||
"no-unnecessary-semicolons": true,
|
"no-unnecessary-semicolons": true,
|
||||||
"no-unused-expression": true,
|
"no-unused-expression": true,
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-with-statement": true,
|
"no-with-statement": true,
|
||||||
"semicolon": true,
|
"semicolon": true,
|
||||||
"trailing-comma": false,
|
"trailing-comma": false,
|
||||||
|
|
Loading…
Reference in New Issue