@blazeo.com/appointment-client 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/blazeo.com-appointment-client-1.0.14.tgz +0 -0
  2. package/package.json +3 -2
  3. package/sample/src/EventTab.jsx +435 -395
  4. package/src/calendar/calendarCreation.ts +62 -15
  5. package/src/events/getAppointmentsByFilter.ts +98 -0
  6. package/src/index.ts +15 -4
  7. package/blazeo.com-appointment-client-1.0.11.tgz +0 -0
  8. package/blazeo.com-appointment-client-1.0.13.tgz +0 -0
  9. package/dist/calendar/blazeoCalendarRelationMethods.d.ts +0 -8
  10. package/dist/calendar/blazeoCalendarRelationMethods.d.ts.map +0 -1
  11. package/dist/calendar/blazeoCalendarRelationMethods.js +0 -16
  12. package/dist/calendar/blazeoCalendarRelationMethods.js.map +0 -1
  13. package/dist/calendar/buildUnifiedCalendarView.d.ts +0 -39
  14. package/dist/calendar/buildUnifiedCalendarView.js +0 -301
  15. package/dist/calendar/calendarCreation.d.ts +0 -27
  16. package/dist/calendar/calendarCreation.js +0 -191
  17. package/dist/calendar/calendarCreationFacade.d.ts +0 -27
  18. package/dist/calendar/calendarCreationFacade.d.ts.map +0 -1
  19. package/dist/calendar/calendarCreationFacade.js +0 -167
  20. package/dist/calendar/calendarCreationFacade.js.map +0 -1
  21. package/dist/calendar/createCalendar.d.ts +0 -81
  22. package/dist/calendar/createCalendar.d.ts.map +0 -1
  23. package/dist/calendar/createCalendar.js +0 -206
  24. package/dist/calendar/createCalendar.js.map +0 -1
  25. package/dist/calendar/fetchCalendarDetails.d.ts +0 -41
  26. package/dist/calendar/fetchCalendarDetails.js +0 -265
  27. package/dist/calendar/fetchCalendarWithOpeningHours.d.ts +0 -25
  28. package/dist/calendar/fetchCalendarWithOpeningHours.js +0 -114
  29. package/dist/calendar/getAllParticipantOpeningHours.d.ts +0 -22
  30. package/dist/calendar/getAllParticipantOpeningHours.js +0 -22
  31. package/dist/calendar/getCalendarsByCompany.d.ts +0 -9
  32. package/dist/calendar/getCalendarsByCompany.js +0 -62
  33. package/dist/calendar/getOpeningHours.d.ts +0 -8
  34. package/dist/calendar/getOpeningHours.js +0 -9
  35. package/dist/calendar/getParticipantOpeningHours.d.ts +0 -37
  36. package/dist/calendar/getParticipantOpeningHours.js +0 -48
  37. package/dist/calendar/getParticipants.d.ts +0 -7
  38. package/dist/calendar/getParticipants.js +0 -13
  39. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.d.ts +0 -10
  40. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.d.ts.map +0 -1
  41. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.js +0 -44
  42. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.js.map +0 -1
  43. package/dist/calendar/mapCalendarToBlazeoSnapshot.d.ts +0 -29
  44. package/dist/calendar/mapCalendarToBlazeoSnapshot.d.ts.map +0 -1
  45. package/dist/calendar/mapCalendarToBlazeoSnapshot.js +0 -44
  46. package/dist/calendar/mapCalendarToBlazeoSnapshot.js.map +0 -1
  47. package/dist/calendar/mapToDesiredResponse.d.ts +0 -56
  48. package/dist/calendar/mapToDesiredResponse.js +0 -111
  49. package/dist/config/applyBlazeoClientConfig.d.ts +0 -3
  50. package/dist/config/applyBlazeoClientConfig.d.ts.map +0 -1
  51. package/dist/config/applyBlazeoClientConfig.js +0 -14
  52. package/dist/config/applyBlazeoClientConfig.js.map +0 -1
  53. package/dist/config/applyBlazeoDefaults.d.ts +0 -2
  54. package/dist/config/applyBlazeoDefaults.d.ts.map +0 -1
  55. package/dist/config/applyBlazeoDefaults.js +0 -14
  56. package/dist/config/applyBlazeoDefaults.js.map +0 -1
  57. package/dist/config/blazeo.config.d.ts +0 -11
  58. package/dist/config/blazeo.config.d.ts.map +0 -1
  59. package/dist/config/blazeo.config.js +0 -11
  60. package/dist/config/blazeo.config.js.map +0 -1
  61. package/dist/config/blazeoClientDefaults.d.ts +0 -11
  62. package/dist/config/blazeoClientDefaults.d.ts.map +0 -1
  63. package/dist/config/blazeoClientDefaults.js +0 -11
  64. package/dist/config/blazeoClientDefaults.js.map +0 -1
  65. package/dist/config/ensureBlazeoHttpReady.d.ts +0 -17
  66. package/dist/config/ensureBlazeoHttpReady.js +0 -31
  67. package/dist/config/initializeAppointmentClient.d.ts +0 -11
  68. package/dist/config/initializeAppointmentClient.d.ts.map +0 -1
  69. package/dist/config/initializeAppointmentClient.js +0 -15
  70. package/dist/config/initializeAppointmentClient.js.map +0 -1
  71. package/dist/config/syncBlazeoConnection.d.ts +0 -6
  72. package/dist/config/syncBlazeoConnection.js +0 -18
  73. package/dist/events/appointmentEventFacade.d.ts +0 -67
  74. package/dist/events/appointmentEventFacade.d.ts.map +0 -1
  75. package/dist/events/appointmentEventFacade.js +0 -124
  76. package/dist/events/appointmentEventFacade.js.map +0 -1
  77. package/dist/events/mapAppointmentToEventSnapshot.d.ts +0 -5
  78. package/dist/events/mapAppointmentToEventSnapshot.d.ts.map +0 -1
  79. package/dist/events/mapAppointmentToEventSnapshot.js +0 -57
  80. package/dist/events/mapAppointmentToEventSnapshot.js.map +0 -1
  81. package/dist/exampleData.d.ts +0 -119
  82. package/dist/exampleData.d.ts.map +0 -1
  83. package/dist/exampleData.js +0 -71
  84. package/dist/exampleData.js.map +0 -1
  85. package/dist/facade/calendarCreationFacade.d.ts +0 -40
  86. package/dist/facade/calendarCreationFacade.d.ts.map +0 -1
  87. package/dist/facade/calendarCreationFacade.js +0 -96
  88. package/dist/facade/calendarCreationFacade.js.map +0 -1
  89. package/dist/facade/mapCalendarBOToSnapshot.d.ts +0 -10
  90. package/dist/facade/mapCalendarBOToSnapshot.d.ts.map +0 -1
  91. package/dist/facade/mapCalendarBOToSnapshot.js +0 -44
  92. package/dist/facade/mapCalendarBOToSnapshot.js.map +0 -1
  93. package/dist/facades/index.d.ts +0 -12
  94. package/dist/facades/index.d.ts.map +0 -1
  95. package/dist/facades/index.js +0 -12
  96. package/dist/facades/index.js.map +0 -1
  97. package/dist/index.d.ts +0 -79
  98. package/dist/index.d.ts.map +0 -1
  99. package/dist/index.js +0 -39
  100. package/dist/index.js.map +0 -1
  101. package/dist/lead/fetchLeadDetails.d.ts +0 -56
  102. package/dist/lead/fetchLeadDetails.js +0 -61
  103. package/dist/models/CalendarRootModel.d.ts +0 -56
  104. package/dist/models/CalendarRootModel.d.ts.map +0 -1
  105. package/dist/models/CalendarRootModel.js +0 -54
  106. package/dist/models/CalendarRootModel.js.map +0 -1
  107. package/dist/models/CalendarSlotModel.d.ts +0 -9
  108. package/dist/models/CalendarSlotModel.d.ts.map +0 -1
  109. package/dist/models/CalendarSlotModel.js +0 -8
  110. package/dist/models/CalendarSlotModel.js.map +0 -1
  111. package/dist/models/EventModel.d.ts +0 -11
  112. package/dist/models/EventModel.d.ts.map +0 -1
  113. package/dist/models/EventModel.js +0 -10
  114. package/dist/models/EventModel.js.map +0 -1
  115. package/dist/models/ParticipantModel.d.ts +0 -9
  116. package/dist/models/ParticipantModel.d.ts.map +0 -1
  117. package/dist/models/ParticipantModel.js +0 -8
  118. package/dist/models/ParticipantModel.js.map +0 -1
  119. package/dist/models/index.d.ts +0 -5
  120. package/dist/models/index.d.ts.map +0 -1
  121. package/dist/models/index.js +0 -5
  122. package/dist/models/index.js.map +0 -1
  123. package/dist/types/appointment.d.ts +0 -28
  124. package/dist/types/appointment.d.ts.map +0 -1
  125. package/dist/types/appointment.js +0 -6
  126. package/dist/types/appointment.js.map +0 -1
  127. package/dist/types/calendar.d.ts +0 -52
  128. package/dist/types/calendar.d.ts.map +0 -1
  129. package/dist/types/calendar.js +0 -6
  130. package/dist/types/calendar.js.map +0 -1
  131. package/dist/types/calendarBo.d.ts +0 -62
  132. package/dist/types/calendarBo.d.ts.map +0 -1
  133. package/dist/types/calendarBo.js +0 -6
  134. package/dist/types/calendarBo.js.map +0 -1
  135. package/sample/package-lock.json +0 -1778
@@ -1,5 +1,5 @@
1
1
  import { getSnapshot } from "mobx-state-tree";
2
- import { addParticipantToCalendar, saveCalendarOpeningHour, saveCalendarOpeningHoursBatch } from "./blazeoCalendarRelationMethods.js";
2
+ import { addParticipantToCalendar, removeParticipantFromCalendar, saveCalendarOpeningHour, saveCalendarOpeningHoursBatch } from "./blazeoCalendarRelationMethods.js";
3
3
  import { createCalendarAsync, updateCalendarAsync, deleteCalendarAsync } from "./createCalendar.js";
4
4
 
5
5
  function isFailureStatus(res: any) {
@@ -8,7 +8,24 @@ function isFailureStatus(res: any) {
8
8
 
9
9
  function normalizeParticipantGuid(id: any) {
10
10
  if (id == null || !String(id).trim()) return undefined;
11
- return String(id).trim().replace(/^\{|\}$/g, "");
11
+ return String(id).trim().replace(/^\{|\}$/g, "").toLowerCase();
12
+ }
13
+
14
+ /** Coerce MST / envelope shapes into a plain ID list for comparison. */
15
+ function unwrapParticipantIds(raw: any): string[] {
16
+ if (raw == null) return [];
17
+ let list: any[] = [];
18
+ if (Array.isArray(raw)) {
19
+ list = raw;
20
+ } else {
21
+ const d = raw.data ?? raw.Data ?? raw.items ?? raw.Items ?? raw;
22
+ list = Array.isArray(d) ? d : (d?.items ?? d?.Items ?? []);
23
+ }
24
+
25
+ return list.map(p => {
26
+ const id = p.participantId ?? p.ParticipantId ?? p.participant_id ?? p.id ?? p.Id;
27
+ return normalizeParticipantGuid(id);
28
+ }).filter(Boolean) as string[];
12
29
  }
13
30
 
14
31
  function newOpeningHourId() {
@@ -73,8 +90,34 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar: any, calenda
73
90
  };
74
91
  }
75
92
 
93
+ // 1. Participant Reconciliation (Diff-based)
94
+ // Fetch current participants to see who needs to be removed
95
+ let currentParticipantIds: string[] = [];
96
+ try {
97
+ const currentRaw = await calendarNode.getParticipants();
98
+ currentParticipantIds = unwrapParticipantIds(currentRaw);
99
+ } catch (err) {
100
+ console.warn("[calendarCreation] Failed to fetch current participants for reconciliation. Proceeding with additive mode.", err);
101
+ }
102
+
103
+ const desiredMembers = calendar.members ?? [];
104
+ const desiredIds = new Set(desiredMembers.map((m: any) => normalizeParticipantGuid(m.id)).filter(Boolean));
105
+
106
+ // A. Remove missing members
107
+ for (const existingId of currentParticipantIds) {
108
+ if (!desiredIds.has(existingId)) {
109
+ try {
110
+ await removeParticipantFromCalendar(calendarNode, existingId);
111
+ } catch (err) {
112
+ console.warn(`[calendarCreation] Failed to remove participant ${existingId}:`, err);
113
+ }
114
+ }
115
+ }
116
+
117
+ // B. Add new members
118
+ const existingIdSet = new Set(currentParticipantIds);
76
119
  let membersAdded = 0;
77
- for (const m of calendar.members ?? []) {
120
+ for (const m of desiredMembers) {
78
121
  const pid = normalizeParticipantGuid(m.id);
79
122
  if (!pid) {
80
123
  return {
@@ -82,19 +125,23 @@ async function runMembersAndOpeningHoursAfterCalendarSave(calendar: any, calenda
82
125
  error: `Member id ${m.id}: thirdPartyMemberId is required to add a participant.`,
83
126
  };
84
127
  }
85
- const res = await addParticipantToCalendar(calendarNode, pid);
86
- if (isFailureStatus(res)) {
87
- const msg =
88
- res.message ??
89
- (typeof res.data === "string" ? res.data : undefined) ??
90
- JSON.stringify(res);
91
- return {
92
- ok: false,
93
- error: `addParticipant failed for member ${m.id}: ${msg}`,
94
- apiResponse: res,
95
- };
128
+
129
+ // Only add if not already there
130
+ if (!existingIdSet.has(pid)) {
131
+ const res = await addParticipantToCalendar(calendarNode, pid);
132
+ if (isFailureStatus(res)) {
133
+ const msg =
134
+ res.message ??
135
+ (typeof res.data === "string" ? res.data : undefined) ??
136
+ JSON.stringify(res);
137
+ return {
138
+ ok: false,
139
+ error: `addParticipant failed for member ${m.id}: ${msg}`,
140
+ apiResponse: res,
141
+ };
142
+ }
143
+ membersAdded += 1;
96
144
  }
97
- membersAdded += 1;
98
145
  }
99
146
 
100
147
  // 2. Save Opening Hours (Plan V2: Grouped by participant with explicit off-days per slot)
@@ -0,0 +1,98 @@
1
+ import { EventModel, LeadModel } from "@blazeo.com/calendar-client";
2
+ import { getCalendarsByCompany } from "../calendar/getCalendarsByCompany.js";
3
+ import moment from "moment";
4
+
5
+ /**
6
+ * High-level method to fetch appointments with enriched mapping.
7
+ * Resolves names for organizers and calendars, and attempts to resolve missing leadIds.
8
+ */
9
+ export async function getAppointmentsByFilter(
10
+ companyKey: string,
11
+ startDateFrom: string,
12
+ startDateTo: string,
13
+ opts: any = {}
14
+ ) {
15
+ // 1. Fetch raw events
16
+ // Cast to any because getByDateRangeWithFilters is missing from some .d.ts versions but present in .js
17
+ const response: any = await (EventModel as any).getByDateRangeWithFilters(
18
+ companyKey,
19
+ startDateFrom,
20
+ startDateTo,
21
+ opts
22
+ );
23
+
24
+ const events = response?.events || [];
25
+ const totalCount = response?.totalCount || 0;
26
+
27
+ if (events.length === 0) {
28
+ return { events: [], totalCount: 0 };
29
+ }
30
+
31
+ // 2. Fetch company data for name resolution (Calendars & Participants)
32
+ const enrichedCalendars = await getCalendarsByCompany(companyKey);
33
+
34
+ const calendarMap = new Map<string, string>();
35
+ const participantMap = new Map<string, string>();
36
+
37
+ enrichedCalendars.forEach((cal: any) => {
38
+ calendarMap.set(cal.calendarId, cal.name);
39
+ if (Array.isArray(cal.members)) {
40
+ cal.members.forEach((m: any) => {
41
+ participantMap.set(m.id, m.name);
42
+ });
43
+ }
44
+ });
45
+
46
+ // 3. Map events to the desired response schema
47
+ const mappedEvents = await Promise.all(
48
+ events.map(async (event: any) => {
49
+ // Resolve leadId if missing
50
+ // Note: event properties might be uppercase depending on API version, mapEventFromApi usually handles this
51
+ // but let's be defensive.
52
+ const rawEvent = (event as any)._raw || event;
53
+ let resolvedLeadId = event.leadId ?? rawEvent.lead_id ?? opts.leadId ?? null;
54
+
55
+ if (!resolvedLeadId && event.visitorEmail) {
56
+ try {
57
+ const lead: any = await LeadModel.getByEmail(event.visitorEmail, companyKey);
58
+ if (lead) {
59
+ resolvedLeadId = lead.leadId;
60
+ }
61
+ } catch (err) {
62
+ console.warn(`[getAppointmentsByFilter] Failed to resolve lead for ${event.visitorEmail}:`, err);
63
+ }
64
+ }
65
+
66
+ const calendarId = event.calendarId;
67
+ const participantId = event.participantId;
68
+
69
+ return {
70
+ id: event.eventId, // UUID as per feedback
71
+ appointmentId: event.eventId,
72
+ title: event.title || "Appointment",
73
+ organizer: participantMap.get(participantId) || "Member",
74
+ guest: event.visitorName || "Guest",
75
+ serviceType: calendarMap.get(calendarId) || "Calendar",
76
+ status: event.attendeeStatus ?? 1,
77
+ calendarId: calendarId, // UUID
78
+ memberId: participantId, // UUID
79
+ participantId: participantId, // UUID
80
+ leadId: resolvedLeadId,
81
+ notes: event.description || "",
82
+ startDate: event.startDate ? moment(event.startDate).toISOString() : null,
83
+ endDate: event.endDate ? moment(event.endDate).toISOString() : null,
84
+ timeZone: event.timeZone || "Pakistan Standard Time",
85
+ meetingLocationType: 1,
86
+ customMeetingLocation: null,
87
+ __typename: "Appointment",
88
+ // Keep raw fields for potential fallback or reference
89
+ _raw: event
90
+ };
91
+ })
92
+ );
93
+
94
+ return {
95
+ events: mappedEvents,
96
+ totalCount
97
+ };
98
+ }
package/src/index.ts CHANGED
@@ -9,7 +9,13 @@ export { ensureBlazeoHttpReady } from "./config/ensureBlazeoHttpReady.js";
9
9
  export type { EnsureBlazeoHttpOptions } from "./config/ensureBlazeoHttpReady.js";
10
10
  export { blazeoClientConfig } from "./config/blazeoClientDefaults.js";
11
11
  export { applyBlazeoClientConfig } from "./config/applyBlazeoDefaults.js";
12
- export { createCalendarRoot, CalendarRootModel, CalendarSlotModel, EventModel, ParticipantModel } from "./models/CalendarRootModel.js";
12
+ export {
13
+ createCalendarRoot,
14
+ CalendarRootModel,
15
+ CalendarSlotModel,
16
+ EventModel as MSTEventModel,
17
+ ParticipantModel as MSTParticipantModel
18
+ } from "./models/CalendarRootModel.js";
13
19
  export { fetchCalendarBundle, normalizeOpeningHours } from "./calendar/fetchCalendarDetails.js";
14
20
  export {
15
21
  buildUnifiedCalendarView,
@@ -34,13 +40,15 @@ export { mapAppointmentToEventSnapshot } from "./events/mapAppointmentToEventSna
34
40
 
35
41
  import { getCalendarsByCompany } from "./calendar/getCalendarsByCompany.js";
36
42
  import { fetchCalendarDetails } from "./calendar/fetchCalendarDetails.js";
37
- export { getCalendarsByCompany, fetchCalendarDetails };
43
+ import { getAppointmentsByFilter } from "./events/getAppointmentsByFilter.js";
44
+ export { getCalendarsByCompany, fetchCalendarDetails, getAppointmentsByFilter };
38
45
 
39
46
  import {
40
47
  CalendarModel as CoreCalendarModel,
41
48
  EventModel as CoreEventModel,
42
49
  ParticipantModel as CoreParticipantModel,
43
50
  CalendarParticipantModel as CoreCalendarParticipantModel,
51
+ LeadModel as CoreLeadModel,
44
52
  configure,
45
53
  getConfig
46
54
  } from "@blazeo.com/calendar-client";
@@ -53,9 +61,12 @@ export const CalendarModel = {
53
61
  };
54
62
 
55
63
  export {
56
- CoreEventModel as CoreEventModel,
57
- CoreParticipantModel as CoreParticipantModel,
64
+ CoreEventModel as EventModel,
65
+ CoreParticipantModel as ParticipantModel,
58
66
  CoreCalendarParticipantModel as CalendarParticipantModel,
67
+ CoreLeadModel as LeadModel,
68
+ CoreEventModel,
69
+ CoreParticipantModel,
59
70
  configure,
60
71
  getConfig
61
72
  };
@@ -1,8 +0,0 @@
1
- /** `GET /Calendar/Participant/Add` — attach `participantId` to this calendar. */
2
- export declare function addParticipantToCalendar(calendar: any, participantId: string): any;
3
- /** `GET /Calendar/Participant/Remove` */
4
- export declare function removeParticipantFromCalendar(calendar: any, participantId: string): any;
5
- /** `POST /Calendar/Participant/Availability/OpeningHour/Save` — one day/slot. */
6
- export declare function saveCalendarOpeningHour(calendar: any, payload: any): any;
7
- /** `POST /Calendar/Participant/Availability/OpeningHours/Save` — batch body (API-specific shape). */
8
- export declare function saveCalendarOpeningHoursBatch(calendar: any, payload: any): any;
@@ -1 +0,0 @@
1
- {"version":3,"file":"blazeoCalendarRelationMethods.d.ts","sourceRoot":"","sources":["../../src/calendar/blazeoCalendarRelationMethods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,cAAc,GAAG;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC/E,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAClF,eAAe,CACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC3C,gBAAgB,CACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAC3C,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC5C,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,0BAA0B,EACpC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,8BAA8B,CAAC,CAEzC;AAED,yCAAyC;AACzC,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,0BAA0B,EACpC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,8BAA8B,CAAC,CAEzC;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CAEzC;AAED,qGAAqG;AACrG,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAC3C,OAAO,CAAC,8BAA8B,CAAC,CAEzC"}
@@ -1,16 +0,0 @@
1
- /** `GET /Calendar/Participant/Add` — attach `participantId` to this calendar. */
2
- export function addParticipantToCalendar(calendar, participantId) {
3
- return calendar.addParticipant(participantId);
4
- }
5
- /** `GET /Calendar/Participant/Remove` */
6
- export function removeParticipantFromCalendar(calendar, participantId) {
7
- return calendar.removeParticipant(participantId);
8
- }
9
- /** `POST /Calendar/Participant/Availability/OpeningHour/Save` — one day/slot. */
10
- export function saveCalendarOpeningHour(calendar, payload) {
11
- return calendar.saveOpeningHour(payload);
12
- }
13
- /** `POST /Calendar/Participant/Availability/OpeningHours/Save` — batch body (API-specific shape). */
14
- export function saveCalendarOpeningHoursBatch(calendar, payload) {
15
- return calendar.saveOpeningHours(payload);
16
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"blazeoCalendarRelationMethods.js","sourceRoot":"","sources":["../../src/calendar/blazeoCalendarRelationMethods.ts"],"names":[],"mappings":"AAsCA,iFAAiF;AACjF,MAAM,UAAU,wBAAwB,CACtC,QAAoC,EACpC,aAAqB;IAErB,OAAO,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,6BAA6B,CAC3C,QAAoC,EACpC,aAAqB;IAErB,OAAO,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;AACnD,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,uBAAuB,CACrC,QAAoC,EACpC,OAAgC;IAEhC,OAAO,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,6BAA6B,CAC3C,QAAoC,EACpC,OAA4C;IAE5C,OAAO,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -1,39 +0,0 @@
1
- export interface UnifiedCalendarMember {
2
- id: number | string;
3
- name: string;
4
- email: string | null;
5
- /** When API exposes status; otherwise derived from participant info flags. */
6
- status: number | null;
7
- /** Full row from Participants/GetInfo (plain object). */
8
- participantInfo?: Record<string, unknown> | null;
9
- __typename?: string;
10
- }
11
- export interface UnifiedParticipantWithHours extends UnifiedCalendarMember {
12
- openingHours: UnifiedOpeningHourRow[];
13
- }
14
- export interface UnifiedOpeningHourRow {
15
- id?: number | string;
16
- createdOn?: string;
17
- modifiedOn?: string;
18
- member: number | string;
19
- openingHourId?: string;
20
- calendarId?: string;
21
- participantId?: string;
22
- days: string[];
23
- startHour: number;
24
- startMinute: number;
25
- endHour: number;
26
- endMinute: number;
27
- off: boolean;
28
- __typename?: string;
29
- }
30
- export type UnifiedCalendarView = Record<string, unknown> & {
31
- members: UnifiedCalendarMember[];
32
- openingHours: UnifiedOpeningHourRow[];
33
- participants?: UnifiedParticipantWithHours[];
34
- };
35
- /**
36
- * Build a consumer-friendly `{ id, name, members, openingHours }` shape where
37
- * `openingHours[].member` references `members[].id`.
38
- */
39
- export declare function buildUnifiedCalendarView(calendarSnapshot: Record<string, any> | null, openingHoursRows: any[], participants: any[] | null | undefined, participantsInfo: any[] | null | undefined): UnifiedCalendarView | null;
@@ -1,301 +0,0 @@
1
- import { getSnapshot, isStateTreeNode } from "mobx-state-tree";
2
- const DAY_NAMES = ["SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"];
3
- function pick(row, ...keys) {
4
- if (row == null || typeof row !== "object")
5
- return undefined;
6
- for (const k of keys) {
7
- if (row[k] !== undefined && row[k] !== null)
8
- return row[k];
9
- }
10
- return undefined;
11
- }
12
- function toPlain(value) {
13
- if (value == null)
14
- return value;
15
- if (isStateTreeNode(value))
16
- return getSnapshot(value);
17
- if (Array.isArray(value))
18
- return value.map((x) => toPlain(x));
19
- return value;
20
- }
21
- function normParticipantKey(v) {
22
- if (v == null)
23
- return "";
24
- return String(v).trim().toLowerCase();
25
- }
26
- function coerceMemberId(v) {
27
- if (v == null || v === "")
28
- return null;
29
- if (typeof v === "number" && !Number.isNaN(v))
30
- return v;
31
- if (typeof v === "string") {
32
- const t = v.trim();
33
- if (/^\d+$/.test(t))
34
- return Number(t);
35
- return t;
36
- }
37
- return null;
38
- }
39
- /**
40
- * Canonical member id used in both `members[].id` and `openingHours[].member`.
41
- */
42
- function resolveParticipantMemberId(calPart) {
43
- // Prefer the participantId GUID when available — it is the stable cross-endpoint identifier.
44
- const sid = pick(calPart, "participantId", "ParticipantId", "participant_id");
45
- if (sid != null && String(sid).trim() !== "") {
46
- const t = String(sid).trim();
47
- if (/^\d+$/.test(t))
48
- return Number(t);
49
- return t;
50
- }
51
- // Fall back to id — accepts both numeric and string (e.g. a GUID stored as id).
52
- const n = pick(calPart, "id", "Id");
53
- if (n != null) {
54
- if (typeof n === "number" && !Number.isNaN(n))
55
- return n;
56
- if (typeof n === "string" && n.trim() !== "")
57
- return n.trim();
58
- }
59
- return "";
60
- }
61
- function dayOrderIndex(d) {
62
- const u = d.toUpperCase();
63
- const i = DAY_NAMES.indexOf(u);
64
- return i >= 0 ? i : 999;
65
- }
66
- /** Merge rows that share participant + time span into one row with combined active `days`. */
67
- function mergeOpeningHoursBySlot(rows) {
68
- const map = new Map();
69
- for (const r of rows) {
70
- // Key excludes 'off' because we want to merge ON and OFF records for the same time slot
71
- const key = [r.member, r.startHour, r.startMinute, r.endHour, r.endMinute].join("|");
72
- const existing = map.get(key);
73
- // We only want to add the day to the 'days' array if it is NOT marked as OFF.
74
- // If the whole record was marked as OFF, we still process it to establish the slot,
75
- // but its days won't be listed as 'active'.
76
- const activeDaysFromThisRow = r.off ? [] : r.days;
77
- if (!existing) {
78
- map.set(key, { ...r, days: [...activeDaysFromThisRow], off: false });
79
- }
80
- else {
81
- const set = new Set([...existing.days, ...activeDaysFromThisRow]);
82
- existing.days = Array.from(set).sort((a, b) => dayOrderIndex(a) - dayOrderIndex(b));
83
- // If we encounter any record that is NOT off, the whole merged slot is NOT off.
84
- if (!r.off)
85
- existing.off = false;
86
- }
87
- }
88
- // Final Pass: If a slot has NO active days, it should be marked as off: true
89
- // (though in Plan V2, these usually just disappear from the UI's 'days' list)
90
- for (const group of map.values()) {
91
- if (group.days.length === 0) {
92
- group.off = true;
93
- }
94
- }
95
- rows.length = 0;
96
- rows.push(...map.values());
97
- }
98
- function normalizeDaysFromRow(row) {
99
- const rawDays = pick(row, "days", "Days");
100
- if (Array.isArray(rawDays)) {
101
- return rawDays.map((d) => String(d).trim().toUpperCase()).filter(Boolean);
102
- }
103
- const dayNum = pick(row, "day", "Day");
104
- if (dayNum != null && typeof dayNum === "number" && dayNum >= 0 && dayNum <= 6) {
105
- return [DAY_NAMES[dayNum]];
106
- }
107
- const dayStr = pick(row, "dayName", "DayName", "dayOfWeek", "DayOfWeek");
108
- if (dayStr != null && String(dayStr).trim() !== "") {
109
- return [String(dayStr).trim().toUpperCase()];
110
- }
111
- return [];
112
- }
113
- function resolveOpeningHourMemberId(row, byParticipantKey, byCalendarParticipantKey) {
114
- const calPartHook = pick(row, "calendarParticipantId", "CalendarParticipantId", "calendarparticipant_id");
115
- if (calPartHook != null && String(calPartHook).trim() !== "") {
116
- const ck = normParticipantKey(String(calPartHook));
117
- if (byCalendarParticipantKey.has(ck))
118
- return byCalendarParticipantKey.get(ck);
119
- }
120
- const pid = pick(row, "participantId", "ParticipantId", "participant_id");
121
- if (pid != null && String(pid).trim() !== "") {
122
- const k = normParticipantKey(String(pid));
123
- if (byParticipantKey.has(k))
124
- return byParticipantKey.get(k);
125
- return coerceMemberId(pid);
126
- }
127
- const member = pick(row, "member", "Member");
128
- if (member != null && typeof member === "object") {
129
- const mid = coerceMemberId(pick(member, "id", "Id")) ??
130
- coerceMemberId(pick(member, "participantId", "ParticipantId", "participant_id"));
131
- if (mid != null)
132
- return mid;
133
- }
134
- if (member != null && (typeof member === "number" || typeof member === "string")) {
135
- const m = coerceMemberId(member);
136
- if (m != null) {
137
- const k = normParticipantKey(m);
138
- if (byParticipantKey.has(k))
139
- return byParticipantKey.get(k);
140
- }
141
- return m;
142
- }
143
- return null;
144
- }
145
- function deriveMemberStatus(calPart, info) {
146
- const direct = pick(calPart, "status", "Status") ?? pick(info ?? {}, "status", "Status");
147
- if (direct != null && typeof direct === "number" && !Number.isNaN(direct))
148
- return direct;
149
- const approved = Boolean(pick(calPart, "isApproved", "IsApproved", "is_approved")) ||
150
- Boolean(pick(info ?? {}, "isApproved", "IsApproved", "is_approved"));
151
- if (approved)
152
- return approved ? 1 : 0;
153
- return null;
154
- }
155
- /**
156
- * Build a consumer-friendly `{ id, name, members, openingHours }` shape where
157
- * `openingHours[].member` references `members[].id`.
158
- */
159
- export function buildUnifiedCalendarView(calendarSnapshot, openingHoursRows, participants, participantsInfo) {
160
- if (calendarSnapshot == null || typeof calendarSnapshot !== "object")
161
- return null;
162
- const calSnap = toPlain(calendarSnapshot);
163
- const partsPlain = participants != null ? participants.map((p) => toPlain(p)) : [];
164
- const infoPlain = participantsInfo != null ? participantsInfo.map((p) => toPlain(p)) : [];
165
- const infoByPid = new Map();
166
- for (const inf of infoPlain) {
167
- const pid = inf?.participantId ?? inf?.ParticipantId ?? inf?.participant_id;
168
- if (pid != null && String(pid).trim() !== "") {
169
- infoByPid.set(normParticipantKey(String(pid)), inf);
170
- }
171
- }
172
- const byParticipantKey = new Map();
173
- const byCalendarParticipantKey = new Map();
174
- const members = [];
175
- if (partsPlain.length > 0) {
176
- for (const cp of partsPlain) {
177
- const memberId = resolveParticipantMemberId(cp);
178
- const pidStr = pick(cp, "participantId", "ParticipantId", "participant_id") ?? "";
179
- if (memberId === "" && (!pidStr || pidStr.trim() === ""))
180
- continue;
181
- const ik = normParticipantKey(pidStr || String(memberId));
182
- const inf = ik ? infoByPid.get(ik) : undefined;
183
- const participantInfoPlain = inf != null ? { ...toPlain(inf) } : null;
184
- const alias = inf?.alias ?? inf?.Alias;
185
- const name = typeof alias === "string" && alias.trim() !== ""
186
- ? alias.trim()
187
- : pidStr && pidStr.trim() !== ""
188
- ? pidStr.trim()
189
- : String(memberId);
190
- const email = (inf?.email ?? inf?.Email ?? null);
191
- const id = memberId === "" ? coerceMemberId(pidStr) ?? pidStr : memberId;
192
- const calPartPk = pick(cp, "calendarParticipantId", "CalendarParticipantId", "calendarparticipant_id");
193
- const calPartKey = calPartPk != null ? normParticipantKey(String(calPartPk)) : "";
194
- if (calPartKey)
195
- byCalendarParticipantKey.set(calPartKey, id);
196
- const keyParticipant = ik || normParticipantKey(String(id));
197
- if (keyParticipant) {
198
- byParticipantKey.set(keyParticipant, id);
199
- byParticipantKey.set(normParticipantKey(String(id)), id);
200
- }
201
- members.push({
202
- id,
203
- name,
204
- email: email ?? null,
205
- status: deriveMemberStatus(cp, inf),
206
- participantInfo: participantInfoPlain,
207
- });
208
- }
209
- }
210
- else if (infoPlain.length > 0) {
211
- for (const inf of infoPlain) {
212
- const pid = inf?.participantId ?? inf?.ParticipantId ?? inf?.participant_id;
213
- if (pid == null || String(pid).trim() === "")
214
- continue;
215
- const id = coerceMemberId(pid) ?? String(pid).trim();
216
- const ik = normParticipantKey(String(pid));
217
- const participantInfoPlain = { ...toPlain(inf) };
218
- if (ik)
219
- byParticipantKey.set(ik, id);
220
- byParticipantKey.set(normParticipantKey(id), id);
221
- const alias = inf.alias ?? inf.Alias ?? "";
222
- const name = typeof alias === "string" && alias.trim() !== "" ? alias.trim() : String(pid);
223
- const email = (inf.email ?? inf.Email ?? null);
224
- members.push({
225
- id,
226
- name,
227
- email: email ?? null,
228
- status: deriveMemberStatus({}, inf),
229
- participantInfo: participantInfoPlain,
230
- __typename: "Member",
231
- });
232
- }
233
- }
234
- const rawRows = Array.isArray(openingHoursRows) ? openingHoursRows : [];
235
- const openingHours = [];
236
- for (const raw of rawRows) {
237
- const row = toPlain(raw);
238
- let memberId = resolveOpeningHourMemberId(row, byParticipantKey, byCalendarParticipantKey);
239
- if (memberId == null) {
240
- const m = pick(row, "member", "Member");
241
- memberId = typeof m === "number" || typeof m === "string" ? coerceMemberId(m) : null;
242
- }
243
- if (memberId == null)
244
- continue;
245
- const days = normalizeDaysFromRow(row);
246
- const startHour = Number(pick(row, "startHour", "StartHour", "start_hour") ?? 0) || 0;
247
- const startMinute = Number(pick(row, "startMinute", "StartMinute", "start_minute") ?? 0) || 0;
248
- const endHour = Number(pick(row, "endHour", "EndHour", "end_hour") ?? 0) || 0;
249
- const endMinute = Number(pick(row, "endMinute", "EndMinute", "end_minute") ?? 0) || 0;
250
- const off = Boolean(pick(row, "off", "Off"));
251
- openingHours.push({
252
- id: pick(row, "id", "Id") ?? 0,
253
- createdOn: pick(row, "createdOn", "CreatedOn", "created_on") ?? "0001-01-01T00:00:00.000Z",
254
- modifiedOn: pick(row, "modifiedOn", "ModifiedOn", "modified_on") ?? "0001-01-01T00:00:00.000Z",
255
- member: memberId,
256
- openingHourId: pick(row, "openingHourId", "OpeningHourId", "opening_hour_id") ?? "",
257
- calendarId: pick(row, "calendarId", "CalendarId", "calendar_id") ?? "",
258
- participantId: pick(row, "participantId", "ParticipantId", "participant_id") ?? "",
259
- days,
260
- startHour,
261
- startMinute,
262
- endHour,
263
- endMinute,
264
- off,
265
- __typename: "OpeningHour",
266
- });
267
- }
268
- mergeOpeningHoursBySlot(openingHours);
269
- const view = {
270
- ...calSnap,
271
- members,
272
- openingHours,
273
- participants: buildNestedParticipants(members, openingHours),
274
- __typename: "Calendar",
275
- };
276
- return view;
277
- }
278
- /**
279
- * Groups opening hours into their respective participant objects.
280
- */
281
- function buildNestedParticipants(members, openingHours) {
282
- const nested = [];
283
- members.forEach((m) => {
284
- const hoursForThisMember = openingHours.filter((oh) => {
285
- const mid = String(oh.member).trim().toLowerCase();
286
- const pid = String(m.id).trim().toLowerCase();
287
- return mid === pid;
288
- });
289
- // Remove the 'member' field from the nested opening hours as it's redundant.
290
- const nestedHours = hoursForThisMember.map(({ member, ...rest }) => ({
291
- ...rest,
292
- __typename: "OpeningHour"
293
- }));
294
- nested.push({
295
- ...m,
296
- openingHours: nestedHours,
297
- __typename: "Member",
298
- });
299
- });
300
- return nested;
301
- }
@@ -1,27 +0,0 @@
1
- import { deleteCalendarAsync } from "./createCalendar.js";
2
- /**
3
- * Resolves Blazeo `participantId` for an opening-hour row: explicit `participantId`,
4
- * matching `CalendarCreation.SaveOpeningHours`.
5
- */
6
- export declare function resolveParticipantIdForOpeningHour(openingHour: any): string | undefined;
7
- /**
8
- * Orchestrates the same steps as Apex `CalendarCreation.CreateCalendarAsync`:
9
- * save calendar (`POST /Calendar/Create`), then add participants, then save opening hours
10
- * per day (`POST /Calendar/Participant/Availability/OpeningHour/Save`).
11
- */
12
- export declare function createCalendarWithRelationsAsync(calendar: any, options?: any): Promise<any>;
13
- /**
14
- * Calendar body update, then same member + opening-hour saves as create (Apex-style follow-up).
15
- * For member add/remove *diffs* against existing DB membership, use server-side Apex; this client
16
- * only performs additive Blazeo calls matching the payload.
17
- */
18
- export declare function updateCalendarWithRelationsAsync(calendar: any, options?: any): Promise<any>;
19
- /**
20
- * Aligned with `CalendarCreation`: create/update with members & opening hours,
21
- * or delete calendar only.
22
- */
23
- export declare class CalendarCreation {
24
- static createWithRelationsAsync: typeof createCalendarWithRelationsAsync;
25
- static updateWithRelationsAsync: typeof updateCalendarWithRelationsAsync;
26
- static deleteCalendarAsync: typeof deleteCalendarAsync;
27
- }