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

[NO-ISSUE] feat: allow to query multiple users (freebusy) #26

Merged
Merged
Changes from 6 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
805f4e2
refactor: adapt/update js client
GuillaumeDecMeetsMore Jul 11, 2024
941e65f
chore: update justfile
GuillaumeDecMeetsMore Jul 11, 2024
d2234a7
ci: adapt JS client lib's CI
GuillaumeDecMeetsMore Jul 11, 2024
446f130
test: start adding integration tests for our use cases
GuillaumeDecMeetsMore Jul 11, 2024
0a4f16c
ci: fix actions/setup-node usage for pnpm
GuillaumeDecMeetsMore Jul 11, 2024
1f0bd04
ci: update actions + install pnpm
GuillaumeDecMeetsMore Jul 11, 2024
b1df0f7
ci: remove cache on actions/setup-node as it's pretty fast
GuillaumeDecMeetsMore Jul 11, 2024
cee3d0f
Merge branch 'guillaume/ci/adapt-js-client-ci' into guillaume/test/ad…
GuillaumeDecMeetsMore Jul 11, 2024
a08ea16
Merge branch 'master' into guillaume/test/add-integration-test-for-ou…
GuillaumeDecMeetsMore Jul 16, 2024
8bac479
test: add more tests to integration tests
GuillaumeDecMeetsMore Jul 17, 2024
10439cb
Merge branch 'master' into guillaume/test/add-integration-test-for-ou…
GuillaumeDecMeetsMore Jul 18, 2024
6800201
refactor: rename file + adapt requirements' tests
GuillaumeDecMeetsMore Jul 22, 2024
e556c34
feat(users): allow to provide external userId (uuid)
GuillaumeDecMeetsMore Jul 18, 2024
a08d635
chore: fix formatting
GuillaumeDecMeetsMore Jul 18, 2024
4626cf1
test(requirements): provide userUuid
GuillaumeDecMeetsMore Jul 22, 2024
6d1bf21
feat(js lib): add format + lint biome + fixes
GuillaumeDecMeetsMore Jul 22, 2024
47d560a
refactor: convert unix timestamps to datetimes
GuillaumeDecMeetsMore Jul 24, 2024
1e9d5af
Merge branch 'master' into guillaume/feat/user-allow-to-provide-exter…
GuillaumeDecMeetsMore Jul 25, 2024
0e37677
Merge branch 'guillaume/feat/user-allow-to-provide-external-user-uuid…
GuillaumeDecMeetsMore Jul 25, 2024
a56b001
Merge branch 'guillaume/feat/add-format-lint-via-biome' into guillaum…
GuillaumeDecMeetsMore Jul 25, 2024
515f73e
Merge branch 'master' into guillaume/refactor/convert-unix-timestamps…
GuillaumeDecMeetsMore Jul 25, 2024
8d0f7bd
fix: format & lint
GuillaumeDecMeetsMore Jul 25, 2024
dc66f27
Merge branch 'master' into guillaume/refactor/convert-unix-timestamps…
GuillaumeDecMeetsMore Jul 25, 2024
dc6757e
Merge branch 'master' into guillaume/refactor/convert-unix-timestamps…
GuillaumeDecMeetsMore Jul 26, 2024
f420558
fix: missing imports
GuillaumeDecMeetsMore Jul 26, 2024
11749f3
fix: format
GuillaumeDecMeetsMore Jul 26, 2024
57a181b
fix: make client lib return Dates
GuillaumeDecMeetsMore Jul 29, 2024
bd43e72
chore: add js docs to client lib
GuillaumeDecMeetsMore Jul 25, 2024
8f1bd7f
chore: add more JSDocs
GuillaumeDecMeetsMore Jul 25, 2024
ee5164a
feat: allow to query multiple calendars + allow to query on name + al…
GuillaumeDecMeetsMore Jul 29, 2024
c14dfc5
chore: remove debug logs
GuillaumeDecMeetsMore Jul 29, 2024
804da1c
feat: add query freebusy on multiple users + fix metadata
GuillaumeDecMeetsMore Jul 30, 2024
0f55a28
refactor: extract convertEventDates & convertInstanceDates
GuillaumeDecMeetsMore Jul 30, 2024
3861c55
chore: remove comment
GuillaumeDecMeetsMore Jul 30, 2024
72147a9
Merge branch 'guillaume/refactor/convert-unix-timestamps-to-datetimes…
GuillaumeDecMeetsMore Jul 30, 2024
9bdd463
Merge branch 'master' into guillaume/feat/add-js-docs-client-lib
GuillaumeDecMeetsMore Jul 30, 2024
5ff58a4
chore: add more comments
GuillaumeDecMeetsMore Jul 30, 2024
ba6229a
refactor: rework result of "freebusy of multiple users"
GuillaumeDecMeetsMore Jul 31, 2024
7f0b094
fix: client lib multiple freebusy
GuillaumeDecMeetsMore Jul 31, 2024
af390af
Merge branch 'guillaume/feat/add-js-docs-client-lib' into guillaume/f…
GuillaumeDecMeetsMore Jul 31, 2024
821a881
chore: remove duplicate requirements
GuillaumeDecMeetsMore Jul 31, 2024
1b8e859
Merge branch 'master' into guillaume/feat/allow-to-query-free-busy-mu…
GuillaumeDecMeetsMore Aug 5, 2024
9693b49
refactor: change multipleFreeBusy URL path
GuillaumeDecMeetsMore Aug 19, 2024
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
9 changes: 9 additions & 0 deletions scheduler/clients/javascript/lib/baseClient.ts
Original file line number Diff line number Diff line change
@@ -62,6 +62,9 @@ export abstract class NettuBaseClient {
}
}

/**
* Response from the API
*/
export class APIResponse<T> {
readonly data?: T // Could be a failed response and therefore nullable
readonly status: number
@@ -74,6 +77,9 @@ export class APIResponse<T> {
}
}

/**
* Credentials for the API for end users (usually frontend)
*/
export class UserCreds implements ICredentials {
private readonly nettuAccount: string
private readonly token?: string
@@ -95,6 +101,9 @@ export class UserCreds implements ICredentials {
}
}

/**
* Credentials for the API for admins (usually backend)
*/
export class AccountCreds implements ICredentials {
private readonly apiKey: string

133 changes: 126 additions & 7 deletions scheduler/clients/javascript/lib/calendarClient.ts
Original file line number Diff line number Diff line change
@@ -14,46 +14,117 @@ import type {
import type { Timespan } from './eventClient'
import { convertInstanceDates } from './helpers/datesConverters'

/**
* Request for creating a calendar
*/
type CreateCalendarRequest = {
/**
* Timezone used in the calendar
*/
timezone: string
/**
* Start of the week used in the calendar
* @format 0-6 - 0 is Monday, 1 is Tuesday, etc.
* @default 0
*/
weekStart?: number
/**
* Possible metadata
*/
metadata?: {
key: string
value: string
}
}

/**
* Request for updating a calendar
*/
type UpdateCalendarRequest = CreateCalendarRequest

/**
* Response for getting the events of a calendar
*/
type GetCalendarEventsResponse = {
/**
* Calendar object
*/
calendar: Calendar
/**
* List of events with their instances
*/
events: {
/**
* Event object
*/
event: CalendarEvent
/**
* List of instances of the event
* Especially useful for recurring events
*/
instances: CalendarEventInstance[]
}[]
}

/**
* Response for getting a calendar
*/
type CalendarResponse = {
/**
* Calendar object
*/
calendar: Calendar
}

/**
* Payload sent for enabling the sync of a calendar with an external calendar
*/
type SyncCalendarInput = {
/**
* Uuid of the user
*/
userId: string
/**
* Uuid of the calendar
*/
calendarId: string
/**
* Uuid of the external calendar
*/
extCalendarId: string
/**
* Provider of the external calendar
* @format IntegrationProvider (Google, Outlook)
*/
provider: IntegrationProvider
}

/**
* Payload sent for disabling the sync of a calendar with an external calendar
*/
type StopCalendarSyncInput = {
/**
* Uuid of the user
*/
userId: string
/**
* Uuid of the calendar
*/
calendarId: string
/**
* Uuid of the external calendar
*/
extCalendarId: string
/**
* Provider of the external calendar
* @format IntegrationProvider (Google, Outlook)
*/
provider: IntegrationProvider
}

/**
* Client for the calendar endpoints
* This is an admin client
* This is an admin client (usually backend)
*/
export class NettuCalendarClient extends NettuBaseClient {
/**
@@ -66,10 +137,22 @@ export class NettuCalendarClient extends NettuBaseClient {
return this.post<CalendarResponse>(`/user/${userId}/calendar`, data)
}

/**
* Find a calendar by id
* @param calendarId - uuid of the calendar to find
* @returns CalendarResponse - found calendar, if any
*/
public findById(calendarId: string) {
return this.get<CalendarResponse>(`/user/calendar/${calendarId}`)
}

/**
* Find calendars by metadata
* @param meta - metadata to search for
* @param skip - number of calendars to skip
* @param limit - number of calendars to return
* @returns CalendarResponse - found calendars
*/
public findByMeta(
meta: {
key: string
@@ -86,6 +169,12 @@ export class NettuCalendarClient extends NettuBaseClient {
})
}

/**
* Find Google calendars for an user
* @param userId - uuid of the user to find the calendars for
* @param minAccessRole - minimum access role required
* @returns - found Google calendars
*/
async findGoogle(userId: string, minAccessRole: GoogleCalendarAccessRole) {
return this.get<{ calendars: GoogleCalendarListEntry[] }>(
`/user/${userId}/calendar/provider/google`,
@@ -95,17 +184,34 @@ export class NettuCalendarClient extends NettuBaseClient {
)
}

/**
* Find Outlook calendars for an user
* @param userId - uuid of the user to find the calendars for
* @param minAccessRole - minimum access role required
* @returns - found Outlook calendars
*/
async findOutlook(userId: string, minAccessRole: OutlookCalendarAccessRole) {
return this.get<{ calendars: OutlookCalendar[] }>(
`/user/${userId}/calendar/provider/outlook`,
{ minAccessRole }
)
}

/**
* Remove the calendar with the given id
* @param calendarId - uuid of the calendar to remove
* @returns CalendarResponse - removed calendar
*/
public remove(calendarId: string) {
return this.delete<CalendarResponse>(`/user/calendar/${calendarId}`)
}

/**
* Update the calendar with the given id
* @param calendarId - uuid of the calendar to update
* @param data - data to update the calendar with
* @returns CalendarResponse - updated calendar
*/
public update(calendarId: string, data: UpdateCalendarRequest) {
return this.put<CalendarResponse>(`/user/calendar/${calendarId}`, {
settings: {
@@ -116,6 +222,13 @@ export class NettuCalendarClient extends NettuBaseClient {
})
}

/**
* Get the events for a calendar within a timespan
* @param calendarId - uuid of the calendar to get the events for
* @param startTime - start of the timespan
* @param endTime - end of the timespan
* @returns GetCalendarEventsResponse - events within the timespan
*/
public async getEvents(
calendarId: string,
startTime: Date,
@@ -140,16 +253,17 @@ export class NettuCalendarClient extends NettuBaseClient {
calendar: res.data.calendar,
events: res.data.events.map(event => ({
event: event.event,
instances: event.instances.map(instance => ({
startTime: new Date(instance.startTime),
endTime: new Date(instance.endTime),
busy: instance.busy,
})),
instances: event.instances.map(convertInstanceDates),
})),
},
}
}

/**
* Enable automated sync of a calendar with an external calendar
* @param input - data for syncing the calendar
* @returns - void
*/
public syncCalendar(input: SyncCalendarInput) {
const body = {
calendarId: input.calendarId,
@@ -159,6 +273,11 @@ export class NettuCalendarClient extends NettuBaseClient {
return this.put(`user/${input.userId}/calendar/sync`, body)
}

/**
* Disable automated sync of a calendar with an external calendar
* @param input - data for stopping the calendar sync
* @returns - void
*/
public stopCalendarSync(input: StopCalendarSyncInput) {
const body = {
calendarId: input.calendarId,
@@ -171,7 +290,7 @@ export class NettuCalendarClient extends NettuBaseClient {

/**
* Client for the calendar endpoints
* This is a user client
* This is an end user client (usually frontend)
*/
export class NettuCalendarUserClient extends NettuBaseClient {
public create(data: CreateCalendarRequest) {
58 changes: 34 additions & 24 deletions scheduler/clients/javascript/lib/eventClient.ts
Original file line number Diff line number Diff line change
@@ -10,11 +10,25 @@ import {
convertInstanceDates,
} from './helpers/datesConverters'

/**
* Reminder for an event
*/
interface EventReminder {
/**
* Time before the event to trigger the reminder
* @format minutes
*/
delta: number
/**
* Identifier of the reminder
* @format uuid
*/
identifier: string
}

/**
* Request for creating a calendar event
*/
type CreateCalendarEventReq = {
calendarId: string
startTime: Date
@@ -26,6 +40,9 @@ type CreateCalendarEventReq = {
metadata?: Metadata
}

/**
* Request for updating a calendar event
*/
type UpdateCalendarEventReq = {
startTime?: Date
duration?: number
@@ -37,43 +54,32 @@ type UpdateCalendarEventReq = {
metadata?: Metadata
}

/**
* Timespan for getting event instances
*/
export type Timespan = {
startTime: Date
endTime: Date
}

/**
* Response for getting event instances
*/
type GetEventInstancesResponse = {
instances: CalendarEventInstance[]
}

/**
* Response for an event
*/
type EventReponse = {
event: CalendarEvent
}

function convertEventDates(event: CalendarEvent): CalendarEvent {
if (!event) {
return event
}
return {
...event,
startTime: new Date(event.startTime),
exdates: event.exdates.map(date => new Date(date)),
}
}

export function convertInstanceDates(
instance: CalendarEventInstance
): CalendarEventInstance {
if (!instance) {
return instance
}
return {
...instance,
startTime: new Date(instance.startTime),
endTime: new Date(instance.endTime),
}
}

/**
* Client for the events' endpoints
* This is an admin client (usually backend)
*/
export class NettuEventClient extends NettuBaseClient {
public async update(
eventId: string,
@@ -187,6 +193,10 @@ export class NettuEventClient extends NettuBaseClient {
}
}

/**
* Client for the event endpoints
* This is an end user client (usually frontend)
*/
export class NettuEventUserClient extends NettuBaseClient {
public async update(
eventId: string,
Loading