@pisell/private-materials 6.11.650 → 6.11.651

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.
@@ -11,6 +11,7 @@ const require_index$1 = require("../shared/index.js");
11
11
  const require_index$2 = require("../../../../../components/eventBooking/components/timeResourceSelector/index.js");
12
12
  const require_utils$3 = require("../../../../../components/eventBooking/components/bookingAvailabilityCalendar/utils.js");
13
13
  const require_autoResolution = require("../autoResolution.js");
14
+ const require_posCustomTime = require("./posCustomTime.js");
14
15
  let dayjs = require("dayjs");
15
16
  dayjs = require_runtime.__toESM(dayjs);
16
17
  let react = require("react");
@@ -99,7 +100,18 @@ const getProductDurationMinutes = (context) => {
99
100
  const duration = (_normalizeDurationMin = normalizeDurationMinutesValue(product === null || product === void 0 ? void 0 : product.duration)) !== null && _normalizeDurationMin !== void 0 ? _normalizeDurationMin : normalizeDurationMinutesValue(product === null || product === void 0 ? void 0 : product.service_duration);
100
101
  return duration ? Math.floor(duration) : null;
101
102
  };
102
- const isPosDurationAvailabilityContext = (context) => context.services.presentationPlatform === "pos" && getProductDurationMinutes(context) !== null;
103
+ const isPosDurationAvailabilityContext = (context) => {
104
+ var _product$cartDetailVa2, _product$_extend2;
105
+ const product = context.draft.productData;
106
+ const isSession = Boolean(require_utils$2.isSessionProduct(product) || (product === null || product === void 0 || (_product$cartDetailVa2 = product.cartDetailValue) === null || _product$cartDetailVa2 === void 0 ? void 0 : _product$cartDetailVa2.session) || (product === null || product === void 0 || (_product$_extend2 = product._extend) === null || _product$_extend2 === void 0 || (_product$_extend2 = _product$_extend2.other) === null || _product$_extend2 === void 0 ? void 0 : _product$_extend2.session));
107
+ return context.services.presentationPlatform === "pos" && !isSession && (getProductDurationMinutes(context) !== null || require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration));
108
+ };
109
+ const isPosSessionAvailabilityContext = (context) => {
110
+ var _product$cartDetailVa3, _product$_extend3;
111
+ const product = context.draft.productData;
112
+ return context.services.presentationPlatform === "pos" && Boolean(require_utils$2.isSessionProduct(product) || (product === null || product === void 0 || (_product$cartDetailVa3 = product.cartDetailValue) === null || _product$cartDetailVa3 === void 0 ? void 0 : _product$cartDetailVa3.session) || (product === null || product === void 0 || (_product$_extend3 = product._extend) === null || _product$_extend3 === void 0 || (_product$_extend3 = _product$_extend3.other) === null || _product$_extend3 === void 0 ? void 0 : _product$_extend3.session));
113
+ };
114
+ const isPosCustomTimeAvailabilityContext = (context) => isPosDurationAvailabilityContext(context) || isPosSessionAvailabilityContext(context);
103
115
  const getDraftRangeDurationMinutes = (context) => {
104
116
  const { startDate, endDate, startTime, endTime } = context.draft.booking;
105
117
  const normalizedStartTime = normalizeStartTimeValue(startTime);
@@ -113,13 +125,13 @@ const getDraftRangeDurationMinutes = (context) => {
113
125
  };
114
126
  const getAvailabilityDurationOverride = (context, durationOverride) => {
115
127
  var _ref, _ref2, _normalizeDurationMin2;
116
- if (!isPosDurationAvailabilityContext(context)) return void 0;
128
+ if (!isPosCustomTimeAvailabilityContext(context)) return void 0;
117
129
  const duration = (_ref = (_ref2 = (_normalizeDurationMin2 = normalizeDurationMinutesValue(durationOverride)) !== null && _normalizeDurationMin2 !== void 0 ? _normalizeDurationMin2 : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref2 !== void 0 ? _ref2 : getDraftRangeDurationMinutes(context)) !== null && _ref !== void 0 ? _ref : getProductDurationMinutes(context);
118
130
  return duration && duration > 0 ? Math.floor(duration) : void 0;
119
131
  };
120
132
  const getAvailabilityStartTimeOverride = (context, startTimeOverride) => {
121
133
  var _normalizeStartTimeVa;
122
- if (!isPosDurationAvailabilityContext(context)) return void 0;
134
+ if (!isPosCustomTimeAvailabilityContext(context)) return void 0;
123
135
  return ((_normalizeStartTimeVa = normalizeStartTimeValue(startTimeOverride)) !== null && _normalizeStartTimeVa !== void 0 ? _normalizeStartTimeVa : normalizeStartTimeValue(context.draft.booking.startTime)) || void 0;
124
136
  };
125
137
  /**
@@ -154,20 +166,23 @@ const finalizeCandidateWithoutResourceStep = function() {
154
166
  };
155
167
  }();
156
168
  const refreshAvailabilityTimes = function() {
157
- var _ref4 = require_asyncToGenerator._asyncToGenerator(function* (context, module, durationOverride, startTimeOverride) {
158
- var _context$getModuleDat2;
169
+ var _ref5 = require_asyncToGenerator._asyncToGenerator(function* (context, module, options = {}) {
170
+ var _context$getModuleDat2, _ref4;
171
+ const { durationOverride, startTimeOverride, selectionIntent = "restore" } = options;
159
172
  const availability = context.services.availability;
160
173
  const allowUnavailable = context.services.allowUnavailableBookingSelection === true;
161
174
  const posDurationAvailability = isPosDurationAvailabilityContext(context);
175
+ const posSessionAvailability = isPosSessionAvailabilityContext(context);
176
+ const posCustomTimeAvailability = posDurationAvailability || posSessionAvailability;
162
177
  const requestedDuration = getAvailabilityDurationOverride(context, durationOverride);
163
178
  const requestedStartTime = getAvailabilityStartTimeOverride(context, startTimeOverride);
164
179
  const selectedDate = context.draft.booking.startDate.format("YYYY-MM-DD");
165
180
  const requestId = Date.now() + Math.random();
166
- const posDurationHydrationKey = posDurationAvailability && requestedDuration && requestedStartTime ? `${selectedDate}|${requestedStartTime}|${requestedDuration}` : void 0;
181
+ const posCustomTimeHydrationKey = posCustomTimeAvailability && requestedDuration && requestedStartTime ? `${selectedDate}|${requestedStartTime}|${requestedDuration}` : void 0;
167
182
  context.setModuleData(module.key, {
168
183
  requestId,
169
184
  timeSlots: [],
170
- posDurationHydrationKey
185
+ posCustomTimeHydrationKey
171
186
  });
172
187
  const group = (yield availability.getProductTimeRanges(availability.contextId, require_objectSpread2._objectSpread2({
173
188
  productIds: [availability.productId],
@@ -178,6 +193,39 @@ const refreshAvailabilityTimes = function() {
178
193
  partySize: require_index$1.resolveSelectionFlowQueryPartySize(context.draft, availability.partySize)
179
194
  }, requestedDuration ? require_objectSpread2._objectSpread2({ durationMinutesByProductId: { [String(availability.productId)]: requestedDuration } }, requestedStartTime ? { durationStartTimesByProductId: { [String(availability.productId)]: [requestedStartTime] } } : {}) : {}))).find((item) => String(item.productId) === String(availability.productId));
180
195
  const candidates = (group === null || group === void 0 ? void 0 : group.ranges) || [];
196
+ const product = context.draft.productData;
197
+ if (posDurationAvailability && selectionIntent === "restore" && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration)) {
198
+ var _context$hostContext, _moduleOptions$slice, _normalizeDurationMin3;
199
+ const moduleOptions = require_index$1.getModuleOptions(module);
200
+ const configuredSlice = (_context$hostContext = context.hostContext) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.bookingConfig) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.config) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.basic) === null || _context$hostContext === void 0 ? void 0 : _context$hostContext.service_time;
201
+ const fallbackSlice = (_moduleOptions$slice = moduleOptions.slice) !== null && _moduleOptions$slice !== void 0 ? _moduleOptions$slice : typeof configuredSlice === "object" ? configuredSlice === null || configuredSlice === void 0 ? void 0 : configuredSlice.value : configuredSlice;
202
+ const baseDurationMinutes = require_posCustomTime.resolvePosCustomTimeBaseMinutes(group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
203
+ const nextStartTime = require_posCustomTime.resolvePosCustomTimeDefaultStartTime(context.draft.booking.startTime, baseDurationMinutes);
204
+ const nextDuration = require_posCustomTime.resolvePosCustomTimeDefaultDurationMinutes((_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes);
205
+ const changedFields = [];
206
+ if (nextStartTime !== context.draft.booking.startTime) changedFields.push("booking.startTime");
207
+ if (nextDuration !== context.draft.booking.duration) changedFields.push("booking.duration");
208
+ if (context.draft.booking.selectedCandidate) changedFields.push("booking.selectedCandidate");
209
+ if (context.draft.booking.commitCandidate) changedFields.push("booking.commitCandidate");
210
+ if (changedFields.length > 0 && nextStartTime) {
211
+ context.updateDraft({ booking: {
212
+ startTime: nextStartTime,
213
+ duration: nextDuration,
214
+ selectedCandidate: void 0,
215
+ commitCandidate: void 0
216
+ } }, {
217
+ changedFields,
218
+ sourceModuleKey: module.key,
219
+ sourceModuleType: "time"
220
+ });
221
+ yield refreshAvailabilityTimes(context, module, {
222
+ durationOverride: nextDuration,
223
+ startTimeOverride: nextStartTime,
224
+ selectionIntent: "custom"
225
+ });
226
+ return;
227
+ }
228
+ }
181
229
  if (candidates.length === 0) {
182
230
  var _context$getModuleDat;
183
231
  if (((_context$getModuleDat = context.getModuleData(module.key)) === null || _context$getModuleDat === void 0 ? void 0 : _context$getModuleDat.requestId) !== requestId) return;
@@ -186,7 +234,7 @@ const refreshAvailabilityTimes = function() {
186
234
  timeSlots: [],
187
235
  selectedCandidate: void 0,
188
236
  slotStepMinutes: group === null || group === void 0 ? void 0 : group.slotStepMinutes,
189
- posDurationHydrationKey
237
+ posCustomTimeHydrationKey
190
238
  });
191
239
  return;
192
240
  }
@@ -203,17 +251,42 @@ const refreshAvailabilityTimes = function() {
203
251
  const draftStartTime = normalizeStartTimeValue(context.draft.booking.startTime);
204
252
  const draftEndTime = normalizeStartTimeValue(context.draft.booking.endTime);
205
253
  const requestedPosStartTime = requestedStartTime || draftStartTime;
206
- const restoredDraftCandidate = draftStartTime ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && isSameCandidateStart(candidate, selectedDate, draftStartTime) && (posDurationAvailability || normalizeStartTimeValue(candidate.endTime) === draftEndTime)) : void 0;
207
- const restoredExistingCandidate = existingCandidate ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (candidate.key === existingCandidate.key || posDurationAvailability && isSameCandidateStart(candidate, existingCandidate.date, normalizeStartTimeValue(existingCandidate.startTime)))) : void 0;
208
- const fallbackOsCandidate = posDurationAvailability && requestedPosStartTime ? candidates.find((candidate) => isSameCandidateStart(candidate, selectedDate, requestedPosStartTime)) : void 0;
209
- const restoredCandidate = restoredDraftCandidate || restoredExistingCandidate || fallbackOsCandidate;
254
+ const requestedPosDuration = (_ref4 = requestedDuration !== null && requestedDuration !== void 0 ? requestedDuration : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref4 !== void 0 ? _ref4 : getDraftRangeDurationMinutes(context);
255
+ const restoredDraftCandidate = draftStartTime ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (posSessionAvailability ? require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
256
+ date: selectedDate,
257
+ startTime: draftStartTime,
258
+ durationMinutes: requestedPosDuration
259
+ }) : isSameCandidateStart(candidate, selectedDate, draftStartTime) && (posDurationAvailability || normalizeStartTimeValue(candidate.endTime) === draftEndTime))) : void 0;
260
+ const restoredExistingCandidate = existingCandidate ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (candidate.key === existingCandidate.key || (posSessionAvailability ? candidate.source === existingCandidate.source && require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
261
+ date: existingCandidate.date,
262
+ startTime: normalizeStartTimeValue(existingCandidate.startTime),
263
+ durationMinutes: require_posCustomTime.getAvailabilityCandidateDurationMinutes(existingCandidate)
264
+ }) : posDurationAvailability && isSameCandidateStart(candidate, existingCandidate.date, normalizeStartTimeValue(existingCandidate.startTime))))) : void 0;
265
+ const fallbackOsCandidate = posCustomTimeAvailability && requestedPosStartTime ? candidates.find((candidate) => posSessionAvailability ? require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
266
+ date: selectedDate,
267
+ startTime: requestedPosStartTime,
268
+ durationMinutes: requestedPosDuration
269
+ }) : isSameCandidateStart(candidate, selectedDate, requestedPosStartTime)) : void 0;
270
+ const customSelectionIntent = posCustomTimeAvailability && selectionIntent === "custom";
271
+ const restoredCandidate = require_posCustomTime.resolvePosCustomTimeCandidate({
272
+ candidates: times.filter((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable)),
273
+ customSelectionIntent,
274
+ requestedCustomRange: customSelectionIntent && requestedPosStartTime && requestedPosDuration ? {
275
+ date: selectedDate,
276
+ startTime: requestedPosStartTime,
277
+ durationMinutes: requestedPosDuration
278
+ } : void 0,
279
+ restoredDraftCandidate,
280
+ restoredExistingCandidate,
281
+ fallbackCandidate: fallbackOsCandidate
282
+ });
210
283
  const normallySelectableCandidates = times.filter((candidate) => isAvailabilityCandidateSelectable(candidate));
211
284
  const selectableCandidates = normallySelectableCandidates.length > 0 || !allowUnavailable ? normallySelectableCandidates : times;
212
- const initialCandidate = restoredCandidate || (posDurationAvailability && Boolean(requestedPosStartTime) ? void 0 : selectableCandidates[0]);
285
+ const initialCandidate = restoredCandidate || (posCustomTimeAvailability && Boolean(requestedPosStartTime && requestedPosDuration) ? void 0 : selectableCandidates[0]);
213
286
  context.setModuleData(module.key, {
214
287
  requestId,
215
288
  slotStepMinutes: group === null || group === void 0 ? void 0 : group.slotStepMinutes,
216
- timeSlots: times.map((candidate) => ({
289
+ timeSlots: (posSessionAvailability ? require_posCustomTime.getSessionPresetCandidates(times) : times).map((candidate) => ({
217
290
  id: candidate.key,
218
291
  start_time: candidate.startTime,
219
292
  end_time: candidate.endTime,
@@ -223,9 +296,9 @@ const refreshAvailabilityTimes = function() {
223
296
  candidate
224
297
  })),
225
298
  selectedCandidate: initialCandidate,
226
- posDurationHydrationKey
299
+ posCustomTimeHydrationKey
227
300
  });
228
- const shouldWriteInitialCandidate = Boolean(initialCandidate) && (posDurationAvailability || !existingCandidate || initialCandidate.key !== existingCandidate.key);
301
+ const shouldWriteInitialCandidate = Boolean(initialCandidate) && (posCustomTimeAvailability || !existingCandidate || initialCandidate.key !== existingCandidate.key);
229
302
  if (initialCandidate && shouldWriteInitialCandidate) {
230
303
  const startAt = (0, dayjs.default)(initialCandidate.startAt);
231
304
  const endAt = (0, dayjs.default)(initialCandidate.endAt);
@@ -253,8 +326,8 @@ const refreshAvailabilityTimes = function() {
253
326
  }
254
327
  if (initialCandidate && !hasCompiledResourceModule(context)) yield finalizeCandidateWithoutResourceStep(context, initialCandidate);
255
328
  });
256
- return function refreshAvailabilityTimes(_x3, _x4, _x5, _x6) {
257
- return _ref4.apply(this, arguments);
329
+ return function refreshAvailabilityTimes(_x3, _x4) {
330
+ return _ref5.apply(this, arguments);
258
331
  };
259
332
  }();
260
333
  const hasDurationValue = (value) => typeof value === "number" && value > 0 || typeof value === "string" && value.length > 0;
@@ -332,7 +405,7 @@ const getFlexibleDuration = (timeObj) => {
332
405
  return (timeObj === null || timeObj === void 0 || (_timeObj$durationSlic = timeObj.durationSlicesBasedOnTime) === null || _timeObj$durationSlic === void 0 || (_timeObj$durationSlic = _timeObj$durationSlic.find((item) => typeof (item === null || item === void 0 ? void 0 : item.value) === "string" && item.value.startsWith("flexible_") && !item.disabled)) === null || _timeObj$durationSlic === void 0 ? void 0 : _timeObj$durationSlic.value) || (timeObj === null || timeObj === void 0 || (_timeObj$durationSlic2 = timeObj.durationSlicesBasedOnTime) === null || _timeObj$durationSlic2 === void 0 || (_timeObj$durationSlic2 = _timeObj$durationSlic2.find((item) => typeof (item === null || item === void 0 ? void 0 : item.value) === "string" && item.value.startsWith("flexible_"))) === null || _timeObj$durationSlic2 === void 0 ? void 0 : _timeObj$durationSlic2.value);
333
406
  };
334
407
  const resolveInitialDuration = (context) => {
335
- var _context$services$get, _context$services, _serviceCacheItem$_ex, _serviceCacheItem$_ex2, _context$draft$produc, _context$draft$produc2, _timeObj$durationSlic3, _ref5, _configuredOption$val, _timeObj$durationSlic4;
408
+ var _context$services$get, _context$services, _serviceCacheItem$_ex, _serviceCacheItem$_ex2, _context$draft$produc, _context$draft$produc2, _timeObj$durationSlic3, _ref6, _configuredOption$val, _timeObj$durationSlic4;
336
409
  if (hasDurationValue(context.draft.booking.duration)) return context.draft.booking.duration;
337
410
  const serviceCacheItem = (_context$services$get = (_context$services = context.services).getCurrentCacheItem) === null || _context$services$get === void 0 ? void 0 : _context$services$get.call(_context$services);
338
411
  const existingDuration = normalizeSelectionDuration((_serviceCacheItem$_ex = serviceCacheItem === null || serviceCacheItem === void 0 || (_serviceCacheItem$_ex2 = serviceCacheItem._extend) === null || _serviceCacheItem$_ex2 === void 0 ? void 0 : _serviceCacheItem$_ex2.duration) !== null && _serviceCacheItem$_ex !== void 0 ? _serviceCacheItem$_ex : (_context$draft$produc = context.draft.productData) === null || _context$draft$produc === void 0 || (_context$draft$produc = _context$draft$produc._extend) === null || _context$draft$produc === void 0 ? void 0 : _context$draft$produc.duration);
@@ -344,7 +417,7 @@ const resolveInitialDuration = (context) => {
344
417
  if (hasDurationValue(normalizedDuration)) return normalizedDuration;
345
418
  const configuredValue = productDuration === null || productDuration === void 0 ? void 0 : productDuration.value;
346
419
  const configuredOption = timeObj === null || timeObj === void 0 || (_timeObj$durationSlic3 = timeObj.durationSlicesBasedOnTime) === null || _timeObj$durationSlic3 === void 0 ? void 0 : _timeObj$durationSlic3.find((item) => (item === null || item === void 0 ? void 0 : item.value) == configuredValue);
347
- return (_ref5 = (_configuredOption$val = configuredOption === null || configuredOption === void 0 ? void 0 : configuredOption.value) !== null && _configuredOption$val !== void 0 ? _configuredOption$val : timeObj === null || timeObj === void 0 || (_timeObj$durationSlic4 = timeObj.durationSlicesBasedOnTime) === null || _timeObj$durationSlic4 === void 0 || (_timeObj$durationSlic4 = _timeObj$durationSlic4[0]) === null || _timeObj$durationSlic4 === void 0 ? void 0 : _timeObj$durationSlic4.value) !== null && _ref5 !== void 0 ? _ref5 : null;
420
+ return (_ref6 = (_configuredOption$val = configuredOption === null || configuredOption === void 0 ? void 0 : configuredOption.value) !== null && _configuredOption$val !== void 0 ? _configuredOption$val : timeObj === null || timeObj === void 0 || (_timeObj$durationSlic4 = timeObj.durationSlicesBasedOnTime) === null || _timeObj$durationSlic4 === void 0 || (_timeObj$durationSlic4 = _timeObj$durationSlic4[0]) === null || _timeObj$durationSlic4 === void 0 ? void 0 : _timeObj$durationSlic4.value) !== null && _ref6 !== void 0 ? _ref6 : null;
348
421
  };
349
422
  const deriveTimeBooking = (context, startTime, duration) => {
350
423
  let nextDuration = duration;
@@ -391,7 +464,7 @@ const refreshTimeModule = (context, module) => {
391
464
  });
392
465
  };
393
466
  const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
394
- var _context$moduleState$2, _context$moduleState$3, _context$moduleState$4, _context$hostContext, _options$slice, _durationProps$select2, _options$durationSele2;
467
+ var _context$moduleState$2, _context$moduleState$3, _context$moduleState$4, _context$hostContext2, _options$slice, _durationProps$select2, _options$durationSele2;
395
468
  const options = require_index$1.getModuleOptions(module);
396
469
  const unsupportedReason = require_index$1.getUnsupportedBookingFlowReason(context.draft.productData);
397
470
  const required = options.required !== false;
@@ -399,7 +472,9 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
399
472
  const duration = context.draft.booking.duration;
400
473
  const useAvailability = options.mode === "availability";
401
474
  const productDurationMinutes = getProductDurationMinutes(context);
402
- const usePosDurationAvailability = useAvailability && isPosDurationAvailabilityContext(context) && Boolean(productDurationMinutes);
475
+ const usePosDurationAvailability = useAvailability && isPosDurationAvailabilityContext(context);
476
+ const usePosSessionAvailability = useAvailability && isPosSessionAvailabilityContext(context);
477
+ const usePosCustomTimeAvailability = usePosDurationAvailability || usePosSessionAvailability;
403
478
  const availability = useAvailability ? context.services.availability : void 0;
404
479
  const availabilityData = context.getModuleData(module.key);
405
480
  const capacityDisplaySettings = getCapacityDisplaySettings(context.hostContext);
@@ -409,7 +484,7 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
409
484
  const dateModule = context.steps.flatMap((step) => step.modules).find((item) => item.type === "date");
410
485
  const isDateModuleLoading = dateModule ? ((_context$moduleState$3 = context.moduleState[dateModule.key]) === null || _context$moduleState$3 === void 0 ? void 0 : _context$moduleState$3.status) === "loading" : false;
411
486
  const hasNoSelectableAvailabilityDate = Boolean(useAvailability && dateModule && ((_context$moduleState$4 = context.moduleState[dateModule.key]) === null || _context$moduleState$4 === void 0 ? void 0 : _context$moduleState$4.status) === "ready" && !isAvailabilityDateReadyForTime(context));
412
- const configuredSlice = (_context$hostContext = context.hostContext) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.bookingConfig) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.config) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.basic) === null || _context$hostContext === void 0 ? void 0 : _context$hostContext.service_time;
487
+ const configuredSlice = (_context$hostContext2 = context.hostContext) === null || _context$hostContext2 === void 0 || (_context$hostContext2 = _context$hostContext2.bookingConfig) === null || _context$hostContext2 === void 0 || (_context$hostContext2 = _context$hostContext2.config) === null || _context$hostContext2 === void 0 || (_context$hostContext2 = _context$hostContext2.basic) === null || _context$hostContext2 === void 0 ? void 0 : _context$hostContext2.service_time;
413
488
  const slice = (_options$slice = options.slice) !== null && _options$slice !== void 0 ? _options$slice : typeof configuredSlice === "object" ? configuredSlice === null || configuredSlice === void 0 ? void 0 : configuredSlice.value : configuredSlice;
414
489
  const resourceModule = context.steps.flatMap((step) => step.modules).find((item) => item.type === "resource");
415
490
  const resourceModuleData = resourceModule ? context.getModuleData(resourceModule.key) : void 0;
@@ -430,14 +505,16 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
430
505
  resourceModuleData === null || resourceModuleData === void 0 ? void 0 : resourceModuleData.cacheItem,
431
506
  resourceModuleData === null || resourceModuleData === void 0 ? void 0 : resourceModuleData.requestId
432
507
  ]);
433
- const posDurationTimeObj = (0, react.useMemo)(() => usePosDurationAvailability && productDurationMinutes ? buildPosDurationTimeObj(runtime.timeObj, productDurationMinutes, duration) : runtime.timeObj, [
434
- usePosDurationAvailability,
435
- productDurationMinutes,
508
+ const posCustomTimeBaseMinutes = usePosDurationAvailability ? require_posCustomTime.resolvePosCustomTimeBaseMinutes(productDurationMinutes, availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes, slice) : usePosSessionAvailability ? availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes : null;
509
+ const posCustomTimeObj = (0, react.useMemo)(() => usePosCustomTimeAvailability && posCustomTimeBaseMinutes ? buildPosDurationTimeObj(runtime.timeObj, posCustomTimeBaseMinutes, duration) : runtime.timeObj, [
510
+ usePosCustomTimeAvailability,
511
+ posCustomTimeBaseMinutes,
436
512
  runtime.timeObj,
437
513
  duration
438
514
  ]);
439
515
  const durationProps = runtime.durationProps;
440
516
  const applyAvailabilityCandidate = (candidate) => {
517
+ if (!availabilityData) return;
441
518
  context.setModuleData(module.key, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, availabilityData), {}, { selectedCandidate: candidate }));
442
519
  if (!candidate) return;
443
520
  const startAt = (0, dayjs.default)(candidate.startAt);
@@ -512,7 +589,7 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
512
589
  }, [handle, registerHandle]);
513
590
  (0, react.useEffect)(() => {
514
591
  var _context$draft$bookin2;
515
- if (!usePosDurationAvailability || !availability) return;
592
+ if (!usePosCustomTimeAvailability || !availability) return;
516
593
  if (!startTime || !hasDurationValue(duration)) return;
517
594
  if (availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate) return;
518
595
  if (moduleStatus === "loading") return;
@@ -521,12 +598,16 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
521
598
  const requestedStartTime = getAvailabilityStartTimeOverride(context);
522
599
  if (!selectedDate || !requestedDuration || !requestedStartTime) return;
523
600
  const hydrationKey = `${selectedDate}|${requestedStartTime}|${requestedDuration}`;
524
- if ((availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.posDurationHydrationKey) === hydrationKey) return;
601
+ if ((availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.posCustomTimeHydrationKey) === hydrationKey) return;
525
602
  context.setModuleStatus(module.key, "loading");
526
- refreshAvailabilityTimes(context, module, duration, startTime).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
603
+ refreshAvailabilityTimes(context, module, {
604
+ durationOverride: duration,
605
+ startTimeOverride: startTime,
606
+ selectionIntent: "custom"
607
+ }).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
527
608
  }, [
528
609
  availability,
529
- availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.posDurationHydrationKey,
610
+ availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.posCustomTimeHydrationKey,
530
611
  availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate,
531
612
  context,
532
613
  context.draft.booking.startDate,
@@ -534,8 +615,23 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
534
615
  module,
535
616
  moduleStatus,
536
617
  startTime,
537
- usePosDurationAvailability
618
+ usePosCustomTimeAvailability
538
619
  ]);
620
+ const renderAvailabilityTimeSelector = () => /* @__PURE__ */ react.default.createElement(require_index$2.default, {
621
+ className: (0, classnames.default)("selection-flow-time-resource-selector", `selection-flow-time-resource-selector--columns-${timeSlotColumns}`),
622
+ displayMode: "plain",
623
+ timeSlots: hasNoSelectableAvailabilityDate ? [] : (availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.timeSlots) || [],
624
+ defaultSelectFirst: false,
625
+ showEmptySelectionError: false,
626
+ columns: timeSlotColumns,
627
+ capacityDisplaySettings,
628
+ allowUnavailableSelection: context.services.allowUnavailableBookingSelection === true,
629
+ value: !hasNoSelectableAvailabilityDate && (availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate) ? [availabilityData.selectedCandidate.key] : [],
630
+ onSelectionChange: (items) => {
631
+ var _items$;
632
+ applyAvailabilityCandidate((_items$ = items[0]) === null || _items$ === void 0 ? void 0 : _items$.candidate);
633
+ }
634
+ });
539
635
  if (unsupportedReason) return /* @__PURE__ */ react.default.createElement(antd.Alert, {
540
636
  type: "error",
541
637
  showIcon: true,
@@ -549,15 +645,20 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
549
645
  if (useAvailability) {
550
646
  if (isDateModuleLoading) return null;
551
647
  if (!hasNoSelectableAvailabilityDate && (moduleStatus === "loading" || !(availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.timeSlots))) return /* @__PURE__ */ react.default.createElement(require_LoadingPanel.default, null);
552
- if (usePosDurationAvailability) {
648
+ if (usePosCustomTimeAvailability) {
553
649
  var _availabilityData$slo, _durationProps$select, _options$durationSele;
650
+ if (usePosSessionAvailability && !posCustomTimeBaseMinutes) return /* @__PURE__ */ react.default.createElement(antd.Alert, {
651
+ type: "error",
652
+ showIcon: true,
653
+ message: require_i18n.selectionFlowText("pisell2.text.sku.detail.modal.validation.availability.wait")
654
+ });
554
655
  const selectedCandidate = availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate;
555
- const posStartTimeSlice = (_availabilityData$slo = availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes) !== null && _availabilityData$slo !== void 0 ? _availabilityData$slo : slice;
656
+ const posStartTimeSlice = usePosSessionAvailability ? availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes : (_availabilityData$slo = availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes) !== null && _availabilityData$slo !== void 0 ? _availabilityData$slo : slice;
556
657
  selectedCandidate && context.services.allowUnavailableBookingSelection === true && isAvailabilityCandidateSelectable(selectedCandidate);
557
658
  return /* @__PURE__ */ react.default.createElement(antd.Space, {
558
659
  direction: "vertical",
559
660
  style: { width: "100%" }
560
- }, /* @__PURE__ */ react.default.createElement("div", { style: { fontWeight: 500 } }, require_i18n.selectionFlowText("pisell2.text.start_time")), /* @__PURE__ */ react.default.createElement(_pisell_materials.SelectTime, {
661
+ }, usePosSessionAvailability ? renderAvailabilityTimeSelector() : null, /* @__PURE__ */ react.default.createElement("div", { style: { fontWeight: 500 } }, require_i18n.selectionFlowText("pisell2.text.start_time")), /* @__PURE__ */ react.default.createElement(_pisell_materials.SelectTime, {
561
662
  value: startTime || "",
562
663
  slice: posStartTimeSlice,
563
664
  theme: options.theme,
@@ -581,10 +682,14 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
581
682
  sourceModuleType: "time"
582
683
  });
583
684
  context.setModuleStatus(module.key, "loading");
584
- refreshAvailabilityTimes(context, module, duration, nextStartTime).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
685
+ refreshAvailabilityTimes(context, module, {
686
+ durationOverride: duration,
687
+ startTimeOverride: nextStartTime,
688
+ selectionIntent: "custom"
689
+ }).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
585
690
  }
586
691
  }), /* @__PURE__ */ react.default.createElement("div", { style: { fontWeight: 500 } }, require_i18n.selectionFlowText("pisell2.text.duration")), /* @__PURE__ */ react.default.createElement(require_index.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, durationProps), options.durationProps), {}, {
587
- timeObj: posDurationTimeObj,
692
+ timeObj: posCustomTimeObj,
588
693
  value: duration !== null && duration !== void 0 ? duration : void 0,
589
694
  selectProps: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, (durationProps === null || durationProps === void 0 ? void 0 : durationProps.selectProps) || {}), options.durationSelectProps), {}, { style: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({ width: "100%" }, (durationProps === null || durationProps === void 0 || (_durationProps$select = durationProps.selectProps) === null || _durationProps$select === void 0 ? void 0 : _durationProps$select.style) || {}), ((_options$durationSele = options.durationSelectProps) === null || _options$durationSele === void 0 ? void 0 : _options$durationSele.style) || {}) }),
590
695
  style: { width: "100%" },
@@ -604,25 +709,15 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
604
709
  sourceModuleType: "time"
605
710
  });
606
711
  context.setModuleStatus(module.key, "loading");
607
- refreshAvailabilityTimes(context, module, nextDuration, startTime).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
712
+ refreshAvailabilityTimes(context, module, {
713
+ durationOverride: nextDuration,
714
+ startTimeOverride: startTime,
715
+ selectionIntent: "custom"
716
+ }).then(() => context.setModuleStatus(module.key, "ready")).catch((error) => context.setModuleStatus(module.key, "error", error instanceof Error ? error.message : String(error), error));
608
717
  }
609
718
  })));
610
719
  }
611
- return /* @__PURE__ */ react.default.createElement(require_index$2.default, {
612
- className: (0, classnames.default)("selection-flow-time-resource-selector", `selection-flow-time-resource-selector--columns-${timeSlotColumns}`),
613
- displayMode: "plain",
614
- timeSlots: hasNoSelectableAvailabilityDate ? [] : (availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.timeSlots) || [],
615
- defaultSelectFirst: false,
616
- showEmptySelectionError: false,
617
- columns: timeSlotColumns,
618
- capacityDisplaySettings,
619
- allowUnavailableSelection: context.services.allowUnavailableBookingSelection === true,
620
- value: !hasNoSelectableAvailabilityDate && (availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate) ? [availabilityData.selectedCandidate.key] : [],
621
- onSelectionChange: (items) => {
622
- var _items$;
623
- applyAvailabilityCandidate((_items$ = items[0]) === null || _items$ === void 0 ? void 0 : _items$.candidate);
624
- }
625
- });
720
+ return renderAvailabilityTimeSelector();
626
721
  }
627
722
  if (!_pisell_materials.SelectTime) return /* @__PURE__ */ react.default.createElement(antd.Alert, {
628
723
  type: "error",
@@ -704,8 +799,8 @@ const timeFlowModule = {
704
799
  "booking.capacity"
705
800
  ],
706
801
  isApplicable: (context) => {
707
- var _context$hostContext2;
708
- return !require_utils$1.isNormalProductByDurationSchedule(context.draft.productData) && ((_context$hostContext2 = context.hostContext) === null || _context$hostContext2 === void 0 ? void 0 : _context$hostContext2.renderType) !== "eventBooking";
802
+ var _context$hostContext3;
803
+ return !require_utils$1.isNormalProductByDurationSchedule(context.draft.productData) && ((_context$hostContext3 = context.hostContext) === null || _context$hostContext3 === void 0 ? void 0 : _context$hostContext3.renderType) !== "eventBooking";
709
804
  },
710
805
  canInitialize: (context, module) => {
711
806
  const unsupportedReason = require_index$1.getUnsupportedBookingFlowReason(context.draft.productData);
@@ -0,0 +1,67 @@
1
+ const require_runtime = require("../../../../../_virtual/_rolldown/runtime.js");
2
+ let dayjs = require("dayjs");
3
+ dayjs = require_runtime.__toESM(dayjs);
4
+ //#region src/pro/skuDetailModal/flow/modules/time/posCustomTime.ts
5
+ const isFlexibleDurationValue = (value) => {
6
+ if (typeof value === "string") {
7
+ const text = value.trim().toLowerCase();
8
+ return text === "flexible" || text.startsWith("flexible_");
9
+ }
10
+ return Boolean(value && typeof value === "object" && String(value.type || "").trim().toLowerCase() === "flexible");
11
+ };
12
+ const resolvePosCustomTimeBaseMinutes = (...values) => {
13
+ for (const value of values) {
14
+ const minutes = Number(value);
15
+ if (Number.isFinite(minutes) && minutes > 0) return Math.max(1, Math.floor(minutes));
16
+ }
17
+ return 30;
18
+ };
19
+ const resolvePosCustomTimeDefaultStartTime = (currentValue, sliceMinutes, now) => {
20
+ if (typeof currentValue === "string") {
21
+ const matched = currentValue.trim().match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);
22
+ if (matched) return `${matched[1]}:${matched[2]}`;
23
+ }
24
+ const current = now === void 0 ? (0, dayjs.default)() : (0, dayjs.default)(now);
25
+ if (!current.isValid()) return null;
26
+ const step = Math.min(resolvePosCustomTimeBaseMinutes(sliceMinutes), 1440);
27
+ const minuteOfDay = current.hour() * 60 + current.minute();
28
+ const alignedMinute = Math.floor(minuteOfDay / step) * step;
29
+ const hours = Math.floor(alignedMinute / 60);
30
+ const minutes = alignedMinute % 60;
31
+ return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
32
+ };
33
+ const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes) => {
34
+ if (typeof currentValue === "string") {
35
+ const flexibleMatch = currentValue.trim().toLowerCase().match(/^flexible_(\d+(?:\.\d+)?)$/);
36
+ if (flexibleMatch) return Math.max(1, Math.floor(Number(flexibleMatch[1])));
37
+ }
38
+ const currentMinutes = Number(currentValue);
39
+ if (Number.isFinite(currentMinutes) && currentMinutes > 0) return Math.max(1, Math.floor(currentMinutes));
40
+ return resolvePosCustomTimeBaseMinutes(baseDurationMinutes);
41
+ };
42
+ const getAvailabilityCandidateDurationMinutes = (candidate) => {
43
+ const startAt = (0, dayjs.default)(candidate.startAt);
44
+ const endAt = (0, dayjs.default)(candidate.endAt);
45
+ if (!startAt.isValid() || !endAt.isValid()) return null;
46
+ const duration = endAt.diff(startAt, "minute");
47
+ return duration > 0 ? duration : null;
48
+ };
49
+ const isSameAvailabilityCandidateRange = (candidate, params) => Boolean(params.startTime) && candidate.date === params.date && candidate.startTime.slice(0, 5) === params.startTime && Boolean(params.durationMinutes) && getAvailabilityCandidateDurationMinutes(candidate) === params.durationMinutes;
50
+ const resolvePosCustomTimeCandidate = (params) => {
51
+ const requestedCustomRange = params.requestedCustomRange;
52
+ if (params.customSelectionIntent) {
53
+ if (!requestedCustomRange) return void 0;
54
+ return params.candidates.find((candidate) => candidate.source === "duration_window" && isSameAvailabilityCandidateRange(candidate, requestedCustomRange));
55
+ }
56
+ return params.restoredDraftCandidate || params.restoredExistingCandidate || params.fallbackCandidate;
57
+ };
58
+ const getSessionPresetCandidates = (candidates) => candidates.filter((candidate) => candidate.source === "session_schedule");
59
+ //#endregion
60
+ exports.getAvailabilityCandidateDurationMinutes = getAvailabilityCandidateDurationMinutes;
61
+ exports.getSessionPresetCandidates = getSessionPresetCandidates;
62
+ exports.isFlexibleDurationValue = isFlexibleDurationValue;
63
+ exports.isSameAvailabilityCandidateRange = isSameAvailabilityCandidateRange;
64
+ exports.resolvePosCustomTimeBaseMinutes = resolvePosCustomTimeBaseMinutes;
65
+ exports.resolvePosCustomTimeCandidate = resolvePosCustomTimeCandidate;
66
+ exports.resolvePosCustomTimeDefaultDurationMinutes = resolvePosCustomTimeDefaultDurationMinutes;
67
+ exports.resolvePosCustomTimeDefaultStartTime = resolvePosCustomTimeDefaultStartTime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pisell/private-materials",
3
- "version": "6.11.650",
3
+ "version": "6.11.651",
4
4
  "main": "./lib/index.js",
5
5
  "module": "./es/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -69,11 +69,11 @@
69
69
  "react-zoom-pan-pinch": "^3.7.0",
70
70
  "styled-components": "^6.0.0-rc.3",
71
71
  "use-sync-external-store": "^1.6.0",
72
- "@pisell/materials": "6.11.256",
73
72
  "@pisell/pi-payment-sdk": "0.0.3",
74
- "@pisell/icon": "0.0.11",
75
73
  "@pisell/utils": "3.0.4",
76
- "@pisell/date-picker": "3.0.10"
74
+ "@pisell/icon": "0.0.11",
75
+ "@pisell/date-picker": "3.0.10",
76
+ "@pisell/materials": "6.11.256"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "react": "^18.0.0",