Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React calendar - Added category component to filter events #5176

Merged
merged 3 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/react-calendar/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v14.17.6
v12.13.0
1 change: 1 addition & 0 deletions samples/react-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Version|Date|Comments
1.0.16|December 21, 2021|Upgraded to SPFx 1.12.1
1.0.17|October 25, 2022|Fixed issue deleting events (#2693)
1.0.18|December 29, 2022|Fixed stylelint issue (#4029)| Cleaned up old Type script versions and Upgraded Type script version
1.0.19|June 28, 2024| added filter by category | fixed the packages.json issues which prevent solution to build successfully.

## Minimal Path to Awesome

Expand Down
2 changes: 1 addition & 1 deletion samples/react-calendar/assets/sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"This Web Part allows you to manage events in a calendar. Uses a list of existing calendars on any website. The location and name of the list and the dates of the events to be displayed are defined in the properties of the web part."
],
"creationDateTime": "2020-12-04",
"updateDateTime": "2023-12-29",
"updateDateTime": "2024-06-28",
"products": [
"SharePoint"
],
Expand Down
2 changes: 1 addition & 1 deletion samples/react-calendar/config/package-solution.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"solution": {
"name": "react-calendar-client-side-solution",
"id": "3a13208b-3874-4036-9262-4edd22e88187",
"version": "1.0.18.0",
"version": "1.0.19.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false
Expand Down
10 changes: 3 additions & 7 deletions samples/react-calendar/config/serve.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
"port": 4321,
"https": true,
"initialPage": "https://localhost:5432/workbench",
"api": {
"port": 5432,
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
}
}
"initialPage": "https://cotoso.sharepoint.com/_layouts/workbench.aspx"
}
65,917 changes: 23,741 additions & 42,176 deletions samples/react-calendar/package-lock.json

Large diffs are not rendered by default.

33 changes: 20 additions & 13 deletions samples/react-calendar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"main": "lib/index.js",
"version": "1.0.12",
"private": true,
"engines": {
"node": ">=12.13.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
Expand All @@ -23,48 +26,52 @@
"@pnp/spfx-property-controls": "1.14.1",
"@types/draft-js": "^0.10.30",
"@types/globalize": "0.0.34",
"@types/jquery": "^3.3.29",
"@types/jquery": "3.5.30",
"@types/react-big-calendar": "^0.24.6",
"@uifabric/fluent-theme": "^0.16.7",
"browserslist": "^4.12.0",
"browserslist": "4.23.1",
"draft-js": "^0.10.5",
"draftjs-to-html": "^0.8.4",
"globalize": "^1.4.2",
"immutable": "^4.0.0-rc.12",
"jquery": "^3.5.0",
"moment": "^2.29.2",
"immutable": "4.3.6",
"jquery": "3.7.1",
"moment": "2.30.1",
"office-ui-fabric-react": "7.156.0",
"react": "16.9.0",
"react-big-calendar": "^0.24.6",
"react-dom": "16.9.0",
"react-draft-wysiwyg": "^1.13.2",
"react-draft-wysiwyg": "1.15.0",
"react-select": "^4.3.1",
"spfx-uifabric-themes": "^0.6.0",
"string-format": "^2.0.0",
"typescript": "^3.2.4",
"xml2js": "^0.5.0"
"typescript": "3.9.10",
"xml2js": "^0.4.19"
},
"resolutions": {
"@types/react": "16.7.22"
},
"devDependencies": {
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
"@microsoft/sp-build-web": "1.18.2",
"@microsoft/sp-build-web": "1.12.1",
"@microsoft/sp-module-interfaces": "1.12.1",
"@microsoft/sp-tslint-rules": "1.12.1",
"@microsoft/sp-webpart-workbench": "1.12.1",
"@types/es6-promise": "0.0.33",
"@types/react": "16.9.36",
"@types/react-dom": "16.9.8",
"@types/webpack-env": "1.13.1",
"@types/xml2js": "^0.4.4",
"@types/xml2js": "0.4.14",
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
"ajv": "~5.2.2",
"gulp": "4.0.2",
"gulp-sequence": "1.0.0",
"gulp-stylelint": "^8.0.0",
"jest": "^23.6.0",
"karma-junit-reporter": "^1.2.0",
"spfx-uifabric-themes": "^0.6.0",
"tslint-microsoft-contrib": "6.2.0",
"stylelint": "^9.10.1",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.5.4",
"tslint": "^6.1.3",
"tslint-microsoft-contrib": "^6.2.0",
"webpack-bundle-analyzer": "^3.1.0"
},
"solution": {
Expand Down
73 changes: 73 additions & 0 deletions samples/react-calendar/src/common/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as strings from "CalendarWebPartStrings";
import { IDatePickerStrings } from "office-ui-fabric-react";

export const Constants = {
CategoryColumn: "Category",
MetaDataFieldType: "SP.Taxonomy.TaxonomyFieldValue",
EventResult_LocalStorage: "eventResult",
CalendarEventsWithLocalTime_LocalStorage: "calendarEventsWithLocalTime",
AndConditionStart: "<And>",
AndConditionEnd: "</And>",
OrConditionStart: "<Or>",
OrConditionEnd: "</Or>",
latitude: 58.485601,
longitude: 19.807854,
eventLayoutOverviewPageURL: `{0}/_layouts/15/Event.aspx?ListGuid={1}&ItemId={2}`
};

export const DayPickerStrings: IDatePickerStrings = {
months: [
strings.January,
strings.February,
strings.March,
strings.April,
strings.May,
strings.June,
strings.July,
strings.August,
strings.September,
strings.October,
strings.November,
strings.December,
],
shortMonths: [
strings.Jan,
strings.Feb,
strings.Mar,
strings.Apr,
strings.May,
strings.Jun,
strings.Jul,
strings.Aug,
strings.Sep,
strings.Oct,
strings.Nov,
strings.Dez,
],
days: [
strings.Sunday,
strings.Monday,
strings.Tuesday,
strings.Wednesday,
strings.Thursday,
strings.Friday,
strings.Saturday,
],
shortDays: [
strings.ShortDay_S,
strings.ShortDay_M,
strings.ShortDay_T,
strings.ShortDay_W,
strings.ShortDay_Thursday,
strings.ShortDay_Friday,
strings.ShortDay_Sunday,
],
goToToday: strings.GoToDay,
prevMonthAriaLabel: strings.PrevMonth,
nextMonthAriaLabel: strings.NextMonth,
prevYearAriaLabel: strings.PrevYear,
nextYearAriaLabel: strings.NextYear,
closeButtonAriaLabel: strings.CloseDate,
isRequiredErrorMessage: strings.IsRequired,
invalidInputErrorMessage: strings.InvalidDateFormat,
};
4 changes: 4 additions & 0 deletions samples/react-calendar/src/services/IOption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IOption {
key: string;
text: string;
}
104 changes: 86 additions & 18 deletions samples/react-calendar/src/services/spservices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import * as moment from 'moment';
import { SiteUser } from "@pnp/sp/src/siteusers";
import { IUserPermissions } from './IUserPermissions';
import parseRecurrentEvent from './parseRecurrentEvent';
import { IComboBoxOption } from '@fluentui/react';
import { Constants } from "../common/Constants";
import { Text } from "@microsoft/sp-core-library";

// Class Services
export default class spservices {
Expand Down Expand Up @@ -450,7 +453,7 @@ export default class spservices {
* @returns {Promise< IEventData[]>}
* @memberof spservices
*/
public async getEvents(siteUrl: string, listId: string, eventStartDate: Date, eventEndDate: Date): Promise<IEventData[]> {
public async getEvents(siteUrl: string, listId: string, eventStartDate: Date, eventEndDate: Date, categories: IComboBoxOption[]): Promise<IEventData[]> {

let events: IEventData[] = [];
if (!siteUrl) {
Expand All @@ -463,28 +466,13 @@ export default class spservices {
for (const cat of categoryDropdownOption) {
categoryColor.push({ category: cat.text, color: await this.colorGenerate() });
}
let camlQueryExpression = this.setUpQueryExpression(eventStartDate, eventEndDate, categories);

const web = new Web(siteUrl);
const results = await web.lists.getById(listId).usingCaching().renderListDataAsStream(
{
DatesInUtc: true,
ViewXml: `<View><ViewFields><FieldRef Name='RecurrenceData'/><FieldRef Name='Duration'/><FieldRef Name='Author'/><FieldRef Name='Category'/><FieldRef Name='Description'/><FieldRef Name='ParticipantsPicker'/><FieldRef Name='Geolocation'/><FieldRef Name='ID'/><FieldRef Name='EndDate'/><FieldRef Name='EventDate'/><FieldRef Name='ID'/><FieldRef Name='Location'/><FieldRef Name='Title'/><FieldRef Name='fAllDayEvent'/><FieldRef Name='EventType'/><FieldRef Name='UID' /><FieldRef Name='fRecurrence' /></ViewFields>
<Query>
<Where>
<And>
<Geq>
<FieldRef Name='EventDate' />
<Value IncludeTimeValue='false' Type='DateTime'>${moment(eventStartDate).format('YYYY-MM-DD')}</Value>
</Geq>
<Leq>
<FieldRef Name='EventDate' />
<Value IncludeTimeValue='false' Type='DateTime'>${moment(eventEndDate).format('YYYY-MM-DD')}</Value>
</Leq>
</And>
</Where>
</Query>
<RowLimit Paged=\"FALSE\">2000</RowLimit>
</View>`
ViewXml: camlQueryExpression
}
);

Expand Down Expand Up @@ -571,6 +559,86 @@ export default class spservices {
}
}

/**
*
* @private
* @param {Date} eventStartDate
* @param {Date} eventEndDate
* @param {IOption[]} departments
* @returns {string} camlQuery
* @memberof spservices
*/
private setUpQueryExpression(
eventStartDate: Date,
eventEndDate: Date,
categories: IComboBoxOption[]
) {
let camlQuery = `
<View>
<ViewFields>
<FieldRef Name='RecurrenceData'/>
<FieldRef Name='Duration'/>
<FieldRef Name='Author'/>
<FieldRef Name='Category'/>
<FieldRef Name='Description'/>
<FieldRef Name='ParticipantsPicker'/>
<FieldRef Name='Geolocation'/>
<FieldRef Name='ID'/>
<FieldRef Name='EndDate'/>
<FieldRef Name='EventDate'/>
<FieldRef Name='Location'/>
<FieldRef Name='Title'/>
<FieldRef Name='fAllDayEvent'/>
<FieldRef Name='EventType'/>
<FieldRef Name='UID' />
<FieldRef Name='fRecurrence' />
</ViewFields>
<Query>
<Where>
<And>
<Geq>
<FieldRef Name='EventDate' />
<Value IncludeTimeValue='false' Type='DateTime'>${moment(eventStartDate).format("YYYY-MM-DD")}</Value>
</Geq>
{0}
<Leq>
<FieldRef Name='EventDate' />
<Value IncludeTimeValue='false' Type='DateTime'>${moment(eventEndDate).format("YYYY-MM-DD")}</Value>
</Leq>
{1}
{2}
</And>
</Where>
</Query>
<RowLimit Paged=\"FALSE\">2000</RowLimit>
</View>`;

let categoryCondition = `
<Eq>
<FieldRef Name='Category' />
<Value Type='Choice'>{0}</Value>
</Eq>`;

const deptsLength: number = categories.length;
let queryResult: string = "";

if (deptsLength > 0) {
if (deptsLength == 1) {
return Text.format(camlQuery, Constants.AndConditionStart, Text.format(categoryCondition, categories[0].key), Constants.AndConditionEnd);
} else {
let orCondition: string = `${Constants.OrConditionStart}{0}{1}${Constants.OrConditionEnd}`;
queryResult = Text.format(orCondition, Text.format(categoryCondition, categories[0].key), Text.format(categoryCondition, categories[1]));

for (let i = 2; i < categories.length; i++) {
const category = categories[i];
queryResult = Text.format(orCondition, Text.format(categoryCondition, category.key), queryResult);
}
}
return Text.format(camlQuery, Constants.AndConditionStart, queryResult, Constants.AndConditionEnd);
}
return Text.format(camlQuery, "", queryResult, "");
}

/**
*
* @private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
} from '@microsoft/sp-property-pane';

import * as strings from 'CalendarWebPartStrings';
import Calendar from './components/Calendar';
import { ICalendarProps } from './components/ICalendarProps';
import Calendar from './components/Calendar/Calendar';
import { ICalendarProps } from './components/Calendar/ICalendarProps';
import { PropertyFieldDateTimePicker, DateConvention, TimeConvention, IDateTimeFieldValue } from '@pnp/spfx-property-controls/lib/PropertyFieldDateTimePicker';

import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
Expand Down Expand Up @@ -299,4 +299,4 @@ export default class CalendarWebPart extends BaseClientSideWebPart<ICalendarWebP
]
};
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
@import "~office-ui-fabric-react/dist/sass/References.scss";
@import "./node_modules/spfx-uifabric-themes/office.theme.vars";
@import "../../themes";
@import "../../../themes";

:export {
/* stylelint-disable property-case */
Expand Down
Loading
Loading