@qite/tide-components 1.0.7 → 1.0.9
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/build-cjs/index.js +637 -114
- package/build/build-cjs/src/booking-product/types.d.ts +10 -0
- package/build/build-cjs/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
- package/build/build-cjs/src/search-results/hooks/use-bookable-entry.d.ts +11 -0
- package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +3 -1
- package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +48 -10
- package/build/build-esm/index.js +638 -115
- package/build/build-esm/src/booking-product/types.d.ts +10 -0
- package/build/build-esm/src/search-results/components/itinerary/itinerary-utils.d.ts +12 -0
- package/build/build-esm/src/search-results/hooks/use-bookable-entry.d.ts +11 -0
- package/build/build-esm/src/search-results/store/search-results-slice.d.ts +3 -1
- package/build/build-esm/src/search-results/utils/traject-utils.d.ts +48 -10
- package/package.json +2 -2
- package/styles/components/_search.scss +20 -1
|
@@ -21,6 +21,16 @@ export interface Settings {
|
|
|
21
21
|
* to the Tide API is unchanged.
|
|
22
22
|
*/
|
|
23
23
|
disableRooms?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* When true, the traveller may pick the same day as departure and return
|
|
26
|
+
* (a 0-night stay), e.g. 20/09 - 20/09. By default a second click on the
|
|
27
|
+
* departure day restarts the selection instead of closing the range, which
|
|
28
|
+
* stays the behaviour for products that always span at least one night.
|
|
29
|
+
*
|
|
30
|
+
* Only affects `searchType: 0`; with `searchType: 1` the return date is
|
|
31
|
+
* dictated by the available date pairs coming from the API.
|
|
32
|
+
*/
|
|
33
|
+
allowSingleDayDateSelect?: boolean;
|
|
24
34
|
/**
|
|
25
35
|
* Icon name shown next to the price whenever a price is available.
|
|
26
36
|
* Defaults to `'ui-bed'` for backwards compatibility. Customers booking
|
|
@@ -7,6 +7,18 @@ export declare const numberOfNights: (segment: PackagingEntryLine) => number;
|
|
|
7
7
|
/** Icon per service type, so every node on the itinerary reads at a glance. */
|
|
8
8
|
export declare const getServiceTypeIcon: (serviceType?: number) => string;
|
|
9
9
|
export declare const getServiceTypeBadgeModifier: (serviceType?: number) => string;
|
|
10
|
+
/**
|
|
11
|
+
* How long a node takes, in the same shape the flight legs are written in — an hour count only
|
|
12
|
+
* once there is one, so a short drive reads as plain minutes.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getTrajectNodeDuration: (node: PackagingTrajectNode) => string;
|
|
15
|
+
/** Icon per way of travelling, where the route records one. */
|
|
16
|
+
export declare const getTransportTypeIcon: (transportType?: number | null) => string | null;
|
|
10
17
|
export declare const POI_TRAJECT_NODE_TYPE = 2;
|
|
18
|
+
/**
|
|
19
|
+
* A point of interest is a place on the map rather than a service, so it gets a marker. Anything
|
|
20
|
+
* else goes by how it is travelled where the route says so — a leg on foot or by bike is sold as
|
|
21
|
+
* nothing, and its service type falls back to a transfer — and by what it is where it does not.
|
|
22
|
+
*/
|
|
11
23
|
export declare const getTrajectNodeIcon: (node: PackagingTrajectNode) => string;
|
|
12
24
|
export declare const getTrajectNodeBadgeModifier: (node: PackagingTrajectNode) => string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PackagingEntry } from '@qite/tide-client';
|
|
2
|
+
/**
|
|
3
|
+
* The entry to send to the backend, as opposed to the one the page works with.
|
|
4
|
+
*
|
|
5
|
+
* They differ only for a traject: the page keeps the line guids the traject was rendered with,
|
|
6
|
+
* because that is what joins its nodes to its lines, while pricing and booking need the guids the
|
|
7
|
+
* searches cached their lines under. Anything else passes through untouched, so this can be used
|
|
8
|
+
* wherever the entry leaves the component without checking which flow is running.
|
|
9
|
+
*/
|
|
10
|
+
declare const useBookableEntry: () => PackagingEntry | null;
|
|
11
|
+
export default useBookableEntry;
|
|
@@ -45,6 +45,8 @@ export interface SearchResultsState {
|
|
|
45
45
|
trajectDaySuggestions: Record<number, TrajectDaySuggestions>;
|
|
46
46
|
trajectEditLineGuid: string | null;
|
|
47
47
|
trajectActivitiesDayOrder: number | null;
|
|
48
|
+
trajectResolving: boolean;
|
|
49
|
+
trajectItineraryView: boolean;
|
|
48
50
|
}
|
|
49
51
|
export type TrajectNodeStatus = 'idle' | 'loading' | 'resolved' | 'unavailable';
|
|
50
52
|
export interface TrajectNodeAvailability {
|
|
@@ -86,7 +88,7 @@ export declare const setResults: import("@reduxjs/toolkit").ActionCreatorWithPay
|
|
|
86
88
|
}, "searchResults/setTrajectNodeAvailability">, setTrajectNodeSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
87
89
|
lineGuid: string;
|
|
88
90
|
code: string;
|
|
89
|
-
}, "searchResults/setTrajectNodeSelection">, setTrajectFlightLoading: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "searchResults/setTrajectFlightLoading">, setTrajectFlightAvailability: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
91
|
+
}, "searchResults/setTrajectNodeSelection">, setTrajectResolving: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "searchResults/setTrajectResolving">, setTrajectItineraryView: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "searchResults/setTrajectItineraryView">, setTrajectFlightLoading: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "searchResults/setTrajectFlightLoading">, setTrajectFlightAvailability: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
90
92
|
lineGuid: string;
|
|
91
93
|
results: PackagingFlightResponse[];
|
|
92
94
|
selectedGuid: string | null;
|
|
@@ -23,31 +23,49 @@ export interface TrajectSearchContext {
|
|
|
23
23
|
}
|
|
24
24
|
export declare const buildTrajectClientConfig: (context: SearchResultsConfiguration) => TideClientConfig;
|
|
25
25
|
export declare const buildTrajectSearchContext: (context: SearchResultsConfiguration, trajectEntry: PackagingTrajectResponse) => TrajectSearchContext;
|
|
26
|
-
export declare const buildTrajectNodeRequest: ({ node, line }: TrajectNodeWithLine, context: TrajectSearchContext, productCode: string) => PackagingAccommodationRequest;
|
|
26
|
+
export declare const buildTrajectNodeRequest: ({ node, line }: TrajectNodeWithLine, context: TrajectSearchContext, productCode: string, destination?: PackagingDestination) => PackagingAccommodationRequest;
|
|
27
27
|
export declare const getDayDestinationItem: (items: TrajectNodeWithLine[], dayOrder: number) => TrajectNodeWithLine | null;
|
|
28
28
|
export declare const getDayDestination: (items: TrajectNodeWithLine[], availability: Record<string, {
|
|
29
29
|
results: PackagingAccommodationResponse[];
|
|
30
30
|
selectedCode: string | null;
|
|
31
31
|
}>, dayOrder: number) => PackagingDestination | null;
|
|
32
32
|
export declare const buildTrajectDayExcursionRequest: (date: string, destination: PackagingDestination, context: TrajectSearchContext) => PackagingAccommodationRequest;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* A traject node already has its lines and only needs stamping; a suggestion has none, so this
|
|
37
|
-
* builds them — one per selected option, as the regular day-by-day excursion flow does, since an
|
|
38
|
-
* excursion's options are ticket types (adult, child) rather than rooms. Where the search marks no
|
|
39
|
-
* default, the first option of each room stands in.
|
|
40
|
-
*/
|
|
33
|
+
type ExcursionOption = PackagingAccommodationResponse['rooms'][number]['options'][number];
|
|
34
|
+
export declare const getExcursionOptionGroups: (result: PackagingAccommodationResponse) => ExcursionOption[][];
|
|
35
|
+
export declare const excursionNeedsChoice: (result: PackagingAccommodationResponse) => boolean;
|
|
41
36
|
export declare const buildTrajectExcursionLines: (result: PackagingAccommodationResponse) => PackagingEntryLine[];
|
|
37
|
+
export declare const buildExcursionSearchParams: (result: PackagingAccommodationResponse) => {
|
|
38
|
+
date: string;
|
|
39
|
+
fromDate: string;
|
|
40
|
+
toDate: string;
|
|
41
|
+
countryId: number | null | undefined;
|
|
42
|
+
regionId: number | null | undefined;
|
|
43
|
+
oordId: number | null | undefined;
|
|
44
|
+
locationId: number | null | undefined;
|
|
45
|
+
locationName: string;
|
|
46
|
+
accommodationCode: null;
|
|
47
|
+
accommodationName: null;
|
|
48
|
+
hotelCode: string;
|
|
49
|
+
hotelName: string;
|
|
50
|
+
rooms: import("@qite/tide-client").PackageMainRoom[];
|
|
51
|
+
};
|
|
42
52
|
export interface DayActivityCard {
|
|
43
53
|
result: PackagingAccommodationResponse;
|
|
44
|
-
/** The traject node this result answers, where it is one of the trip's own excursions. */
|
|
45
54
|
item?: TrajectNodeWithLine;
|
|
46
55
|
}
|
|
47
56
|
export declare const buildDayActivityCards: (items: TrajectNodeWithLine[], availability: Record<string, {
|
|
48
57
|
results: PackagingAccommodationResponse[];
|
|
49
58
|
selectedCode: string | null;
|
|
50
59
|
}>, suggestions: PackagingAccommodationResponse[]) => DayActivityCard[];
|
|
60
|
+
/**
|
|
61
|
+
* Where to search for a node.
|
|
62
|
+
*
|
|
63
|
+
* Normally the node says so itself, through the product it was configured with. An excursion slot
|
|
64
|
+
* left empty on the traject says nothing at all — no code, no alternatives, and a line with no
|
|
65
|
+
* place on it — so it falls back to wherever the party is staying that day, the same anchor the
|
|
66
|
+
* day's own activity search uses.
|
|
67
|
+
*/
|
|
68
|
+
export declare const getNodeSearchDestination: (items: TrajectNodeWithLine[], item: TrajectNodeWithLine) => PackagingDestination;
|
|
51
69
|
export declare const getConfiguredExcursionCodes: (items: TrajectNodeWithLine[], dayOrder: number) => Set<string>;
|
|
52
70
|
export declare const getNodeCandidates: (node: PackagingTrajectNode) => PackagingTrajectAlternative[];
|
|
53
71
|
export declare const findCandidateForResult: (node: PackagingTrajectNode, result: PackagingAccommodationResponse) => PackagingTrajectAlternative | null;
|
|
@@ -57,6 +75,25 @@ export declare const pickCheapest: (results: PackagingAccommodationResponse[]) =
|
|
|
57
75
|
export declare const applyResultToLines: (lines: PackagingEntryLine[], result: PackagingAccommodationResponse) => PackagingEntryLine[];
|
|
58
76
|
export declare const applyResultToLine: (line: PackagingEntryLine, result: PackagingAccommodationResponse, roomIndex?: number) => PackagingEntryLine;
|
|
59
77
|
export declare const buildTrajectFlightRequest: ({ node, line }: TrajectNodeWithLine, context: TrajectSearchContext, pax: FlightSearchRequest["pax"]) => FlightSearchRequest;
|
|
78
|
+
/**
|
|
79
|
+
* The entry as the backend can price it.
|
|
80
|
+
*
|
|
81
|
+
* A search caches an EntryLine per option and hands back that line's guid on the option. The
|
|
82
|
+
* backend then rebuilds the entry by looking each line up in that cache on its guid, so a line
|
|
83
|
+
* it cannot find is dropped — PackagingEntryBuilder.SyncEntryLines skips it, and an entry whose
|
|
84
|
+
* lines all came off a traject prices as nothing at all.
|
|
85
|
+
*
|
|
86
|
+
* A traject entry is rendered before any search runs, so its lines carry the guids the traject
|
|
87
|
+
* mapper gave them. This swaps in the guid of whatever each line resolved onto, leaving the
|
|
88
|
+
* lines the traveller added themselves alone — those were built from a search result and already
|
|
89
|
+
* carry the right one.
|
|
90
|
+
*/
|
|
91
|
+
export declare const withCachedEntryLineGuids: (entry: PackagingEntry, trajectEntry: PackagingTrajectResponse, nodeAvailability: Record<string, {
|
|
92
|
+
results: PackagingAccommodationResponse[];
|
|
93
|
+
selectedCode: string | null;
|
|
94
|
+
}>, flightAvailability: Record<string, {
|
|
95
|
+
selectedGuid: string | null;
|
|
96
|
+
}>) => PackagingEntry;
|
|
60
97
|
export declare const pickCheapestFlight: (flights: PackagingFlightResponse[]) => PackagingFlightResponse | null;
|
|
61
98
|
export declare const applyFlightToLine: (line: PackagingEntryLine, flight: PackagingFlightResponse) => PackagingEntryLine;
|
|
62
99
|
/**
|
|
@@ -66,3 +103,4 @@ export declare const applyFlightToLine: (line: PackagingEntryLine, flight: Packa
|
|
|
66
103
|
*/
|
|
67
104
|
export declare const isExternalResult: (result: PackagingAccommodationResponse) => boolean;
|
|
68
105
|
export declare const isExternalCandidate: (candidate: PackagingTrajectAlternative) => boolean;
|
|
106
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qite/tide-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "React components for Tide (booking, product availability, form, ...)",
|
|
5
5
|
"main": "build/build-cjs/index.js",
|
|
6
6
|
"types": "build/build-cjs/src/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@jsonurl/jsonurl": "^1.1.4",
|
|
38
38
|
"@popperjs/core": "^2.10.2",
|
|
39
|
-
"@qite/tide-client": "^2.0.
|
|
39
|
+
"@qite/tide-client": "^2.0.17",
|
|
40
40
|
"@reduxjs/toolkit": "^2.8.2",
|
|
41
41
|
"@rollup/plugin-commonjs": "^19.0.1",
|
|
42
42
|
"@rollup/plugin-json": "^4.1.0",
|
|
@@ -371,12 +371,12 @@
|
|
|
371
371
|
display: flex;
|
|
372
372
|
flex-direction: column;
|
|
373
373
|
justify-content: center;
|
|
374
|
+
gap: 10px;
|
|
374
375
|
|
|
375
376
|
height: 173.5px;
|
|
376
377
|
padding: 0 20px;
|
|
377
378
|
|
|
378
379
|
&__wrapper {
|
|
379
|
-
padding: 20px 0px;
|
|
380
380
|
display: flex;
|
|
381
381
|
flex-direction: column;
|
|
382
382
|
align-items: center;
|
|
@@ -949,6 +949,25 @@
|
|
|
949
949
|
border: var(--tide-booking-search-results-label-date-border--secondary);
|
|
950
950
|
}
|
|
951
951
|
}
|
|
952
|
+
|
|
953
|
+
// Something inside a day rather than a day of its own: no date, no box, and quieter type,
|
|
954
|
+
// sitting close to what it introduces.
|
|
955
|
+
&--sub {
|
|
956
|
+
grid-template-columns: 1fr;
|
|
957
|
+
grid-template-rows: auto;
|
|
958
|
+
margin-top: 20px;
|
|
959
|
+
|
|
960
|
+
.search__results__label__text {
|
|
961
|
+
height: auto;
|
|
962
|
+
border: none;
|
|
963
|
+
padding: 0px;
|
|
964
|
+
gap: 8px;
|
|
965
|
+
|
|
966
|
+
h3 {
|
|
967
|
+
font-size: 16px;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
952
971
|
}
|
|
953
972
|
|
|
954
973
|
&__options {
|