initial commit (#139)

This commit is contained in:
Joseph Velliah 2017-03-13 05:37:32 -05:00 committed by Vesa Juvonen
parent a7e61b7a5d
commit 982ac90fb6
28 changed files with 525 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

1
samples/angular-yammer/.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto

32
samples/angular-yammer/.gitignore vendored Normal file
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,14 @@
# Folders
.vscode
coverage
node_modules
sharepoint
src
temp
# Files
*.csproj
.git*
.yo-rc.json
gulpfile.js
tsconfig.json

View File

@ -0,0 +1,8 @@
{
"@microsoft/generator-sharepoint": {
"libraryName": "angular-yammer",
"framework": "none",
"version": "1.0.0",
"libraryId": "f3f740d2-5a08-4e10-8f7c-b64846dc4f23"
}
}

View File

@ -0,0 +1,54 @@
# Yammer Feed WebPart using Angular
## Summary
This Web Part displays the feeds from yammer using https://c64.assets-yammer.com/assets/platform_embed.js.
![Yammer Feed WebPart using Angular](./assets/feed.PNG)
![Yammer Feed WebPart Properties](./assets/properties.PNG)
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/version-GA-green.svg)
## Applies to
* [SharePoint Framework](https://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
* [SharePoint Online Tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
## Solution
Solution|Author(s)
--------|---------
angular-yammer|Joseph Velliah (SPRIDER, @sprider)
## Version history
Version|Date|Comments
-------|----|--------
1.0|March 03, 2017|Initial release
## Disclaimer
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
---
## Minimal Path to Awesome
- clone this repo
- in the command line run:
- `npm i`
- `tsd install`
- `gulp serve`
## Features
The Yammer Feed is a sample Client-Side Web Part built on the SharePoint Framework using Angular.
This Web Part illustrates the following concepts on top of the SharePoint Framework:
- using Angular for building SharePoint Framework Client-Side Web Parts
- including Angular in the Web Part bundle
- using non-reactive Web Part Property Pane and custom Properties
- using conditional rendering for one-time Web Part setup
- passing Web Part configuration to Angular and reacting to configuration changes
- display the yammer feed based on configuration changes

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,13 @@
{
"entries": [
{
"entry": "./lib/webparts/angularYammer/AngularYammerWebPart.js",
"manifest": "./src/webparts/angularYammer/AngularYammerWebPart.manifest.json",
"outputPath": "./dist/angular-yammer.bundle.js"
}
],
"externals": {},
"localizedResources": {
"angularYammerStrings": "webparts/angularYammer/loc/{locale}.js"
}
}

View File

@ -0,0 +1,3 @@
{
"deployCdnPath": "temp/deploy"
}

View File

@ -0,0 +1,6 @@
{
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "angular-yammer",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,10 @@
{
"solution": {
"name": "angular-yammer-client-side-solution",
"id": "f3f740d2-5a08-4e10-8f7c-b64846dc4f23",
"version": "1.0.0.0"
},
"paths": {
"zippedPackage": "solution/angular-yammer.sppkg"
}
}

View File

@ -0,0 +1,9 @@
{
"port": 4321,
"initialPage": "https://localhost:5432/workbench",
"https": true,
"api": {
"port": 5432,
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
}
}

View File

@ -0,0 +1,46 @@
{
// 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-unused-imports": 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,
"prefer-const": true
}
}
}

View File

@ -0,0 +1,3 @@
{
"cdnBasePath": "<!-- PATH TO CDN -->"
}

6
samples/angular-yammer/gulpfile.js vendored Normal file
View File

@ -0,0 +1,6 @@
'use strict';
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.initialize(gulp);

View File

@ -0,0 +1,28 @@
{
"name": "angular-yammer",
"version": "0.0.1",
"private": true,
"engines": {
"node": ">=0.10.0"
},
"dependencies": {
"@microsoft/sp-client-base": "~1.0.0",
"@microsoft/sp-core-library": "~1.0.0",
"@microsoft/sp-webpart-base": "~1.0.0",
"@types/webpack-env": ">=1.12.1 <1.14.0",
"angular": "^1.6.2"
},
"devDependencies": {
"@microsoft/sp-build-web": "~1.0.0",
"@microsoft/sp-module-interfaces": "~1.0.0",
"@microsoft/sp-webpart-workbench": "~1.0.0",
"gulp": "~3.9.1",
"@types/chai": ">=3.4.34 <3.6.0",
"@types/mocha": ">=2.2.33 <2.6.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
}
}

View File

@ -0,0 +1,26 @@
{
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
"id": "0d6ed52f-59a5-452e-aeb5-856d59a5105e",
"alias": "AngularYammerWebPart",
"componentType": "WebPart",
"version": "0.0.1",
"manifestVersion": 2,
"preconfiguredEntries": [{
"groupId": "0d6ed52f-59a5-452e-aeb5-856d59a5105e",
"group": { "default": "Under Development" },
"title": { "default": "angular-yammer" },
"description": { "default": "Yammer Feed Add-in" },
"officeFabricIconFontName": "Page",
"properties": {
"network": "domain.com",
"feedType": "group",
"defaultGroupId": 10869974,
"showOpenGraphPreview": false,
"promptText": "Your thoughts?",
"header": false,
"footer": false
}
}]
}

View File

@ -0,0 +1,101 @@
import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneToggle,
PropertyPaneSlider,
PropertyPaneDropdown,
IWebPartContext
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';
import { Environment, EnvironmentType } from '@microsoft/sp-core-library';
import styles from './AngularYammer.module.scss';
import * as strings from 'angularYammerStrings';
import { IAngularYammerWebPartProps } from './IAngularYammerWebPartProps';
import * as angular from 'angular';
export default class AngularYammerWebPart extends BaseClientSideWebPart<IAngularYammerWebPartProps> {
private $injector: angular.auto.IInjectorService;
public render(): void {
if (this.renderedOnce === false) {
require('./app/home.controller.js');
this.domElement.innerHTML = `
<div data-ng-controller="homeController">
<div id="{{yamfeedid}}" style="height:400px;width:100%">
</div>
</div>`;
this.$injector = angular.bootstrap(this.domElement, ['yammerApp']);
}
this.$injector.get('$rootScope').$broadcast('configurationChanged', {
network : escape(this.properties.network),
feedType : escape(this.properties.feedType),
defaultGroupId: this.properties.defaultGroupId,
showOpenGraphPreview: this.properties.showOpenGraphPreview,
promptText: escape(this.properties.promptText),
header: this.properties.header,
footer: this.properties.footer,
environment: Environment.type,
environmentType: EnvironmentType,
domElement: 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('network', {
label: strings.NetworkFieldLabel
}),
PropertyPaneTextField('feedtype', {
label: strings.FeedTypeFieldLabel
}),
PropertyPaneTextField('defaultGroupId', {
label: strings.DefaultGroupIdFieldLabel
}),
PropertyPaneToggle('showOpenGraphPreview', {
label: strings.ShowOpenGraphPreviewFieldLabel,
onText: 'On',
offText: 'Off'
}),
PropertyPaneTextField('promptText', {
label: strings.PromptTextFieldLabel
}),
PropertyPaneToggle('header', {
label: strings.HeaderFieldLabel,
onText: 'On',
offText: 'Off'
}),
PropertyPaneToggle('footer', {
label: strings.FooterFieldLabel,
onText: 'On',
offText: 'Off'
})
]
}
]
}
]
};
}
protected get disableReactivePropertyChanges(): boolean {
return true;
}
}

View File

@ -0,0 +1,9 @@
export interface IAngularYammerWebPartProps {
network: string;
feedType: string;
defaultGroupId: number;
showOpenGraphPreview: boolean;
promptText: string;
header: boolean;
footer: boolean;
}

View File

@ -0,0 +1,69 @@
(function () {
'use strict';
var yammerApp = angular.module('yammerApp', []);
yammerApp.controller('homeController', ['$rootScope', '$scope', '$http', '$location', '$window', homeController]);
function homeController($rootScope, $scope, $http, $location, $window) {
$scope.yamfeedid = 'yamfeed' + generateGuid();
function generateGuid() {
var d = new Date().getTime();
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
};
$rootScope.$on('configurationChanged', function(event, args) {
$scope.network = args.network;
$scope.feedType = args.feedType;
$scope.defaultGroupId = args.defaultGroupId;
$scope.showOpenGraphPreview = args.showOpenGraphPreview;
$scope.promptText = args.promptText;
$scope.header = args.header;
$scope.footer = args.footer;
$scope.environment = args.environment;
$scope.environmentType = args.environmentType;
var currentfeedcontainer = args.domElement.querySelector("#"+$scope.yamfeedid);
var feedparentNode = currentfeedcontainer.parentElement;
if(currentfeedcontainer)
{
currentfeedcontainer.remove();
feedparentNode.innerHTML += '<div id="'+$scope.yamfeedid+'" style="height:400px;width:100%"></div>';
}
$scope.loadFeeds();
});
$scope.loadFeeds = function () {
var feedOptions = {
container: '#'+$scope.yamfeedid,
network: $scope.network,
feedType: $scope.feedtype,
config: {
defaultGroupId: $scope.defaultgroupid,
showOpenGraphPreview: $scope.showopengraphpreview,
promptText: $scope.prompttext,
header: $scope.header,
footer: $scope.footer
}
};
yam.connect.embedFeed(feedOptions);
}
}
})();
!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="https://s0.assets-yammer.com/assets/",b(0)}([function(a,b,c){c(1),c(2),a.exports=c(3)},function(a,b){"use strict";window.yam=window.yam||{config:function a(b){return Object.keys(b||{}).forEach(function(a){yam._configData[a]=b[a]}),yam._configData},_configData:{}}},function(a,b){"use strict";var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(){function a(a){window.console&&"function"==typeof console.log&&console.log("[yammer] "+a)}function b(a,b,c){a.addEventListener?a.addEventListener(b,c):a.attachEvent("on"+b,function(b){c.call(a,b)})}function d(a){function b(a,e){Object.keys(a||{}).forEach(function(f){if(Object.prototype.hasOwnProperty.call(a,f)){var g=""===e?f:e+"["+f+"]";"object"===c(a[f])?b(a[f],g):d[g]=a[f]}})}var d={};b(a,"");var e=[];return Object.keys(d||{}).forEach(function(a){Object.prototype.hasOwnProperty.call(d,a)&&e.push(encodeURIComponent(a)+"="+encodeURIComponent(d[a]))}),e.join("&")}function e(a){a=a||{};var b=a.style||j,c=document.createElement("iframe");return c.id=a.id,c.name=a.name||a.id,c.frameBorder="none",c.scrolling="no",Object.keys(b||{}).forEach(function(a){Object.prototype.hasOwnProperty.call(b,a)&&(c.style[a]=b[a])}),c.src="javascript://",c}function f(a){var b=a.objectProperties||{};b.url||(b.url=document.location.href,a.objectProperties=b)}function g(b){var c=b||document.body;return"string"==typeof c&&(c=document.querySelector(c)),c?c:void a("Could not find container to embed in")}function h(a){a=a||{};var c=Date.now().toString(),h=g(a.container);if(h){a.feedType&&"open-graph"===a.feedType&&f(a);var i=e({id:"embed-feed"});i.className="yj-embed-widget yj-embed-feed",h.appendChild(i),b(window,"message",function(a){if(a.origin===yam.config().baseURI){var b=JSON.parse(a.data),d=b.data;d&&"yam.trigger"===d.method&&d.uniqueToken===c&&yam.trigger(d.eventId,d.msg)}}),a.network&&(a.network_permalink=a.network),a.bust=c;var j=d(a),k=yam.config().baseURI+"/embed-feed?"+j;i.src=k}}function i(a){a=a||{};var c=Date.now().toString(),h=g(a.container);if(h){f(a);var i=e({id:"embed-button"+k++});i.style.width=h.clientWidth+"px",i.style.height=h.clientHeight+"px",i.className="yj-embed-widget yj-embed-button",h.appendChild(i),b(window,"message",function(a){if(a.origin===yam.config().baseURI){var b=JSON.parse(a.data),d=b.data;d&&d.uniqueToken===c&&("yam.resize"===d.method?(i.style.width=d.width+"px",i.style.height=d.height+"px"):"yam.trigger"===d.method&&yam.trigger(d.eventId,d.msg))}}),a.bust=c;var j=d(a);i.src=yam.config().baseURI+"/platform_embed/button?"+j}}var j={border:"0px",overflow:"hidden","min-height":"26px",width:"100%",height:"100%"},k=0;if("function"!=typeof yam.on){var l={},m=function a(b,c){var d=l[b];if(d)for(var e=0,f=d.length;e<f;e++){var g=d[e];g.fn.apply(g.ctx,c)}};yam.trigger=function(a){var b=[].slice.call(arguments,1);m(a,b),m("all",arguments)},yam.on=function(a,b,c){l[a]||(l[a]=[]),l[a].push({fn:b,ctx:c||null})},yam.off=function(a,b,c){var d=l[a];if(c=c||null,d){for(var e=-1,f=0,g=d.length;f<g&&e===-1;f++)d[f].fn===b&&d[f].ctx===c&&(e=f);e!==-1&&d.splice(e,1)}}}yam.connect=yam.connect||{},yam.connect.actionButton=i,yam.connect.embedFeed=h}()},function(a,b,c){var d;d=function(a){var b=c(4);yam.config(b)}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports={assetHost:"https://s0.assets-yammer.com",cdnAssetHost:"https://s0.assets-yammer.com",mugshotHost:"https://www.yammer.com/mugshot",cdnMugshotHost:"https://mug0.assets-yammer.com/mugshot",polarisHost:"https://polaris.yammer.com/",baseURI:"https://www.yammer.com",apiBaseURI:"https://api.yammer.com",videoStreamingUri:"rtmpt://s1fqyiixzut1oy.cloudfront.net:80/cfx/st",reportAuthorizationHeader:"Receiver MTosLDIzQTBEMTA1LTM4RUItNDcyMS05RTM2LTQxNEY5QUI1RTQ3MyA=",reportPerfRequestUri:"https://receiver.yamalytics.yammer.com/prod/web_ui",filesHost:"https://files.yammer.com/v2/files",paddieHost:"https://pad0.assets-yammer.com",msgraphUri:"https://msgraph.yammer.com",yammer_environment:"production"}}]);

View File

@ -0,0 +1,13 @@
define([], function() {
return {
"PropertyPaneDescription": "Settings",
"BasicGroupName": "Personalization",
"NetworkFieldLabel": "Network",
"FeedTypeFieldLabel": "Feed Type",
"DefaultGroupIdFieldLabel": "Default Group Id",
"ShowOpenGraphPreviewFieldLabel": "Show Open Graph Preview",
"PromptTextFieldLabel": "Prompt Text",
"HeaderFieldLabel": "Header",
"FooterFieldLabel": "Footer"
}
});

View File

@ -0,0 +1,16 @@
declare interface IAngularYammerStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
NetworkFieldLabel: string;
FeedTypeFieldLabel: string;
DefaultGroupIdFieldLabel: string;
ShowOpenGraphPreviewFieldLabel: string;
PromptTextFieldLabel: string;
HeaderFieldLabel: string;
FooterFieldLabel: string;
}
declare module 'angularYammerStrings' {
const strings: IAngularYammerStrings;
export = strings;
}

View File

@ -0,0 +1,9 @@
/// <reference types="mocha" />
import { assert } from 'chai';
describe('AngularYammerWebPart', () => {
it('should do something', () => {
assert.ok(true);
});
});

View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"types": [
"es6-promise",
"es6-collections",
"webpack-env"
]
}
}

View File

@ -0,0 +1,8 @@
// Type definitions for Microsoft ODSP projects
// Project: ODSP
/* Global definition for UNIT_TEST builds
Code that is wrapped inside an if(UNIT_TEST) {...}
block will not be included in the final bundle when the
--ship flag is specified */
declare const UNIT_TEST: boolean;

View File

@ -0,0 +1 @@
/// <reference path="@ms/odsp.d.ts" />