Skip to content

Commit

Permalink
feat: Add recurrenceRule field resolver, and more recurrence proper…
Browse files Browse the repository at this point in the history
…ties (PalisadoesFoundation#2095)

* add interval to recurrence rule

* add test for recurrence interval

* add bysetpos to recurrenceRule

* add tests for bysetpos

* add recurrenceRule field and field resolver to the event schema

* fix linting

* test
meetulr authored Mar 25, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 4121616 commit 802d7d6
Showing 15 changed files with 604 additions and 144 deletions.
2 changes: 2 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
@@ -93,6 +93,8 @@ const config: CodegenConfig = {

Post: "../models/Post#InterfacePost",

RecurrenceRule: "../models/RecurrenceRule#InterfaceRecurrenceRule",

UserTag: "../models/OrganizationTagUser#InterfaceOrganizationTagUser",

User: "../models/User#InterfaceUser",
27 changes: 19 additions & 8 deletions schema.graphql
Original file line number Diff line number Diff line change
@@ -604,6 +604,7 @@ type Event {
longitude: Longitude
organization: Organization
recurrance: Recurrance
recurrenceRule: RecurrenceRule
recurring: Boolean!
startDate: Date!
startTime: Time
@@ -1404,9 +1405,19 @@ enum Recurrance {
YEARLY
}

type RecurrenceRule {
count: PositiveInt
frequency: Frequency
interval: PositiveInt
weekDayOccurenceInMonth: Int
weekDays: [WeekDays]
}

input RecurrenceRuleInput {
count: Int
count: PositiveInt
frequency: Frequency
interval: PositiveInt
weekDayOccurenceInMonth: Int
weekDays: [WeekDays]
}

@@ -1839,13 +1850,13 @@ input VenueInput {
}

enum WeekDays {
FR
MO
SA
SU
TH
TU
WE
FRIDAY
MONDAY
SATURDAY
SUNDAY
THURSDAY
TUESDAY
WEDNESDAY
}

input createChatInput {
10 changes: 10 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -703,6 +703,16 @@ export const RECURRENCE_WEEKDAYS = [
"SUNDAY",
];

export const RECURRENCE_WEEKDAYS_MAPPING = {
MONDAY: "MO",
TUESDAY: "TU",
WEDNESDAY: "WE",
THURSDAY: "TH",
FRIDAY: "FR",
SATURDAY: "SA",
SUNDAY: "SU",
};

export const key = ENV.ENCRYPTION_KEY as string;
export const iv = crypto.randomBytes(16).toString("hex");

14 changes: 11 additions & 3 deletions src/helpers/event/recurringEventHelpers/createRecurrenceRule.ts
Original file line number Diff line number Diff line change
@@ -33,7 +33,10 @@ export const createRecurrenceRule = async (
): Promise<InterfaceRecurrenceRule> => {
const recurrenceRuleObject = rrulestr(recurrenceRuleString);

const { freq, byweekday } = recurrenceRuleObject.options;
const { freq, byweekday, interval, count, bysetpos } =
recurrenceRuleObject.options;

const frequency = RECURRENCE_FREQUENCIES[freq];

const weekDays: string[] = [];
if (byweekday) {
@@ -42,7 +45,10 @@ export const createRecurrenceRule = async (
}
}

const frequency = RECURRENCE_FREQUENCIES[freq];
let weekDayOccurenceInMonth = undefined;
if (bysetpos?.length) {
weekDayOccurenceInMonth = bysetpos[0];
}

const recurrenceRule = await RecurrenceRule.create(
[
@@ -53,8 +59,10 @@ export const createRecurrenceRule = async (
startDate: recurrenceStartDate,
endDate: recurrenceEndDate,
frequency,
count: recurrenceRuleObject.options.count,
weekDays,
interval,
count,
weekDayOccurenceInMonth,
latestInstanceDate,
},
],
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RECURRENCE_WEEKDAYS_MAPPING } from "../../../constants";
import type { RecurrenceRuleInput } from "../../../types/generatedGraphQLTypes";
import { convertToRRuleDateString } from "../../../utilities/recurrenceDatesUtil";

@@ -28,10 +29,20 @@ export const generateRecurrenceRuleString = (
}

// destructure the recurrence rules
const { frequency, count, weekDays } = recurrenceRuleData;
const { frequency, weekDays, interval, count, weekDayOccurenceInMonth } =
recurrenceRuleData;

// get weekdays for recurrence rule string, i.e. "MO", "TU", etc.
const recurrenceWeekDays = weekDays?.map((weekDay) => {
if (weekDay) {
return RECURRENCE_WEEKDAYS_MAPPING[weekDay];
}
});

// string representing the days of the week the event would recur
const weekDaysString = weekDays?.length ? weekDays.join(",") : "";
const weekDaysString = recurrenceWeekDays?.length
? recurrenceWeekDays.join(",")
: "";

// initiate recurrence rule string
let recurrenceRuleString = `DTSTART:${recurrenceStartDateString}\nRRULE:FREQ=${frequency}`;
@@ -40,11 +51,22 @@ export const generateRecurrenceRuleString = (
recurrenceRuleString += `;UNTIL=${recurrenceEndDateString}`;
}

if (interval) {
// interval of recurrence
recurrenceRuleString += `;INTERVAL=${interval}`;
}

if (count) {
// maximum number of instances to generate
recurrenceRuleString += `;COUNT=${count}`;
}

if (weekDayOccurenceInMonth) {
// occurence of week day in month
// i.e. 1 = first monday, 3 = third monday, -1 = last monday
recurrenceRuleString += `;BYSETPOS=${weekDayOccurenceInMonth}`;
}

if (weekDaysString) {
recurrenceRuleString += `;BYDAY=${weekDaysString}`;
}
25 changes: 19 additions & 6 deletions src/models/RecurrenceRule.ts
Original file line number Diff line number Diff line change
@@ -31,8 +31,10 @@ export interface InterfaceRecurrenceRule {
startDate: Date;
endDate: Date;
frequency: Frequency;
count: number;
weekDays: WeekDays[];
interval: number;
count: number;
weekDayOccurenceInMonth: number;
latestInstanceDate: Date;
}

@@ -44,8 +46,10 @@ export interface InterfaceRecurrenceRule {
* @param startDate - Start date of the recurrence pattern (not necessarily the startDate of the first recurring instance)
* @param endDate - Start date of the recurrence pattern (not necessarily the startDate of the last recurring instance)
* @param frequency - Frequency of recurrence
* @param count - Number of recurring instances
* @param weekDays - Array containing the days of the week the recurring instance occurs
* @param interval - Interval of recurrence (i.e. 1 = every week, 2 = every other week, etc.)
* @param count - Number of recurring instances
* @param weekDayOccurenceInMonth - Occurence of week day in the month (i.e. 1 = first monday, 3 = third monday, -1 = last monday)
* @param latestInstanceDate - The startDate of the last recurring instance generated using this recurrence rule
*/

@@ -78,15 +82,24 @@ const recurrenceRuleSchema = new Schema(
required: true,
enum: Object.values(Frequency),
},
count: {
type: Number,
required: false,
},
weekDays: { type: [String], required: true, enum: Object.values(WeekDays) },
latestInstanceDate: {
type: Date,
required: true,
},
interval: {
type: Number,
required: false,
default: 1,
},
count: {
type: Number,
required: false,
},
weekDayOccurenceInMonth: {
type: Number,
required: false,
},
},
{
timestamps: true,
2 changes: 2 additions & 0 deletions src/resolvers/Event/index.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import { feedback } from "./feedback";
import { organization } from "./organization";
import { actionItems } from "./actionItems";
import { creator } from "./creator";
import { recurrenceRule } from "./recurrenceRule";

export const Event: EventResolvers = {
actionItems,
@@ -15,4 +16,5 @@ export const Event: EventResolvers = {
feedback,
organization,
creator,
recurrenceRule,
};
16 changes: 16 additions & 0 deletions src/resolvers/Event/recurrenceRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { EventResolvers } from "../../types/generatedGraphQLTypes";
import { RecurrenceRule } from "../../models/RecurrenceRule";

/**
* This resolver function will fetch and return the recurrenceRule that the event is following.
* @param parent - An object that is the return value of the resolver for this field's parent.
* @returns An object that contains the RecurrenceRule of the event.
*/

export const recurrenceRule: EventResolvers["recurrenceRule"] = async (
parent,
) => {
return await RecurrenceRule.findOne({
_id: parent.recurrenceRuleId,
}).lean();
};
14 changes: 7 additions & 7 deletions src/typeDefs/enums.ts
Original file line number Diff line number Diff line change
@@ -118,13 +118,13 @@ export const enums = gql`
}
enum WeekDays {
MO
TU
WE
TH
FR
SA
SU
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
}
enum EducationGrade {
4 changes: 3 additions & 1 deletion src/typeDefs/inputs.ts
Original file line number Diff line number Diff line change
@@ -352,7 +352,9 @@ export const inputs = gql`
input RecurrenceRuleInput {
frequency: Frequency
weekDays: [WeekDays]
count: Int
interval: PositiveInt
count: PositiveInt
weekDayOccurenceInMonth: Int
}
input SocialMediaUrlsInput {
9 changes: 9 additions & 0 deletions src/typeDefs/types.ts
Original file line number Diff line number Diff line change
@@ -230,6 +230,7 @@ export const types = gql`
endTime: Time
allDay: Boolean!
recurring: Boolean!
recurrenceRule: RecurrenceRule
recurrance: Recurrance
isPublic: Boolean!
isRegisterable: Boolean!
@@ -519,6 +520,14 @@ export const types = gql`
pinned: Boolean
}
type RecurrenceRule {
frequency: Frequency
weekDays: [WeekDays]
interval: PositiveInt
count: PositiveInt
weekDayOccurenceInMonth: Int
}
type SocialMediaUrls {
facebook: String
instagram: String
Loading

0 comments on commit 802d7d6

Please sign in to comment.