Facebook Page Social Plugin web part sample (#607)

* Facebook plugin: initial commit

* Facebook plugin: TSLint config

* Facebook plugin: VSCode config

* Facebook plugin: webpart draft

* Facebook plugin: webpart settings

* Facebook plugin: webpart properties update

* Facebook plugin: readme
This commit is contained in:
Andrew Koltyakov 2018-09-10 13:11:45 +03:00 committed by Vesa Juvonen
parent 274801e2fc
commit 417376a1d4
28 changed files with 18395 additions and 0 deletions

View File

@ -0,0 +1,24 @@
# 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,5 @@
{
"recommendations": [
"msjsdiag.debugger-for-chrome"
]
}

View File

@ -0,0 +1,41 @@
{
/**
* Install Chrome Debugger Extension for Visual Studio Code to debug your components with the
* Chrome browser: https://aka.ms/spfx-debugger-extensions
*/
"version": "0.2.0",
"configurations": [{
"name": "Local workbench",
"type": "chrome",
"request": "launch",
"url": "https://localhost:4321/temp/workbench.html",
"webRoot": "${workspaceRoot}",
"sourceMaps": true,
"sourceMapPathOverrides": {
"webpack:///../../../src/*": "${webRoot}/src/*",
"webpack:///../../../../src/*": "${webRoot}/src/*",
"webpack:///../../../../../src/*": "${webRoot}/src/*"
},
"runtimeArgs": [
"--remote-debugging-port=9222"
]
},
{
"name": "Hosted workbench",
"type": "chrome",
"request": "launch",
"url": "https://enter-your-SharePoint-site/_layouts/workbench.aspx",
"webRoot": "${workspaceRoot}",
"sourceMaps": true,
"sourceMapPathOverrides": {
"webpack:///../../../src/*": "${webRoot}/src/*",
"webpack:///../../../../src/*": "${webRoot}/src/*",
"webpack:///../../../../../src/*": "${webRoot}/src/*"
},
"runtimeArgs": [
"--remote-debugging-port=9222",
"-incognito"
]
}
]
}

View File

@ -0,0 +1,22 @@
// Place your settings in this file to overwrite default and user settings.
{
// Configure glob patterns for excluding files and folders in the file explorer.
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/bower_components": true,
"**/coverage": true,
"**/lib-amd": true,
"src/**/*.scss.ts": true,
"**/node_modules": true,
"**/typings": true,
"**/.editorconfig": true,
"**/.yo-rc.json": true,
"**/package-lock.json": true,
"**/.vscode": true,
"**/temp": true,
"**/lib": true,
"**/dist": true
},
"typescript.tsdk": ".\\node_modules\\typescript\\lib"
}

View File

@ -0,0 +1,11 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": true,
"environment": "spo",
"version": "1.5.1",
"libraryName": "react-facebook-plugin",
"libraryId": "2608d0f3-26fe-4142-941e-d5937bbbb952",
"packageManager": "npm",
"componentType": "webpart"
}
}

View File

@ -0,0 +1,57 @@
# SharePoint Framework Facebook Page Social Plugin web part sample
## Summary
This sample shows how to implement iFrame-based web parts with a dynamic responsive behavior on the example of Facebook Page Social Plugin.
The key differences between using Embed web part and current example are the strong parametrization of web part properties and responsive behavior of the iFrame depending on parent container width changes.
![preview](./assets/preview.png)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/drop-1.5.1-blue.svg)
## Applies to
* [SharePoint Framework](https:/dev.office.com/sharepoint)
* [Office 365 tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment)
## Solution
Solution | Author(s)
---------|----------
react-facebook-plugin | Andrew Koltyakov ([@AndrewKoltyakov](https://twitter.com/AndrewKoltyakov))
## Version history
Version | Date| Comments
--------|-----|---------
1.0 | August 26, 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.**
---
## Minimal Path to Awesome
### Local testing
* Clone the repository
* `cd` to web part's project folder
* In the command line run:
* `npm install`
* `gulp serve`
### Deployment
Follow the usual SPFx deployment process up to your preferences.
## Features
This web part illustrates the following concepts on top of the SharePoint Framework:
* Observe parent container width and dynamic adaptation of absolute-width'ed HTML elements
* React

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 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": {
"facebook-page-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/facebookPage/FacebookPageWebPart.js",
"manifest": "./src/webparts/facebookPage/FacebookPageWebPart.manifest.json"
}
]
}
},
"localizedResources": {
"FacebookPageWebPartStrings": "lib/webparts/facebookPage/loc/{locale}.js"
},
"externals": {}
}

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-facebook-plugin",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,12 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "react-facebook-plugin-client-side-solution",
"id": "a395e8a8-07fd-4a20-bc10-ad1cd91fb5b9",
"version": "1.0.0.0",
"includeClientSideAssets": true
},
"paths": {
"zippedPackage": "solution/react-facebook-plugin.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,45 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/tslint.schema.json",
// Display errors as warnings
"displayAsWarning": true,
// The TSLint task may have been configured with several custom lint rules
// before this config file is read (for example lint rules from the tslint-microsoft-contrib
// project). If true, this flag will deactivate any of these rules.
"removeExistingRules": true,
// When true, the TSLint task is configured with some default TSLint "rules.":
"useDefaultConfigAsBase": false,
// Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
// which are active, other than the list of rules below.
"lintConfig": {
// Opt-in to Lint rules which help to eliminate bugs in JavaScript
"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-case": true,
"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,
"valid-typeof": true,
"variable-name": false,
"whitespace": false
}
}
}

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,39 @@
{
"name": "react-facebook-plugin",
"version": "0.0.1",
"private": true,
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "npm run clean && gulp build && gulp bundle && gulp package-solution",
"build:prod": "npm run clean && gulp build --ship && gulp bundle --ship && gulp package-solution --ship",
"dev": "gulp serve",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.5.1",
"@microsoft/sp-lodash-subset": "1.5.1",
"@microsoft/sp-office-ui-fabric-core": "1.5.1",
"@microsoft/sp-webpart-base": "1.5.1",
"@types/es6-promise": "0.0.33",
"@types/react": "15.6.6",
"@types/react-dom": "15.5.6",
"@types/webpack-env": "1.13.1",
"on-el-resize": "0.0.4",
"react": "15.6.2",
"react-dom": "15.6.2"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.5.1",
"@microsoft/sp-module-interfaces": "1.5.1",
"@microsoft/sp-webpart-workbench": "1.5.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2",
"gulp": "~3.9.1",
"tslint-config-standard": "^7.1.0",
"tslint-react": "^3.6.0"
}
}

View File

@ -0,0 +1,21 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "fada13df-a74a-4c80-8b56-5166e8ebf4f8",
"alias": "FacebookPageWebPart",
"componentType": "WebPart",
"version": "*",
"manifestVersion": 2,
"requiresCustomScript": false,
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
"group": { "default": "Other" },
"title": { "default": "Facebook Page" },
"description": { "default": "Facebook Page Social Plugin webpart" },
// "iconImageUrl": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSIwIDAgNjAgNjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPg0KICAgIDxwYXRoIGQ9Ik0wLjExMjI5MDM0NCwzMCBDMC4xMTIyOTAzNDQsMTMuNDMxNDU2NyAxMy4zNDI2NTA2LDAgMjkuNjYzMTI5LDAgQzQ1Ljk4MzYwNzMsMCA1OS4yMTM5Njc2LDEzLjQzMTQ1NjcgNTkuMjEzOTY3NiwzMCBDNTkuMjEzOTY3Niw0Ni41Njg1NDMzIDQ1Ljk4MzYwNzMsNjAgMjkuNjYzMTI5LDYwIEMxMy4zNDI2NTA2LDYwIDAuMTEyMjkwMzQ0LDQ2LjU2ODU0MzMgMC4xMTIyOTAzNDQsMzAgWiBNMC4xMTIyOTAzNDQsMzAiIGZpbGw9IiMzQjU5OTgiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4NCgk8cGF0aCBkPSJNMzIuMTM0MTQ1Nyw0Ni4zMTk2NzI5IEwzMi4xMzQxNDU3LDI5Ljk5ODA4OTEgTDM2LjU2NTc1NjUsMjkuOTk4MDg5MSBMMzcuMTUzMDQwNiwyNC4zNzM1ODA5IEwzMi4xMzQxNDU3LDI0LjM3MzU4MDkgTDMyLjE0MTY3NSwyMS41NTg0NjA0IEMzMi4xNDE2NzUsMjAuMDkxNTAyIDMyLjI3ODc3MDcsMTkuMzA1NDcyMiAzNC4zNTEyMDYsMTkuMzA1NDcyMiBMMzcuMTIxNjY4NiwxOS4zMDU0NzIyIEwzNy4xMjE2Njg2LDEzLjY4MDMyNzEgTDMyLjY4OTQzMDQsMTMuNjgwMzI3MSBDMjcuMzY1NTk5NSwxMy42ODAzMjcxIDI1LjQ5MTc0OSwxNi40MDg4MTg3IDI1LjQ5MTc0OSwyMC45OTcyODM1IEwyNS40OTE3NDksMjQuMzc0MjE3OSBMMjIuMTczMjE3MywyNC4zNzQyMTc5IEwyMi4xNzMyMTczLDI5Ljk5ODcyNiBMMjUuNDkxNzQ5LDI5Ljk5ODcyNiBMMjUuNDkxNzQ5LDQ2LjMxOTY3MjkgTDMyLjEzNDE0NTcsNDYuMzE5NjcyOSBaIE0zMi4xMzQxNDU3LDQ2LjMxOTY3MjkiIGlkPSJQYXRoIiBmaWxsPSIjRkZGRkZGIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj48L3BhdGg+DQoJPHBhdGggZD0iTTU5LjIxMzk2NzYsMzAgQzU5LjIxMzk2NzYsNDYuNTY4NTQzMyA0NS45ODM2MDczLDYwIDI5LjY2MzEyOSw2MCBDMjMuNjEwMjUwMiw2MCAxNy45ODI0MTQ3LDU4LjE1MjUxMzQgMTMuMjk3MDM0MSw1NC45ODI3NzU0IEw0Ny4xNTcyNTU0LDUuODE5NDExMDMgQzU0LjQ2OTE1MzQsMTEuMjgwNjUwMyA1OS4yMTM5Njc2LDIwLjA3Nzc5NzMgNTkuMjEzOTY3NiwzMCBaIE01OS4yMTM5Njc2LDMwIiBpZD0icmVmbGVjIiBmaWxsLW9wYWNpdHk9IjAuMDgiIGZpbGw9IiMwMDAwMDAiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4NCjwvc3ZnPg==",
"iconImageUrl": "https://spoprod-a.akamaihd.net/files/sp-client-prod_2018-08-17.009/facebook_cdd011c89467d86664bb8331411d5ef5.svg",
"properties": {
"company" : "Microsoft",
"height" : 600
}
}]
}

View File

@ -0,0 +1,67 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneToggle
} from '@microsoft/sp-webpart-base';
import * as strings from 'FacebookPageWebPartStrings';
import FacebookPage from './components/FacebookPage';
import { IFacebookPageProps } from './components/IFacebookPageProps';
import { IFacebookPageWebPartProps } from './IFacebookPageWebPart';
export default class FacebookPageWebPart extends BaseClientSideWebPart<IFacebookPageWebPartProps> {
public render(): void {
const props: IFacebookPageProps = {
company: this.properties.company,
height: Number(this.properties.height),
smallHeader: this.properties.smallHeader,
hideCover: this.properties.hideCover,
showFacepile: this.properties.showFacepile
};
const element = React.createElement(FacebookPage, props);
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('company', {
label: strings.CompanyFieldLabel
}),
PropertyPaneTextField('height', {
label: strings.HeightFieldLabel
}),
PropertyPaneToggle('smallHeader', {
label: strings.SmallHeaderFieldLabel
}),
PropertyPaneToggle('hideCover', {
label: strings.HideCoverFieldLabel
}),
PropertyPaneToggle('showFacepile', {
label: strings.ShowFacepileFieldLabel
})
]
}]
}]
};
}
}

View File

@ -0,0 +1,7 @@
export interface IFacebookPageWebPartProps {
company: string;
height: string;
smallHeader?: boolean;
hideCover?: boolean;
showFacepile?: boolean;
}

View File

@ -0,0 +1,11 @@
.facebookPageContainer {
display: flex;
justify-content: center;
> iframe {
margin: 0 auto;
max-width: 500px;
}
}

View File

@ -0,0 +1,44 @@
import * as React from 'react';
import { Resizable } from 'on-el-resize/lib/components';
import { IFacebookPageProps } from './IFacebookPageProps';
import styles from './FacebookPage.module.scss';
export default class FacebookPage extends React.Component<IFacebookPageProps, {}> {
public render() {
return (
<Resizable
className={styles.facebookPageContainer}
render={({ width }) => {
return (
<iframe
src={this.buildIFrameUrl(width)}
width={width}
height={this.props.height || 500}
style={{
border: 'none',
overflow: 'hidden',
width: '100%'
}}
scrolling='no'
allowTransparency={true}
/>
);
}}
/>
);
}
private buildIFrameUrl(width: number): string {
return `https://www.facebook.com/plugins/page.php?` +
`href=${encodeURIComponent(`https://www.facebook.com/${this.props.company || 'Microsoft'}`)}&` +
`width=${width}&` +
`height=${this.props.height || 500}&` +
`small_header=${typeof this.props.smallHeader !== 'undefined' ? this.props.smallHeader : false}&` +
`hide_cover=${typeof this.props.hideCover !== 'undefined' ? this.props.hideCover : false}&` +
`show_facepile=${typeof this.props.showFacepile !== 'undefined' ? this.props.showFacepile : false}&` +
`adapt_container_width=true&` +
`tabs=timeline`;
}
}

View File

@ -0,0 +1,7 @@
export interface IFacebookPageProps {
company: string;
height: number;
smallHeader?: boolean;
hideCover?: boolean;
showFacepile?: boolean;
}

View File

@ -0,0 +1,11 @@
define([], function() {
return {
"PropertyPaneDescription": "Facebook Page Social Plugin webpart",
"BasicGroupName": "Webpart settings",
"CompanyFieldLabel": "Company page (uri)",
"HeightFieldLabel": "Webpart height",
"SmallHeaderFieldLabel": "Small header",
"HideCoverFieldLabel": "Hide cover",
"ShowFacepileFieldLabel": "Show facepile"
};
});

View File

@ -0,0 +1,16 @@
declare interface IFacebookPageWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
BasicGroupName: string;
CompanyFieldLabel: string;
HeightFieldLabel: string;
SmallHeaderFieldLabel: string;
HideCoverFieldLabel: string;
ShowFacepileFieldLabel: string;
}
declare module 'FacebookPageWebPartStrings' {
const strings: IFacebookPageWebPartStrings;
export = strings;
}

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
],
"types": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
}
}

View File

@ -0,0 +1,9 @@
{
"extends": ["tslint-config-standard", "tslint-react", "./config/tslint.json"],
"rules": {
"space-before-function-paren": false,
"semicolon": [ true, "always", "ignore-interfaces" ],
"jsx-no-multiline-js": false,
"jsx-no-lambda": false
}
}