Added spfx sample for Employee Spotlight webpart (#244)
Added the sample webpart code to display the Employee Spotlight details from a configured list using javascript and SharePoint framework
This commit is contained in:
parent
db3a0653a2
commit
5c8f6a644d
|
@ -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 @@
|
|||
* text=auto
|
|
@ -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,14 @@
|
|||
# Folders
|
||||
.vscode
|
||||
coverage
|
||||
node_modules
|
||||
sharepoint
|
||||
src
|
||||
temp
|
||||
|
||||
# Files
|
||||
*.csproj
|
||||
.git*
|
||||
.yo-rc.json
|
||||
gulpfile.js
|
||||
tsconfig.json
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"libraryName": "js-employee-spotlight",
|
||||
"framework": "none",
|
||||
"version": "1.0.2",
|
||||
"libraryId": "d57c7f34-22d4-45b5-9c26-441ef9fef48a"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
# Display Employee Spotlight JavaScript Client-Side Web Part
|
||||
|
||||
## Summary
|
||||
Simple Web Part that demonstrates the use of SharePoint Framework for show casing Employee Spotlight. The web part pulls data from a configured list and User Profile service.
|
||||
The properties pane for this web part has 5 canscading dropdowns.
|
||||
- A drop down list of sites(webs) in the current site collection.
|
||||
- A drop down list of list titles in the selected site(web).
|
||||
- 3 drop downs with list of field names from selected list, which includes
|
||||
* Name(Person or Group Column).
|
||||
* Splotlight Description (Multiline - Enriched text Column).
|
||||
* Expiry date for Spotlight event (DateTime Column with Date only option).
|
||||
- The properties pane also has options for following slider effects.
|
||||
* Background color - A color picker to choose Slider background color
|
||||
* Font color - A color picker to choose Slider font color
|
||||
* Set Auto slide - A switch to enable/disable auto slide for slider
|
||||
* Slider Speed - A Slider control to select slider speed from 0sec - 7sec with 0.5sec as a step.
|
||||
|
||||
![Screeshot of the Employee Spotlight web part options](./assets/Employee-spotlight-options.png).
|
||||
|
||||
Once the user selects all the configuration details, the web part displays the spotlight details from the configured list.
|
||||
|
||||
![Screeshot of the Employee Spotlight web part](./assets/Employee-spotlight-priview.png).
|
||||
|
||||
> Data is displayed only when hosted in SharePoint. No mock data included at this point for local testing.
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/drop-GA-green.svg)
|
||||
|
||||
## Applies to
|
||||
* [SharePoint Framework Developer](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)
|
||||
--------|---------
|
||||
js-employee-spotlight| SPS (Strategic Products and Services)
|
||||
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|June 12, 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 repository
|
||||
- in the command line run:
|
||||
- `npm install`
|
||||
- `tsd install`
|
||||
- `gulp serve`
|
||||
- `Open the workbench on your Office 365 Developer tenant`
|
||||
- Basic functionality can be tested locally, data is only shown when used in context of SharePoint
|
||||
|
||||
## Features
|
||||
The js-employee-spotlight web part displays the content of the list specified in the web part properties pane, The list should have the 3 mandatory fields.
|
||||
|
||||
This Web Part illustrates the following concepts on top of the SharePoint Framework:
|
||||
|
||||
* Using a dynamic drop down box in the web part properties pane to display cascading dropdowns, which contains
|
||||
- the titles webs in current sitecollection
|
||||
- titles of the lists in the selected web
|
||||
- fields of a selected list
|
||||
* Use of a third party control(sp-client-custom-fields) for selecting webpart foregroud and background colors.
|
||||
* Use of switch, slider controls to configure slider speed and auto scrolling.
|
||||
* Using a javascript slider.
|
||||
* Fetching the user details from User Profile service like user designation, user profile image.
|
||||
* Logging.
|
||||
* Rendering error messages.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"entries": [{
|
||||
"entry": "./lib/webparts/employeeSpotlight/EmployeeSpotlightWebPart.js",
|
||||
"manifest": "./src/webparts/employeeSpotlight/EmployeeSpotlightWebPart.manifest.json",
|
||||
"outputPath": "./dist/employee-spotlight.bundle.js"
|
||||
}],
|
||||
"externals": {
|
||||
"sp-client-custom-fields": "node_modules/sp-client-custom-fields/dist/sp-client-custom-fields.bundle.js"
|
||||
},
|
||||
"localizedResources": {
|
||||
"sp-client-custom-fields/strings": "../node_modules/sp-client-custom-fields/lib/loc/{locale}.js",
|
||||
"employeeSpotlightStrings": "webparts/employeeSpotlight/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "js-employee-spotlight",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"solution": {
|
||||
"name": "Employee Spotlight-v1",
|
||||
"id": "d57c7f34-22d4-45b5-9c26-441ef9fef482",
|
||||
"version": "2.0.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/EmployeeSpotlight-v1.sppkg"
|
||||
}
|
||||
}
|
|
@ -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/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cdnBasePath": ""
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.initialize(gulp);
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "js-employee-spotlight",
|
||||
"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",
|
||||
"sp-client-custom-fields": "^1.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.0.1",
|
||||
"@microsoft/sp-module-interfaces": "~1.0.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.0.0",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0",
|
||||
"gulp": "~3.9.1",
|
||||
"gulp-util": "^3.0.8"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
* {
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box!important;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box
|
||||
}
|
||||
/* Slideshow container */
|
||||
|
||||
.containers {
|
||||
max-width: 1000px;
|
||||
min-width: 350px;
|
||||
min-height: 160px;
|
||||
position: relative;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mySlides {
|
||||
display: none;
|
||||
transition: 1s all ease-in-out;
|
||||
-webkit-animation: slideIn 1s forwards;
|
||||
-moz-animation: slideIn 1s forwards;
|
||||
animation: slideIn 1s forwards;
|
||||
}
|
||||
|
||||
/* Next & previous buttons */
|
||||
.prev{
|
||||
left:0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.prev,
|
||||
.next {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: auto;
|
||||
margin-top: -22px;
|
||||
padding: 8px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
transition: 0.6s all ease;
|
||||
}
|
||||
/* Position the "next button" to the right */
|
||||
|
||||
.next {
|
||||
right: 0;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
/* On hover, add a black background color with a little bit see-through */
|
||||
|
||||
.prev:hover,
|
||||
.next:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
@-webkit-keyframes slideIn {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(900px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes slideIn {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(900px);
|
||||
}
|
||||
}
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
transform: translateX(-900px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
||||
|
||||
"id": "54d10877-595f-464d-81f0-19fb840c766f",
|
||||
"alias": "EmployeeSpotlightWebPart",
|
||||
"componentType": "WebPart",
|
||||
"version": "0.0.1",
|
||||
"manifestVersion": 2,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "54d10877-595f-464d-81f0-19fb840c766f",
|
||||
"group": { "default": "SPFx Webparts" },
|
||||
"title": { "default": "Employee Spotlight" },
|
||||
"description": { "default": "This webpart shows the employee spotlight information." },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "Employee Spotlight",
|
||||
"spotlightBGColor": "#3f0d3e",
|
||||
"spotlightFontColor": "#ffffff",
|
||||
"enabledSpotlightAutoPlay": true
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,467 @@
|
|||
/**
|
||||
* @file
|
||||
* Spotlight Web Part with SharePoint Framework
|
||||
* Author: SPS-COM
|
||||
* Copyright (c) 2017
|
||||
*/
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
IPropertyPaneDropdownOption,
|
||||
PropertyPaneDropdown,
|
||||
PropertyPaneToggle,
|
||||
PropertyPaneSlider
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
import { SPComponentLoader } from '@microsoft/sp-loader';
|
||||
import { SPHttpClient } from '@microsoft/sp-http';
|
||||
import {
|
||||
Environment,
|
||||
EnvironmentType
|
||||
} from '@microsoft/sp-core-library';
|
||||
import { PropertyFieldColorPickerMini } from 'sp-client-custom-fields/lib/PropertyFieldColorPickerMini';
|
||||
import * as jQuery from 'jquery';
|
||||
import * as _ from "lodash";
|
||||
import styles from './EmployeeSpotlight.module.scss';
|
||||
import * as strings from 'employeeSpotlightStrings';
|
||||
import { IEmployeeSpotlightWebPartProps } from './IEmployeeSpotlightWebPartProps';
|
||||
import { SliderHelper } from './Helper';
|
||||
|
||||
/**
|
||||
* An interface to hold the key and value.
|
||||
*/
|
||||
export interface ResponceDetails {
|
||||
title: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface to hold the ResponceDetails collection.
|
||||
*/
|
||||
export interface ResponceCollection {
|
||||
value: ResponceDetails[];
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface to hold the SpotlightDetails.
|
||||
*/
|
||||
export interface SpotlightDetails {
|
||||
userDisplayName: string;
|
||||
userEmail: string;
|
||||
userProfilePic: string;
|
||||
description: string;
|
||||
designation?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that contains spotlight webpart operations and corresponding properties to hold the data.
|
||||
*/
|
||||
export default class EmployeeSpotlightWebPart extends BaseClientSideWebPart<IEmployeeSpotlightWebPartProps> {
|
||||
private spotlightListFieldOptions: IPropertyPaneDropdownOption[] = [];
|
||||
private spotlightListOptions: IPropertyPaneDropdownOption[] = [];
|
||||
private siteOptions: IPropertyPaneDropdownOption[] = [];
|
||||
private defaultProfileImageUrl: string = "/_layouts/15/userphoto.aspx?size=L";
|
||||
private helper: SliderHelper = new SliderHelper();
|
||||
private sliderControl: any = null;
|
||||
/**
|
||||
* Constructor of SpotlightWebpart class.
|
||||
*/
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
SPComponentLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js', { globalExportsName: 'jQuery' });
|
||||
// Next button functionality
|
||||
jQuery(document).on("click", "." + styles.next, (event) => {
|
||||
event.preventDefault(); //prevent default action of <a>
|
||||
this.helper.moveSlides(1);
|
||||
});
|
||||
|
||||
// Previous button functionality
|
||||
jQuery(document).on("click", "." + styles.prev, (event) => {
|
||||
event.preventDefault(); //prevent default action of <a>
|
||||
this.helper.moveSlides(-1);
|
||||
});
|
||||
|
||||
// start and stop slider on hover
|
||||
jQuery(document).ready(() => {
|
||||
jQuery(document).on('mouseenter', '.' + styles.containers, () => {
|
||||
if (this.properties.enabledSpotlightAutoPlay)
|
||||
clearInterval(this.sliderControl);
|
||||
}).on('mouseleave', '.' + styles.containers, () => {
|
||||
var carouselSpeed: number = this.properties.spotlightSliderSpeed * 1000;
|
||||
if (carouselSpeed && this.properties.enabledSpotlightAutoPlay)
|
||||
this.sliderControl = setInterval(this.helper.startAutoPlay, carouselSpeed);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A starting point for application.
|
||||
*/
|
||||
public render(): void {
|
||||
this.domElement.innerHTML = `<div id="spListContainer" />`;
|
||||
this._renderSpotlightTemplateAsync();
|
||||
this._renderSpotlightDataAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the spotlight details collection with necessary details.
|
||||
*/
|
||||
private _renderSpotlightTemplateAsync(): void {
|
||||
if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) {
|
||||
this._getSiteCollectionRootWeb().then((response) => {
|
||||
this.properties.spotlightSiteCollectionURL = response['Url'];
|
||||
});
|
||||
if (this.properties.spotlightSiteURL && this.properties.spotlightListName && this.properties.spotlightEmployeeEmailColumn && this.properties.spotlightDescriptionColumn) {
|
||||
let spotlightDataCollection: SpotlightDetails[] = [];
|
||||
this._getSpotlightListData(this.properties.spotlightSiteURL, this.properties.spotlightListName, this.properties.spotlightEmployeeExpirationDateColumn, this.properties.spotlightEmployeeEmailColumn, this.properties.spotlightDescriptionColumn)
|
||||
.then((listDataResponse) => {
|
||||
var spotlightListData = listDataResponse.value;
|
||||
if (spotlightListData) {
|
||||
debugger;
|
||||
for (var key in listDataResponse.value) {
|
||||
var email = listDataResponse.value[key][this.properties.spotlightEmployeeEmailColumn]["EMail"];
|
||||
var id = listDataResponse.value[key]["ID"];
|
||||
this._getUserImage(email)
|
||||
.then((response) => {
|
||||
spotlightListData.forEach((item: ResponceDetails) => {
|
||||
let userSpotlightDetails: SpotlightDetails = { userDisplayName: "", userEmail: "", userProfilePic: "", description: "" };
|
||||
if (item[this.properties.spotlightEmployeeEmailColumn]["EMail"] == response["Email"]) {
|
||||
var userName = item[this.properties.spotlightEmployeeEmailColumn];
|
||||
var description = item[this.properties.spotlightDescriptionColumn];
|
||||
var userDescription = "";
|
||||
try {
|
||||
userDescription = $(description).text();
|
||||
}
|
||||
catch (err) {
|
||||
userDescription = description;
|
||||
}
|
||||
if (userDescription.length > 140) {
|
||||
var displayFormUrl = this.properties.spotlightSiteURL + '/Lists/' + this.properties.spotlightListName + '/DispForm.aspx?ID=' + id;
|
||||
userDescription = userDescription.substring(0, 140) + ` <a href="${displayFormUrl}">ReadMore...</a>`;
|
||||
}
|
||||
var displayName = response["DisplayName"];
|
||||
var designationProperty = _.filter(response["UserProfileProperties"], { Key: "SPS-JobTitle" })[0];
|
||||
var designation = designationProperty["Value"] ? designationProperty["Value"] : "";
|
||||
// uses default image if user image not exist
|
||||
var profilePicture = response["PictureUrl"] != null && response["PictureUrl"] != undefined ? (<string>response["PictureUrl"]).replace("MThumb", "LThumb") : this.defaultProfileImageUrl;
|
||||
// var profilePicture = response["PictureUrl"] != null && response["PictureUrl"] != undefined ? (<string>response["PictureUrl"]) : this.defaultProfileImageUrl;
|
||||
profilePicture = '/_layouts/15/userphoto.aspx?accountname=' + displayName + '&size=M&url=' + profilePicture.split("?")[0];
|
||||
userSpotlightDetails = {
|
||||
userDisplayName: response["DisplayName"],
|
||||
userEmail: response["Email"],
|
||||
userProfilePic: profilePicture,
|
||||
description: userDescription,
|
||||
designation: designation
|
||||
};
|
||||
spotlightDataCollection.push(userSpotlightDetails);
|
||||
}
|
||||
});
|
||||
this._addSpotlightTemplateContent(spotlightDataCollection);
|
||||
if (this.sliderControl == null && this.properties && this.properties.enabledSpotlightAutoPlay) {
|
||||
setTimeout(this.helper.moveSlides(), 2000);
|
||||
this.sliderControl = setInterval(this.helper.startAutoPlay, this.properties.spotlightSliderSpeed * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the webpart html with the given spotlight details collection.
|
||||
* @param spotlightDetails - a collection of spotlight details.
|
||||
*/
|
||||
private _addSpotlightTemplateContent(spotlightDetails: SpotlightDetails[]): void {
|
||||
this.domElement.innerHTML = '';
|
||||
var innerContent: string = '';
|
||||
for (let i: number = 0; i < spotlightDetails.length; i++) {
|
||||
innerContent += `
|
||||
<div class="${styles.mySlides}">
|
||||
<div style="width:100%;">
|
||||
<div style="width:36%;float:left;padding:10% 0;">
|
||||
<img style="border-radius:50%;width: 90px;" src="${spotlightDetails[i].userProfilePic}" />
|
||||
</div>
|
||||
<div style="width:60%;float:left;text-align:left;">
|
||||
<h5 style="margin-bottom:0; text-transform: uppercase;text-align:center;">${spotlightDetails[i].userDisplayName}</h5>
|
||||
<h6 style="text-align:center;">${spotlightDetails[i].designation}</h6>
|
||||
<p>${spotlightDetails[i].description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
this.domElement.innerHTML +=
|
||||
`<div class="${styles.containers}" id="slideshow" style="background-color: ${this.properties.spotlightBGColor}; cursor:pointer; width: 100%!important; padding: 5px;border-radius: 15px;box-shadow: rgba(0,0,0,0.25) 0 0 20px 0;text-align:center;color:${this.properties.spotlightFontColor};">
|
||||
` + innerContent + `
|
||||
<a class="${styles.prev}">❮</a>
|
||||
<a class="${styles.next}">❯</a>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic utility function to execute the rest api call and return the corresponding result as a promise.
|
||||
* @param url - The string containing api url.
|
||||
*/
|
||||
private _callAPI(url: string): Promise<ResponceCollection> {
|
||||
return this.context.spHttpClient.get(url, SPHttpClient.configurations.v1).then((response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns user image url and name.
|
||||
* @param email - The string containing user email id.
|
||||
*/
|
||||
private _getUserImage(email: string): Promise<ResponceCollection> {
|
||||
return this._callAPI(this.properties.spotlightSiteCollectionURL + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='i:0%23.f|membership|" + email + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns sitecollection rootweb url.
|
||||
*/
|
||||
private _getSiteCollectionRootWeb(): Promise<ResponceCollection> {
|
||||
return this._callAPI(this.context.pageContext.web.absoluteUrl + `/_api/Site/RootWeb?$select=Title,Url`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns all the subsite names from the given sitecollection.
|
||||
* @param spotlightSiteCollectionURL - The string containing user email id.
|
||||
*/
|
||||
private _getAllSubsites(spotlightSiteCollectionURL: string): Promise<ResponceCollection> {
|
||||
return this._callAPI(spotlightSiteCollectionURL + `/_api/web/webs?$select=Title,Url`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns all the list names in corresponding site.
|
||||
* @param siteUrl - The string containing site url.
|
||||
*/
|
||||
private _getAllLists(siteUrl: string): Promise<ResponceCollection> {
|
||||
if (siteUrl != "" && siteUrl != undefined) {
|
||||
return this._callAPI(siteUrl + `/_api/web/lists?$orderby=Id desc&$filter=Hidden eq false and BaseTemplate eq 100`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns spotlight list field names.
|
||||
* @param siteUrl - The string containing site url.
|
||||
* @param spotlightListName - The string containing spotlight list name.
|
||||
*/
|
||||
private _getSpotlightListFields(siteUrl: string, spotlightListName: string): Promise<ResponceCollection> {
|
||||
if (siteUrl != "" && spotlightListName != "" && siteUrl != undefined && spotlightListName != undefined) {
|
||||
return this._callAPI(siteUrl + `/_api/web/lists/GetByTitle('${spotlightListName}')/Fields?$orderby=Id desc&$filter=Hidden eq false and ReadOnlyField eq false`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the subsites in the current sitecollection and initiates the corresponding dropdown values loading.
|
||||
*/
|
||||
private _renderSpotlightDataAsync(): void {
|
||||
this._getSiteCollectionRootWeb()
|
||||
.then((response) => {
|
||||
this.properties.spotlightSiteCollectionURL = response['Url'];
|
||||
this._getAllSubsites(response['Url'])
|
||||
.then((sitesResponse) => {
|
||||
this.siteOptions = this._getDropDownCollection(sitesResponse, 'Url', 'Title');
|
||||
this.context.propertyPane.refresh();
|
||||
if (this.properties.spotlightSiteURL != "") {
|
||||
this._loadAllListsDropDown(this.properties.spotlightSiteURL);
|
||||
}
|
||||
if (this.properties.spotlightListName != "") {
|
||||
this._loadSpotlightListFieldsDropDown(this.properties.spotlightSiteURL, this.properties.spotlightListName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the list names in the selected site for spotlight list dropdown.
|
||||
* @param siteUrl - The string containing site url.
|
||||
*/
|
||||
private _loadAllListsDropDown(siteUrl: string): void {
|
||||
this._getAllLists(siteUrl)
|
||||
.then((response) => {
|
||||
this.spotlightListOptions = this._getDropDownCollection(response, 'Title', 'Title');
|
||||
this.context.propertyPane.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the spotlight list fields for fields dropdown.
|
||||
* @param siteUrl - The string containing site url.
|
||||
* @param spotlightListName - The string containing spotlight list name.
|
||||
*/
|
||||
private _loadSpotlightListFieldsDropDown(siteUrl: string, spotlightListName: string): void {
|
||||
this._getSpotlightListFields(siteUrl, spotlightListName)
|
||||
.then((response) => {
|
||||
this.spotlightListFieldOptions = this._getDropDownCollection(response, 'Title', 'Title');
|
||||
this.context.propertyPane.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dropdown key and values collection.
|
||||
* @param response - The collection containing keys and values.
|
||||
* @param key - The string containing key.
|
||||
* @param text - The string containing value.
|
||||
*/
|
||||
private _getDropDownCollection(response: ResponceCollection, key: string, text: string): IPropertyPaneDropdownOption[] {
|
||||
var dropdownOptions: IPropertyPaneDropdownOption[] = [];
|
||||
if (key == 'Url')
|
||||
dropdownOptions.push({ key: this.context.pageContext.web.absoluteUrl, text: 'This Site' });
|
||||
for (var itemKey in response.value) {
|
||||
dropdownOptions.push({ key: response.value[itemKey][key], text: response.value[itemKey][text] });
|
||||
}
|
||||
return dropdownOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that returns spotlight list items.
|
||||
* @param siteUrl - The string containing site url.
|
||||
* @param spotlightListName - The string containing spotlight list name.
|
||||
*/
|
||||
private _getSpotlightListData(siteUrl: string, spotlightListName: string, expiryDateColumn: string, emailColumn: string, descriptionColumn: string): Promise<ResponceCollection> {
|
||||
if (siteUrl != "" && spotlightListName != "") {
|
||||
var today: Date = new Date();
|
||||
var dd: any = today.getDate();
|
||||
var mm: any = today.getMonth() + 1; //January is 0!
|
||||
var yyyy: any = today.getFullYear();
|
||||
dd = (dd < 10) ? '0' + dd : dd;
|
||||
mm = (mm < 10) ? '0' + mm : mm;
|
||||
var dateString: string = `${yyyy}-${mm}-${dd}`;
|
||||
emailColumn = emailColumn.replace(" ", "_x0020_");
|
||||
descriptionColumn = descriptionColumn.replace(" ", "_x0020_");
|
||||
expiryDateColumn = expiryDateColumn.replace(" ", "_x0020_");
|
||||
return this._callAPI(siteUrl + `/_api/web/lists/GetByTitle('${spotlightListName}')/items?$select=ID,${descriptionColumn},${emailColumn}/EMail&$expand=${emailColumn}/Id&$orderby=Id desc&$filter=${expiryDateColumn} ge '${dateString}'`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the Property pane fields for null checks
|
||||
* @param value - The string value of the field to be validated.
|
||||
*/
|
||||
private _validateFiledValue(value: string): string {
|
||||
var validationMessage: string = '';
|
||||
if (value === null || value.trim().length === 0) {
|
||||
validationMessage = 'Please select a value';
|
||||
}
|
||||
return validationMessage;
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Propertypane with specific configurations.
|
||||
*/
|
||||
protected onPropertyPaneConfigurationStart(): void {
|
||||
// Stops execution, if the list values already exists
|
||||
if (this.spotlightListOptions.length > 0) return;
|
||||
// Calls function to append the list names to dropdown
|
||||
this._renderSpotlightTemplateAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers foreach Property pane value update and loads the corresponding details.
|
||||
* @param propertyPath - The string containing property path.
|
||||
* @param oldValue - The string containing old value of property.
|
||||
* @param newValue - The string containing new value of property.
|
||||
*/
|
||||
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
|
||||
switch (propertyPath) {
|
||||
case "spotlightSiteURL":
|
||||
this.properties.spotlightListName = "";
|
||||
this._loadAllListsDropDown(this.properties.spotlightSiteURL);
|
||||
break;
|
||||
case "spotlightListName":
|
||||
this.properties.spotlightEmployeeEmailColumn = "";
|
||||
this.properties.spotlightDescriptionColumn = "";
|
||||
this._loadSpotlightListFieldsDropDown(this.properties.spotlightSiteURL, this.properties.spotlightListName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retuns the property pane configuration.
|
||||
*/
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.propertyPaneHeading,
|
||||
groupFields: [
|
||||
PropertyPaneDropdown('spotlightSiteURL', {
|
||||
label: strings.selectSiteLableMessage,
|
||||
options: this.siteOptions,
|
||||
selectedKey: this._validateFiledValue.bind(this)
|
||||
}),
|
||||
PropertyPaneDropdown('spotlightListName', {
|
||||
label: strings.selectListLableMessage,
|
||||
options: this.spotlightListOptions,
|
||||
selectedKey: this._validateFiledValue.bind(this)
|
||||
}),
|
||||
PropertyPaneDropdown('spotlightEmployeeEmailColumn', {
|
||||
label: strings.employeeEmailcolumnLableMessage,
|
||||
options: this.spotlightListFieldOptions,
|
||||
selectedKey: this._validateFiledValue.bind(this)
|
||||
}),
|
||||
PropertyPaneDropdown('spotlightDescriptionColumn', {
|
||||
label: strings.descriptioncolumnLableMessage,
|
||||
options: this.spotlightListFieldOptions,
|
||||
selectedKey: this._validateFiledValue.bind(this)
|
||||
}),
|
||||
PropertyPaneDropdown('spotlightEmployeeExpirationDateColumn', {
|
||||
label: strings.expirationDateColumnLableMessage,
|
||||
options: this.spotlightListFieldOptions,
|
||||
selectedKey: this._validateFiledValue.bind(this)
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
groupName: strings.effectsGroupName,
|
||||
groupFields: [
|
||||
PropertyFieldColorPickerMini('spotlightBGColor', {
|
||||
label: strings.spotlightBGColorLableMessage,
|
||||
initialColor: this.properties.spotlightBGColor,
|
||||
disabled: false,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
|
||||
properties: this.properties,
|
||||
onGetErrorMessage: null,
|
||||
deferredValidationTime: 0,
|
||||
key: 'spotlightBGColorFieldId'
|
||||
}),
|
||||
PropertyFieldColorPickerMini('spotlightFontColor', {
|
||||
label: strings.spotlightFontColorLableMessage,
|
||||
initialColor: this.properties.spotlightFontColor,
|
||||
disabled: false,
|
||||
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
|
||||
properties: this.properties,
|
||||
onGetErrorMessage: null,
|
||||
deferredValidationTime: 0,
|
||||
key: 'spotlightFontColorFieldId'
|
||||
}),
|
||||
PropertyPaneToggle('enabledSpotlightAutoPlay', {
|
||||
label: strings.enableAutoSlideLableMessage
|
||||
}),
|
||||
PropertyPaneSlider('spotlightSliderSpeed', {
|
||||
label: strings.carouselSpeedLableMessage,
|
||||
min: 0,
|
||||
max: 7,
|
||||
value: 3,
|
||||
showValue: true,
|
||||
step: 0.5
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import styles from './EmployeeSpotlight.module.scss';
|
||||
|
||||
export class SliderHelper {
|
||||
public static slideIndex: number = 0;
|
||||
// /**
|
||||
// * Constructor of helper class.
|
||||
// */
|
||||
public constructor() {
|
||||
SliderHelper.slideIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* auto play slider
|
||||
*/
|
||||
public startAutoPlay(): void {
|
||||
var slides = <HTMLScriptElement[]><any>document.getElementsByClassName(styles.mySlides);
|
||||
debugger;
|
||||
if (slides.length > 0) {
|
||||
for (var i: number = 0; i < slides.length; i++) {
|
||||
slides[i].style.display = SliderHelper.slideIndex == i ? "block" : "none";
|
||||
}
|
||||
SliderHelper.slideIndex = (++SliderHelper.slideIndex) >= slides.length ? 0 : SliderHelper.slideIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* move slide
|
||||
* @param n - slide index.
|
||||
*/
|
||||
public moveSlides(n: number = 0): boolean {
|
||||
SliderHelper.slideIndex += n;
|
||||
var slides = (<HTMLScriptElement[]><any>document.getElementsByClassName(styles.mySlides));
|
||||
if (slides.length > 0) {
|
||||
if (SliderHelper.slideIndex >= slides.length) { SliderHelper.slideIndex = 0; }
|
||||
if (SliderHelper.slideIndex < 0) { SliderHelper.slideIndex = slides.length - 1; }
|
||||
for (var i: number = 0; i < slides.length; i++) {
|
||||
slides[i].style.display = SliderHelper.slideIndex == i ? "block" : "none";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
export interface IEmployeeSpotlightWebPartProps {
|
||||
description: string;
|
||||
spotlightSiteCollectionURL: string;
|
||||
spotlightSiteURL: string;
|
||||
spotlightListName: string;
|
||||
spotlightEmployeeEmailColumn: string;
|
||||
spotlightEmployeeExpirationDateColumn: string;
|
||||
spotlightBGColor:string;
|
||||
spotlightFontColor:string;
|
||||
spotlightDescriptionColumn: string;
|
||||
spotlightSliderSpeed: number;
|
||||
enabledSpotlightAutoPlay: boolean;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"propertyPaneHeading": "Spotlight Configuration",
|
||||
"selectSiteLableMessage": "Select Site",
|
||||
"selectListLableMessage": "Select List Name",
|
||||
"employeeEmailcolumnLableMessage": "Select Employee Name column",
|
||||
"descriptioncolumnLableMessage": "Select Description column",
|
||||
"expirationDateColumnLableMessage": "Select ExpiryDate column",
|
||||
"effectsGroupName": "Slider Effects",
|
||||
"spotlightBGColorLableMessage": "Background Color",
|
||||
"spotlightFontColorLableMessage": "Font Color",
|
||||
"enableAutoSlideLableMessage": "Enable auto slide",
|
||||
"carouselSpeedLableMessage": "Slider speed(in seconds)"
|
||||
}
|
||||
});
|
18
samples/js-employee-spotlight/src/webparts/employeeSpotlight/loc/mystrings.d.ts
vendored
Normal file
18
samples/js-employee-spotlight/src/webparts/employeeSpotlight/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
declare interface IEmployeeSpotlightStrings {
|
||||
propertyPaneHeading: string;
|
||||
selectSiteLableMessage: string;
|
||||
selectListLableMessage: string;
|
||||
employeeEmailcolumnLableMessage: string;
|
||||
descriptioncolumnLableMessage: string;
|
||||
expirationDateColumnLableMessage: string;
|
||||
effectsGroupName: string;
|
||||
spotlightBGColorLableMessage:string;
|
||||
spotlightFontColorLableMessage:string;
|
||||
enableAutoSlideLableMessage: string;
|
||||
carouselSpeedLableMessage: string;
|
||||
}
|
||||
|
||||
declare module 'employeeSpotlightStrings' {
|
||||
const strings: IEmployeeSpotlightStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/// <reference types="mocha" />
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
describe('EmployeeSpotlightWebPart', () => {
|
||||
it('should do something', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1 @@
|
|||
/// <reference path="@ms/odsp.d.ts" />
|
Loading…
Reference in New Issue