From fa8de53a12fcb76580a02a0496703b110178c638 Mon Sep 17 00:00:00 2001 From: Eli Date: Fri, 7 May 2021 21:33:48 +0200 Subject: [PATCH 1/5] Added local storage to avoid all the api-requests getting called on every refresh of the page. Which again could lead to throttling --- samples/react-calendar/package-lock.json | 2 +- .../src/webparts/calendar/components/Calendar.tsx | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/samples/react-calendar/package-lock.json b/samples/react-calendar/package-lock.json index e6ee108fd..72f9f73a5 100644 --- a/samples/react-calendar/package-lock.json +++ b/samples/react-calendar/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-calendar", - "version": "1.0.4", + "version": "1.0.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx b/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx index 03d86829d..52151075a 100644 --- a/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx +++ b/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx @@ -122,8 +122,17 @@ export default class Calendar extends React.Component Date: Mon, 10 May 2021 09:47:34 +0200 Subject: [PATCH 2/5] removed the localStorage thing again. If this is to be used I need to add a compare-function to make sure that new events are added to the local storage. --- .../src/webparts/calendar/components/Calendar.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx b/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx index 52151075a..1bb4a50fa 100644 --- a/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx +++ b/samples/react-calendar/src/webparts/calendar/components/Calendar.tsx @@ -123,16 +123,9 @@ export default class Calendar extends React.Component Date: Mon, 10 May 2021 12:42:56 +0200 Subject: [PATCH 3/5] Added save to local storage so that the api-calls to getLocalTime is not made for every event, on every refresh. No the code will first compare the results with the localStorage results - and if they are equal - use the local to display the event. If they are not equal, the for loop will run like before. WARNING: This triggers a bug in the 'week'-view. Have not fixed this yet --- .../react-calendar/src/services/spservices.ts | 119 ++++++++++-------- 1 file changed, 70 insertions(+), 49 deletions(-) diff --git a/samples/react-calendar/src/services/spservices.ts b/samples/react-calendar/src/services/spservices.ts index 7f916b5eb..ef9b791df 100644 --- a/samples/react-calendar/src/services/spservices.ts +++ b/samples/react-calendar/src/services/spservices.ts @@ -490,59 +490,80 @@ export default class spservices { if (results && results.Row.length > 0) { let event: any = ''; - - for (event of results.Row) { - const eventDate = await this.getLocalTime(event.EventDate); - const endDate = await this.getLocalTime(event.EndDate); - const initialsArray: string[] = event.Author[0].title.split(' '); - const initials: string = initialsArray[0].charAt(0) + initialsArray[initialsArray.length - 1].charAt(0); - const userPictureUrl = await this.getUserProfilePictureUrl(`i:0#.f|membership|${event.Author[0].email}`); - const attendees: number[] = []; - const first: number = event.Geolocation.indexOf('(') + 1; - const last: number = event.Geolocation.indexOf(')'); - const geo = event.Geolocation.substring(first, last); - const geolocation = geo.split(' '); - const CategoryColorValue: any[] = categoryColor.filter((value) => { - return value.category == event.Category; - }); - const isAllDayEvent: boolean = event["fAllDayEvent.value"] === "1"; + const mapEvents = async () : Promise => { + for (event of results.Row) { + const eventDate = await this.getLocalTime(event.EventDate); + const endDate = await this.getLocalTime(event.EndDate); + const initialsArray: string[] = event.Author[0].title.split(' '); + const initials: string = initialsArray[0].charAt(0) + initialsArray[initialsArray.length - 1].charAt(0); + const userPictureUrl = await this.getUserProfilePictureUrl(`i:0#.f|membership|${event.Author[0].email}`); + const attendees: number[] = []; + const first: number = event.Geolocation.indexOf('(') + 1; + const last: number = event.Geolocation.indexOf(')'); + const geo = event.Geolocation.substring(first, last); + const geolocation = geo.split(' '); + const CategoryColorValue: any[] = categoryColor.filter((value) => { + return value.category == event.Category; + }); + const isAllDayEvent: boolean = event["fAllDayEvent.value"] === "1"; - for (const attendee of event.ParticipantsPicker) { - attendees.push(parseInt(attendee.id)); + for (const attendee of event.ParticipantsPicker) { + attendees.push(parseInt(attendee.id)); + } + + events.push({ + Id: event.ID, + ID: event.ID, + EventType: event.EventType, + title: await this.deCodeHtmlEntities(event.Title), + Description: event.Description, + EventDate: isAllDayEvent ? new Date(event.EventDate.slice(0, -1)) : new Date(eventDate), + EndDate: isAllDayEvent ? new Date(event.EndDate.slice(0, -1)) : new Date(endDate), + location: event.Location, + ownerEmail: event.Author[0].email, + ownerPhoto: userPictureUrl ? + `https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=${event.Author[0].email}&UA=0&size=HR96x96` : '', + ownerInitial: initials, + color: CategoryColorValue.length > 0 ? CategoryColorValue[0].color : '#1a75ff', // blue default + ownerName: event.Author[0].title, + attendes: attendees, + fAllDayEvent: isAllDayEvent, + geolocation: { Longitude: parseFloat(geolocation[0]), Latitude: parseFloat(geolocation[1]) }, + Category: event.Category, + Duration: event.Duration, + RecurrenceData: event.RecurrenceData ? await this.deCodeHtmlEntities(event.RecurrenceData) : "", + fRecurrence: event.fRecurrence, + RecurrenceID: event.RecurrenceID ? event.RecurrenceID : undefined, + MasterSeriesItemID: event.MasterSeriesItemID, + UID: event.UID.replace("{", "").replace("}", ""), + }); + } + + let parseEvt: parseRecurrentEvent = new parseRecurrentEvent(); + events = parseEvt.parseEvents(events, null, null); + return true; + }; + //Checks to see if there are any results saved in local storage + if(window.localStorage.getItem("eventResult")){ + //if there is a local version - compares it to the current version + if(window.localStorage.getItem("eventResult") === JSON.stringify(results)){ + //No update needed use current savedEvents + events = JSON.parse(window.localStorage.getItem("calendarEventsWithLocalTime")); + }else{ + //update local storage + window.localStorage.setItem("eventResult", JSON.stringify(results)); + //when they are not equal then we loop through the results and maps them to IEventData + /* tslint:disable:no-unused-expression */ + await mapEvents() ? window.localStorage.setItem("calendarEventsWithLocalTime", JSON.stringify(events)) : null; } - - events.push({ - Id: event.ID, - ID: event.ID, - EventType: event.EventType, - title: await this.deCodeHtmlEntities(event.Title), - Description: event.Description, - EventDate: isAllDayEvent ? new Date(event.EventDate.slice(0, -1)) : new Date(eventDate), - EndDate: isAllDayEvent ? new Date(event.EndDate.slice(0, -1)) : new Date(endDate), - location: event.Location, - ownerEmail: event.Author[0].email, - ownerPhoto: userPictureUrl ? - `https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=${event.Author[0].email}&UA=0&size=HR96x96` : '', - ownerInitial: initials, - color: CategoryColorValue.length > 0 ? CategoryColorValue[0].color : '#1a75ff', // blue default - ownerName: event.Author[0].title, - attendes: attendees, - fAllDayEvent: isAllDayEvent, - geolocation: { Longitude: parseFloat(geolocation[0]), Latitude: parseFloat(geolocation[1]) }, - Category: event.Category, - Duration: event.Duration, - RecurrenceData: event.RecurrenceData ? await this.deCodeHtmlEntities(event.RecurrenceData) : "", - fRecurrence: event.fRecurrence, - RecurrenceID: event.RecurrenceID ? event.RecurrenceID : undefined, - MasterSeriesItemID: event.MasterSeriesItemID, - UID: event.UID.replace("{", "").replace("}", ""), - }); + }else{ + //if there is no local storage of the events we create them + window.localStorage.setItem("eventResult", JSON.stringify(results)); + //we also needs to map through the events the first time and save the mapped version to local storage + await mapEvents() ? window.localStorage.setItem("calendarEventsWithLocalTime", JSON.stringify(events)) : null; } - - let parseEvt: parseRecurrentEvent = new parseRecurrentEvent(); - events = parseEvt.parseEvents(events, null, null); } - + // Return Data return events; } catch (error) { From 894ed03ca08b9e05075fcaa987742d386b378b66 Mon Sep 17 00:00:00 2001 From: Eli Date: Mon, 10 May 2021 13:12:59 +0200 Subject: [PATCH 4/5] Moved the recurrent event parsing further down in the function, and now the week-view seems to work fine again --- samples/react-calendar/src/services/spservices.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/react-calendar/src/services/spservices.ts b/samples/react-calendar/src/services/spservices.ts index ef9b791df..08559d591 100644 --- a/samples/react-calendar/src/services/spservices.ts +++ b/samples/react-calendar/src/services/spservices.ts @@ -538,9 +538,6 @@ export default class spservices { UID: event.UID.replace("{", "").replace("}", ""), }); } - - let parseEvt: parseRecurrentEvent = new parseRecurrentEvent(); - events = parseEvt.parseEvents(events, null, null); return true; }; //Checks to see if there are any results saved in local storage @@ -563,6 +560,8 @@ export default class spservices { await mapEvents() ? window.localStorage.setItem("calendarEventsWithLocalTime", JSON.stringify(events)) : null; } } + let parseEvt: parseRecurrentEvent = new parseRecurrentEvent(); + events = parseEvt.parseEvents(events, null, null); // Return Data return events; From 65703eace0f66c8b23bf4b72953739206203b54d Mon Sep 17 00:00:00 2001 From: Hugo Bernier Date: Wed, 19 May 2021 23:27:40 -0400 Subject: [PATCH 5/5] Updated readme and sample.json --- samples/react-calendar/README.md | 36 ++++++++++++++++------- samples/react-calendar/assets/sample.json | 4 +++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/samples/react-calendar/README.md b/samples/react-calendar/README.md index 741cac615..0c556e8c5 100644 --- a/samples/react-calendar/README.md +++ b/samples/react-calendar/README.md @@ -114,12 +114,13 @@ The Web Part Use PnPjs library, Office-ui-fabric-react components. react Big-Cal Solution|Author(s) --------|--------- -Calendar Web PArt|[Mohammed Amer](https://www.linkedin.com/in/mohammad3mer/) ([@https://twitter.com/Mohammad3mer](https://twitter.com/Mohammad3mer)) -Calendar Web Part|Abderahman Moujahid -Calendar Web Part|Hugo Bernier ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/)) -Calendar Web Part|João Mendes -Calendar Web Part|Mohamed Derhalli -Calendar Web Part|Nanddeep Nachan ([@NanddeepNachan](https://twitter.com/NanddeepNachan)) +Calendar Web Part|[Abderahman Moujahid](https://github.com/Abderahman88) +Calendar Web Part|[Eli H. Schei](https://github.com/Eli-Schei) +Calendar Web Part|[Hugo Bernier](https://github.com/hugoabernier) ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/)) +Calendar Web Part|[João Mendes](https://github.com/joaojmendes) +Calendar Web Part|[Mohamed Derhalli](https://github.com/derhallim) +Calendar Web PArt|[Mohammed Amer](https://www.linkedin.com/in/mohammad3mer/) ([@Mohammad3mer](https://twitter.com/Mohammad3mer)) +Calendar Web Part|[Nanddeep Nachan](https://github.com/nanddeepn) ([@NanddeepNachan](https://twitter.com/NanddeepNachan)) ## Version history @@ -136,12 +137,8 @@ Version|Date|Comments 1.0.8|December 24, 2020|Fixed timezone difference (#1646) 1.0.9|March 16, 2021|Fixed issue deleting events (#1773) 1.0.10|March 27, 2021|Updated prompt message when deleting single v/s multi-event. +1.0.11|May 10, 2021|Optimized page refresh using local storage -## 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 @@ -153,4 +150,21 @@ Version|Date|Comments - `gulp package-solution --ship` - Add to **AppCatalog** and deploy +## 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.** + + +## Support + +We do not support samples, but we do use GitHub to track issues and constantly want to improve these samples. + +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-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%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-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%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-calendar&authors=@Abderahman88,%20@Eli-Schei,%20@hugoabernier,%20@joaojmendes,%20@derhallim,%20@nanddeepn,%20@mohammadamer&title=react-calendar%20-%20). + + + diff --git a/samples/react-calendar/assets/sample.json b/samples/react-calendar/assets/sample.json index 285c2abe2..96e90ab38 100644 --- a/samples/react-calendar/assets/sample.json +++ b/samples/react-calendar/assets/sample.json @@ -200,6 +200,10 @@ "pictureUrl": "https://avatars.githubusercontent.com/u/19314043?s=460&u=79acb7fd0ad466e1040ddd8a739fa93385018b81&v=4", "name": "Mohammed Amer", "twitter": "Mohammad3mer" + }, { + "gitHubAccount": "Eli-Schei", + "name": "Eli H. Schei", + "pictureUrl": "https://github.com/Eli-Schei" } ], "references": [