Added sample react-adaptive-cards-image-gallery (#700)
* added react-display-hierarchy * Added sample react-adaptive-cards-image-gallery
This commit is contained in:
parent
d9fefb7bd4
commit
e69d235991
|
@ -0,0 +1,25 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
|
||||||
|
# change these settings to your own preference
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# we recommend you to keep these unchanged
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[{package,bower}.json]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.7.0",
|
||||||
|
"libraryName": "react-adaptive-cards-image-gallery",
|
||||||
|
"libraryId": "2321325f-19a4-4895-8bdd-9a5447d462b1",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
## Image Gallery Web Part Built with Adaptive Cards
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
This sample demonstrates the capability of using [Adaptive Cards] (https://adaptivecards.io/) with SharePoint Framework. Adaptive cards are great fit for Bot, however they can be effectively used with SPFx to render the content. This web part helps to display the image gallery from SharePoint list.
|
||||||
|
|
||||||
|
![Web part preview][figure1]
|
||||||
|
|
||||||
|
When added to SharePoint site, the source list containing images information, number of images to display can be configured from web part properties.
|
||||||
|
The sample also provisions the list called "Adaptive Card Images" which can be used as an example to start using the web part.
|
||||||
|
![SharePoint Run][figure2]
|
||||||
|
|
||||||
|
### SharePoint Asset
|
||||||
|
A SharePoint list (named "Adaptive Card Images") is provisioned to store the image information. The schema of the list is as below.
|
||||||
|
![List Schema][figure3]
|
||||||
|
- The "Image Link" column stores the url of image to be displayed in adaptive card.
|
||||||
|
- The "Navigation URL" column represents the url to navigate by clicking on image in adaptive card.
|
||||||
|
- The "Sort Order" column represents the order in which images to be displayed in adaptive card.
|
||||||
|
|
||||||
|
The solution also provisions sample data to the "Adaptive Card Images" list.
|
||||||
|
![List Sample Data][figure4]
|
||||||
|
|
||||||
|
### NPM Packages Used
|
||||||
|
Below NPM packages are used to develop this sample.
|
||||||
|
1. sp-pnp-js (https://www.npmjs.com/package/sp-pnp-js)
|
||||||
|
2. adaptivecards (https://www.npmjs.com/package/adaptivecards)
|
||||||
|
|
||||||
|
## Used SharePoint Framework Version
|
||||||
|
![drop](https://img.shields.io/badge/drop-1.7-green.svg)
|
||||||
|
|
||||||
|
## Applies to
|
||||||
|
|
||||||
|
* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
|
||||||
|
* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
react-adaptive-cards-image-gallery|[Nanddeep Nachan](https://www.linkedin.com/in/nanddeepnachan/) (SharePoint Consultant, [@NanddeepNachan](https://http://twitter.com/NanddeepNachan) )
|
||||||
|
|[Ravi Kulkarni](https://www.linkedin.com/in/ravi-kulkarni-a5381723/) (SharePoint Consultant)
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0.0|November 28, 2018|Initial release
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- SharePoint Online tenant
|
||||||
|
- Site Collection created under the **/sites/** or **/**
|
||||||
|
|
||||||
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
- Clone this repo
|
||||||
|
- npm i
|
||||||
|
- gulp serve --nobrowser
|
||||||
|
- Open workbench on your tennant, i.e. https://contoso.sharepoint.com/sites/salesteam/_layouts/15/workbench.aspx
|
||||||
|
- Search and add web part "Adaptive Cards Image Gallery"
|
||||||
|
|
||||||
|
## Features
|
||||||
|
This sample web part shows how adaptive cards can be used effectively with SharePoint Framework to render an image gallery with data stored in a SharePoint list.
|
||||||
|
- Integrating adaptive cards
|
||||||
|
- Rendering image gallery
|
||||||
|
- SharePoint assets provisioning
|
||||||
|
- Creating extensible services
|
||||||
|
- Using @sp-pnp-js
|
||||||
|
- Using @adaptivecards
|
||||||
|
|
||||||
|
|
||||||
|
[figure1]: ./assets/webpart-preview.png
|
||||||
|
[figure2]: ./assets/sharepoint-run.gif
|
||||||
|
[figure3]: ./assets/list-schema.png
|
||||||
|
[figure4]: ./assets/list-sample-data.png
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
|
"version": "2.0",
|
||||||
|
"bundles": {
|
||||||
|
"adaptive-cards-image-gallery-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/adaptiveCardsImageGallery/AdaptiveCardsImageGalleryWebPart.js",
|
||||||
|
"manifest": "./src/webparts/adaptiveCardsImageGallery/AdaptiveCardsImageGalleryWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externals": {},
|
||||||
|
"localizedResources": {
|
||||||
|
"AdaptiveCardsImageGalleryWebPartStrings": "lib/webparts/adaptiveCardsImageGallery/loc/{locale}.js"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||||
|
"deployCdnPath": "temp/deploy"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
|
"workingDir": "./temp/deploy/",
|
||||||
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
|
"container": "react-adaptive-cards-image-gallery",
|
||||||
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
|
"solution": {
|
||||||
|
"name": "react-adaptive-cards-image-gallery-client-side-solution",
|
||||||
|
"id": "2321325f-19a4-4895-8bdd-9a5447d462b1",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"includeClientSideAssets": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"title": "react-adaptive-cards-image-gallery-deployment",
|
||||||
|
"description": "react-adaptive-cards-image-gallery-deployment",
|
||||||
|
"id": "bf461e6f-0fd4-4f3c-a77a-bd185e91cf8f",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"assets": {
|
||||||
|
"elementManifests": [
|
||||||
|
"elements.xml"
|
||||||
|
],
|
||||||
|
"elementFiles": [
|
||||||
|
"schema.xml"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"zippedPackage": "solution/react-adaptive-cards-image-gallery.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,7 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const gulp = require('gulp');
|
||||||
|
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.initialize(gulp);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "react-adaptive-cards-image-gallery",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp bundle",
|
||||||
|
"clean": "gulp clean",
|
||||||
|
"test": "gulp test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@microsoft/sp-core-library": "1.7.0",
|
||||||
|
"@microsoft/sp-lodash-subset": "1.7.0",
|
||||||
|
"@microsoft/sp-office-ui-fabric-core": "1.7.0",
|
||||||
|
"@microsoft/sp-webpart-base": "1.7.0",
|
||||||
|
"@types/es6-promise": "0.0.33",
|
||||||
|
"@types/react": "16.4.2",
|
||||||
|
"@types/react-dom": "16.0.5",
|
||||||
|
"@types/webpack-env": "1.13.1",
|
||||||
|
"adaptivecards": "^1.1.0",
|
||||||
|
"react": "16.3.2",
|
||||||
|
"react-dom": "16.3.2",
|
||||||
|
"sp-pnp-js": "^3.0.10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@microsoft/sp-build-web": "1.7.0",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.7.0",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.7.0",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.7.0",
|
||||||
|
"gulp": "~3.9.1",
|
||||||
|
"@types/chai": "3.4.34",
|
||||||
|
"@types/mocha": "2.2.38",
|
||||||
|
"ajv": "~5.2.2"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
|
||||||
|
|
||||||
|
<ListInstance
|
||||||
|
CustomSchema="schema.xml"
|
||||||
|
FeatureId="00bfea71-de22-43b2-a848-c05709900100"
|
||||||
|
Title="Adaptive Card Images"
|
||||||
|
Description="List with image information"
|
||||||
|
TemplateType="100"
|
||||||
|
Url="Lists/AdaptiveCardImages">
|
||||||
|
<Data>
|
||||||
|
<Rows>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Sea</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/200/200?image=100, Sea Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Sea, Sea Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">1</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Yak</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=200, Yak Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Domestic_yak, Yak Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">2</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Autumn</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=301, Autumn Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Autumn, Autumn Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">3</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Plant</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=400, Plant Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Plant, Plant Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">4</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Building</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=500, Building Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Building, Building Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">5</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Forest</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=600, Forest Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Forest, Forest Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">6</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Fish</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=700, Fish Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Fish, Fish Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">7</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Auditorium</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=800, Auditorium Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Auditorium, Auditorium Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">8</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Bridge</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=900, Bridge Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Bridge, Bridge Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">9</Field>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Field Name="Title">Sea Link</Field>
|
||||||
|
<Field Name="ImageLink">https://picsum.photos/300/200?image=950, Sea Link Image</Field>
|
||||||
|
<Field Name="NavigationURL">https://en.wikipedia.org/wiki/Sealink, Sea Link Wikipedia</Field>
|
||||||
|
<Field Name="SortOrder">10</Field>
|
||||||
|
</Row>
|
||||||
|
</Rows>
|
||||||
|
</Data>
|
||||||
|
</ListInstance>
|
||||||
|
|
||||||
|
</Elements>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<List xmlns:ows="Microsoft SharePoint" Title="Image Gallery" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/ImageGallery" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
|
||||||
|
<MetaData>
|
||||||
|
<Fields>
|
||||||
|
<Field ID="{e6954092-6678-4538-b809-cf9065480a5d}" Type="URL" DisplayName="Image Link" Required="TRUE" Format="Hyperlink" Title="ImageLink" StaticName="ImageLink" Name="ImageLink" ColName="nvarchar4" RowOrdinal="0" ColName2="nvarchar5" RowOrdinal2="0" CustomFormatter="" EnforceUniqueValues="FALSE" Indexed="FALSE" Version="1" />
|
||||||
|
<Field ID="{3e142196-f3dc-49f1-8147-c7d8b05775d0}" Type="URL" DisplayName="Navigation URL" Required="TRUE" EnforceUniqueValues="FALSE" Indexed="FALSE" Format="Hyperlink" StaticName="NavigationURL" Name="NavigationURL" ColName="nvarchar6" RowOrdinal="0" ColName2="nvarchar7" RowOrdinal2="0" CustomFormatter="" Version="1" />
|
||||||
|
<Field ID="{8e328744-f48d-4981-8720-d4efa4730f0e}" Type="Number" DisplayName="Sort Order" Required="TRUE" EnforceUniqueValues="FALSE" Indexed="FALSE" StaticName="SortOrder" Name="SortOrder" ColName="float1" RowOrdinal="0" />
|
||||||
|
</Fields>
|
||||||
|
<Views>
|
||||||
|
<View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
|
||||||
|
<XslLink Default="TRUE">main.xsl</XslLink>
|
||||||
|
<JSLink>clienttemplates.js</JSLink>
|
||||||
|
<RowLimit Paged="TRUE">30</RowLimit>
|
||||||
|
<Toolbar Type="Standard" />
|
||||||
|
<ViewFields>
|
||||||
|
<FieldRef Name="SortOrder"></FieldRef>
|
||||||
|
<FieldRef Name="LinkTitle"></FieldRef>
|
||||||
|
<FieldRef Name="ImageLink"></FieldRef>
|
||||||
|
<FieldRef Name="NavigationURL"></FieldRef>
|
||||||
|
</ViewFields>
|
||||||
|
<Query>
|
||||||
|
<OrderBy>
|
||||||
|
<FieldRef Name="SortOrder" />
|
||||||
|
</OrderBy>
|
||||||
|
</Query>
|
||||||
|
</View>
|
||||||
|
</Views>
|
||||||
|
<Forms>
|
||||||
|
<Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
|
||||||
|
<Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
|
||||||
|
<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
|
||||||
|
</Forms>
|
||||||
|
</MetaData>
|
||||||
|
</List>
|
|
@ -0,0 +1 @@
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
"id": "769ec7d3-bd0d-4afc-9426-23a0c279acb4",
|
||||||
|
"alias": "AdaptiveCardsImageGalleryWebPart",
|
||||||
|
"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,
|
||||||
|
|
||||||
|
"preconfiguredEntries": [{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
"group": { "default": "Other" },
|
||||||
|
"title": { "default": "Adaptive Cards Image Gallery" },
|
||||||
|
"description": { "default": "Image Gallery implemented with Adaptive Cards" },
|
||||||
|
"officeFabricIconFontName": "ImageDiff",
|
||||||
|
"properties": {
|
||||||
|
"description": "AdaptiveCardsImageGallery"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDom from 'react-dom';
|
||||||
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
|
import {
|
||||||
|
BaseClientSideWebPart,
|
||||||
|
IPropertyPaneConfiguration,
|
||||||
|
PropertyPaneTextField
|
||||||
|
} from '@microsoft/sp-webpart-base';
|
||||||
|
|
||||||
|
import * as strings from 'AdaptiveCardsImageGalleryWebPartStrings';
|
||||||
|
import AdaptiveCardsImageGallery from './components/AdaptiveCardsImageGallery';
|
||||||
|
import { IAdaptiveCardsImageGalleryProps } from './components/IAdaptiveCardsImageGalleryProps';
|
||||||
|
import pnp from 'sp-pnp-js';
|
||||||
|
|
||||||
|
export interface IAdaptiveCardsImageGalleryWebPartProps {
|
||||||
|
imageGalleryName: string;
|
||||||
|
imagesToDisplay: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AdaptiveCardsImageGalleryWebPart extends BaseClientSideWebPart<IAdaptiveCardsImageGalleryWebPartProps> {
|
||||||
|
public async onInit(): Promise<void> {
|
||||||
|
return super.onInit().then(_ => {
|
||||||
|
pnp.setup({
|
||||||
|
spfxContext: this.context
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): void {
|
||||||
|
const element: React.ReactElement<IAdaptiveCardsImageGalleryProps > = React.createElement(
|
||||||
|
AdaptiveCardsImageGallery,
|
||||||
|
{
|
||||||
|
serviceScope: this.context.serviceScope,
|
||||||
|
imageGalleryName: this.properties.imageGalleryName || "Adaptive Card Images",
|
||||||
|
imagesToDisplay: this.properties.imagesToDisplay || 10
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ReactDom.render(element, this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onDispose(): void {
|
||||||
|
ReactDom.unmountComponentAtNode(this.domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get dataVersion(): Version {
|
||||||
|
return Version.parse('1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
return {
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
header: {
|
||||||
|
description: strings.PropertyPaneDescription
|
||||||
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
groupName: strings.BasicGroupName,
|
||||||
|
groupFields: [
|
||||||
|
PropertyPaneTextField('imageGalleryName', {
|
||||||
|
label: strings.ImageGalleryNameFieldLabel
|
||||||
|
}),
|
||||||
|
PropertyPaneTextField('imagesToDisplay', {
|
||||||
|
label: strings.ImagesToDisplayFieldLabel
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||||
|
|
||||||
|
.adaptiveCardsImageGallery {
|
||||||
|
.spinner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 0px auto;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
@include ms-Grid-row;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
background-color: $ms-color-themeDark;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
@include ms-Grid-col;
|
||||||
|
@include ms-lg10;
|
||||||
|
@include ms-xl8;
|
||||||
|
@include ms-xlPush2;
|
||||||
|
@include ms-lgPush1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include ms-font-xl;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subTitle {
|
||||||
|
@include ms-font-l;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@include ms-font-l;
|
||||||
|
@include ms-fontColor-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
// Our button
|
||||||
|
text-decoration: none;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
// Primary Button
|
||||||
|
min-width: 80px;
|
||||||
|
background-color: $ms-color-themePrimary;
|
||||||
|
border-color: $ms-color-themePrimary;
|
||||||
|
color: $ms-color-white;
|
||||||
|
|
||||||
|
// Basic Button
|
||||||
|
outline: transparent;
|
||||||
|
position: relative;
|
||||||
|
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: $ms-font-size-m;
|
||||||
|
font-weight: $ms-font-weight-regular;
|
||||||
|
border-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 16px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: $ms-font-weight-semibold;
|
||||||
|
font-size: $ms-font-size-m;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
margin: 0 4px;
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styles from './AdaptiveCardsImageGallery.module.scss';
|
||||||
|
import { IAdaptiveCardsImageGalleryProps } from './IAdaptiveCardsImageGalleryProps';
|
||||||
|
import { IAdaptiveCardsImageGalleryState } from './IAdaptiveCardsImageGalleryState';
|
||||||
|
import { escape } from '@microsoft/sp-lodash-subset';
|
||||||
|
|
||||||
|
import * as AdaptiveCards from "adaptivecards";
|
||||||
|
import { ImageGalleryService, IImageGalleryService } from '../services/ImageGalleryService';
|
||||||
|
import { ServiceScope, Environment, EnvironmentType } from '@microsoft/sp-core-library';
|
||||||
|
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||||
|
|
||||||
|
export default class AdaptiveCardsImageGallery extends React.Component<IAdaptiveCardsImageGalleryProps, IAdaptiveCardsImageGalleryState> {
|
||||||
|
private ImageGalleryServiceInstance: IImageGalleryService;
|
||||||
|
private _galleryListName: string;
|
||||||
|
private _noOfItems: number;
|
||||||
|
private card: any;
|
||||||
|
private renderedCard: any = "";
|
||||||
|
private imagesJSON = [];
|
||||||
|
|
||||||
|
constructor(props: IAdaptiveCardsImageGalleryProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
galleryItems: null,
|
||||||
|
isLoading: true,
|
||||||
|
showErrorMessage: false
|
||||||
|
};
|
||||||
|
|
||||||
|
let serviceScope: ServiceScope;
|
||||||
|
serviceScope = this.props.serviceScope;
|
||||||
|
|
||||||
|
this._galleryListName = this.props.imageGalleryName;
|
||||||
|
this._noOfItems = this.props.imagesToDisplay;
|
||||||
|
|
||||||
|
// Based on the type of environment, return the correct instance of the ImageGalleryServiceInstance interface
|
||||||
|
if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) {
|
||||||
|
// Mapping to be used when webpart runs in SharePoint.
|
||||||
|
this.ImageGalleryServiceInstance = serviceScope.consume(ImageGalleryService.serviceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ImageGalleryServiceInstance.getGalleryImages(this._galleryListName, this._noOfItems).then((galleryImages: any[]) => {
|
||||||
|
galleryImages.forEach(adaptiveImage => {
|
||||||
|
let image = {};
|
||||||
|
image["type"] = "Image";
|
||||||
|
image["url"] = adaptiveImage.ImageLink.Url;
|
||||||
|
|
||||||
|
// Compose image action
|
||||||
|
let imageAction = {};
|
||||||
|
imageAction["title"] = adaptiveImage.NavigationURL.Description;
|
||||||
|
imageAction["type"] = "Action.OpenUrl";
|
||||||
|
imageAction["url"] = adaptiveImage.NavigationURL.Url;
|
||||||
|
imageAction["iconUrl"] = adaptiveImage.NavigationURL.Url;
|
||||||
|
|
||||||
|
image["selectAction"] = imageAction;
|
||||||
|
this.imagesJSON.push(image);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.card = {
|
||||||
|
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
||||||
|
"type": "AdaptiveCard",
|
||||||
|
"version": "1.0",
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "TextBlock",
|
||||||
|
"text": "Adaptive Image Gallery",
|
||||||
|
"size": "medium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ImageSet",
|
||||||
|
"imageSize": "medium",
|
||||||
|
"images": this.imagesJSON
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an AdaptiveCard instance
|
||||||
|
var adaptiveCard = new AdaptiveCards.AdaptiveCard();
|
||||||
|
|
||||||
|
// Set its hostConfig property unless you want to use the default Host Config
|
||||||
|
// Host Config defines the style and behavior of a card
|
||||||
|
adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
|
||||||
|
fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the adaptive card's event handlers. onExecuteAction is invoked
|
||||||
|
// whenever an action is clicked in the card
|
||||||
|
adaptiveCard.onExecuteAction = function(action) {
|
||||||
|
window.location.href = action.iconUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse the card
|
||||||
|
adaptiveCard.parse(this.card);
|
||||||
|
|
||||||
|
// Render the card to an HTML element
|
||||||
|
this.renderedCard = adaptiveCard.render();
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactElement<IAdaptiveCardsImageGalleryProps> {
|
||||||
|
return (
|
||||||
|
<div className={styles.adaptiveCardsImageGallery}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
{this.state.isLoading && <Spinner className={styles.spinner} size={SpinnerSize.large} />}
|
||||||
|
{!this.state.isLoading && <div ref={(n) => { n && n.appendChild(this.renderedCard) }} />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { ServiceScope } from '@microsoft/sp-core-library';
|
||||||
|
|
||||||
|
export interface IAdaptiveCardsImageGalleryProps {
|
||||||
|
serviceScope: ServiceScope;
|
||||||
|
imageGalleryName: string;
|
||||||
|
imagesToDisplay: number;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface IAdaptiveCardsImageGalleryState {
|
||||||
|
galleryItems: any[];
|
||||||
|
isLoading: boolean;
|
||||||
|
showErrorMessage: boolean;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"PropertyPaneDescription": "Description",
|
||||||
|
"BasicGroupName": "Group Name",
|
||||||
|
"DescriptionFieldLabel": "Description Field",
|
||||||
|
"ImageGalleryNameFieldLabel": "Image Gallery",
|
||||||
|
"ImagesToDisplayFieldLabel": "Number of images to display",
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
declare interface IAdaptiveCardsImageGalleryWebPartStrings {
|
||||||
|
PropertyPaneDescription: string;
|
||||||
|
BasicGroupName: string;
|
||||||
|
ImageGalleryNameFieldLabel: string;
|
||||||
|
ImagesToDisplayFieldLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'AdaptiveCardsImageGalleryWebPartStrings' {
|
||||||
|
const strings: IAdaptiveCardsImageGalleryWebPartStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { ServiceKey, ServiceScope } from '@microsoft/sp-core-library';
|
||||||
|
import { PageContext } from '@microsoft/sp-page-context';
|
||||||
|
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
||||||
|
import * as pnp from "sp-pnp-js";
|
||||||
|
|
||||||
|
export interface IImageGalleryService {
|
||||||
|
getGalleryImages: (listName: string, rowLimit: number) => Promise<any[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ImageGalleryService implements IImageGalleryService {
|
||||||
|
public static readonly serviceKey: ServiceKey<IImageGalleryService> = ServiceKey.create<IImageGalleryService>('ImageGallery:ImageGalleryService', ImageGalleryService);
|
||||||
|
private _pageContext: PageContext;
|
||||||
|
|
||||||
|
constructor(serviceScope: ServiceScope) {
|
||||||
|
serviceScope.whenFinished(() => {
|
||||||
|
this._pageContext = serviceScope.consume(PageContext.serviceKey);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGalleryImages(listName: string, rowLimit: number): Promise<any[]> {
|
||||||
|
const xml = `<View>
|
||||||
|
<ViewFields>
|
||||||
|
<FieldRef Name='ID' />
|
||||||
|
<FieldRef Name='Title' />
|
||||||
|
<FieldRef Name='ImageLink' />
|
||||||
|
<FieldRef Name='NavigationURL' />
|
||||||
|
</ViewFields>
|
||||||
|
<Query>
|
||||||
|
<OrderBy>
|
||||||
|
<FieldRef Name='SortOrder' />
|
||||||
|
</OrderBy>
|
||||||
|
</Query>
|
||||||
|
<RowLimit>` + rowLimit + `</RowLimit>
|
||||||
|
</View>`;
|
||||||
|
|
||||||
|
const q: any = {
|
||||||
|
ViewXml: xml,
|
||||||
|
};
|
||||||
|
|
||||||
|
return this._ensureList(listName).then((list) => {
|
||||||
|
if (list) {
|
||||||
|
return pnp.sp.web.lists.getByTitle(listName).getItemsByCAMLQuery(q).then((items: any[]) => {
|
||||||
|
return Promise.resolve(items);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _ensureList(listName: string): Promise<pnp.List> {
|
||||||
|
if (listName) {
|
||||||
|
return pnp.sp.web.lists.ensure(listName).then((listEnsureResult) => Promise.resolve(listEnsureResult.list));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.2/MicrosoftTeams.schema.json",
|
||||||
|
"manifestVersion": "1.2",
|
||||||
|
"packageName": "AdaptiveCardsImageGallery",
|
||||||
|
"id": "769ec7d3-bd0d-4afc-9426-23a0c279acb4",
|
||||||
|
"version": "0.1",
|
||||||
|
"developer": {
|
||||||
|
"name": "SPFx + Teams Dev",
|
||||||
|
"websiteUrl": "https://products.office.com/en-us/sharepoint/collaboration",
|
||||||
|
"privacyUrl": "https://privacy.microsoft.com/en-us/privacystatement",
|
||||||
|
"termsOfUseUrl": "https://www.microsoft.com/en-us/servicesagreement"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"short": "AdaptiveCardsImageGallery"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"short": "Image Gallery implemented with Adaptive Cards",
|
||||||
|
"full": "Image Gallery implemented with Adaptive Cards"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"outline": "tab20x20.png",
|
||||||
|
"color": "tab96x96.png"
|
||||||
|
},
|
||||||
|
"accentColor": "#004578",
|
||||||
|
"configurableTabs": [
|
||||||
|
{
|
||||||
|
"configurationUrl": "https://{teamSiteDomain}{teamSitePath}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx%3FopenPropertyPane=true%26teams%26componentId=769ec7d3-bd0d-4afc-9426-23a0c279acb4",
|
||||||
|
"canUpdateConfiguration": false,
|
||||||
|
"scopes": [
|
||||||
|
"team"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validDomains": [
|
||||||
|
"*.login.microsoftonline.com",
|
||||||
|
"*.sharepoint.com",
|
||||||
|
"*.sharepoint-df.com",
|
||||||
|
"spoppe-a.akamaihd.net",
|
||||||
|
"spoprod-a.akamaihd.net",
|
||||||
|
"resourceseng.blob.core.windows.net",
|
||||||
|
"msft.spoppe.com"
|
||||||
|
],
|
||||||
|
"webApplicationInfo": {
|
||||||
|
"resource": "https://{teamSiteDomain}",
|
||||||
|
"id": "00000003-0000-0ff1-ce00-000000000000"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 933 B |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react",
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@microsoft"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"es6-promise",
|
||||||
|
"webpack-env"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es5",
|
||||||
|
"dom",
|
||||||
|
"es2015.collection"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"extends": "@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