Skip to content

Commit

Permalink
Merge pull request #2936 from bcameron1231/v4-Calendars
Browse files Browse the repository at this point in the history
V4 calendars
  • Loading branch information
juliemturner authored Feb 23, 2024
2 parents 625c8c2 + 35803ab commit b920619
Show file tree
Hide file tree
Showing 8 changed files with 1,169 additions and 153 deletions.
497 changes: 458 additions & 39 deletions docs/graph/calendars.md

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions packages/graph/attachments/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,21 @@ export const Attachment = graphInvokableFactory<IAttachment>(_Attachment);
export class _Attachments extends _GraphCollection<IAttachmentType[]> {

// TODO: Adding attachments is not implemented correctly. I believe it requires updating the parent item but needs further investigation.

/**
* Add attachment to this collection
*
* @param name Name given to the attachment file
* @param attachmentInfo Attachment properties
* @param bytes File content
*/
public addFile(name: string, bytes: string | Blob): Promise<IAttachmentType> {
public addFile(attachmentInfo: IAttachmentType, bytes: string | Blob): Promise<IAttachmentType> {

return graphPost(GraphInstance(this), body(type("#microsoft.graph.fileAttachment", {
contentBytes: bytes,
name,
...attachmentInfo,
})));
}

}
export interface IAttachments extends _Attachments, IGetById<IAttachment> {}
export const Attachments = graphInvokableFactory<IAttachments>(_Attachments);
60 changes: 49 additions & 11 deletions packages/graph/calendars/funcs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { IGraphQueryable, GraphCollection, IGraphCollection } from "../graphqueryable.js";
import { EmailAddress, Event as IEvent } from "@microsoft/microsoft-graph-types";
import { Endpoint } from "../behaviors/endpoint.js";
import { body } from "@pnp/queryable/index.js";
import { IGraphQueryable, GraphCollection, IGraphCollection, IGraphInstance, graphPost } from "../graphqueryable.js";
import {
EmailAddress,
Event as IEvent,
Reminder as IReminder,
MeetingTimeSuggestionsResult,
LocationConstraint, TimeConstraint,
AttendeeBase,
} from "@microsoft/microsoft-graph-types";
import { CalendarView, ICalendarView } from "./types.js";

interface IEventWithTag extends IEvent {
"@odata.etag": string;
}

export interface IFindMeetingTimesRequest{
attendees?: AttendeeBase[];
locationConstraint?: LocationConstraint;
timeConstraint?: TimeConstraint;
meetingDuration?: string;
maxCandidates?: number;
isOrganizerOptional?: boolean;
returnSuggestionReasons?: boolean;
minimumAttendeePercentage?: number;
}

/**
* Get the occurrences, exceptions, and single instances of events in a calendar view defined by a time range,
* from the user's default calendar, or from some other calendar of the user's
Expand All @@ -14,26 +33,30 @@ interface IEventWithTag extends IEvent {
* @param start start time
* @param end end time
*/
export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphCollection<ICalendarViewInfo[]> {

const query = GraphCollection(this, "calendarView");
query.query.set("startDateTime", start);
query.query.set("endDateTime", end);
return query;
export function calendarView(this: IGraphQueryable, start: string, end: string): ICalendarView {
return CalendarView(this, start, end);
}

export type ICalendarViewInfo = IEventWithTag;

/**
* Suggest meeting times and locations based on organizer and attendee availability, and time or location constraints specified as parameters.
* @param this IGraphQueryable instance
* @param properties The body of the meetingTimeSuggestionsRequest resource that contains the parameters for the operation.
*/
export async function findMeetingTimes(this: IGraphQueryable, properties?: IFindMeetingTimesRequest): Promise<IGraphInstance<MeetingTimeSuggestionsResult>> {
return graphPost(GraphCollection(this,"findMeetingTimes"), body(properties));
}

/**
* Get the emailAddress objects that represent all the meeting rooms in the user's tenant or in a specific room list.
* - This is a beta graph feature and uses the beta endpoint.
*
* @param this IGraphQueryable instance
* @param roomList The SMTP address associated with the room list.
*/
export function findRooms(this: IGraphQueryable, roomList?: string): IGraphCollection<EmailAddress[]> {
const query = GraphCollection(this, roomList ? "findRooms(RoomList=@roomList)" : "findRooms");
query.using(Endpoint("beta"));
if (roomList) {
query.query.set("@roomList", `'${roomList}'`);
}
Expand All @@ -56,3 +79,18 @@ export function instances(this: IGraphQueryable, start: string, end: string): IG
}

export type IInstance = IEventWithTag;

/**
* Get the list of event remindres defined by a time range,
*
* @param this IGraphQueryable instance
* @param start start time
* @param end end time
*/
export function reminderView(this: IGraphQueryable, start: string, end: string): IGraphCollection<IReminderInfo[]> {

const query = GraphCollection(this, `reminderView(startDateTime='${start}',endDateTime='${end}')`);
return query;
}

export type IReminderInfo = IReminder;
6 changes: 5 additions & 1 deletion packages/graph/calendars/groups.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { addProp } from "@pnp/queryable";
import { _Group } from "../groups/types.js";
import { Calendar, ICalendar, IEvents, Events } from "./types.js";
import { Calendar, ICalendar, IEvents, Events, ICalendarView } from "./types.js";
import { calendarView } from "./funcs.js";

declare module "../groups/types" {
interface _Group {
readonly calendar: ICalendar;
readonly attachmentFiles: ICalendar;
readonly events: IEvents;
calendarView(start: string, end: string): ICalendarView;
}
interface IGroup {
readonly calendar: ICalendar;
readonly attachmentFiles: ICalendar;
readonly events: IEvents;
calendarView(start: string, end: string): ICalendarView;
}
}

addProp(_Group, "calendar", Calendar);
addProp(_Group, "events", Events);
_Group.prototype.calendarView = calendarView;
18 changes: 13 additions & 5 deletions packages/graph/calendars/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ import "./users.js";
export {
Calendar,
Calendars,
CalendarGroup,
CalendarGroups,
CalendarPermission,
CalendarPermissions,
CalendarView,
Event,
IEventAddResult,
Events,
ICalendar,
ICalendars,
ICalendarGroup,
ICalendarGroups,
ICalendarPermission,
ICalendarPermissions,
ICalendarView,
IEvent,
IEvents,
IEventAddResult,
IForwardEvent,
IGetScheduleRequest,
} from "./types.js";

export {
ICalendarViewInfo,
} from "./funcs.js";
162 changes: 139 additions & 23 deletions packages/graph/calendars/types.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,115 @@
import { body } from "@pnp/queryable";
import { Event as IEventType, Calendar as ICalendarType } from "@microsoft/microsoft-graph-types";
import { _GraphCollection, _GraphInstance, graphInvokableFactory, graphPost } from "../graphqueryable.js";
import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById } from "../decorators.js";
import {
Event as IEventType,
Calendar as ICalendarType,
CalendarGroup as ICalendarGroupType,
CalendarPermission as ICalendarPermissionType,
ScheduleInformation as IScheduleInformationType,
DateTimeTimeZone as IDateTimeTimeZoneType,
Recipient,
TimeSlot,
} from "@microsoft/microsoft-graph-types";
import { GraphQueryable, IGraphQueryable, _GraphCollection, _GraphInstance, _GraphQueryable, graphInvokableFactory, graphPost } from "../graphqueryable.js";
import { defaultPath, IDeleteable, deleteable, IUpdateable, updateable, getById, IGetById, IAddable, addable } from "../decorators.js";
import { calendarView, instances } from "./funcs.js";

/**
* Calendar
*/
@deleteable()
@updateable()
export class _Calendar extends _GraphInstance<ICalendarType> {

public calendarView = calendarView;

public get calendarPermissions(): ICalendarPermissions {
return CalendarPermissions(this);
}
public get events(): IEvents {
return Events(this);
}

public calendarView = calendarView;
/**
* Get the free/busy availability information for a collection of users,
* distributions lists, or resources (rooms or equipment) for a specified time period.
*
* @param properties The set of properties used to get the schedule
*/
public async getSchedule(properties: IGetScheduleRequest): Promise<IScheduleInformationType[]> {
return graphPost(Calendar(this, "getSchedule"), body(properties));
}
}
export interface ICalendar extends _Calendar { }
export interface ICalendar extends _Calendar, IUpdateable<ICalendarType>, IDeleteable { }
export const Calendar = graphInvokableFactory<ICalendar>(_Calendar);

/**
* Calendars
*/
@defaultPath("calendars")
@getById(Calendar)
export class _Calendars extends _GraphCollection<ICalendarType[]> { }
export interface ICalendars extends _Calendars, IGetById<ICalendar> { }
@addable()
export class _Calendars extends _GraphCollection<ICalendarType[]> {}
export interface ICalendars extends _Calendars, IGetById<ICalendar>, IAddable<ICalendarType> { }
export const Calendars = graphInvokableFactory<ICalendars>(_Calendars);

/**
* CalendarView
*/
export class _CalendarView extends _GraphCollection<IEventType[]> {
constructor(baseUrl: string | _GraphQueryable, start: string, end: string) {
super(baseUrl, "calendarView");
this.query.set("startDateTime", start);
this.query.set("endDateTime", end);
}

public async delta(token?: string): Promise<IEventType[]> {
return graphPost(GraphQueryable(this, `delta?${this.query}`), body({ token }));
}
}
export interface ICalendarView extends _CalendarView { }
export const CalendarView = (baseUrl: string | IGraphQueryable, start: string, end: string): _CalendarView => new _CalendarView(baseUrl, start, end);

/**
* Event
*/
@deleteable()
@updateable()
export class _Event extends _GraphInstance<IEventType> {
public instances = instances;

public async accept(comment?: string, sendResponse?: boolean): Promise<void> {
return graphPost(Event(this, "accept"), body({ comment, sendResponse }));
}

public async cancel(comment?: string): Promise<void> {
return graphPost(Event(this, "cancel"), body({ comment }));
}

public async decline(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise<void> {
if (proposedNewTime) {
sendResponse = true;
}
return graphPost(Event(this, "decline"), body({ comment, sendResponse, proposedNewTime }));
}

public async dismissReminder(): Promise<void> {
return graphPost(Event(this, "dismissReminder"));
}

public async forward(fowardEventInfo: IForwardEvent): Promise<void> {
return graphPost(Event(this, "forward"), body(fowardEventInfo));
}

public async snoozeReminder(reminderTime: IDateTimeTimeZoneType): Promise<void> {
return graphPost(Event(this, "snoozeReminder"), body({ newReminderTime: reminderTime }));
}

public async tentativelyAccept(comment?: string, sendResponse?: boolean, proposedNewTime?: TimeSlot): Promise<void> {
if (proposedNewTime) {
sendResponse = true;
}
return graphPost(Event(this, "tentativelyAccept"), body({ comment, sendResponse, proposedNewTime }));
}

}
export interface IEvent extends _Event, IDeleteable, IUpdateable { }
export const Event = graphInvokableFactory<IEvent>(_Event);
Expand All @@ -43,25 +119,53 @@ export const Event = graphInvokableFactory<IEvent>(_Event);
*/
@defaultPath("events")
@getById(Event)
export class _Events extends _GraphCollection<IEventType[]> {

/**
* Adds a new event to the collection
*
* @param properties The set of properties used to create the event
*/
public async add(properties: IEventType): Promise<IEventAddResult> {
@addable()
export class _Events extends _GraphCollection<IEventType[]> { }
export interface IEvents extends _Events, IGetById<IEvent>, IAddable<IEventType, IEventType> { }
export const Events = graphInvokableFactory<IEvents>(_Events);

const data = await graphPost(this, body(properties));
/**
* Event
*/
@deleteable()
@updateable()
export class _CalendarGroup extends _GraphInstance<ICalendarGroupType> {

return {
data,
event: (<any>this).getById(data.id),
};
public get calendars(): ICalendars {
return Calendars(this);
}
}
export interface IEvents extends _Events, IGetById<IEvent> { }
export const Events = graphInvokableFactory<IEvents>(_Events);
export interface ICalendarGroup extends _CalendarGroup, IDeleteable, IUpdateable { }
export const CalendarGroup = graphInvokableFactory<ICalendarGroup>(_CalendarGroup);

/**
* CalendarGroups
*/
@defaultPath("calendarGroups")
@getById(CalendarGroup)
@addable()
export class _CalendarGroups extends _GraphCollection<ICalendarGroupType[]> { }
export interface ICalendarGroups extends _Events, IGetById<ICalendarGroup>, IAddable<ICalendarGroupType, ICalendarGroupType> { }
export const CalendarGroups = graphInvokableFactory<ICalendarGroups>(_CalendarGroups);

/**
* CalendarPermission
*/
@updateable()
@deleteable()
export class _CalendarPermission extends _GraphInstance<ICalendarPermissionType> { }
export interface ICalendarPermission extends _CalendarPermission, IUpdateable, IDeleteable { }
export const CalendarPermission = graphInvokableFactory<ICalendarPermission>(_CalendarPermission);

/**
* CalendarPermissions
*/
@defaultPath("calendarPermissions")
@getById(CalendarPermission)
@addable()
export class _CalendarPermissions extends _GraphCollection<ICalendarPermissionType[]> { }
export interface ICalendarPermissions extends _CalendarPermissions, IGetById<ICalendarPermission>, IAddable<ICalendarPermissionType, ICalendarPermissionType> { }
export const CalendarPermissions = graphInvokableFactory<ICalendarPermissions>(_CalendarPermissions);

/**
* EventAddResult
Expand All @@ -70,3 +174,15 @@ export interface IEventAddResult {
data: IEventType;
event: IEvent;
}

export interface IForwardEvent {
Comment?: string;
ToRecipients: Recipient[];
}

export interface IGetScheduleRequest {
schedules: string[];
startTime: IDateTimeTimeZoneType;
endTime: IDateTimeTimeZoneType;
availabilityViewInterval?: number;
}
Loading

0 comments on commit b920619

Please sign in to comment.