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

V4 calendars #2936

Merged
merged 7 commits into from
Feb 23, 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
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
Loading