@blazeo.com/appointment-client 1.0.11 → 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.
- package/blazeo.com-appointment-client-1.0.14.tgz +0 -0
- package/package.json +3 -2
- package/sample/src/EventTab.jsx +435 -395
- package/sample/src/FetchCalendarTab.jsx +19 -33
- package/sample/src/LeadTab.jsx +335 -0
- package/src/calendar/calendarCreation.ts +62 -15
- package/src/calendar/fetchCalendarDetails.ts +10 -2
- package/src/calendar/getCalendarsByCompany.ts +17 -64
- package/src/calendar/mapToDesiredResponse.ts +31 -17
- package/src/events/getAppointmentsByFilter.ts +98 -0
- package/src/index.ts +23 -14
- package/src/lead/fetchLeadDetails.ts +106 -0
- package/blazeo.com-appointment-client-1.0.11.tgz +0 -0
- package/dist/calendar/blazeoCalendarRelationMethods.d.ts +0 -8
- package/dist/calendar/blazeoCalendarRelationMethods.d.ts.map +0 -1
- package/dist/calendar/blazeoCalendarRelationMethods.js +0 -16
- package/dist/calendar/blazeoCalendarRelationMethods.js.map +0 -1
- package/dist/calendar/buildUnifiedCalendarView.d.ts +0 -39
- package/dist/calendar/buildUnifiedCalendarView.js +0 -301
- package/dist/calendar/calendarCreation.d.ts +0 -27
- package/dist/calendar/calendarCreation.js +0 -191
- package/dist/calendar/calendarCreationFacade.d.ts +0 -27
- package/dist/calendar/calendarCreationFacade.d.ts.map +0 -1
- package/dist/calendar/calendarCreationFacade.js +0 -167
- package/dist/calendar/calendarCreationFacade.js.map +0 -1
- package/dist/calendar/createCalendar.d.ts +0 -81
- package/dist/calendar/createCalendar.d.ts.map +0 -1
- package/dist/calendar/createCalendar.js +0 -206
- package/dist/calendar/createCalendar.js.map +0 -1
- package/dist/calendar/fetchCalendarDetails.d.ts +0 -41
- package/dist/calendar/fetchCalendarDetails.js +0 -262
- package/dist/calendar/fetchCalendarWithOpeningHours.d.ts +0 -25
- package/dist/calendar/fetchCalendarWithOpeningHours.js +0 -114
- package/dist/calendar/getAllParticipantOpeningHours.d.ts +0 -22
- package/dist/calendar/getAllParticipantOpeningHours.js +0 -22
- package/dist/calendar/getCalendarsByCompany.d.ts +0 -9
- package/dist/calendar/getCalendarsByCompany.js +0 -107
- package/dist/calendar/getOpeningHours.d.ts +0 -8
- package/dist/calendar/getOpeningHours.js +0 -9
- package/dist/calendar/getParticipantOpeningHours.d.ts +0 -37
- package/dist/calendar/getParticipantOpeningHours.js +0 -48
- package/dist/calendar/getParticipants.d.ts +0 -7
- package/dist/calendar/getParticipants.js +0 -13
- package/dist/calendar/mapCalendarBoToBlazeoSnapshot.d.ts +0 -10
- package/dist/calendar/mapCalendarBoToBlazeoSnapshot.d.ts.map +0 -1
- package/dist/calendar/mapCalendarBoToBlazeoSnapshot.js +0 -44
- package/dist/calendar/mapCalendarBoToBlazeoSnapshot.js.map +0 -1
- package/dist/calendar/mapCalendarToBlazeoSnapshot.d.ts +0 -29
- package/dist/calendar/mapCalendarToBlazeoSnapshot.d.ts.map +0 -1
- package/dist/calendar/mapCalendarToBlazeoSnapshot.js +0 -44
- package/dist/calendar/mapCalendarToBlazeoSnapshot.js.map +0 -1
- package/dist/calendar/mapToDesiredResponse.d.ts +0 -70
- package/dist/calendar/mapToDesiredResponse.js +0 -99
- package/dist/config/applyBlazeoClientConfig.d.ts +0 -3
- package/dist/config/applyBlazeoClientConfig.d.ts.map +0 -1
- package/dist/config/applyBlazeoClientConfig.js +0 -14
- package/dist/config/applyBlazeoClientConfig.js.map +0 -1
- package/dist/config/applyBlazeoDefaults.d.ts +0 -2
- package/dist/config/applyBlazeoDefaults.d.ts.map +0 -1
- package/dist/config/applyBlazeoDefaults.js +0 -14
- package/dist/config/applyBlazeoDefaults.js.map +0 -1
- package/dist/config/blazeo.config.d.ts +0 -11
- package/dist/config/blazeo.config.d.ts.map +0 -1
- package/dist/config/blazeo.config.js +0 -11
- package/dist/config/blazeo.config.js.map +0 -1
- package/dist/config/blazeoClientDefaults.d.ts +0 -11
- package/dist/config/blazeoClientDefaults.d.ts.map +0 -1
- package/dist/config/blazeoClientDefaults.js +0 -11
- package/dist/config/blazeoClientDefaults.js.map +0 -1
- package/dist/config/ensureBlazeoHttpReady.d.ts +0 -17
- package/dist/config/ensureBlazeoHttpReady.js +0 -31
- package/dist/config/initializeAppointmentClient.d.ts +0 -11
- package/dist/config/initializeAppointmentClient.d.ts.map +0 -1
- package/dist/config/initializeAppointmentClient.js +0 -15
- package/dist/config/initializeAppointmentClient.js.map +0 -1
- package/dist/config/syncBlazeoConnection.d.ts +0 -6
- package/dist/config/syncBlazeoConnection.js +0 -18
- package/dist/events/appointmentEventFacade.d.ts +0 -67
- package/dist/events/appointmentEventFacade.d.ts.map +0 -1
- package/dist/events/appointmentEventFacade.js +0 -124
- package/dist/events/appointmentEventFacade.js.map +0 -1
- package/dist/events/mapAppointmentToEventSnapshot.d.ts +0 -5
- package/dist/events/mapAppointmentToEventSnapshot.d.ts.map +0 -1
- package/dist/events/mapAppointmentToEventSnapshot.js +0 -57
- package/dist/events/mapAppointmentToEventSnapshot.js.map +0 -1
- package/dist/exampleData.d.ts +0 -119
- package/dist/exampleData.d.ts.map +0 -1
- package/dist/exampleData.js +0 -71
- package/dist/exampleData.js.map +0 -1
- package/dist/facade/calendarCreationFacade.d.ts +0 -40
- package/dist/facade/calendarCreationFacade.d.ts.map +0 -1
- package/dist/facade/calendarCreationFacade.js +0 -96
- package/dist/facade/calendarCreationFacade.js.map +0 -1
- package/dist/facade/mapCalendarBOToSnapshot.d.ts +0 -10
- package/dist/facade/mapCalendarBOToSnapshot.d.ts.map +0 -1
- package/dist/facade/mapCalendarBOToSnapshot.js +0 -44
- package/dist/facade/mapCalendarBOToSnapshot.js.map +0 -1
- package/dist/facades/index.d.ts +0 -12
- package/dist/facades/index.d.ts.map +0 -1
- package/dist/facades/index.js +0 -12
- package/dist/facades/index.js.map +0 -1
- package/dist/index.d.ts +0 -40
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -39
- package/dist/index.js.map +0 -1
- package/dist/models/CalendarRootModel.d.ts +0 -56
- package/dist/models/CalendarRootModel.d.ts.map +0 -1
- package/dist/models/CalendarRootModel.js +0 -54
- package/dist/models/CalendarRootModel.js.map +0 -1
- package/dist/models/CalendarSlotModel.d.ts +0 -9
- package/dist/models/CalendarSlotModel.d.ts.map +0 -1
- package/dist/models/CalendarSlotModel.js +0 -8
- package/dist/models/CalendarSlotModel.js.map +0 -1
- package/dist/models/EventModel.d.ts +0 -11
- package/dist/models/EventModel.d.ts.map +0 -1
- package/dist/models/EventModel.js +0 -10
- package/dist/models/EventModel.js.map +0 -1
- package/dist/models/ParticipantModel.d.ts +0 -9
- package/dist/models/ParticipantModel.d.ts.map +0 -1
- package/dist/models/ParticipantModel.js +0 -8
- package/dist/models/ParticipantModel.js.map +0 -1
- package/dist/models/index.d.ts +0 -5
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js +0 -5
- package/dist/models/index.js.map +0 -1
- package/dist/types/appointment.d.ts +0 -28
- package/dist/types/appointment.d.ts.map +0 -1
- package/dist/types/appointment.js +0 -6
- package/dist/types/appointment.js.map +0 -1
- package/dist/types/calendar.d.ts +0 -52
- package/dist/types/calendar.d.ts.map +0 -1
- package/dist/types/calendar.js +0 -6
- package/dist/types/calendar.js.map +0 -1
- package/dist/types/calendarBo.d.ts +0 -62
- package/dist/types/calendarBo.d.ts.map +0 -1
- package/dist/types/calendarBo.js +0 -6
- package/dist/types/calendarBo.js.map +0 -1
- package/sample/package-lock.json +0 -1778
|
@@ -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
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { getSnapshot } from "mobx-state-tree";
|
|
2
|
-
import { addParticipantToCalendar, saveCalendarOpeningHoursBatch } from "./blazeoCalendarRelationMethods.js";
|
|
3
|
-
import { createCalendarAsync, updateCalendarAsync, deleteCalendarAsync } from "./createCalendar.js";
|
|
4
|
-
function isFailureStatus(res) {
|
|
5
|
-
return res.status !== "success" && res.status !== "Success";
|
|
6
|
-
}
|
|
7
|
-
function normalizeParticipantGuid(id) {
|
|
8
|
-
if (id == null || !String(id).trim())
|
|
9
|
-
return undefined;
|
|
10
|
-
return String(id).trim().replace(/^\{|\}$/g, "");
|
|
11
|
-
}
|
|
12
|
-
function newOpeningHourId() {
|
|
13
|
-
const c = globalThis.crypto;
|
|
14
|
-
if (c?.randomUUID)
|
|
15
|
-
return c.randomUUID();
|
|
16
|
-
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Resolves Blazeo `participantId` for an opening-hour row: explicit `participantId`,
|
|
20
|
-
* matching `CalendarCreation.SaveOpeningHours`.
|
|
21
|
-
*/
|
|
22
|
-
export function resolveParticipantIdForOpeningHour(openingHour) {
|
|
23
|
-
const direct = normalizeParticipantGuid(openingHour.participantId);
|
|
24
|
-
if (direct)
|
|
25
|
-
return direct;
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
28
|
-
function effectiveCalendarId(calendarNode, input) {
|
|
29
|
-
const snap = getSnapshot(calendarNode);
|
|
30
|
-
const fromNode = snap.calendarId?.trim();
|
|
31
|
-
if (fromNode && fromNode !== "new")
|
|
32
|
-
return fromNode;
|
|
33
|
-
return (input.calendarId?.trim() || undefined);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Orchestrates the same steps as Apex `CalendarCreation.CreateCalendarAsync`:
|
|
37
|
-
* save calendar (`POST /Calendar/Create`), then add participants, then save opening hours
|
|
38
|
-
* per day (`POST /Calendar/Participant/Availability/OpeningHour/Save`).
|
|
39
|
-
*/
|
|
40
|
-
export async function createCalendarWithRelationsAsync(calendar, options = {}) {
|
|
41
|
-
const hasMembers = (calendar.members?.length ?? 0) > 0;
|
|
42
|
-
const hasHours = (calendar.openingHours?.length ?? 0) > 0;
|
|
43
|
-
if (!hasMembers && !hasHours) {
|
|
44
|
-
const r = await createCalendarAsync(calendar, options);
|
|
45
|
-
if (!r.ok)
|
|
46
|
-
return r;
|
|
47
|
-
return { ...r, membersAdded: 0, openingHoursSaved: 0 };
|
|
48
|
-
}
|
|
49
|
-
if (options.localOnly) {
|
|
50
|
-
const r = await createCalendarAsync(calendar, options);
|
|
51
|
-
if (!r.ok)
|
|
52
|
-
return r;
|
|
53
|
-
return { ...r, membersAdded: 0, openingHoursSaved: 0 };
|
|
54
|
-
}
|
|
55
|
-
const created = await createCalendarAsync(calendar, options);
|
|
56
|
-
if (!created.ok)
|
|
57
|
-
return created;
|
|
58
|
-
return runMembersAndOpeningHoursAfterCalendarSave(calendar, created.calendar, created);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* After calendar `create` or `update`, add members and opening hours (same order as Apex facade).
|
|
62
|
-
*/
|
|
63
|
-
async function runMembersAndOpeningHoursAfterCalendarSave(calendar, calendarNode, baseSuccess) {
|
|
64
|
-
const calendarIdStr = effectiveCalendarId(calendarNode, calendar);
|
|
65
|
-
if (!calendarIdStr) {
|
|
66
|
-
return {
|
|
67
|
-
ok: false,
|
|
68
|
-
error: "Could not resolve calendar id after save. Ensure the API returned a calendar id.",
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
let membersAdded = 0;
|
|
72
|
-
for (const m of calendar.members ?? []) {
|
|
73
|
-
const pid = normalizeParticipantGuid(m.id);
|
|
74
|
-
if (!pid) {
|
|
75
|
-
return {
|
|
76
|
-
ok: false,
|
|
77
|
-
error: `Member id ${m.id}: thirdPartyMemberId is required to add a participant.`,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const res = await addParticipantToCalendar(calendarNode, pid);
|
|
81
|
-
if (isFailureStatus(res)) {
|
|
82
|
-
const msg = res.message ??
|
|
83
|
-
(typeof res.data === "string" ? res.data : undefined) ??
|
|
84
|
-
JSON.stringify(res);
|
|
85
|
-
return {
|
|
86
|
-
ok: false,
|
|
87
|
-
error: `addParticipant failed for member ${m.id}: ${msg}`,
|
|
88
|
-
apiResponse: res,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
membersAdded += 1;
|
|
92
|
-
}
|
|
93
|
-
// 2. Save Opening Hours (Plan V2: Grouped by participant with explicit off-days per slot)
|
|
94
|
-
const openingHours = calendar.openingHours ?? [];
|
|
95
|
-
const hoursByParticipant = new Map();
|
|
96
|
-
for (const oh of openingHours) {
|
|
97
|
-
const participantId = resolveParticipantIdForOpeningHour(oh);
|
|
98
|
-
if (!participantId) {
|
|
99
|
-
return {
|
|
100
|
-
ok: false,
|
|
101
|
-
error: `Opening hour id ${oh.id}: participantId is required.`,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
if (!hoursByParticipant.has(participantId)) {
|
|
105
|
-
hoursByParticipant.set(participantId, []);
|
|
106
|
-
}
|
|
107
|
-
// Plan V2 Logic: For every opening hour object, generate EXACTLY 7 entries (days 0-6).
|
|
108
|
-
// If the day is in oh.days, it's ON. If not, it's OFF.
|
|
109
|
-
const activeDays = oh.days ?? [];
|
|
110
|
-
const openingHourId = oh.openingHourId?.trim() || newOpeningHourId();
|
|
111
|
-
for (let day = 0; day <= 6; day++) {
|
|
112
|
-
const isIncluded = activeDays.includes(day);
|
|
113
|
-
const isOff = isIncluded ? !!oh.off : true; // If not in days array, it's explicitly OFF
|
|
114
|
-
hoursByParticipant.get(participantId)?.push({
|
|
115
|
-
calendarId: calendarIdStr,
|
|
116
|
-
participantId,
|
|
117
|
-
day,
|
|
118
|
-
startHour: oh.startHour,
|
|
119
|
-
startMinute: oh.startMinute,
|
|
120
|
-
endHour: oh.endHour,
|
|
121
|
-
endMinute: oh.endMinute,
|
|
122
|
-
off: isOff,
|
|
123
|
-
// Plan V2 Optimization: Generate a unique ID for EVERY day record.
|
|
124
|
-
// This prevents the backend from deduplicating/overwriting when multiple
|
|
125
|
-
// records for the same participant + slot are sent in one batch.
|
|
126
|
-
openingHourId: newOpeningHourId(),
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
let openingHoursSaved = 0;
|
|
131
|
-
for (const [participantId, payload] of hoursByParticipant.entries()) {
|
|
132
|
-
if (payload.length === 0)
|
|
133
|
-
continue;
|
|
134
|
-
// Plan V2 Optimization: Clear existing records for this participant first.
|
|
135
|
-
// This ensures that when we save the new batch (with unique per-day IDs),
|
|
136
|
-
// we don't leak orphaned records or create duplicates during updates.
|
|
137
|
-
await calendarNode.removeParticipantOpeningHours(participantId);
|
|
138
|
-
// Use the batch save method (plural)
|
|
139
|
-
const res = await saveCalendarOpeningHoursBatch(calendarNode, payload);
|
|
140
|
-
if (isFailureStatus(res)) {
|
|
141
|
-
const msg = res.message ??
|
|
142
|
-
(typeof res.data === "string" ? res.data : undefined) ??
|
|
143
|
-
JSON.stringify(res);
|
|
144
|
-
return {
|
|
145
|
-
ok: false,
|
|
146
|
-
error: `saveOpeningHours batch failed for participant ${participantId}: ${msg}`,
|
|
147
|
-
apiResponse: res,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
openingHoursSaved += payload.length;
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
...baseSuccess,
|
|
154
|
-
membersAdded,
|
|
155
|
-
openingHoursSaved,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Calendar body update, then same member + opening-hour saves as create (Apex-style follow-up).
|
|
160
|
-
* For member add/remove *diffs* against existing DB membership, use server-side Apex; this client
|
|
161
|
-
* only performs additive Blazeo calls matching the payload.
|
|
162
|
-
*/
|
|
163
|
-
export async function updateCalendarWithRelationsAsync(calendar, options = {}) {
|
|
164
|
-
const hasMembers = (calendar.members?.length ?? 0) > 0;
|
|
165
|
-
const hasHours = (calendar.openingHours?.length ?? 0) > 0;
|
|
166
|
-
if (!hasMembers && !hasHours) {
|
|
167
|
-
const r = await updateCalendarAsync(calendar, options);
|
|
168
|
-
if (!r.ok)
|
|
169
|
-
return r;
|
|
170
|
-
return { ...r, membersAdded: 0, openingHoursSaved: 0 };
|
|
171
|
-
}
|
|
172
|
-
if (options.localOnly) {
|
|
173
|
-
const r = await updateCalendarAsync(calendar, options);
|
|
174
|
-
if (!r.ok)
|
|
175
|
-
return r;
|
|
176
|
-
return { ...r, membersAdded: 0, openingHoursSaved: 0 };
|
|
177
|
-
}
|
|
178
|
-
const updated = await updateCalendarAsync(calendar, options);
|
|
179
|
-
if (!updated.ok)
|
|
180
|
-
return updated;
|
|
181
|
-
return runMembersAndOpeningHoursAfterCalendarSave(calendar, updated.calendar, updated);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Aligned with `CalendarCreation`: create/update with members & opening hours,
|
|
185
|
-
* or delete calendar only.
|
|
186
|
-
*/
|
|
187
|
-
export class CalendarCreation {
|
|
188
|
-
static createWithRelationsAsync = createCalendarWithRelationsAsync;
|
|
189
|
-
static updateWithRelationsAsync = updateCalendarWithRelationsAsync;
|
|
190
|
-
static deleteCalendarAsync = deleteCalendarAsync;
|
|
191
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { deleteCalendarAsync } from "./createCalendar.js";
|
|
2
|
-
/**
|
|
3
|
-
* Resolves Blazeo `participantId` for an opening-hour row: explicit `participantId`,
|
|
4
|
-
* matching `CalendarCreationAPIFacade.SaveOpeningHours`.
|
|
5
|
-
*/
|
|
6
|
-
export declare function resolveParticipantIdForOpeningHour(openingHour: any): string | undefined;
|
|
7
|
-
/**
|
|
8
|
-
* Orchestrates the same steps as Apex `CalendarCreationAPIFacade.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
|
-
* Facade aligned with `CalendarCreationAPIFacade`: create/update with members & opening hours,
|
|
21
|
-
* or delete calendar only.
|
|
22
|
-
*/
|
|
23
|
-
export declare class CalendarCreationFacade {
|
|
24
|
-
static createWithRelationsAsync: typeof createCalendarWithRelationsAsync;
|
|
25
|
-
static updateWithRelationsAsync: typeof updateCalendarWithRelationsAsync;
|
|
26
|
-
static deleteCalendarAsync: typeof deleteCalendarAsync;
|
|
27
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"calendarCreationFacade.d.ts","sourceRoot":"","sources":["../../src/calendar/calendarCreationFacade.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAGL,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAiB7B;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,kBAAkB,GAC9B,MAAM,GAAG,SAAS,CAIpB;AAeD,MAAM,MAAM,4BAA4B,GAAG,qBAAqB,GAAG;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC,4BAA4B,GAC5B,OAAO,CAAC,oBAAoB,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAEjD;;;;GAIG;AACH,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CAwBtC;AAuFD;;;;GAIG;AACH,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CAwBtC;AAED;;;GAGG;AACH,qBAAa,sBAAsB;IACjC,MAAM,CAAC,wBAAwB,0CAAoC;IACnE,MAAM,CAAC,wBAAwB,0CAAoC;IACnE,MAAM,CAAC,mBAAmB,6BAAuB;CAClD"}
|