@wix/headless-bookings 0.0.16 → 0.0.17
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/cjs/dist/api/time-slot-list/index.d.ts +21 -1
- package/cjs/dist/api/time-slot-list/index.js +46 -8
- package/cjs/dist/react/core/time-slot-list/TimeSlot.d.ts +22 -18
- package/cjs/dist/react/core/time-slot-list/TimeSlot.js +41 -28
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +39 -7
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +56 -11
- package/cjs/dist/react/time-slot-list/TimeSlot.js +3 -3
- package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +55 -12
- package/cjs/dist/react/time-slot-list/TimeSlotList.js +47 -17
- package/cjs/dist/services/index.d.ts +2 -2
- package/cjs/dist/services/time-slot-list/index.d.ts +1 -1
- package/cjs/dist/services/time-slot-list/time-slot-list.d.ts +3 -3
- package/cjs/dist/services/time-slot-list/time-slot-list.def.d.ts +23 -4
- package/cjs/dist/services/time-slot-list/time-slot-list.js +37 -9
- package/dist/api/time-slot-list/index.d.ts +21 -1
- package/dist/api/time-slot-list/index.js +46 -8
- package/dist/react/core/time-slot-list/TimeSlot.d.ts +22 -18
- package/dist/react/core/time-slot-list/TimeSlot.js +41 -28
- package/dist/react/core/time-slot-list/TimeSlotList.d.ts +39 -7
- package/dist/react/core/time-slot-list/TimeSlotList.js +56 -11
- package/dist/react/time-slot-list/TimeSlot.js +3 -3
- package/dist/react/time-slot-list/TimeSlotList.d.ts +55 -12
- package/dist/react/time-slot-list/TimeSlotList.js +47 -17
- package/dist/services/index.d.ts +2 -2
- package/dist/services/time-slot-list/index.d.ts +1 -1
- package/dist/services/time-slot-list/time-slot-list.d.ts +3 -3
- package/dist/services/time-slot-list/time-slot-list.def.d.ts +23 -4
- package/dist/services/time-slot-list/time-slot-list.js +37 -9
- package/package.json +3 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Defines interfaces and service contract for time slot management
|
|
4
4
|
*/
|
|
5
5
|
import type { Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
-
import type { TimeSlot as ApiTimeSlot } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
6
|
+
import type { TimeSlot as ApiTimeSlot, Location } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
7
7
|
import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
8
8
|
export declare enum ViewMode {
|
|
9
9
|
CLASSIC = "classic",
|
|
@@ -42,6 +42,26 @@ export interface SlotSelection {
|
|
|
42
42
|
locationId: string | null;
|
|
43
43
|
staffMemberId: string | null;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Filters for narrowing down available time slots
|
|
47
|
+
* Matches Wix Bookings API filter parameters
|
|
48
|
+
*/
|
|
49
|
+
export interface TimeSlotsFilters {
|
|
50
|
+
/** Filter by specific locations */
|
|
51
|
+
locations?: Location[];
|
|
52
|
+
/** Filter by specific staff member IDs */
|
|
53
|
+
staffMemberIds?: string[];
|
|
54
|
+
/** Maximum slots to return per day (useful for calendar views) */
|
|
55
|
+
slotsPerDay?: number;
|
|
56
|
+
/** Filter by bookable status. If undefined, returns both bookable and non-bookable */
|
|
57
|
+
bookable?: boolean;
|
|
58
|
+
/** Filter by booking policy violations */
|
|
59
|
+
bookingPolicyViolations?: {
|
|
60
|
+
tooEarlyToBook?: boolean;
|
|
61
|
+
tooLateToBook?: boolean;
|
|
62
|
+
bookOnlineDisabled?: boolean;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
45
65
|
export interface TimeSlotListServiceConfig {
|
|
46
66
|
/** Services to fetch time slots for */
|
|
47
67
|
services?: Service[];
|
|
@@ -53,8 +73,8 @@ export interface TimeSlotListServiceConfig {
|
|
|
53
73
|
endDate?: Date;
|
|
54
74
|
/** Timezone for formatting */
|
|
55
75
|
timezone?: string;
|
|
56
|
-
/**
|
|
57
|
-
|
|
76
|
+
/** Filters for narrowing down time slots */
|
|
77
|
+
filters?: TimeSlotsFilters;
|
|
58
78
|
}
|
|
59
79
|
export interface TimeSlotListServiceActions {
|
|
60
80
|
selectSlot: (slot: TimeSlot) => void;
|
|
@@ -71,7 +91,6 @@ export interface TimeSlotListServiceAPI {
|
|
|
71
91
|
isLoading: Signal<boolean>;
|
|
72
92
|
error: Signal<string | null>;
|
|
73
93
|
hasMore: Signal<boolean>;
|
|
74
|
-
viewMode: Signal<ViewMode>;
|
|
75
94
|
startDate: Signal<Date>;
|
|
76
95
|
endDate: Signal<Date>;
|
|
77
96
|
timezone: Signal<string | undefined>;
|
|
@@ -68,7 +68,8 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
68
68
|
const isLoadingSignal = signalsService.signal(false);
|
|
69
69
|
const errorSignal = signalsService.signal(null);
|
|
70
70
|
const hasMoreSignal = signalsService.signal(false);
|
|
71
|
-
|
|
71
|
+
// Internal only - viewMode is auto-detected based on service types
|
|
72
|
+
const viewModeSignal = signalsService.signal(ViewMode.CLASSIC);
|
|
72
73
|
const startDateSignal = signalsService.signal(config.startDate || currentDate);
|
|
73
74
|
const endDateSignal = signalsService.signal(config.endDate || getDefaultEndDate());
|
|
74
75
|
const timezoneSignal = signalsService.signal(config.timezone ?? getClientTimezone());
|
|
@@ -81,12 +82,35 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
81
82
|
return config.services;
|
|
82
83
|
return bookingService.bookingItems.get().map((s) => s.service);
|
|
83
84
|
};
|
|
85
|
+
/**
|
|
86
|
+
* Helper: Get filters from config or BookingService
|
|
87
|
+
*/
|
|
88
|
+
const getFilters = () => {
|
|
89
|
+
// Get BookingService selections (these take priority)
|
|
90
|
+
const location = bookingService.location.get();
|
|
91
|
+
const selections = bookingService.bookingItems.get();
|
|
92
|
+
const selectedStaffMemberIds = selections
|
|
93
|
+
.map(({ resources }) => resources.map((r) => r._id))
|
|
94
|
+
.flat();
|
|
95
|
+
const selectedLocation = location ? { _id: location.id } : null;
|
|
96
|
+
// Merge config filters with BookingService selections (selections win)
|
|
97
|
+
return {
|
|
98
|
+
...config.filters,
|
|
99
|
+
locations: selectedLocation
|
|
100
|
+
? [selectedLocation]
|
|
101
|
+
: config.filters?.locations,
|
|
102
|
+
staffMemberIds: selectedStaffMemberIds.length
|
|
103
|
+
? selectedStaffMemberIds
|
|
104
|
+
: config.filters?.staffMemberIds,
|
|
105
|
+
};
|
|
106
|
+
};
|
|
84
107
|
/**
|
|
85
108
|
* Fetch time slots from API
|
|
86
109
|
* Called on initialization or when filters change
|
|
87
110
|
*/
|
|
88
111
|
const fetchTimeSlots = async () => {
|
|
89
112
|
const selectedServices = getServices();
|
|
113
|
+
const filters = getFilters();
|
|
90
114
|
isLoadingSignal.set(true);
|
|
91
115
|
errorSignal.set(null);
|
|
92
116
|
cursorSignal.set(undefined);
|
|
@@ -97,6 +121,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
97
121
|
toLocalDate: toLocalDateString(endDateSignal.get()),
|
|
98
122
|
timeZone: timezoneSignal.get(),
|
|
99
123
|
viewMode: viewModeSignal.get(),
|
|
124
|
+
...filters,
|
|
100
125
|
});
|
|
101
126
|
timeSlotsSignal.set(response.timeSlots);
|
|
102
127
|
const nextCursor = response.cursorPagingMetadata?.cursors?.next ?? undefined;
|
|
@@ -279,6 +304,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
279
304
|
const selectedServices = getServices();
|
|
280
305
|
if (selectedServices.length === 0)
|
|
281
306
|
return;
|
|
307
|
+
const filters = getFilters();
|
|
282
308
|
isLoadingSignal.set(true);
|
|
283
309
|
try {
|
|
284
310
|
const response = await fetchAvailability({
|
|
@@ -288,6 +314,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
288
314
|
timeZone: timezoneSignal.get(),
|
|
289
315
|
cursorPaging: { cursor },
|
|
290
316
|
viewMode: viewModeSignal.get(),
|
|
317
|
+
...filters,
|
|
291
318
|
});
|
|
292
319
|
// API returns grouped slots, merge with existing
|
|
293
320
|
const existing = timeSlotsSignal.get();
|
|
@@ -310,6 +337,12 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
310
337
|
* Action: Update date range and refetch slots
|
|
311
338
|
*/
|
|
312
339
|
const setDateRange = (newStartDate, newEndDate) => {
|
|
340
|
+
const currentStartDate = startDateSignal.get();
|
|
341
|
+
const currentEndDate = endDateSignal.get();
|
|
342
|
+
if (currentStartDate.getTime() === newStartDate.getTime() &&
|
|
343
|
+
currentEndDate.getTime() === newEndDate.getTime()) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
313
346
|
startDateSignal.set(newStartDate);
|
|
314
347
|
endDateSignal.set(newEndDate);
|
|
315
348
|
fetchTimeSlots();
|
|
@@ -333,8 +366,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
333
366
|
isLoading: isLoadingSignal,
|
|
334
367
|
error: errorSignal,
|
|
335
368
|
hasMore: hasMoreSignal,
|
|
336
|
-
// Configuration Signals
|
|
337
|
-
viewMode: viewModeSignal,
|
|
369
|
+
// Configuration Signals (viewMode is internal only)
|
|
338
370
|
startDate: startDateSignal,
|
|
339
371
|
endDate: endDateSignal,
|
|
340
372
|
timezone: timezoneSignal,
|
|
@@ -375,23 +407,19 @@ export async function loadTimeSlotListConfig(options) {
|
|
|
375
407
|
const now = new Date();
|
|
376
408
|
const startDate = options.startDate || now;
|
|
377
409
|
const endDate = options.endDate || getDefaultEndDate();
|
|
378
|
-
const viewMode = options.viewMode || ViewMode.CLASSIC;
|
|
379
|
-
// check for location and staff in config
|
|
380
410
|
try {
|
|
381
411
|
const response = await fetchAvailability({
|
|
382
412
|
services: options.services || [],
|
|
383
413
|
fromLocalDate: toLocalDateString(startDate),
|
|
384
414
|
toLocalDate: toLocalDateString(endDate),
|
|
385
415
|
timeZone: options.timezone ?? getClientTimezone(),
|
|
386
|
-
|
|
416
|
+
...options.filters,
|
|
387
417
|
});
|
|
388
418
|
const config = {
|
|
389
|
-
|
|
419
|
+
...options,
|
|
390
420
|
timeSlots: response.timeSlots || [],
|
|
391
421
|
startDate,
|
|
392
422
|
endDate,
|
|
393
|
-
timezone: options.timezone,
|
|
394
|
-
viewMode,
|
|
395
423
|
};
|
|
396
424
|
return { type: 'success', config };
|
|
397
425
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-bookings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@wix/auto_sdk_bookings_event-time-slots": "^1.0.64",
|
|
36
37
|
"@wix/bookings": "^1.0.122",
|
|
37
38
|
"@wix/form-public": "^0.64.0",
|
|
38
39
|
"@wix/headless-media": "0.0.18",
|
|
@@ -68,5 +69,5 @@
|
|
|
68
69
|
"groupId": "com.wixpress.headless-components"
|
|
69
70
|
}
|
|
70
71
|
},
|
|
71
|
-
"falconPackageHash": "
|
|
72
|
+
"falconPackageHash": "8c910b633cde19227cb0209fec691701a57a7e53b577ee76971bfa2a"
|
|
72
73
|
}
|