Merge pull request #1933 from smaity/feature/anniversary

This commit is contained in:
Hugo Bernier 2021-06-27 00:54:36 -04:00 committed by GitHub
commit fc4392579b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 15022 additions and 8262 deletions

View File

@ -11,6 +11,7 @@ dist
lib
solution
temp
release
*.sppkg
# Coverage directory used by tools like istanbul

View File

@ -15,9 +15,13 @@ But you can synchronize the Birthdays list with other applications HR Systems, o
![Birthdays Web Part](./assets/birthdays.png)
## Compatibility
## Used SharePoint Framework Version
![1.8.2](https://img.shields.io/badge/version-1.8.2-green.svg)
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
## Applies to
@ -37,13 +41,14 @@ userAADGUID| Text| no | required if used Azure Function to get Birthdays from AA
Title| Text| true
email| Text| true
## After create a column Index on column "Birthday" - Important!
> **IMPORTANT:** After create a column Index on column "Birthday"
## Solution
Solution|Author(s)
--------|---------
react Birthday Web Part|João Mendes
react Birthday Web Part|[João Mendes](https://github.com/joaojmendes)
react Birthday Web Part|[Sajal Maity](https://github.com/smaity)
## Version history
@ -51,13 +56,9 @@ Version|Date|Comments
-------|----|--------
1.0.0|November 6, 2018|Initial release
1.1.0|July 23, 2019 | new version
2.0.0|June 16, 2021 | Upgraded to SPFx 1.12.1
## 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 - please follow all the steps.
## Minimal Path to Awesome
- Clone this repository
- in the command line run:
@ -65,10 +66,9 @@ Version|Date|Comments
- `gulp build`
- `gulp bundle --ship`
- `gulp package-solution --ship`
- `Add and Deploy Package to AppCatalog `
- `Go to API Management - from SharePoint Admin Center new experience, and Approve the Permission Require to Use Graph API SCOPES`
- Add and Deploy Package to AppCatalog
- Go to API Management - from SharePoint Admin Center new experience, and Approve the Permission Require to Use Graph API SCOPES
## Features
This project contains sample Birthday web parts built on the SharePoint Framework using React
@ -79,7 +79,22 @@ This sample illustrates the following concepts on top of the SharePoint Framewor
- using MSGraph API to get data from SharePoint Lists
- using MSGraph API to read users from AAD
- using @PnP/PnPjs to create a List, add, update, delete Items.
## 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.**
## Help
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-birthdays&authors=@smaity%20@joaojmendes&title=react-birthdays%20-%20).
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-birthdays&authors=@smaity%20@joaojmendes&title=react-birthdays%20-%20).
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-birthdays&authors=@smaity%20@joaojmendes&title=react-birthdays%20-%20).
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-birthdays" />

View File

@ -9,7 +9,7 @@
"The Web Part Birthdays shows the upcoming birthdays in the company, the web part reads birthdays from a list located on the tenant\u0027s root site with title \u0022Birthdays.\u0022"
],
"creationDateTime": "2019-07-23",
"updateDateTime": "2019-07-23",
"updateDateTime": "2021-06-16",
"products": [
"SharePoint",
"Office"
@ -21,7 +21,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.8.2"
"value": "1.12.1"
},
{
"key": "SPFX-TEAMSTAB",
@ -227,6 +227,12 @@
"pictureUrl": "https://github.com/joaojmendes.png",
"name": "Jo\u00E3o Mendes",
"twitter": "joaojmendes"
},
{
"gitHubAccount": "smaity",
"company": "JP Morgan Chase",
"pictureUrl": "https://github.com/smaity.png",
"name": "Sajal Maity"
}
],
"references": [

View File

@ -1,9 +1,9 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "happy-birdthay-client-side-solution",
"id": "57890dd1-b655-4ec8-85ec-e47a9b696e7c",
"version": "1.0.0.0",
"name": "happy-birdthay-anniversary-client-side-solution",
"id": "474e78f8-113f-4057-a9a9-640241137620",
"version": "2.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false,
@ -26,6 +26,6 @@
}]
},
"paths": {
"zippedPackage": "solution/birdthays.sppkg"
"zippedPackage": "solution/birthdays-anniversary.sppkg"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "Birthdays",
"version": "0.0.1",
"name": "birthdays-anniversay",
"version": "2.0.0",
"private": true,
"engines": {
"node": ">=0.10.0"
@ -11,35 +11,35 @@
"test": "gulp test"
},
"dependencies": {
"@microsoft/loader-set-webpack-public-path": "^3.2.102",
"@microsoft/rush-stack-compiler-3.2": "^0.3.20",
"@microsoft/loader-set-webpack-public-path": "^3.4.5",
"@microsoft/rush-stack-compiler-3.2": "^0.3.37",
"@microsoft/sp-core-library": "1.8.2",
"@microsoft/sp-lodash-subset": "1.8.2",
"@microsoft/sp-office-ui-fabric-core": "1.8.2",
"@microsoft/sp-webpart-base": "1.8.2",
"@pnp/common": "^1.2.5",
"@pnp/graph": "^1.2.5",
"@pnp/logging": "^1.2.5",
"@pnp/odata": "^1.2.5",
"@pnp/sp": "^1.2.5",
"@microsoft/sp-webpart-base": "^1.12.1",
"@pnp/common": "^1.3.11",
"@pnp/graph": "^1.3.11",
"@pnp/logging": "^1.3.11",
"@pnp/odata": "^1.3.11",
"@pnp/sp": "^1.3.11",
"@pnp/spfx-controls-react": "1.10.0",
"@pnp/spfx-property-controls": "1.12.0",
"@types/es6-promise": "0.0.33",
"@types/react": "16.7.22",
"@types/react-dom": "16.8.0",
"@types/webpack-env": "1.13.1",
"moment": "^2.22.2",
"moment": "^2.29.1",
"office-ui-fabric-react": "6.143.0",
"react": "16.7.0",
"react-dom": "16.7.0"
},
"devDependencies": {
"@microsoft/rush-stack-compiler-2.9": "0.7.7",
"@microsoft/set-webpack-public-path-plugin": "^2.1.58",
"@microsoft/sp-build-web": "1.8.2",
"@microsoft/set-webpack-public-path-plugin": "^2.4.0",
"@microsoft/sp-build-web": "^1.12.1",
"@microsoft/sp-module-interfaces": "1.8.2",
"@microsoft/sp-tslint-rules": "1.8.2",
"@microsoft/sp-webpart-workbench": "1.8.2",
"@microsoft/sp-webpart-workbench": "^1.12.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2",

View File

@ -109,7 +109,8 @@ export class HappyBirthdayCard extends React.Component<IHappyBirthdayCardProps,
}
// Render
public render(): React.ReactElement<IHappyBirthdayCardProps> {
this._birthdayMsg = this.state.isBirthdayToday ? strings.HappyBirthdayMsg : strings.NextBirthdayMsg;
this._birthdayMsg = this.state.isBirthdayToday ? (this.props.anniversary? strings.HappyAnniversaryMsg: strings.HappyBirthdayMsg) : (this.props.anniversary? strings.NextAnniversaryMsg: strings.NextBirthdayMsg);
return (
<div className={styles.happyBirdthay}>
<div className={styles.documentCardWrapper}>

View File

@ -2,6 +2,7 @@ export interface IHappyBirthdayCardProps {
userName?:string;
jobDescription?: string;
birthday: string;
anniversary: boolean;
userEmail:string;
congratulationsMsg?: string;
imageTemplate:string;

View File

@ -3,6 +3,8 @@ define([], function() {
"BirdthayControlDefaultDay": "Today",
"HappyBirthdayMsg": "Happy Birthday!",
"NextBirthdayMsg": "Next Birthday",
"MessageNoBirthdays": "There are no birthdays for the next days."
"HappyAnniversaryMsg": "Happy Anniversary!",
"NextAnniversaryMsg": "Next Anniversary",
"MessageNoBirthdays": "There are no birthdays and anniversaries for the next days."
}
});

View File

@ -2,6 +2,8 @@ declare interface IControlStrings {
BirdthayControlDefaultDay: string,
HappyBirthdayMsg: string,
NextBirthdayMsg: string,
HappyAnniversaryMsg: string,
NextAnniversaryMsg: string,
MessageNoBirthdays: string
}

View File

@ -35,6 +35,8 @@ export class HappyBirthday extends React.Component<IHappyBirthdayProps, IHappbir
<HappyBirdthayCard userName={user.userName}
jobDescription={user.jobDescription}
birthday={moment(user.birthday, ["MM-DD-YYYY", "YYYY-MM-DD", "DD/MM/YYYY", "MM/DD/YYYY"]).format('Do MMMM')}
anniversary={user.anniversary}
congratulationsMsg={user.message}
userEmail={user.userEmail}
imageTemplate={this.props.imageTemplate}
/>

View File

@ -4,4 +4,6 @@ export interface IUser {
jobDescription?: string;
birthday: string;
userEmail: string;
message: string;
anniversary: boolean;
}

View File

@ -4,4 +4,6 @@ export interface IUser {
jobDescription?: string;
birthday: string;
userEmail: string;
message: string;
anniversary: boolean;
}

View File

@ -12,35 +12,45 @@ export class SPService {
}
// Get Profiles
public async getPBirthdays(upcommingDays: number): Promise<any[]> {
let _results, _today: string, _month: string, _day: number;
let _results, _today: string, _month: number, _day: number;
let _filter: string, _countdays: number, _f:number, _nextYearStart: string;
let _FinalDate: string;
try {
_results = null;
_today = '2000-' + moment().format('MM-DD');
_month = moment().format('MM');
_month = parseInt(moment().format('MM'));
_day = parseInt(moment().format('DD'));
_filter = "fields/Birthday ge '" + _today + "'";
// If we are in Dezember we have to look if there are birthday in January
// we have to build a condition to select birthday in January based on number of upcommingDays
// we can not use the year for teste , the year is always 2000.
console.log(_month);
if (_month === '12') {
_countdays = _day + upcommingDays;
_f = 0;
_countdays = _day + upcommingDays;
_f = 0;
if (_month === 12 && _countdays > 31) {
_nextYearStart = '2000-01-01';
_FinalDate = '2000-01-';
_f = _countdays - 31;
_FinalDate = _FinalDate + _f;
_filter = "fields/Birthday ge '" + _today + "' or (fields/Birthday ge '" + _nextYearStart + "' and fields/Birthday le '" + _FinalDate + "')";
}
else{
_FinalDate = '2000-';
if ((_countdays) > 31) {
_f = _countdays - 31;
_FinalDate = _FinalDate + _f;
_filter = "fields/Birthday ge '" + _today + "' or (fields/Birthday ge '" + _nextYearStart + "' and fields/Birthday le '" + _FinalDate + "')";
_month = _month + 1;
_FinalDate = _FinalDate +_month + '-' + _f;
}else{
_FinalDate = _FinalDate +_month + '-' + _countdays;
}
_filter = "fields/Birthday ge '" + _today + "' and fields/Birthday le '" + _FinalDate + "'";
}
this.graphClient = await this._context.msGraphClientFactory.getClient();
_results = await this.graphClient.api(`sites/root/lists('${this.birthdayListTitle}')/items?orderby=Fields/Birthday`)
.version('v1.0')
.expand('fields')
.top(upcommingDays)
//.top(upcommingDays)
.filter(_filter)
.get();

View File

@ -1,7 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "e629ef30-a9ec-4713-b39a-2cfa8b323902",
"alias": "BirthdaysWebPart",
"id": "b0069b7e-8ec8-4e14-a76c-0c8bcb33993e",
"alias": "BirthdaysAnniversaryWebPart",
"componentType": "WebPart",
// The "*" signifies that the version should be taken from the package.json
@ -14,13 +14,13 @@
"requiresCustomScript": false,
"supportedHosts": ["SharePointWebPart", "SharePointFullPage", "TeamsTab"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
"groupId": "d91dd629-2857-4944-be9c-7cf65bcc693d",
"group": { "default": "Other" },
"title": { "default": "Birthdays Web Part" },
"description": { "default": "Birthdays Web Part" },
"title": { "default": "Birthdays & Anniversary Web Part" },
"description": { "default": "Birthdays & Anniversary Web Part" },
"officeFabricIconFontName": "BirthdayCake",
"properties": {
"title": "Birthdays",
"title": "Birthdays & Anniversaries",
"numberUpcomingDays": 5,
"template": 8
}

View File

@ -1,6 +1,5 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { PropertyFieldNumber } from '@pnp/spfx-property-controls/lib/PropertyFieldNumber';
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import {
@ -14,7 +13,7 @@ import {
import * as strings from 'BirthdaysWebPartStrings';
import Birthdays from './components/Birthdays';
import { IBirthdaysProps } from './components/IBirthdaysProps';
import { MSGraphClient } from '@microsoft/sp-http';
import { Version } from '@microsoft/sp-core-library';
export interface IBirthdaysWebPartProps {
title: string;
@ -120,10 +119,6 @@ export default class BirthdaysWebPart extends BaseClientSideWebPart<IBirthdaysWe
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
@ -144,7 +139,7 @@ export default class BirthdaysWebPart extends BaseClientSideWebPart<IBirthdaysWe
description: strings.NumberUpComingDaysLabel,
value: this.properties.numberUpcomingDays,
maxValue: 10,
minValue: 5,
minValue: 1,
disabled: false
}),
PropertyPaneChoiceGroup('template', {

View File

@ -80,7 +80,7 @@ export default class Birthdays extends React.Component<IBirthdaysProps, IBirthda
_otherMonthsBirthdays = [];
_dezemberBirthdays = [];
for (const item of listItems) {
this._users.push({ key: item.fields.email, userName: item.fields.Title, userEmail: item.fields.email, jobDescription: item.fields.JobTitle, birthday: moment.utc(item.fields.Birthday).local().format() });
this._users.push({ key: item.fields.email, userName: item.fields.Title, message: item.fields.message,anniversary: item.fields.anniversary, userEmail: item.fields.email, jobDescription: item.fields.JobTitle, birthday: moment.utc(item.fields.Birthday).local().format() });
}
// Sort Items by Birthday MSGraph List Items API don't support ODATA orderBy
// for end of year teste and sorting

View File

@ -1,21 +1,21 @@
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.2/MicrosoftTeams.schema.json",
"manifestVersion": "1.2",
"packageName": "HappyBirdthay",
"id": "e629ef30-a9ec-4713-b39a-2cfa8b323902",
"packageName": "HappyBirdthayAnniversary",
"id": "b0069b7e-8ec8-4e14-a76c-0c8bcb33993e",
"version": "0.1",
"developer": {
"name": "SPFx + Teams Dev",
"name": "SPFx + Teams Dev + Sajal Maity",
"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": "HappyBirdthay"
"short": "HappyBirthdayAnniversary"
},
"description": {
"short": "HappyBirdthay description",
"full": "HappyBirdthay description"
"short": "HappyBirdthay & anniversary description",
"full": "HappyBirdthay & anniversary description"
},
"icons": {
"outline": "tab20x20.png",
@ -24,7 +24,7 @@
"accentColor": "#004578",
"configurableTabs": [
{
"configurationUrl": "https://{teamSiteDomain}{teamSitePath}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx%3FopenPropertyPane=true%26teams%26componentId=e629ef30-a9ec-4713-b39a-2cfa8b323902",
"configurationUrl": "https://{teamSiteDomain}{teamSitePath}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx%3FopenPropertyPane=true%26teams%26componentId=b0069b7e-8ec8-4e14-a76c-0c8bcb33993e",
"canUpdateConfiguration": false,
"scopes": [
"team"
@ -42,6 +42,6 @@
],
"webApplicationInfo": {
"resource": "https://{teamSiteDomain}",
"id": "00000003-0000-0ff1-ce00-000000000000"
"id": "16492248-a978-4d4b-bb85-c7557c1f2d19"
}
}