@qite/tide-components 1.0.2 → 1.0.4
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 +182 -162
- package/build/build-cjs/src/search-results/components/traject/traject-node-card.d.ts +2 -0
- package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +16 -2
- package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +7 -8
- package/build/build-esm/index.js +182 -162
- package/build/build-esm/src/search-results/components/traject/traject-node-card.d.ts +2 -0
- package/build/build-esm/src/search-results/store/search-results-slice.d.ts +16 -2
- package/build/build-esm/src/search-results/utils/traject-utils.d.ts +7 -8
- package/package.json +2 -2
package/build/build-cjs/index.js
CHANGED
|
@@ -27370,7 +27370,7 @@ const initialState$1 = {
|
|
|
27370
27370
|
currentStep: 0,
|
|
27371
27371
|
bookingNumber: undefined,
|
|
27372
27372
|
trajectNodeAvailability: {},
|
|
27373
|
-
|
|
27373
|
+
trajectFlightAvailability: {}
|
|
27374
27374
|
};
|
|
27375
27375
|
const searchResultsSlice = toolkit.createSlice({
|
|
27376
27376
|
name: 'searchResults',
|
|
@@ -27592,16 +27592,38 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
27592
27592
|
const guids = new Set(action.payload);
|
|
27593
27593
|
state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
|
|
27594
27594
|
},
|
|
27595
|
-
|
|
27596
|
-
|
|
27595
|
+
setTrajectFlightLoading(state, action) {
|
|
27596
|
+
const lineGuid = action.payload;
|
|
27597
|
+
state.trajectFlightAvailability[lineGuid] = {
|
|
27598
|
+
lineGuid,
|
|
27599
|
+
status: 'loading',
|
|
27600
|
+
results: state.trajectFlightAvailability[lineGuid]?.results ?? [],
|
|
27601
|
+
selectedGuid: state.trajectFlightAvailability[lineGuid]?.selectedGuid ?? null
|
|
27602
|
+
};
|
|
27603
|
+
},
|
|
27604
|
+
setTrajectFlightAvailability(state, action) {
|
|
27605
|
+
const { lineGuid, results, selectedGuid } = action.payload;
|
|
27606
|
+
state.trajectFlightAvailability[lineGuid] = {
|
|
27607
|
+
lineGuid,
|
|
27608
|
+
status: selectedGuid ? 'resolved' : 'unavailable',
|
|
27609
|
+
results,
|
|
27610
|
+
selectedGuid
|
|
27611
|
+
};
|
|
27612
|
+
},
|
|
27613
|
+
setTrajectFlightSelection(state, action) {
|
|
27614
|
+
const flight = state.trajectFlightAvailability[action.payload.lineGuid];
|
|
27615
|
+
if (!flight)
|
|
27616
|
+
return;
|
|
27617
|
+
flight.selectedGuid = action.payload.guid;
|
|
27618
|
+
flight.status = 'resolved';
|
|
27597
27619
|
},
|
|
27598
27620
|
resetTrajectAvailability(state) {
|
|
27599
27621
|
state.trajectNodeAvailability = {};
|
|
27600
|
-
state.
|
|
27622
|
+
state.trajectFlightAvailability = {};
|
|
27601
27623
|
}
|
|
27602
27624
|
}
|
|
27603
27625
|
});
|
|
27604
|
-
const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection,
|
|
27626
|
+
const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection, setTrajectFlightLoading, setTrajectFlightAvailability, setTrajectFlightSelection, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
|
|
27605
27627
|
var searchResultsReducer = searchResultsSlice.reducer;
|
|
27606
27628
|
|
|
27607
27629
|
const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
|
|
@@ -32967,6 +32989,8 @@ const buildDestination = (line) => {
|
|
|
32967
32989
|
return { id: line.region.id, isRegion: true };
|
|
32968
32990
|
if (line.country?.id)
|
|
32969
32991
|
return { id: line.country.id, isCountry: true };
|
|
32992
|
+
if (line.latitude && line.longitude)
|
|
32993
|
+
return { latitude: line.latitude, longitude: line.longitude };
|
|
32970
32994
|
return { id: 0 };
|
|
32971
32995
|
};
|
|
32972
32996
|
const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
|
|
@@ -32986,10 +33010,27 @@ const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
|
|
|
32986
33010
|
rooms: context.rooms,
|
|
32987
33011
|
tagIds: []
|
|
32988
33012
|
});
|
|
32989
|
-
const
|
|
32990
|
-
const
|
|
32991
|
-
|
|
33013
|
+
const getNodeCandidates = (node) => {
|
|
33014
|
+
const configured = (node.alternatives ?? []).filter((x) => !!x.code && x.code.trim().length > 0);
|
|
33015
|
+
if (configured.length)
|
|
33016
|
+
return configured;
|
|
33017
|
+
const fallbackCode = node.code ?? node.preferredAccommodationCode;
|
|
33018
|
+
if (!fallbackCode || !fallbackCode.trim().length)
|
|
33019
|
+
return [];
|
|
33020
|
+
return [
|
|
33021
|
+
{
|
|
33022
|
+
code: fallbackCode,
|
|
33023
|
+
name: node.name,
|
|
33024
|
+
description: node.description,
|
|
33025
|
+
imageUrl: node.imageUrl,
|
|
33026
|
+
contentSource: node.contentSource,
|
|
33027
|
+
vendor: node.vendor,
|
|
33028
|
+
externalVendorId: node.externalVendorId,
|
|
33029
|
+
isPreferred: true
|
|
33030
|
+
}
|
|
33031
|
+
];
|
|
32992
33032
|
};
|
|
33033
|
+
const findCandidateForResult = (node, result) => getNodeCandidates(node).find((candidate) => matchesCode(result, candidate.code)) ?? null;
|
|
32993
33034
|
const matchesCode = (result, code) => {
|
|
32994
33035
|
if (result.code === code)
|
|
32995
33036
|
return true;
|
|
@@ -33053,8 +33094,26 @@ const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => (
|
|
|
33053
33094
|
arrivalAirportDescription: segment.arrivalAirportName,
|
|
33054
33095
|
durationInTicks: segment.durationInTicks
|
|
33055
33096
|
}));
|
|
33056
|
-
const
|
|
33057
|
-
|
|
33097
|
+
const buildTrajectFlightRequest = ({ node, line }, context, pax) => ({
|
|
33098
|
+
transactionId: context.transactionId,
|
|
33099
|
+
officeId: context.officeId,
|
|
33100
|
+
catalogueId: context.catalogueId,
|
|
33101
|
+
agentId: context.agentId ?? null,
|
|
33102
|
+
language: context.language,
|
|
33103
|
+
departureAirportCode: node.departureAirportCode ?? '',
|
|
33104
|
+
arrivalAirportCode: node.arrivalAirportCode ?? '',
|
|
33105
|
+
returnAirportCode: null,
|
|
33106
|
+
luggageIncluded: null,
|
|
33107
|
+
maxStops: null,
|
|
33108
|
+
travelClass: null,
|
|
33109
|
+
vendorConfigurationId: node.externalVendorId ?? null,
|
|
33110
|
+
pax,
|
|
33111
|
+
outward: { date: dateToDateStruct(new Date(line.from)) },
|
|
33112
|
+
return: null
|
|
33113
|
+
});
|
|
33114
|
+
const pickCheapestFlight = (flights) => [...flights].sort((a, b) => a.price - b.price)[0] ?? null;
|
|
33115
|
+
const applyFlightToLine = (line, flight) => {
|
|
33116
|
+
const segments = flight.outward?.segments ?? [];
|
|
33058
33117
|
if (!segments.length)
|
|
33059
33118
|
return line;
|
|
33060
33119
|
const firstSegment = segments[0];
|
|
@@ -33074,14 +33133,6 @@ const applyFlightToLine = (line, flight, isOutbound) => {
|
|
|
33074
33133
|
isChanged: true
|
|
33075
33134
|
};
|
|
33076
33135
|
};
|
|
33077
|
-
const pairTrajectFlights = (nodes) => {
|
|
33078
|
-
const flights = nodes.filter((x) => isTrajectFlightNode(x.node));
|
|
33079
|
-
return {
|
|
33080
|
-
outbound: flights[0] ?? null,
|
|
33081
|
-
inbound: flights.length > 1 ? flights[flights.length - 1] : null,
|
|
33082
|
-
unsupported: flights.slice(1, Math.max(flights.length - 1, 1))
|
|
33083
|
-
};
|
|
33084
|
-
};
|
|
33085
33136
|
|
|
33086
33137
|
const getLocation = (result) => {
|
|
33087
33138
|
const place = result.locationName || result.regionName || result.oordName;
|
|
@@ -33089,10 +33140,26 @@ const getLocation = (result) => {
|
|
|
33089
33140
|
return result.countryName ?? '';
|
|
33090
33141
|
return result.countryName ? `${place}, ${result.countryName}` : place;
|
|
33091
33142
|
};
|
|
33092
|
-
const
|
|
33143
|
+
const toPlainText = (value) => {
|
|
33144
|
+
if (!value)
|
|
33145
|
+
return '';
|
|
33146
|
+
return he
|
|
33147
|
+
.decode(value.replace(/<[^>]*>/g, ' '))
|
|
33148
|
+
.replace(/\s+/g, ' ')
|
|
33149
|
+
.trim();
|
|
33150
|
+
};
|
|
33151
|
+
const TrajectNodeCard = ({ item, result, isSelected, languageCode, translations, onSelect, showNights }) => {
|
|
33152
|
+
const { node } = item;
|
|
33093
33153
|
const selectedOption = lodash.first(result.rooms)?.options?.find((x) => x.isSelected) ?? lodash.first(result.rooms)?.options?.[0];
|
|
33094
33154
|
const price = formatPrice$3(result.price, result.currencyCode, languageCode);
|
|
33095
33155
|
const nights = calculateNights(new Date(result.fromDate), new Date(result.toDate));
|
|
33156
|
+
const candidate = findCandidateForResult(node, result);
|
|
33157
|
+
const image = candidate?.imageUrl ?? null;
|
|
33158
|
+
const description = toPlainText(candidate?.description);
|
|
33159
|
+
const title = candidate?.name ?? result.name;
|
|
33160
|
+
const priceBlock = (React__default["default"].createElement("div", { className: "search__result-card__price__wrapper" },
|
|
33161
|
+
React__default["default"].createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
|
|
33162
|
+
React__default["default"].createElement("span", { className: "search__result-card__price" }, price)));
|
|
33096
33163
|
const selectButton = (React__default["default"].createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT));
|
|
33097
33164
|
if (result.contents?.length) {
|
|
33098
33165
|
return (React__default["default"].createElement("div", { className: `search__result-card__wrapper search__result-card__wrapper--custom ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
|
|
@@ -33100,21 +33167,22 @@ const TrajectNodeCard = ({ result, isSelected, languageCode, translations, onSel
|
|
|
33100
33167
|
React__default["default"].createElement("div", { className: "search__result-card__footer" }, selectButton)));
|
|
33101
33168
|
}
|
|
33102
33169
|
return (React__default["default"].createElement("div", { className: `search__result-card__wrapper ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
|
|
33170
|
+
image && (React__default["default"].createElement("div", { className: "search__result-card__img-wrapper" },
|
|
33171
|
+
React__default["default"].createElement("img", { src: image, alt: title, className: "search__result-card__img" }),
|
|
33172
|
+
priceBlock)),
|
|
33103
33173
|
React__default["default"].createElement("div", { className: "search__result-card__content" },
|
|
33104
33174
|
React__default["default"].createElement("div", { className: "search__result-card__content__wrapper" },
|
|
33105
33175
|
React__default["default"].createElement("div", { className: "search__result-card__header" },
|
|
33106
33176
|
React__default["default"].createElement("div", { className: "search__result-card__header__wrapper" },
|
|
33107
33177
|
!!result.stars && (React__default["default"].createElement("div", { className: "rating" }, [...Array(result.stars)].map((_, index) => (React__default["default"].createElement(Icon, { name: "ui-star", key: `rating-star-${index + 1}`, width: 14, height: 14 }))))),
|
|
33108
|
-
React__default["default"].createElement("h3", { className: "search__result-card__title" },
|
|
33109
|
-
|
|
33110
|
-
React__default["default"].createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
|
|
33111
|
-
React__default["default"].createElement("span", { className: "search__result-card__price" }, price))),
|
|
33178
|
+
React__default["default"].createElement("h3", { className: "search__result-card__title" }, title)),
|
|
33179
|
+
!image && priceBlock),
|
|
33112
33180
|
React__default["default"].createElement("span", { className: "search__result-card__location" },
|
|
33113
33181
|
React__default["default"].createElement(Icon, { name: "ui-location", height: 16 }),
|
|
33114
33182
|
getLocation(result)),
|
|
33115
33183
|
React__default["default"].createElement("div", { className: "search__result-card__options" },
|
|
33116
33184
|
showNights && nights > 0 && (React__default["default"].createElement("div", { className: "search__result-card__option" },
|
|
33117
|
-
React__default["default"].createElement(Icon, { name: "ui-
|
|
33185
|
+
React__default["default"].createElement(Icon, { name: "ui-moon", height: 16 }),
|
|
33118
33186
|
nights,
|
|
33119
33187
|
" ",
|
|
33120
33188
|
translations?.SRP.NIGHTS)),
|
|
@@ -33123,7 +33191,8 @@ const TrajectNodeCard = ({ result, isSelected, languageCode, translations, onSel
|
|
|
33123
33191
|
selectedOption.accommodationName)),
|
|
33124
33192
|
selectedOption?.regimeName && (React__default["default"].createElement("div", { className: "search__result-card__option" },
|
|
33125
33193
|
React__default["default"].createElement(Icon, { name: "ui-utensils", height: 16 }),
|
|
33126
|
-
selectedOption.regimeName)))
|
|
33194
|
+
selectedOption.regimeName))),
|
|
33195
|
+
description && React__default["default"].createElement("p", { className: "search__result-card__description" }, description)),
|
|
33127
33196
|
React__default["default"].createElement("div", { className: "search__result-card__footer" }, selectButton))));
|
|
33128
33197
|
};
|
|
33129
33198
|
|
|
@@ -33141,15 +33210,10 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33141
33210
|
const dispatch = reactRedux.useDispatch();
|
|
33142
33211
|
const translations = getTranslations(context?.languageCode ?? 'en-GB');
|
|
33143
33212
|
const locale = getLocale(context?.languageCode ?? 'en-GB');
|
|
33144
|
-
const { trajectNodeAvailability,
|
|
33145
|
-
const uniqueOutwardFlights = reactRedux.useSelector(selectUniqueOutwardFlights);
|
|
33146
|
-
const uniqueReturnFlights = reactRedux.useSelector(selectUniqueReturnFlights);
|
|
33147
|
-
const selectedOutward = reactRedux.useSelector(selectSelectedOutward);
|
|
33148
|
-
const selectedReturn = reactRedux.useSelector(selectSelectedReturn);
|
|
33213
|
+
const { trajectNodeAvailability, trajectFlightAvailability } = reactRedux.useSelector((state) => state.searchResults);
|
|
33149
33214
|
const [expandedNodes, setExpandedNodes] = React.useState({});
|
|
33150
33215
|
const trajectEntry = context?.trajectEntry;
|
|
33151
33216
|
const nodesWithLines = React.useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
|
|
33152
|
-
const flightPairing = React.useMemo(() => pairTrajectFlights(nodesWithLines), [nodesWithLines]);
|
|
33153
33217
|
const lineByNodeId = React.useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
|
|
33154
33218
|
const nodesByDay = React.useMemo(() => {
|
|
33155
33219
|
const map = new Map();
|
|
@@ -33174,12 +33238,14 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33174
33238
|
dispatch(updateEditableEntryLine(applyResultToLine(item.line, result)));
|
|
33175
33239
|
};
|
|
33176
33240
|
const renderServiceNode = (item) => {
|
|
33241
|
+
console.log('renderServiceNode', item);
|
|
33177
33242
|
const { node, line } = item;
|
|
33178
33243
|
const availability = trajectNodeAvailability[line.guid];
|
|
33179
33244
|
const isExpanded = !!expandedNodes[line.guid];
|
|
33180
33245
|
const results = availability?.results ?? [];
|
|
33181
33246
|
const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
|
|
33182
|
-
const
|
|
33247
|
+
const configured = results.filter((x) => x.code !== selected?.code && !!findCandidateForResult(node, x));
|
|
33248
|
+
const others = results.filter((x) => x.code !== selected?.code && !findCandidateForResult(node, x));
|
|
33183
33249
|
// No entry yet means the node's search has been queued but not dispatched — still loading.
|
|
33184
33250
|
const status = availability?.status ?? 'loading';
|
|
33185
33251
|
return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
|
|
@@ -33188,9 +33254,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33188
33254
|
React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(line.from), 'd', { locale })),
|
|
33189
33255
|
React__default["default"].createElement("p", null, dateFns.format(new Date(line.from), 'MMM', { locale }))),
|
|
33190
33256
|
React__default["default"].createElement("div", { className: "search__results__label__text" },
|
|
33191
|
-
React__default["default"].createElement(Icon, { name: getNodeIcon(node), height: 16 }),
|
|
33192
|
-
React__default["default"].createElement("h3", null,
|
|
33193
|
-
React__default["default"].createElement("strong", null, node.name)))),
|
|
33257
|
+
React__default["default"].createElement(Icon, { name: getNodeIcon(node), height: 16 }))),
|
|
33194
33258
|
status === 'loading' && (React__default["default"].createElement(Spinner, { label: node.serviceType === EXCURSION_SERVICE_TYPE ? translations.SRP.LOADING_EXCURSIONS : translations.SRP.LOADING_ACCOMMODATIONS })),
|
|
33195
33259
|
status === 'unavailable' && React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
33196
33260
|
status === 'resolved' && selected && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
@@ -33199,37 +33263,23 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33199
33263
|
node.preferredAccommodationName,
|
|
33200
33264
|
" \u2014 ",
|
|
33201
33265
|
translations.SRP.NO_RESULTS))),
|
|
33202
|
-
React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
33203
|
-
|
|
33204
|
-
isExpanded
|
|
33205
|
-
|
|
33206
|
-
|
|
33207
|
-
|
|
33266
|
+
React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" }, [selected, ...configured, ...(isExpanded ? others : [])].map((result) => (React__default["default"].createElement(TrajectNodeCard, { key: result.code, item: item, result: result, isSelected: result.code === selected.code, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, result.code), showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE })))),
|
|
33267
|
+
others.length > 0 && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
33268
|
+
React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${others.length})`)))))));
|
|
33269
|
+
};
|
|
33270
|
+
const handleSelectFlight = (item, flight) => {
|
|
33271
|
+
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
33272
|
+
dispatch(updateEditableEntryLine(applyFlightToLine(item.line, flight)));
|
|
33208
33273
|
};
|
|
33209
33274
|
const renderFlightNode = (item) => {
|
|
33210
33275
|
const { node, line } = item;
|
|
33211
|
-
const
|
|
33212
|
-
const
|
|
33213
|
-
|
|
33214
|
-
|
|
33215
|
-
|
|
33216
|
-
|
|
33217
|
-
|
|
33218
|
-
React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(line.from), 'd', { locale })),
|
|
33219
|
-
React__default["default"].createElement("p", null, dateFns.format(new Date(line.from), 'MMM', { locale }))),
|
|
33220
|
-
React__default["default"].createElement("div", { className: "search__results__label__text" },
|
|
33221
|
-
React__default["default"].createElement(Icon, { name: "ui-flight", height: 16 }),
|
|
33222
|
-
React__default["default"].createElement("h3", null,
|
|
33223
|
-
React__default["default"].createElement("strong", null, node.name)))),
|
|
33224
|
-
React__default["default"].createElement("div", { className: "no-results" },
|
|
33225
|
-
node.departureAirportCode,
|
|
33226
|
-
" \u2192 ",
|
|
33227
|
-
node.arrivalAirportCode)));
|
|
33228
|
-
}
|
|
33229
|
-
const flights = isOutbound ? uniqueOutwardFlights : uniqueReturnFlights;
|
|
33230
|
-
const selectedFlight = isOutbound ? selectedOutward : selectedReturn;
|
|
33231
|
-
const selectedKey = isOutbound ? selectedOutwardKey : selectedReturnKey;
|
|
33232
|
-
const visible = flights.filter((x) => getFlightKey(isOutbound ? x.outward.segments : x.return.segments) !== selectedKey);
|
|
33276
|
+
const availability = trajectFlightAvailability[line.guid];
|
|
33277
|
+
const status = availability?.status ?? 'loading';
|
|
33278
|
+
const flights = availability?.results ?? [];
|
|
33279
|
+
const selected = flights.find((x) => x.outwardGuid === availability?.selectedGuid) ?? null;
|
|
33280
|
+
const others = flights.filter((x) => x.outwardGuid !== availability?.selectedGuid);
|
|
33281
|
+
const isExpanded = !!expandedNodes[line.guid];
|
|
33282
|
+
const visible = isExpanded ? others : others.slice(0, 2);
|
|
33233
33283
|
return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
|
|
33234
33284
|
React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
33235
33285
|
React__default["default"].createElement("div", { className: "search__results__label__date" },
|
|
@@ -33239,42 +33289,37 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33239
33289
|
React__default["default"].createElement(Icon, { name: "ui-flight", height: 16 }),
|
|
33240
33290
|
React__default["default"].createElement("h3", null,
|
|
33241
33291
|
translations.SRP.SELECT,
|
|
33242
|
-
|
|
33243
|
-
React__default["default"].createElement("strong", null,
|
|
33244
|
-
|
|
33245
|
-
|
|
33246
|
-
|
|
33247
|
-
|
|
33248
|
-
|
|
33249
|
-
|
|
33250
|
-
|
|
33251
|
-
|
|
33252
|
-
|
|
33253
|
-
|
|
33254
|
-
|
|
33292
|
+
' ',
|
|
33293
|
+
React__default["default"].createElement("strong", null,
|
|
33294
|
+
node.departureAirportCode,
|
|
33295
|
+
" - ",
|
|
33296
|
+
node.arrivalAirportCode)))),
|
|
33297
|
+
status === 'loading' && React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS }),
|
|
33298
|
+
status === 'unavailable' && React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
33299
|
+
status === 'resolved' && selected && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
33300
|
+
React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
33301
|
+
React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price }),
|
|
33302
|
+
visible.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, isOutward: true, price: result.price, currentSelectedPrice: selected.price, onSelect: () => handleSelectFlight(item, result) })))),
|
|
33303
|
+
others.length > 2 && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
33304
|
+
React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${others.length - 2})`)))))));
|
|
33305
|
+
};
|
|
33255
33306
|
if (isLoading)
|
|
33256
33307
|
return React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
|
|
33257
33308
|
return (React__default["default"].createElement(React__default["default"].Fragment, null, trajectEntry.traject.days.map((day) => {
|
|
33258
33309
|
const dayNodes = nodesByDay.get(day.order) ?? [];
|
|
33259
33310
|
if (!dayNodes.length)
|
|
33260
33311
|
return null;
|
|
33261
|
-
return (React__default["default"].createElement(React__default["default"].Fragment, { key: `day-${day.order}` },
|
|
33262
|
-
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33266
|
-
|
|
33267
|
-
|
|
33268
|
-
|
|
33269
|
-
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
return renderContextNode(node);
|
|
33273
|
-
const item = lineByNodeId.get(node.nodeId);
|
|
33274
|
-
if (!item)
|
|
33275
|
-
return renderContextNode(node);
|
|
33276
|
-
return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
|
|
33277
|
-
})));
|
|
33312
|
+
return (React__default["default"].createElement(React__default["default"].Fragment, { key: `day-${day.order}` }, dayNodes.map((node) => {
|
|
33313
|
+
// if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) return null;
|
|
33314
|
+
// if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE) return renderContextNode(node);
|
|
33315
|
+
if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE)
|
|
33316
|
+
return null;
|
|
33317
|
+
const item = lineByNodeId.get(node.nodeId);
|
|
33318
|
+
// if (!item) return renderContextNode(node);
|
|
33319
|
+
if (!item)
|
|
33320
|
+
return null;
|
|
33321
|
+
return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
|
|
33322
|
+
})));
|
|
33278
33323
|
})));
|
|
33279
33324
|
};
|
|
33280
33325
|
|
|
@@ -33282,7 +33327,6 @@ const useTrajectAvailability = () => {
|
|
|
33282
33327
|
const context = React.useContext(SearchResultsConfigurationContext);
|
|
33283
33328
|
const dispatch = reactRedux.useDispatch();
|
|
33284
33329
|
const trajectEntry = context?.trajectEntry;
|
|
33285
|
-
const selectedCombinationFlight = reactRedux.useSelector(selectSelectedCombinationFlight);
|
|
33286
33330
|
React.useEffect(() => {
|
|
33287
33331
|
if (!context || !trajectEntry)
|
|
33288
33332
|
return;
|
|
@@ -33302,31 +33346,40 @@ const useTrajectAvailability = () => {
|
|
|
33302
33346
|
language: context.languageCode ?? 'en-GB',
|
|
33303
33347
|
rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
|
|
33304
33348
|
};
|
|
33349
|
+
// Flight searches take passengers rather than rooms; the API buckets by age.
|
|
33350
|
+
const pax = trajectEntry.entry.pax ?? [];
|
|
33351
|
+
const ageOf = (p) => p.age ?? 30;
|
|
33352
|
+
const adults = pax.filter((p) => ageOf(p) >= 12).length;
|
|
33353
|
+
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
|
|
33354
|
+
const babies = pax.filter((p) => ageOf(p) < 2).length;
|
|
33355
|
+
const flightPax = lodash.concat(Array.from({ length: adults }, (_, index) => ({ id: index, age: 31 })), Array.from({ length: kids }, (_, index) => ({ id: index + adults, age: 8 })), Array.from({ length: babies }, (_, index) => ({ id: index + adults + kids, age: 1 })));
|
|
33305
33356
|
const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
|
|
33306
33357
|
const resolveNode = async (item) => {
|
|
33307
33358
|
const lineGuid = item.line.guid;
|
|
33308
33359
|
const search = item.node.serviceType === EXCURSION_SERVICE_TYPE ? build.searchPackagingExcursions : build.searchPackagingAccommodations;
|
|
33309
33360
|
dispatch(setTrajectNodeLoading(lineGuid));
|
|
33310
33361
|
try {
|
|
33311
|
-
const
|
|
33312
|
-
|
|
33313
|
-
|
|
33314
|
-
|
|
33315
|
-
|
|
33316
|
-
const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, code), controller.signal);
|
|
33317
|
-
const hit = (attempt ?? []).find((result) => matchesCode(result, code));
|
|
33318
|
-
if (hit) {
|
|
33319
|
-
results = attempt;
|
|
33320
|
-
picked = hit;
|
|
33321
|
-
break;
|
|
33362
|
+
const candidates = getNodeCandidates(item.node);
|
|
33363
|
+
const attempts = await Promise.all(candidates.map(async (candidate) => {
|
|
33364
|
+
try {
|
|
33365
|
+
const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, candidate.code), controller.signal);
|
|
33366
|
+
return (attempt ?? []).find((result) => matchesCode(result, candidate.code)) ?? null;
|
|
33322
33367
|
}
|
|
33323
|
-
|
|
33324
|
-
|
|
33368
|
+
catch (error) {
|
|
33369
|
+
if (!controller.signal.aborted)
|
|
33370
|
+
console.error('Traject hotel unavailable', candidate.code, error);
|
|
33371
|
+
return null;
|
|
33372
|
+
}
|
|
33373
|
+
}));
|
|
33374
|
+
let results = attempts.filter((x) => !!x).filter((x, i, all) => all.findIndex((y) => y.code === x.code) === i);
|
|
33375
|
+
let picked = results[0] ?? null;
|
|
33376
|
+
const preferredCandidate = candidates.find((x) => x.isPreferred) ?? candidates[0];
|
|
33377
|
+
let preferredUnavailable = !!preferredCandidate && !results.some((x) => matchesCode(x, preferredCandidate.code));
|
|
33325
33378
|
// Nothing configured was available — fall back to the cheapest result in the destination.
|
|
33326
33379
|
if (!picked) {
|
|
33327
33380
|
results = (await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? [];
|
|
33328
33381
|
picked = pickCheapest(results);
|
|
33329
|
-
preferredUnavailable =
|
|
33382
|
+
preferredUnavailable = candidates.length > 0;
|
|
33330
33383
|
}
|
|
33331
33384
|
if (controller.signal.aborted)
|
|
33332
33385
|
return null;
|
|
@@ -33349,59 +33402,36 @@ const useTrajectAvailability = () => {
|
|
|
33349
33402
|
return lineGuid;
|
|
33350
33403
|
}
|
|
33351
33404
|
};
|
|
33352
|
-
const
|
|
33353
|
-
const
|
|
33354
|
-
if (!
|
|
33355
|
-
dispatch(
|
|
33356
|
-
return;
|
|
33405
|
+
const resolveFlightNode = async (item) => {
|
|
33406
|
+
const lineGuid = item.line.guid;
|
|
33407
|
+
if (!item.node.departureAirportCode || !item.node.arrivalAirportCode) {
|
|
33408
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: [], selectedGuid: null }));
|
|
33409
|
+
return lineGuid;
|
|
33357
33410
|
}
|
|
33358
|
-
dispatch(
|
|
33411
|
+
dispatch(setTrajectFlightLoading(lineGuid));
|
|
33359
33412
|
try {
|
|
33360
|
-
const
|
|
33361
|
-
const ageOf = (p) => p.age ?? 30;
|
|
33362
|
-
const adults = pax.filter((p) => ageOf(p) >= 12).length;
|
|
33363
|
-
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
|
|
33364
|
-
const babies = pax.filter((p) => ageOf(p) < 2).length;
|
|
33365
|
-
const request = {
|
|
33366
|
-
transactionId: trajectEntry.entry.transactionId,
|
|
33367
|
-
officeId: searchContext.officeId,
|
|
33368
|
-
catalogueId: searchContext.catalogueId,
|
|
33369
|
-
agentId: searchContext.agentId,
|
|
33370
|
-
language: searchContext.language,
|
|
33371
|
-
departureAirportCode: outbound.node.departureAirportCode ?? '',
|
|
33372
|
-
arrivalAirportCode: outbound.node.arrivalAirportCode ?? '',
|
|
33373
|
-
returnAirportCode: inbound?.node.arrivalAirportCode ?? outbound.node.departureAirportCode ?? null,
|
|
33374
|
-
luggageIncluded: null,
|
|
33375
|
-
maxStops: null,
|
|
33376
|
-
travelClass: null,
|
|
33377
|
-
pax: lodash.concat(Array.from({ length: adults }, (_, index) => ({ id: index, age: 31 })), Array.from({ length: kids }, (_, index) => ({ id: index + adults, age: 8 })), Array.from({ length: babies }, (_, index) => ({ id: index + adults + kids, age: 1 }))),
|
|
33378
|
-
outward: { date: dateToDateStruct(new Date(outbound.line.from)) },
|
|
33379
|
-
return: { date: dateToDateStruct(new Date((inbound ?? outbound).line.from)) }
|
|
33380
|
-
};
|
|
33381
|
-
const flights = (await build.searchPackagingFlights(config, request, controller.signal)) ?? [];
|
|
33413
|
+
const flights = (await build.searchPackagingFlights(config, buildTrajectFlightRequest(item, searchContext, flightPax), controller.signal)) ?? [];
|
|
33382
33414
|
if (controller.signal.aborted)
|
|
33383
|
-
return;
|
|
33384
|
-
|
|
33385
|
-
|
|
33386
|
-
if (
|
|
33387
|
-
|
|
33388
|
-
|
|
33389
|
-
|
|
33415
|
+
return null;
|
|
33416
|
+
const picked = pickCheapestFlight(flights);
|
|
33417
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: flights, selectedGuid: picked?.outwardGuid ?? null }));
|
|
33418
|
+
if (!picked)
|
|
33419
|
+
return lineGuid;
|
|
33420
|
+
dispatch(updateEditableEntryLine(applyFlightToLine(item.line, picked)));
|
|
33421
|
+
return null;
|
|
33390
33422
|
}
|
|
33391
33423
|
catch (error) {
|
|
33392
|
-
if (
|
|
33393
|
-
|
|
33394
|
-
|
|
33395
|
-
|
|
33396
|
-
|
|
33397
|
-
dispatch(setFlightsLoading(false));
|
|
33398
|
-
dispatch(setTrajectFlightsResolved(true));
|
|
33399
|
-
}
|
|
33424
|
+
if (controller.signal.aborted)
|
|
33425
|
+
return null;
|
|
33426
|
+
console.error('Failed to resolve traject flight', item.node.name, error);
|
|
33427
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: [], selectedGuid: null }));
|
|
33428
|
+
return lineGuid;
|
|
33400
33429
|
}
|
|
33401
33430
|
};
|
|
33402
33431
|
(async () => {
|
|
33403
33432
|
const searchable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node));
|
|
33404
|
-
const
|
|
33433
|
+
const flightNodes = nodesWithLines.filter((x) => isTrajectFlightNode(x.node));
|
|
33434
|
+
const unresolved = await Promise.all([...searchable.map(resolveNode), ...flightNodes.map(resolveFlightNode)]);
|
|
33405
33435
|
if (controller.signal.aborted)
|
|
33406
33436
|
return;
|
|
33407
33437
|
// A node with no availability anywhere cannot be priced or booked, so its line comes off
|
|
@@ -33412,16 +33442,6 @@ const useTrajectAvailability = () => {
|
|
|
33412
33442
|
})();
|
|
33413
33443
|
return () => controller.abort();
|
|
33414
33444
|
}, [trajectEntry]);
|
|
33415
|
-
// Keep the traject's own flight lines in step with whatever outward/return the user picks.
|
|
33416
|
-
React.useEffect(() => {
|
|
33417
|
-
if (!trajectEntry || !selectedCombinationFlight)
|
|
33418
|
-
return;
|
|
33419
|
-
const { outbound, inbound } = pairTrajectFlights(getTrajectNodesWithLines(trajectEntry));
|
|
33420
|
-
if (outbound)
|
|
33421
|
-
dispatch(updateEditableEntryLine(applyFlightToLine(outbound.line, selectedCombinationFlight, true)));
|
|
33422
|
-
if (inbound)
|
|
33423
|
-
dispatch(updateEditableEntryLine(applyFlightToLine(inbound.line, selectedCombinationFlight, false)));
|
|
33424
|
-
}, [trajectEntry, selectedCombinationFlight]);
|
|
33425
33445
|
};
|
|
33426
33446
|
|
|
33427
33447
|
const SearchResultsContainer = ({ onBookingStarted }) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { PackagingAccommodationResponse } from '@qite/tide-client';
|
|
3
|
+
import { TrajectNodeWithLine } from '../../utils/traject-utils';
|
|
3
4
|
interface TrajectNodeCardProps {
|
|
5
|
+
item: TrajectNodeWithLine;
|
|
4
6
|
result: PackagingAccommodationResponse;
|
|
5
7
|
isSelected: boolean;
|
|
6
8
|
languageCode?: string;
|
|
@@ -40,7 +40,8 @@ export interface SearchResultsState {
|
|
|
40
40
|
bookingNumber?: string;
|
|
41
41
|
/** Per-traject-node availability, keyed by the entry line guid the node maps to. */
|
|
42
42
|
trajectNodeAvailability: Record<string, TrajectNodeAvailability>;
|
|
43
|
-
|
|
43
|
+
/** Per-flight-node one-way search results, keyed by the entry line guid. */
|
|
44
|
+
trajectFlightAvailability: Record<string, TrajectFlightAvailability>;
|
|
44
45
|
}
|
|
45
46
|
export type TrajectNodeStatus = 'idle' | 'loading' | 'resolved' | 'unavailable';
|
|
46
47
|
export interface TrajectNodeAvailability {
|
|
@@ -50,6 +51,12 @@ export interface TrajectNodeAvailability {
|
|
|
50
51
|
selectedCode: string | null;
|
|
51
52
|
preferredUnavailable: boolean;
|
|
52
53
|
}
|
|
54
|
+
export interface TrajectFlightAvailability {
|
|
55
|
+
lineGuid: string;
|
|
56
|
+
status: TrajectNodeStatus;
|
|
57
|
+
results: PackagingFlightResponse[];
|
|
58
|
+
selectedGuid: string | null;
|
|
59
|
+
}
|
|
53
60
|
export declare const setResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<BookingPackageItem[], "searchResults/setResults">, setFilteredResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<BookingPackageItem[], "searchResults/setFilteredResults">, setSelectedSearchResult: import("@reduxjs/toolkit").ActionCreatorWithPayload<BookingPackageItem | null, "searchResults/setSelectedSearchResult">, setPackagingAccoResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingAccommodationResponse[], "searchResults/setPackagingAccoResults">, setFilteredPackagingAccoResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingAccommodationResponse[], "searchResults/setFilteredPackagingAccoResults">, setFilteredPackagingFlightResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingFlightResponse[], "searchResults/setFilteredPackagingFlightResults">, setPackagingAccoSearchDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingAccommodationResponse[], "searchResults/setPackagingAccoSearchDetails">, setSelectedPackagingAccoResult: import("@reduxjs/toolkit").ActionCreatorWithPayload<string | null, "searchResults/setSelectedPackagingAccoResult">, setPackagingFlightResults: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingFlightResponse[], "searchResults/setPackagingFlightResults">, setSelectedPackagingFlight: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingFlightResponse | null, "searchResults/setSelectedPackagingFlight">, setSelectedFlight: import("@reduxjs/toolkit").ActionCreatorWithPayload<ExtendedFlightSearchResponseItem | null, "searchResults/setSelectedFlight">, setSelectedFlightDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<ExtendedFlightSearchResponseItem | null, "searchResults/setSelectedFlightDetails">, setBookingPackageDetails: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
54
61
|
details: BookingPackage;
|
|
55
62
|
}, "searchResults/setBookingPackageDetails">, selectFlight: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -71,6 +78,13 @@ export declare const setResults: import("@reduxjs/toolkit").ActionCreatorWithPay
|
|
|
71
78
|
}, "searchResults/setTrajectNodeAvailability">, setTrajectNodeSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
72
79
|
lineGuid: string;
|
|
73
80
|
code: string;
|
|
74
|
-
}, "searchResults/setTrajectNodeSelection">,
|
|
81
|
+
}, "searchResults/setTrajectNodeSelection">, setTrajectFlightLoading: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "searchResults/setTrajectFlightLoading">, setTrajectFlightAvailability: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
82
|
+
lineGuid: string;
|
|
83
|
+
results: PackagingFlightResponse[];
|
|
84
|
+
selectedGuid: string | null;
|
|
85
|
+
}, "searchResults/setTrajectFlightAvailability">, setTrajectFlightSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
86
|
+
lineGuid: string;
|
|
87
|
+
guid: string;
|
|
88
|
+
}, "searchResults/setTrajectFlightSelection">, resetTrajectAvailability: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"searchResults/resetTrajectAvailability">, updateEditableEntryLine: import("@reduxjs/toolkit").ActionCreatorWithPayload<PackagingEntryLine, "searchResults/updateEditableEntryLine">, removeEditableEntryLines: import("@reduxjs/toolkit").ActionCreatorWithPayload<string[], "searchResults/removeEditableEntryLines">;
|
|
75
89
|
declare const _default: import("@reduxjs/toolkit").Reducer<SearchResultsState>;
|
|
76
90
|
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { PackagingAccommodationRequest, PackagingAccommodationResponse, PackagingEntry, PackagingEntryLine, PackagingFlightResponse, PackagingRoom, PackagingTrajectNode, PackagingTrajectResponse } from '@qite/tide-client';
|
|
1
|
+
import { FlightSearchRequest, PackagingAccommodationRequest, PackagingAccommodationResponse, PackagingEntry, PackagingEntryLine, PackagingFlightResponse, PackagingRoom, PackagingTrajectAlternative, PackagingTrajectNode, PackagingTrajectResponse } from '@qite/tide-client';
|
|
2
2
|
export declare const REGULAR_TRAJECT_NODE_TYPE = 0;
|
|
3
|
+
export declare const CONNECTING_TRAJECT_NODE_TYPE = 1;
|
|
3
4
|
export interface TrajectNodeWithLine {
|
|
4
5
|
node: PackagingTrajectNode;
|
|
5
6
|
line: PackagingEntryLine;
|
|
@@ -18,14 +19,12 @@ export interface TrajectSearchContext {
|
|
|
18
19
|
rooms: PackagingAccommodationRequest['rooms'];
|
|
19
20
|
}
|
|
20
21
|
export declare const buildTrajectNodeRequest: ({ node, line }: TrajectNodeWithLine, context: TrajectSearchContext, productCode: string) => PackagingAccommodationRequest;
|
|
21
|
-
export declare const
|
|
22
|
+
export declare const getNodeCandidates: (node: PackagingTrajectNode) => PackagingTrajectAlternative[];
|
|
23
|
+
export declare const findCandidateForResult: (node: PackagingTrajectNode, result: PackagingAccommodationResponse) => PackagingTrajectAlternative | null;
|
|
22
24
|
export declare const matchesCode: (result: PackagingAccommodationResponse, code: string) => boolean;
|
|
23
25
|
export declare const getPackagingRoomsFromEntry: (entry: PackagingEntry) => PackagingRoom[];
|
|
24
26
|
export declare const pickCheapest: (results: PackagingAccommodationResponse[]) => PackagingAccommodationResponse | null;
|
|
25
27
|
export declare const applyResultToLine: (line: PackagingEntryLine, result: PackagingAccommodationResponse) => PackagingEntryLine;
|
|
26
|
-
export declare const
|
|
27
|
-
export declare const
|
|
28
|
-
|
|
29
|
-
inbound: TrajectNodeWithLine | null;
|
|
30
|
-
unsupported: TrajectNodeWithLine[];
|
|
31
|
-
};
|
|
28
|
+
export declare const buildTrajectFlightRequest: ({ node, line }: TrajectNodeWithLine, context: TrajectSearchContext, pax: FlightSearchRequest["pax"]) => FlightSearchRequest;
|
|
29
|
+
export declare const pickCheapestFlight: (flights: PackagingFlightResponse[]) => PackagingFlightResponse | null;
|
|
30
|
+
export declare const applyFlightToLine: (line: PackagingEntryLine, flight: PackagingFlightResponse) => PackagingEntryLine;
|