@pisell/private-materials 6.11.659 → 6.11.661
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/build/lowcode/assets-daily.json +11 -11
- package/build/lowcode/assets-dev.json +2 -2
- package/build/lowcode/assets-prod.json +11 -11
- package/build/lowcode/meta.js +1 -1
- package/build/lowcode/preview.js +1 -1
- package/build/lowcode/render/default/view.js +2 -2
- package/build/lowcode/view.js +2 -2
- package/es/pro/skuDetailModal/flow/modules/time/index.js +5 -5
- package/es/pro/skuDetailModal/flow/modules/time/posCustomTime.js +4 -23
- package/es/pro/skuDetailModal/flow/posAutoResolution.js +3 -1
- package/es/pro/skuDetailModal/index.js +50 -12
- package/lib/pro/skuDetailModal/flow/modules/time/index.js +4 -4
- package/lib/pro/skuDetailModal/flow/modules/time/posCustomTime.js +3 -23
- package/lib/pro/skuDetailModal/flow/posAutoResolution.js +4 -0
- package/lib/pro/skuDetailModal/index.js +49 -11
- package/package.json +2 -2
|
@@ -10,7 +10,7 @@ import { buildDraftCacheItem, getModuleOptions, getUnsupportedBookingFlowReason,
|
|
|
10
10
|
import TimeResourceSelector from "../../../../../components/eventBooking/components/timeResourceSelector/index.js";
|
|
11
11
|
import { resolveAvailabilityStatus } from "../../../../../components/eventBooking/components/bookingAvailabilityCalendar/utils.js";
|
|
12
12
|
import { validateAvailabilityTimeAutoResolution } from "../autoResolution.js";
|
|
13
|
-
import { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime,
|
|
13
|
+
import { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleDurationInitialCandidate, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards } from "./posCustomTime.js";
|
|
14
14
|
import dayjs from "dayjs";
|
|
15
15
|
import React, { useEffect, useMemo } from "react";
|
|
16
16
|
import { Alert, Space } from "antd";
|
|
@@ -191,15 +191,15 @@ const refreshAvailabilityTimes = function() {
|
|
|
191
191
|
}, requestedDuration ? _objectSpread2({ durationMinutesByProductId: { [String(availability.productId)]: requestedDuration } }, requestedStartTime ? { durationStartTimesByProductId: { [String(availability.productId)]: [requestedStartTime] } } : {}) : {}))).find((item) => String(item.productId) === String(availability.productId));
|
|
192
192
|
const candidates = (group === null || group === void 0 ? void 0 : group.ranges) || [];
|
|
193
193
|
const product = context.draft.productData;
|
|
194
|
-
if (posDurationAvailability && selectionIntent === "restore" && isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration)) {
|
|
194
|
+
if (posDurationAvailability && selectionIntent === "restore" && isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && candidates.length === 0) {
|
|
195
195
|
var _context$hostContext, _moduleOptions$slice, _context$draft$bookin2, _normalizeDurationMin3;
|
|
196
196
|
const moduleOptions = getModuleOptions(module);
|
|
197
197
|
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;
|
|
198
198
|
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;
|
|
199
|
-
const baseDurationMinutes = resolvePosCustomTimeBaseMinutes(group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
|
|
199
|
+
const baseDurationMinutes = resolvePosCustomTimeBaseMinutes(getProductDurationMinutes(context), group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
|
|
200
200
|
const resetForSelectedDate = shouldResetPosFlexibleTimeForDate((_context$draft$bookin2 = context.draft.booking.selectedCandidate) !== null && _context$draft$bookin2 !== void 0 ? _context$draft$bookin2 : previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.selectedCandidate, selectedDate);
|
|
201
201
|
const nextStartTime = resolvePosCustomTimeDefaultStartTime(resetForSelectedDate ? null : context.draft.booking.startTime, baseDurationMinutes);
|
|
202
|
-
const nextDuration = resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes
|
|
202
|
+
const nextDuration = resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes);
|
|
203
203
|
const changedFields = [];
|
|
204
204
|
if (nextStartTime !== context.draft.booking.startTime) changedFields.push("booking.startTime");
|
|
205
205
|
if (nextDuration !== context.draft.booking.duration) changedFields.push("booking.duration");
|
|
@@ -292,7 +292,7 @@ const refreshAvailabilityTimes = function() {
|
|
|
292
292
|
restoredCandidate,
|
|
293
293
|
fallbackCandidate,
|
|
294
294
|
preferPreset: preferPosFlexiblePreset,
|
|
295
|
-
|
|
295
|
+
allowRestoredFallback: fallbackSelectionIntent
|
|
296
296
|
}) : restoredCandidate || fallbackCandidate;
|
|
297
297
|
context.setModuleData(module.key, {
|
|
298
298
|
requestId,
|
|
@@ -28,24 +28,9 @@ const resolvePosCustomTimeDefaultStartTime = (currentValue, sliceMinutes, now) =
|
|
|
28
28
|
const minutes = alignedMinute % 60;
|
|
29
29
|
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
|
|
30
30
|
};
|
|
31
|
-
const resolvePosFlexibleBusinessDurationMinutes = (startTime, closingTime) => {
|
|
32
|
-
const toMinuteOfDay = (value) => {
|
|
33
|
-
if (typeof value !== "string") return null;
|
|
34
|
-
const matched = value.trim().match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);
|
|
35
|
-
if (!matched) return null;
|
|
36
|
-
return Number(matched[1]) * 60 + Number(matched[2]);
|
|
37
|
-
};
|
|
38
|
-
const startMinute = toMinuteOfDay(startTime);
|
|
39
|
-
const closingMinute = toMinuteOfDay(closingTime);
|
|
40
|
-
if (startMinute === null || closingMinute === null) return null;
|
|
41
|
-
const duration = closingMinute > startMinute ? closingMinute - startMinute : closingMinute < startMinute ? closingMinute + 1440 - startMinute : 0;
|
|
42
|
-
return duration > 0 ? duration : null;
|
|
43
|
-
};
|
|
44
31
|
const shouldResetPosFlexibleTimeForDate = (candidate, selectedDate) => Boolean(candidate && candidate.date !== selectedDate);
|
|
45
|
-
const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes
|
|
32
|
+
const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes) => {
|
|
46
33
|
if (isFlexibleDurationValue(currentValue)) {
|
|
47
|
-
const flexibleMinutes = Number(flexibleDefaultMinutes);
|
|
48
|
-
if (Number.isFinite(flexibleMinutes) && flexibleMinutes > 0) return Math.max(1, Math.floor(flexibleMinutes));
|
|
49
34
|
if (typeof currentValue === "string") {
|
|
50
35
|
const flexibleMatch = currentValue.trim().toLowerCase().match(/^flexible_(\d+(?:\.\d+)?)$/);
|
|
51
36
|
if (flexibleMatch) return Math.max(1, Math.floor(Number(flexibleMatch[1])));
|
|
@@ -79,15 +64,11 @@ const getPosFlexibleDurationPresetCandidates = (candidates, requestedCustomRange
|
|
|
79
64
|
return candidates.filter((candidate) => !isSameAvailabilityCandidateRange(candidate, requestedCustomRange));
|
|
80
65
|
};
|
|
81
66
|
const resolvePosFlexibleDurationInitialCandidate = (params) => {
|
|
82
|
-
const minimumPresetStartAt = params.minimumPresetStartAt === void 0 ? null : dayjs(params.minimumPresetStartAt);
|
|
83
67
|
const firstAvailablePreset = params.presetCandidates.find((candidate) => {
|
|
84
|
-
|
|
85
|
-
if (!(minimumPresetStartAt === null || minimumPresetStartAt === void 0 ? void 0 : minimumPresetStartAt.isValid())) return true;
|
|
86
|
-
const candidateStartAt = dayjs(candidate.startAt);
|
|
87
|
-
return candidateStartAt.isValid() && !candidateStartAt.isBefore(minimumPresetStartAt);
|
|
68
|
+
return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
|
|
88
69
|
});
|
|
89
|
-
if (params.preferPreset
|
|
70
|
+
if (params.preferPreset) return firstAvailablePreset || (params.allowRestoredFallback ? params.restoredCandidate : void 0);
|
|
90
71
|
return params.restoredCandidate || params.fallbackCandidate;
|
|
91
72
|
};
|
|
92
73
|
//#endregion
|
|
93
|
-
export { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime,
|
|
74
|
+
export { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleDurationInitialCandidate, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards };
|
|
@@ -24,5 +24,7 @@ const getPosAutoResolutionDraftKey = (draft) => {
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
const shouldDirectlyConfirmPosSelectionFlow = ({ eligible, status, currentStepIndex }) => eligible && status === "resolved" && currentStepIndex === 0;
|
|
27
|
+
const shouldPreparePosSelectionFlowOnConfirm = ({ eligible, currentStepIndex, abandoned }) => eligible && currentStepIndex === 0 && !abandoned;
|
|
28
|
+
const isCurrentPosAutoResolutionRun = ({ expectedRunId, currentRunId, expectedOpenTaskId, currentOpenTaskId, expectedDraftKey, currentDraftKey, abandoned, currentStepIndex }) => expectedRunId === currentRunId && expectedOpenTaskId === currentOpenTaskId && expectedDraftKey === currentDraftKey && !abandoned && currentStepIndex === 0;
|
|
27
29
|
//#endregion
|
|
28
|
-
export { getPosAutoResolutionDraftKey, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow };
|
|
30
|
+
export { getPosAutoResolutionDraftKey, isCurrentPosAutoResolutionRun, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow, shouldPreparePosSelectionFlowOnConfirm };
|
|
@@ -35,7 +35,7 @@ import resolveBookingPriceDisplayAmounts, { canOpenBookingManualPriceChange } fr
|
|
|
35
35
|
import { normalizeSelectionDuration } from "./flow/modules/time/index.js";
|
|
36
36
|
import { flowModuleRegistry } from "./flow/registry.js";
|
|
37
37
|
import SkuDetailSelectionFlowView from "./flow/SkuDetailSelectionFlowView.js";
|
|
38
|
-
import { getPosAutoResolutionDraftKey, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow } from "./flow/posAutoResolution.js";
|
|
38
|
+
import { getPosAutoResolutionDraftKey, isCurrentPosAutoResolutionRun, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow, shouldPreparePosSelectionFlowOnConfirm } from "./flow/posAutoResolution.js";
|
|
39
39
|
import dayjs from "dayjs";
|
|
40
40
|
import React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
41
41
|
import { locales } from "@pisell/utils";
|
|
@@ -132,7 +132,7 @@ const resolveInitialAvailabilityCandidate = (source, startDate, endDate, startTi
|
|
|
132
132
|
if (endDate && candidateEndDate && candidateEndDate !== endDate.format("YYYY-MM-DD")) return;
|
|
133
133
|
return rawCandidate;
|
|
134
134
|
};
|
|
135
|
-
const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
|
|
135
|
+
const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isConfirmLoading = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
|
|
136
136
|
const auxiliaryActions = [isShowNote ? /* @__PURE__ */ React.createElement(Button, {
|
|
137
137
|
key: "note",
|
|
138
138
|
type: "default",
|
|
@@ -164,6 +164,7 @@ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChan
|
|
|
164
164
|
type: "primary",
|
|
165
165
|
size: "large",
|
|
166
166
|
disabled: isConfirmDisabled,
|
|
167
|
+
loading: isConfirmLoading,
|
|
167
168
|
onClick: onConfirm,
|
|
168
169
|
className: "sku-detail-side-actions-btn sku-detail-side-actions-confirm-btn"
|
|
169
170
|
}, /* @__PURE__ */ React.createElement("span", { className: "sku-detail-content-footer-confirm-btn-text" }, confirmLabel))) : null);
|
|
@@ -236,8 +237,10 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
236
237
|
const [selectionFlowProcedureSteps, setSelectionFlowProcedureSteps] = useState(null);
|
|
237
238
|
const [compiledSelectionFlowSteps, setCompiledSelectionFlowSteps] = useState(null);
|
|
238
239
|
const [posAutoResolutionStatus, setPosAutoResolutionStatus] = useState("idle");
|
|
240
|
+
const [posAutoResolutionConfirmPending, setPosAutoResolutionConfirmPending] = useState(false);
|
|
239
241
|
const posAutoResolutionRunRef = useRef(0);
|
|
240
242
|
const posAutoResolutionAbandonedRef = useRef(false);
|
|
243
|
+
const posAutoResolutionConfirmPendingRunRef = useRef(null);
|
|
241
244
|
const [effectiveSelectionFlowSteps, setEffectiveSelectionFlowSteps] = useState(void 0);
|
|
242
245
|
const [skuDetailConfig, setSkuDetailConfig] = useState({
|
|
243
246
|
isShowProductSummary: false,
|
|
@@ -786,6 +789,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
786
789
|
setLatestSelectionFlowDraft(null);
|
|
787
790
|
posAutoResolutionRunRef.current += 1;
|
|
788
791
|
posAutoResolutionAbandonedRef.current = false;
|
|
792
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
793
|
+
setPosAutoResolutionConfirmPending(false);
|
|
789
794
|
setPosAutoResolutionStatus("idle");
|
|
790
795
|
setEffectiveSelectionFlowSteps(void 0);
|
|
791
796
|
setNoteModalOpen(false);
|
|
@@ -1296,6 +1301,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1296
1301
|
setLatestSelectionFlowDraft(null);
|
|
1297
1302
|
posAutoResolutionRunRef.current += 1;
|
|
1298
1303
|
posAutoResolutionAbandonedRef.current = false;
|
|
1304
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1305
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1299
1306
|
setPosAutoResolutionStatus("idle");
|
|
1300
1307
|
setCurrentStep(0);
|
|
1301
1308
|
}, []);
|
|
@@ -1303,6 +1310,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1303
1310
|
openTaskIdRef.current += 1;
|
|
1304
1311
|
flowDateHydrationVersionRef.current += 1;
|
|
1305
1312
|
posAutoResolutionRunRef.current += 1;
|
|
1313
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1314
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1306
1315
|
setOpen(false);
|
|
1307
1316
|
setDetailLoading(false);
|
|
1308
1317
|
setNoteModalOpen(false);
|
|
@@ -1321,20 +1330,48 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1321
1330
|
if (isCustomSelectionFlow && !flowDraft) {
|
|
1322
1331
|
const flow = selectionFlowRef.current;
|
|
1323
1332
|
if (!flow) return false;
|
|
1324
|
-
|
|
1333
|
+
const currentFlowStepIndex = flow.getState().currentStepIndex;
|
|
1334
|
+
if (shouldPreparePosSelectionFlowOnConfirm({
|
|
1335
|
+
eligible: isPosCreateAutoResolutionEligible,
|
|
1336
|
+
currentStepIndex: currentFlowStepIndex,
|
|
1337
|
+
abandoned: posAutoResolutionAbandonedRef.current
|
|
1338
|
+
})) {
|
|
1339
|
+
if (posAutoResolutionConfirmPendingRunRef.current !== null) return false;
|
|
1325
1340
|
const openTaskId = openTaskIdRef.current;
|
|
1326
1341
|
const draftKey = getPosAutoResolutionDraftKey(flow.getState().draft);
|
|
1327
1342
|
const runId = posAutoResolutionRunRef.current + 1;
|
|
1328
1343
|
posAutoResolutionRunRef.current = runId;
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1344
|
+
posAutoResolutionConfirmPendingRunRef.current = runId;
|
|
1345
|
+
setPosAutoResolutionConfirmPending(true);
|
|
1346
|
+
setPosAutoResolutionStatus("checking");
|
|
1347
|
+
try {
|
|
1348
|
+
const result = yield flow.prepareSteps({ fromStepIndex: 1 });
|
|
1349
|
+
if (!isCurrentPosAutoResolutionRun({
|
|
1350
|
+
expectedRunId: runId,
|
|
1351
|
+
currentRunId: posAutoResolutionRunRef.current,
|
|
1352
|
+
expectedOpenTaskId: openTaskId,
|
|
1353
|
+
currentOpenTaskId: openTaskIdRef.current,
|
|
1354
|
+
expectedDraftKey: draftKey,
|
|
1355
|
+
currentDraftKey: getPosAutoResolutionDraftKey(flow.getState().draft),
|
|
1356
|
+
abandoned: posAutoResolutionAbandonedRef.current,
|
|
1357
|
+
currentStepIndex: flow.getState().currentStepIndex
|
|
1358
|
+
}) || result.cancelled) return false;
|
|
1359
|
+
if (!result.prepared) {
|
|
1360
|
+
posAutoResolutionAbandonedRef.current = true;
|
|
1361
|
+
posAutoResolutionRunRef.current += 1;
|
|
1362
|
+
setPosAutoResolutionStatus("retained");
|
|
1363
|
+
return (yield flow.next()) || false;
|
|
1364
|
+
}
|
|
1365
|
+
setPosAutoResolutionStatus("resolved");
|
|
1366
|
+
const completed = yield flow.complete();
|
|
1367
|
+
if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
|
|
1368
|
+
return completed;
|
|
1369
|
+
} finally {
|
|
1370
|
+
if (posAutoResolutionConfirmPendingRunRef.current === runId) {
|
|
1371
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1372
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1373
|
+
}
|
|
1334
1374
|
}
|
|
1335
|
-
const completed = yield flow.complete();
|
|
1336
|
-
if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
|
|
1337
|
-
return completed;
|
|
1338
1375
|
}
|
|
1339
1376
|
if (isPosCreateAutoResolutionEligible) {
|
|
1340
1377
|
posAutoResolutionAbandonedRef.current = true;
|
|
@@ -1709,8 +1746,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1709
1746
|
isShowNote: !!(skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowNote),
|
|
1710
1747
|
isShowRemove: (skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowRemove) !== false,
|
|
1711
1748
|
confirmLabel: pcConfirmButtonText,
|
|
1749
|
+
isConfirmLoading: posAutoResolutionConfirmPending,
|
|
1712
1750
|
isManualPriceChangeDisabled: !canOpenManualPriceChange,
|
|
1713
|
-
isConfirmDisabled: hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
|
|
1751
|
+
isConfirmDisabled: posAutoResolutionConfirmPending || hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
|
|
1714
1752
|
onCancel: handleCancel,
|
|
1715
1753
|
onRemove: handleRemove,
|
|
1716
1754
|
onManualPriceChange: handleManualPriceChange,
|
|
@@ -195,15 +195,15 @@ const refreshAvailabilityTimes = function() {
|
|
|
195
195
|
}, requestedDuration ? require_objectSpread2._objectSpread2({ durationMinutesByProductId: { [String(availability.productId)]: requestedDuration } }, requestedStartTime ? { durationStartTimesByProductId: { [String(availability.productId)]: [requestedStartTime] } } : {}) : {}))).find((item) => String(item.productId) === String(availability.productId));
|
|
196
196
|
const candidates = (group === null || group === void 0 ? void 0 : group.ranges) || [];
|
|
197
197
|
const product = context.draft.productData;
|
|
198
|
-
if (posDurationAvailability && selectionIntent === "restore" && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration)) {
|
|
198
|
+
if (posDurationAvailability && selectionIntent === "restore" && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && candidates.length === 0) {
|
|
199
199
|
var _context$hostContext, _moduleOptions$slice, _context$draft$bookin2, _normalizeDurationMin3;
|
|
200
200
|
const moduleOptions = require_index$1.getModuleOptions(module);
|
|
201
201
|
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;
|
|
202
202
|
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;
|
|
203
|
-
const baseDurationMinutes = require_posCustomTime.resolvePosCustomTimeBaseMinutes(group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
|
|
203
|
+
const baseDurationMinutes = require_posCustomTime.resolvePosCustomTimeBaseMinutes(getProductDurationMinutes(context), group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
|
|
204
204
|
const resetForSelectedDate = require_posCustomTime.shouldResetPosFlexibleTimeForDate((_context$draft$bookin2 = context.draft.booking.selectedCandidate) !== null && _context$draft$bookin2 !== void 0 ? _context$draft$bookin2 : previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.selectedCandidate, selectedDate);
|
|
205
205
|
const nextStartTime = require_posCustomTime.resolvePosCustomTimeDefaultStartTime(resetForSelectedDate ? null : context.draft.booking.startTime, baseDurationMinutes);
|
|
206
|
-
const nextDuration = require_posCustomTime.resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes
|
|
206
|
+
const nextDuration = require_posCustomTime.resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes);
|
|
207
207
|
const changedFields = [];
|
|
208
208
|
if (nextStartTime !== context.draft.booking.startTime) changedFields.push("booking.startTime");
|
|
209
209
|
if (nextDuration !== context.draft.booking.duration) changedFields.push("booking.duration");
|
|
@@ -296,7 +296,7 @@ const refreshAvailabilityTimes = function() {
|
|
|
296
296
|
restoredCandidate,
|
|
297
297
|
fallbackCandidate,
|
|
298
298
|
preferPreset: preferPosFlexiblePreset,
|
|
299
|
-
|
|
299
|
+
allowRestoredFallback: fallbackSelectionIntent
|
|
300
300
|
}) : restoredCandidate || fallbackCandidate;
|
|
301
301
|
context.setModuleData(module.key, {
|
|
302
302
|
requestId,
|
|
@@ -30,24 +30,9 @@ const resolvePosCustomTimeDefaultStartTime = (currentValue, sliceMinutes, now) =
|
|
|
30
30
|
const minutes = alignedMinute % 60;
|
|
31
31
|
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
|
|
32
32
|
};
|
|
33
|
-
const resolvePosFlexibleBusinessDurationMinutes = (startTime, closingTime) => {
|
|
34
|
-
const toMinuteOfDay = (value) => {
|
|
35
|
-
if (typeof value !== "string") return null;
|
|
36
|
-
const matched = value.trim().match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);
|
|
37
|
-
if (!matched) return null;
|
|
38
|
-
return Number(matched[1]) * 60 + Number(matched[2]);
|
|
39
|
-
};
|
|
40
|
-
const startMinute = toMinuteOfDay(startTime);
|
|
41
|
-
const closingMinute = toMinuteOfDay(closingTime);
|
|
42
|
-
if (startMinute === null || closingMinute === null) return null;
|
|
43
|
-
const duration = closingMinute > startMinute ? closingMinute - startMinute : closingMinute < startMinute ? closingMinute + 1440 - startMinute : 0;
|
|
44
|
-
return duration > 0 ? duration : null;
|
|
45
|
-
};
|
|
46
33
|
const shouldResetPosFlexibleTimeForDate = (candidate, selectedDate) => Boolean(candidate && candidate.date !== selectedDate);
|
|
47
|
-
const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes
|
|
34
|
+
const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes) => {
|
|
48
35
|
if (isFlexibleDurationValue(currentValue)) {
|
|
49
|
-
const flexibleMinutes = Number(flexibleDefaultMinutes);
|
|
50
|
-
if (Number.isFinite(flexibleMinutes) && flexibleMinutes > 0) return Math.max(1, Math.floor(flexibleMinutes));
|
|
51
36
|
if (typeof currentValue === "string") {
|
|
52
37
|
const flexibleMatch = currentValue.trim().toLowerCase().match(/^flexible_(\d+(?:\.\d+)?)$/);
|
|
53
38
|
if (flexibleMatch) return Math.max(1, Math.floor(Number(flexibleMatch[1])));
|
|
@@ -81,14 +66,10 @@ const getPosFlexibleDurationPresetCandidates = (candidates, requestedCustomRange
|
|
|
81
66
|
return candidates.filter((candidate) => !isSameAvailabilityCandidateRange(candidate, requestedCustomRange));
|
|
82
67
|
};
|
|
83
68
|
const resolvePosFlexibleDurationInitialCandidate = (params) => {
|
|
84
|
-
const minimumPresetStartAt = params.minimumPresetStartAt === void 0 ? null : (0, dayjs.default)(params.minimumPresetStartAt);
|
|
85
69
|
const firstAvailablePreset = params.presetCandidates.find((candidate) => {
|
|
86
|
-
|
|
87
|
-
if (!(minimumPresetStartAt === null || minimumPresetStartAt === void 0 ? void 0 : minimumPresetStartAt.isValid())) return true;
|
|
88
|
-
const candidateStartAt = (0, dayjs.default)(candidate.startAt);
|
|
89
|
-
return candidateStartAt.isValid() && !candidateStartAt.isBefore(minimumPresetStartAt);
|
|
70
|
+
return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
|
|
90
71
|
});
|
|
91
|
-
if (params.preferPreset
|
|
72
|
+
if (params.preferPreset) return firstAvailablePreset || (params.allowRestoredFallback ? params.restoredCandidate : void 0);
|
|
92
73
|
return params.restoredCandidate || params.fallbackCandidate;
|
|
93
74
|
};
|
|
94
75
|
//#endregion
|
|
@@ -101,7 +82,6 @@ exports.resolvePosCustomTimeBaseMinutes = resolvePosCustomTimeBaseMinutes;
|
|
|
101
82
|
exports.resolvePosCustomTimeCandidate = resolvePosCustomTimeCandidate;
|
|
102
83
|
exports.resolvePosCustomTimeDefaultDurationMinutes = resolvePosCustomTimeDefaultDurationMinutes;
|
|
103
84
|
exports.resolvePosCustomTimeDefaultStartTime = resolvePosCustomTimeDefaultStartTime;
|
|
104
|
-
exports.resolvePosFlexibleBusinessDurationMinutes = resolvePosFlexibleBusinessDurationMinutes;
|
|
105
85
|
exports.resolvePosFlexibleDurationInitialCandidate = resolvePosFlexibleDurationInitialCandidate;
|
|
106
86
|
exports.shouldResetPosFlexibleTimeForDate = shouldResetPosFlexibleTimeForDate;
|
|
107
87
|
exports.shouldShowPosCustomTimeCandidateCards = shouldShowPosCustomTimeCandidateCards;
|
|
@@ -24,7 +24,11 @@ const getPosAutoResolutionDraftKey = (draft) => {
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
const shouldDirectlyConfirmPosSelectionFlow = ({ eligible, status, currentStepIndex }) => eligible && status === "resolved" && currentStepIndex === 0;
|
|
27
|
+
const shouldPreparePosSelectionFlowOnConfirm = ({ eligible, currentStepIndex, abandoned }) => eligible && currentStepIndex === 0 && !abandoned;
|
|
28
|
+
const isCurrentPosAutoResolutionRun = ({ expectedRunId, currentRunId, expectedOpenTaskId, currentOpenTaskId, expectedDraftKey, currentDraftKey, abandoned, currentStepIndex }) => expectedRunId === currentRunId && expectedOpenTaskId === currentOpenTaskId && expectedDraftKey === currentDraftKey && !abandoned && currentStepIndex === 0;
|
|
27
29
|
//#endregion
|
|
28
30
|
exports.getPosAutoResolutionDraftKey = getPosAutoResolutionDraftKey;
|
|
31
|
+
exports.isCurrentPosAutoResolutionRun = isCurrentPosAutoResolutionRun;
|
|
29
32
|
exports.isPosCreateAutoResolutionCandidate = isPosCreateAutoResolutionCandidate;
|
|
30
33
|
exports.shouldDirectlyConfirmPosSelectionFlow = shouldDirectlyConfirmPosSelectionFlow;
|
|
34
|
+
exports.shouldPreparePosSelectionFlowOnConfirm = shouldPreparePosSelectionFlowOnConfirm;
|
|
@@ -138,7 +138,7 @@ const resolveInitialAvailabilityCandidate = (source, startDate, endDate, startTi
|
|
|
138
138
|
if (endDate && candidateEndDate && candidateEndDate !== endDate.format("YYYY-MM-DD")) return;
|
|
139
139
|
return rawCandidate;
|
|
140
140
|
};
|
|
141
|
-
const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
|
|
141
|
+
const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isConfirmLoading = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
|
|
142
142
|
const auxiliaryActions = [isShowNote ? /* @__PURE__ */ react.default.createElement(_pisell_materials.Button, {
|
|
143
143
|
key: "note",
|
|
144
144
|
type: "default",
|
|
@@ -170,6 +170,7 @@ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChan
|
|
|
170
170
|
type: "primary",
|
|
171
171
|
size: "large",
|
|
172
172
|
disabled: isConfirmDisabled,
|
|
173
|
+
loading: isConfirmLoading,
|
|
173
174
|
onClick: onConfirm,
|
|
174
175
|
className: "sku-detail-side-actions-btn sku-detail-side-actions-confirm-btn"
|
|
175
176
|
}, /* @__PURE__ */ react.default.createElement("span", { className: "sku-detail-content-footer-confirm-btn-text" }, confirmLabel))) : null);
|
|
@@ -242,8 +243,10 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
242
243
|
const [selectionFlowProcedureSteps, setSelectionFlowProcedureSteps] = (0, react.useState)(null);
|
|
243
244
|
const [compiledSelectionFlowSteps, setCompiledSelectionFlowSteps] = (0, react.useState)(null);
|
|
244
245
|
const [posAutoResolutionStatus, setPosAutoResolutionStatus] = (0, react.useState)("idle");
|
|
246
|
+
const [posAutoResolutionConfirmPending, setPosAutoResolutionConfirmPending] = (0, react.useState)(false);
|
|
245
247
|
const posAutoResolutionRunRef = (0, react.useRef)(0);
|
|
246
248
|
const posAutoResolutionAbandonedRef = (0, react.useRef)(false);
|
|
249
|
+
const posAutoResolutionConfirmPendingRunRef = (0, react.useRef)(null);
|
|
247
250
|
const [effectiveSelectionFlowSteps, setEffectiveSelectionFlowSteps] = (0, react.useState)(void 0);
|
|
248
251
|
const [skuDetailConfig, setSkuDetailConfig] = (0, react.useState)({
|
|
249
252
|
isShowProductSummary: false,
|
|
@@ -792,6 +795,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
792
795
|
setLatestSelectionFlowDraft(null);
|
|
793
796
|
posAutoResolutionRunRef.current += 1;
|
|
794
797
|
posAutoResolutionAbandonedRef.current = false;
|
|
798
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
799
|
+
setPosAutoResolutionConfirmPending(false);
|
|
795
800
|
setPosAutoResolutionStatus("idle");
|
|
796
801
|
setEffectiveSelectionFlowSteps(void 0);
|
|
797
802
|
setNoteModalOpen(false);
|
|
@@ -1302,6 +1307,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1302
1307
|
setLatestSelectionFlowDraft(null);
|
|
1303
1308
|
posAutoResolutionRunRef.current += 1;
|
|
1304
1309
|
posAutoResolutionAbandonedRef.current = false;
|
|
1310
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1311
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1305
1312
|
setPosAutoResolutionStatus("idle");
|
|
1306
1313
|
setCurrentStep(0);
|
|
1307
1314
|
}, []);
|
|
@@ -1309,6 +1316,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1309
1316
|
openTaskIdRef.current += 1;
|
|
1310
1317
|
flowDateHydrationVersionRef.current += 1;
|
|
1311
1318
|
posAutoResolutionRunRef.current += 1;
|
|
1319
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1320
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1312
1321
|
setOpen(false);
|
|
1313
1322
|
setDetailLoading(false);
|
|
1314
1323
|
setNoteModalOpen(false);
|
|
@@ -1327,20 +1336,48 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1327
1336
|
if (isCustomSelectionFlow && !flowDraft) {
|
|
1328
1337
|
const flow = selectionFlowRef.current;
|
|
1329
1338
|
if (!flow) return false;
|
|
1330
|
-
|
|
1339
|
+
const currentFlowStepIndex = flow.getState().currentStepIndex;
|
|
1340
|
+
if (require_posAutoResolution.shouldPreparePosSelectionFlowOnConfirm({
|
|
1341
|
+
eligible: isPosCreateAutoResolutionEligible,
|
|
1342
|
+
currentStepIndex: currentFlowStepIndex,
|
|
1343
|
+
abandoned: posAutoResolutionAbandonedRef.current
|
|
1344
|
+
})) {
|
|
1345
|
+
if (posAutoResolutionConfirmPendingRunRef.current !== null) return false;
|
|
1331
1346
|
const openTaskId = openTaskIdRef.current;
|
|
1332
1347
|
const draftKey = require_posAutoResolution.getPosAutoResolutionDraftKey(flow.getState().draft);
|
|
1333
1348
|
const runId = posAutoResolutionRunRef.current + 1;
|
|
1334
1349
|
posAutoResolutionRunRef.current = runId;
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1350
|
+
posAutoResolutionConfirmPendingRunRef.current = runId;
|
|
1351
|
+
setPosAutoResolutionConfirmPending(true);
|
|
1352
|
+
setPosAutoResolutionStatus("checking");
|
|
1353
|
+
try {
|
|
1354
|
+
const result = yield flow.prepareSteps({ fromStepIndex: 1 });
|
|
1355
|
+
if (!require_posAutoResolution.isCurrentPosAutoResolutionRun({
|
|
1356
|
+
expectedRunId: runId,
|
|
1357
|
+
currentRunId: posAutoResolutionRunRef.current,
|
|
1358
|
+
expectedOpenTaskId: openTaskId,
|
|
1359
|
+
currentOpenTaskId: openTaskIdRef.current,
|
|
1360
|
+
expectedDraftKey: draftKey,
|
|
1361
|
+
currentDraftKey: require_posAutoResolution.getPosAutoResolutionDraftKey(flow.getState().draft),
|
|
1362
|
+
abandoned: posAutoResolutionAbandonedRef.current,
|
|
1363
|
+
currentStepIndex: flow.getState().currentStepIndex
|
|
1364
|
+
}) || result.cancelled) return false;
|
|
1365
|
+
if (!result.prepared) {
|
|
1366
|
+
posAutoResolutionAbandonedRef.current = true;
|
|
1367
|
+
posAutoResolutionRunRef.current += 1;
|
|
1368
|
+
setPosAutoResolutionStatus("retained");
|
|
1369
|
+
return (yield flow.next()) || false;
|
|
1370
|
+
}
|
|
1371
|
+
setPosAutoResolutionStatus("resolved");
|
|
1372
|
+
const completed = yield flow.complete();
|
|
1373
|
+
if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
|
|
1374
|
+
return completed;
|
|
1375
|
+
} finally {
|
|
1376
|
+
if (posAutoResolutionConfirmPendingRunRef.current === runId) {
|
|
1377
|
+
posAutoResolutionConfirmPendingRunRef.current = null;
|
|
1378
|
+
setPosAutoResolutionConfirmPending(false);
|
|
1379
|
+
}
|
|
1340
1380
|
}
|
|
1341
|
-
const completed = yield flow.complete();
|
|
1342
|
-
if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
|
|
1343
|
-
return completed;
|
|
1344
1381
|
}
|
|
1345
1382
|
if (isPosCreateAutoResolutionEligible) {
|
|
1346
1383
|
posAutoResolutionAbandonedRef.current = true;
|
|
@@ -1715,8 +1752,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
|
|
|
1715
1752
|
isShowNote: !!(skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowNote),
|
|
1716
1753
|
isShowRemove: (skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowRemove) !== false,
|
|
1717
1754
|
confirmLabel: pcConfirmButtonText,
|
|
1755
|
+
isConfirmLoading: posAutoResolutionConfirmPending,
|
|
1718
1756
|
isManualPriceChangeDisabled: !canOpenManualPriceChange,
|
|
1719
|
-
isConfirmDisabled: hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
|
|
1757
|
+
isConfirmDisabled: posAutoResolutionConfirmPending || hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
|
|
1720
1758
|
onCancel: handleCancel,
|
|
1721
1759
|
onRemove: handleRemove,
|
|
1722
1760
|
onManualPriceChange: handleManualPriceChange,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pisell/private-materials",
|
|
3
|
-
"version": "6.11.
|
|
3
|
+
"version": "6.11.661",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"module": "./es/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"styled-components": "^6.0.0-rc.3",
|
|
71
71
|
"use-sync-external-store": "^1.6.0",
|
|
72
72
|
"@pisell/pi-payment-sdk": "0.0.3",
|
|
73
|
-
"@pisell/utils": "3.0.4",
|
|
74
73
|
"@pisell/materials": "6.11.256",
|
|
74
|
+
"@pisell/utils": "3.0.4",
|
|
75
75
|
"@pisell/icon": "0.0.11",
|
|
76
76
|
"@pisell/date-picker": "3.0.10"
|
|
77
77
|
},
|