Added sample react-adaptive-cards-image-gallery (#700)

* added react-display-hierarchy

* Added sample react-adaptive-cards-image-gallery
This commit is contained in:
Nanddeep Nachan 2018-12-08 22:26:15 +05:30 committed by Vesa Juvonen
parent d9fefb7bd4
commit e69d235991
34 changed files with 18436 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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"
}
}

View File

@ -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

View File

@ -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"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -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 -->"
}

View File

@ -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"
}
}

View File

@ -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/"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}

View File

@ -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

View File

@ -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"
}
}

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -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"
}
}]
}

View File

@ -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
})
]
}
]
}
]
};
}
}

View File

@ -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;
}
}
}

View File

@ -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>
);
}
}

View File

@ -0,0 +1,7 @@
import { ServiceScope } from '@microsoft/sp-core-library';
export interface IAdaptiveCardsImageGalleryProps {
serviceScope: ServiceScope;
imageGalleryName: string;
imagesToDisplay: number;
}

View File

@ -0,0 +1,5 @@
export interface IAdaptiveCardsImageGalleryState {
galleryItems: any[];
isLoading: boolean;
showErrorMessage: boolean;
}

View File

@ -0,0 +1,9 @@
define([], function() {
return {
"PropertyPaneDescription": "Description",
"BasicGroupName": "Group Name",
"DescriptionFieldLabel": "Description Field",
"ImageGalleryNameFieldLabel": "Image Gallery",
"ImagesToDisplayFieldLabel": "Number of images to display",
}
});

View File

@ -0,0 +1,11 @@
declare interface IAdaptiveCardsImageGalleryWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
ImageGalleryNameFieldLabel: string;
ImagesToDisplayFieldLabel: string;
}
declare module 'AdaptiveCardsImageGalleryWebPartStrings' {
const strings: IAdaptiveCardsImageGalleryWebPartStrings;
export = strings;
}

View File

@ -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));
}
}
}

View File

@ -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

View File

@ -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"
]
}

View File

@ -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
}
}