@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-esm/index.js
CHANGED
|
@@ -27341,7 +27341,7 @@ const initialState$1 = {
|
|
|
27341
27341
|
currentStep: 0,
|
|
27342
27342
|
bookingNumber: undefined,
|
|
27343
27343
|
trajectNodeAvailability: {},
|
|
27344
|
-
|
|
27344
|
+
trajectFlightAvailability: {}
|
|
27345
27345
|
};
|
|
27346
27346
|
const searchResultsSlice = createSlice({
|
|
27347
27347
|
name: 'searchResults',
|
|
@@ -27563,16 +27563,38 @@ const searchResultsSlice = createSlice({
|
|
|
27563
27563
|
const guids = new Set(action.payload);
|
|
27564
27564
|
state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
|
|
27565
27565
|
},
|
|
27566
|
-
|
|
27567
|
-
|
|
27566
|
+
setTrajectFlightLoading(state, action) {
|
|
27567
|
+
const lineGuid = action.payload;
|
|
27568
|
+
state.trajectFlightAvailability[lineGuid] = {
|
|
27569
|
+
lineGuid,
|
|
27570
|
+
status: 'loading',
|
|
27571
|
+
results: state.trajectFlightAvailability[lineGuid]?.results ?? [],
|
|
27572
|
+
selectedGuid: state.trajectFlightAvailability[lineGuid]?.selectedGuid ?? null
|
|
27573
|
+
};
|
|
27574
|
+
},
|
|
27575
|
+
setTrajectFlightAvailability(state, action) {
|
|
27576
|
+
const { lineGuid, results, selectedGuid } = action.payload;
|
|
27577
|
+
state.trajectFlightAvailability[lineGuid] = {
|
|
27578
|
+
lineGuid,
|
|
27579
|
+
status: selectedGuid ? 'resolved' : 'unavailable',
|
|
27580
|
+
results,
|
|
27581
|
+
selectedGuid
|
|
27582
|
+
};
|
|
27583
|
+
},
|
|
27584
|
+
setTrajectFlightSelection(state, action) {
|
|
27585
|
+
const flight = state.trajectFlightAvailability[action.payload.lineGuid];
|
|
27586
|
+
if (!flight)
|
|
27587
|
+
return;
|
|
27588
|
+
flight.selectedGuid = action.payload.guid;
|
|
27589
|
+
flight.status = 'resolved';
|
|
27568
27590
|
},
|
|
27569
27591
|
resetTrajectAvailability(state) {
|
|
27570
27592
|
state.trajectNodeAvailability = {};
|
|
27571
|
-
state.
|
|
27593
|
+
state.trajectFlightAvailability = {};
|
|
27572
27594
|
}
|
|
27573
27595
|
}
|
|
27574
27596
|
});
|
|
27575
|
-
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,
|
|
27597
|
+
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;
|
|
27576
27598
|
var searchResultsReducer = searchResultsSlice.reducer;
|
|
27577
27599
|
|
|
27578
27600
|
const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
|
|
@@ -32938,6 +32960,8 @@ const buildDestination = (line) => {
|
|
|
32938
32960
|
return { id: line.region.id, isRegion: true };
|
|
32939
32961
|
if (line.country?.id)
|
|
32940
32962
|
return { id: line.country.id, isCountry: true };
|
|
32963
|
+
if (line.latitude && line.longitude)
|
|
32964
|
+
return { latitude: line.latitude, longitude: line.longitude };
|
|
32941
32965
|
return { id: 0 };
|
|
32942
32966
|
};
|
|
32943
32967
|
const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
|
|
@@ -32957,10 +32981,27 @@ const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
|
|
|
32957
32981
|
rooms: context.rooms,
|
|
32958
32982
|
tagIds: []
|
|
32959
32983
|
});
|
|
32960
|
-
const
|
|
32961
|
-
const
|
|
32962
|
-
|
|
32984
|
+
const getNodeCandidates = (node) => {
|
|
32985
|
+
const configured = (node.alternatives ?? []).filter((x) => !!x.code && x.code.trim().length > 0);
|
|
32986
|
+
if (configured.length)
|
|
32987
|
+
return configured;
|
|
32988
|
+
const fallbackCode = node.code ?? node.preferredAccommodationCode;
|
|
32989
|
+
if (!fallbackCode || !fallbackCode.trim().length)
|
|
32990
|
+
return [];
|
|
32991
|
+
return [
|
|
32992
|
+
{
|
|
32993
|
+
code: fallbackCode,
|
|
32994
|
+
name: node.name,
|
|
32995
|
+
description: node.description,
|
|
32996
|
+
imageUrl: node.imageUrl,
|
|
32997
|
+
contentSource: node.contentSource,
|
|
32998
|
+
vendor: node.vendor,
|
|
32999
|
+
externalVendorId: node.externalVendorId,
|
|
33000
|
+
isPreferred: true
|
|
33001
|
+
}
|
|
33002
|
+
];
|
|
32963
33003
|
};
|
|
33004
|
+
const findCandidateForResult = (node, result) => getNodeCandidates(node).find((candidate) => matchesCode(result, candidate.code)) ?? null;
|
|
32964
33005
|
const matchesCode = (result, code) => {
|
|
32965
33006
|
if (result.code === code)
|
|
32966
33007
|
return true;
|
|
@@ -33024,8 +33065,26 @@ const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => (
|
|
|
33024
33065
|
arrivalAirportDescription: segment.arrivalAirportName,
|
|
33025
33066
|
durationInTicks: segment.durationInTicks
|
|
33026
33067
|
}));
|
|
33027
|
-
const
|
|
33028
|
-
|
|
33068
|
+
const buildTrajectFlightRequest = ({ node, line }, context, pax) => ({
|
|
33069
|
+
transactionId: context.transactionId,
|
|
33070
|
+
officeId: context.officeId,
|
|
33071
|
+
catalogueId: context.catalogueId,
|
|
33072
|
+
agentId: context.agentId ?? null,
|
|
33073
|
+
language: context.language,
|
|
33074
|
+
departureAirportCode: node.departureAirportCode ?? '',
|
|
33075
|
+
arrivalAirportCode: node.arrivalAirportCode ?? '',
|
|
33076
|
+
returnAirportCode: null,
|
|
33077
|
+
luggageIncluded: null,
|
|
33078
|
+
maxStops: null,
|
|
33079
|
+
travelClass: null,
|
|
33080
|
+
vendorConfigurationId: node.externalVendorId ?? null,
|
|
33081
|
+
pax,
|
|
33082
|
+
outward: { date: dateToDateStruct(new Date(line.from)) },
|
|
33083
|
+
return: null
|
|
33084
|
+
});
|
|
33085
|
+
const pickCheapestFlight = (flights) => [...flights].sort((a, b) => a.price - b.price)[0] ?? null;
|
|
33086
|
+
const applyFlightToLine = (line, flight) => {
|
|
33087
|
+
const segments = flight.outward?.segments ?? [];
|
|
33029
33088
|
if (!segments.length)
|
|
33030
33089
|
return line;
|
|
33031
33090
|
const firstSegment = segments[0];
|
|
@@ -33045,14 +33104,6 @@ const applyFlightToLine = (line, flight, isOutbound) => {
|
|
|
33045
33104
|
isChanged: true
|
|
33046
33105
|
};
|
|
33047
33106
|
};
|
|
33048
|
-
const pairTrajectFlights = (nodes) => {
|
|
33049
|
-
const flights = nodes.filter((x) => isTrajectFlightNode(x.node));
|
|
33050
|
-
return {
|
|
33051
|
-
outbound: flights[0] ?? null,
|
|
33052
|
-
inbound: flights.length > 1 ? flights[flights.length - 1] : null,
|
|
33053
|
-
unsupported: flights.slice(1, Math.max(flights.length - 1, 1))
|
|
33054
|
-
};
|
|
33055
|
-
};
|
|
33056
33107
|
|
|
33057
33108
|
const getLocation = (result) => {
|
|
33058
33109
|
const place = result.locationName || result.regionName || result.oordName;
|
|
@@ -33060,10 +33111,26 @@ const getLocation = (result) => {
|
|
|
33060
33111
|
return result.countryName ?? '';
|
|
33061
33112
|
return result.countryName ? `${place}, ${result.countryName}` : place;
|
|
33062
33113
|
};
|
|
33063
|
-
const
|
|
33114
|
+
const toPlainText = (value) => {
|
|
33115
|
+
if (!value)
|
|
33116
|
+
return '';
|
|
33117
|
+
return he
|
|
33118
|
+
.decode(value.replace(/<[^>]*>/g, ' '))
|
|
33119
|
+
.replace(/\s+/g, ' ')
|
|
33120
|
+
.trim();
|
|
33121
|
+
};
|
|
33122
|
+
const TrajectNodeCard = ({ item, result, isSelected, languageCode, translations, onSelect, showNights }) => {
|
|
33123
|
+
const { node } = item;
|
|
33064
33124
|
const selectedOption = first(result.rooms)?.options?.find((x) => x.isSelected) ?? first(result.rooms)?.options?.[0];
|
|
33065
33125
|
const price = formatPrice$3(result.price, result.currencyCode, languageCode);
|
|
33066
33126
|
const nights = calculateNights(new Date(result.fromDate), new Date(result.toDate));
|
|
33127
|
+
const candidate = findCandidateForResult(node, result);
|
|
33128
|
+
const image = candidate?.imageUrl ?? null;
|
|
33129
|
+
const description = toPlainText(candidate?.description);
|
|
33130
|
+
const title = candidate?.name ?? result.name;
|
|
33131
|
+
const priceBlock = (React__default.createElement("div", { className: "search__result-card__price__wrapper" },
|
|
33132
|
+
React__default.createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
|
|
33133
|
+
React__default.createElement("span", { className: "search__result-card__price" }, price)));
|
|
33067
33134
|
const selectButton = (React__default.createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT));
|
|
33068
33135
|
if (result.contents?.length) {
|
|
33069
33136
|
return (React__default.createElement("div", { className: `search__result-card__wrapper search__result-card__wrapper--custom ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
|
|
@@ -33071,21 +33138,22 @@ const TrajectNodeCard = ({ result, isSelected, languageCode, translations, onSel
|
|
|
33071
33138
|
React__default.createElement("div", { className: "search__result-card__footer" }, selectButton)));
|
|
33072
33139
|
}
|
|
33073
33140
|
return (React__default.createElement("div", { className: `search__result-card__wrapper ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
|
|
33141
|
+
image && (React__default.createElement("div", { className: "search__result-card__img-wrapper" },
|
|
33142
|
+
React__default.createElement("img", { src: image, alt: title, className: "search__result-card__img" }),
|
|
33143
|
+
priceBlock)),
|
|
33074
33144
|
React__default.createElement("div", { className: "search__result-card__content" },
|
|
33075
33145
|
React__default.createElement("div", { className: "search__result-card__content__wrapper" },
|
|
33076
33146
|
React__default.createElement("div", { className: "search__result-card__header" },
|
|
33077
33147
|
React__default.createElement("div", { className: "search__result-card__header__wrapper" },
|
|
33078
33148
|
!!result.stars && (React__default.createElement("div", { className: "rating" }, [...Array(result.stars)].map((_, index) => (React__default.createElement(Icon, { name: "ui-star", key: `rating-star-${index + 1}`, width: 14, height: 14 }))))),
|
|
33079
|
-
React__default.createElement("h3", { className: "search__result-card__title" },
|
|
33080
|
-
|
|
33081
|
-
React__default.createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
|
|
33082
|
-
React__default.createElement("span", { className: "search__result-card__price" }, price))),
|
|
33149
|
+
React__default.createElement("h3", { className: "search__result-card__title" }, title)),
|
|
33150
|
+
!image && priceBlock),
|
|
33083
33151
|
React__default.createElement("span", { className: "search__result-card__location" },
|
|
33084
33152
|
React__default.createElement(Icon, { name: "ui-location", height: 16 }),
|
|
33085
33153
|
getLocation(result)),
|
|
33086
33154
|
React__default.createElement("div", { className: "search__result-card__options" },
|
|
33087
33155
|
showNights && nights > 0 && (React__default.createElement("div", { className: "search__result-card__option" },
|
|
33088
|
-
React__default.createElement(Icon, { name: "ui-
|
|
33156
|
+
React__default.createElement(Icon, { name: "ui-moon", height: 16 }),
|
|
33089
33157
|
nights,
|
|
33090
33158
|
" ",
|
|
33091
33159
|
translations?.SRP.NIGHTS)),
|
|
@@ -33094,7 +33162,8 @@ const TrajectNodeCard = ({ result, isSelected, languageCode, translations, onSel
|
|
|
33094
33162
|
selectedOption.accommodationName)),
|
|
33095
33163
|
selectedOption?.regimeName && (React__default.createElement("div", { className: "search__result-card__option" },
|
|
33096
33164
|
React__default.createElement(Icon, { name: "ui-utensils", height: 16 }),
|
|
33097
|
-
selectedOption.regimeName)))
|
|
33165
|
+
selectedOption.regimeName))),
|
|
33166
|
+
description && React__default.createElement("p", { className: "search__result-card__description" }, description)),
|
|
33098
33167
|
React__default.createElement("div", { className: "search__result-card__footer" }, selectButton))));
|
|
33099
33168
|
};
|
|
33100
33169
|
|
|
@@ -33112,15 +33181,10 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33112
33181
|
const dispatch = useDispatch();
|
|
33113
33182
|
const translations = getTranslations(context?.languageCode ?? 'en-GB');
|
|
33114
33183
|
const locale = getLocale(context?.languageCode ?? 'en-GB');
|
|
33115
|
-
const { trajectNodeAvailability,
|
|
33116
|
-
const uniqueOutwardFlights = useSelector(selectUniqueOutwardFlights);
|
|
33117
|
-
const uniqueReturnFlights = useSelector(selectUniqueReturnFlights);
|
|
33118
|
-
const selectedOutward = useSelector(selectSelectedOutward);
|
|
33119
|
-
const selectedReturn = useSelector(selectSelectedReturn);
|
|
33184
|
+
const { trajectNodeAvailability, trajectFlightAvailability } = useSelector((state) => state.searchResults);
|
|
33120
33185
|
const [expandedNodes, setExpandedNodes] = useState({});
|
|
33121
33186
|
const trajectEntry = context?.trajectEntry;
|
|
33122
33187
|
const nodesWithLines = useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
|
|
33123
|
-
const flightPairing = useMemo(() => pairTrajectFlights(nodesWithLines), [nodesWithLines]);
|
|
33124
33188
|
const lineByNodeId = useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
|
|
33125
33189
|
const nodesByDay = useMemo(() => {
|
|
33126
33190
|
const map = new Map();
|
|
@@ -33145,12 +33209,14 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33145
33209
|
dispatch(updateEditableEntryLine(applyResultToLine(item.line, result)));
|
|
33146
33210
|
};
|
|
33147
33211
|
const renderServiceNode = (item) => {
|
|
33212
|
+
console.log('renderServiceNode', item);
|
|
33148
33213
|
const { node, line } = item;
|
|
33149
33214
|
const availability = trajectNodeAvailability[line.guid];
|
|
33150
33215
|
const isExpanded = !!expandedNodes[line.guid];
|
|
33151
33216
|
const results = availability?.results ?? [];
|
|
33152
33217
|
const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
|
|
33153
|
-
const
|
|
33218
|
+
const configured = results.filter((x) => x.code !== selected?.code && !!findCandidateForResult(node, x));
|
|
33219
|
+
const others = results.filter((x) => x.code !== selected?.code && !findCandidateForResult(node, x));
|
|
33154
33220
|
// No entry yet means the node's search has been queued but not dispatched — still loading.
|
|
33155
33221
|
const status = availability?.status ?? 'loading';
|
|
33156
33222
|
return (React__default.createElement(React__default.Fragment, { key: line.guid },
|
|
@@ -33159,9 +33225,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33159
33225
|
React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
|
|
33160
33226
|
React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
|
|
33161
33227
|
React__default.createElement("div", { className: "search__results__label__text" },
|
|
33162
|
-
React__default.createElement(Icon, { name: getNodeIcon(node), height: 16 }),
|
|
33163
|
-
React__default.createElement("h3", null,
|
|
33164
|
-
React__default.createElement("strong", null, node.name)))),
|
|
33228
|
+
React__default.createElement(Icon, { name: getNodeIcon(node), height: 16 }))),
|
|
33165
33229
|
status === 'loading' && (React__default.createElement(Spinner, { label: node.serviceType === EXCURSION_SERVICE_TYPE ? translations.SRP.LOADING_EXCURSIONS : translations.SRP.LOADING_ACCOMMODATIONS })),
|
|
33166
33230
|
status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
33167
33231
|
status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
|
|
@@ -33170,37 +33234,23 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33170
33234
|
node.preferredAccommodationName,
|
|
33171
33235
|
" \u2014 ",
|
|
33172
33236
|
translations.SRP.NO_RESULTS))),
|
|
33173
|
-
React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
33174
|
-
|
|
33175
|
-
isExpanded
|
|
33176
|
-
|
|
33177
|
-
|
|
33178
|
-
|
|
33237
|
+
React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" }, [selected, ...configured, ...(isExpanded ? others : [])].map((result) => (React__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 })))),
|
|
33238
|
+
others.length > 0 && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
33239
|
+
React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${others.length})`)))))));
|
|
33240
|
+
};
|
|
33241
|
+
const handleSelectFlight = (item, flight) => {
|
|
33242
|
+
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
33243
|
+
dispatch(updateEditableEntryLine(applyFlightToLine(item.line, flight)));
|
|
33179
33244
|
};
|
|
33180
33245
|
const renderFlightNode = (item) => {
|
|
33181
33246
|
const { node, line } = item;
|
|
33182
|
-
const
|
|
33183
|
-
const
|
|
33184
|
-
|
|
33185
|
-
|
|
33186
|
-
|
|
33187
|
-
|
|
33188
|
-
|
|
33189
|
-
React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
|
|
33190
|
-
React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
|
|
33191
|
-
React__default.createElement("div", { className: "search__results__label__text" },
|
|
33192
|
-
React__default.createElement(Icon, { name: "ui-flight", height: 16 }),
|
|
33193
|
-
React__default.createElement("h3", null,
|
|
33194
|
-
React__default.createElement("strong", null, node.name)))),
|
|
33195
|
-
React__default.createElement("div", { className: "no-results" },
|
|
33196
|
-
node.departureAirportCode,
|
|
33197
|
-
" \u2192 ",
|
|
33198
|
-
node.arrivalAirportCode)));
|
|
33199
|
-
}
|
|
33200
|
-
const flights = isOutbound ? uniqueOutwardFlights : uniqueReturnFlights;
|
|
33201
|
-
const selectedFlight = isOutbound ? selectedOutward : selectedReturn;
|
|
33202
|
-
const selectedKey = isOutbound ? selectedOutwardKey : selectedReturnKey;
|
|
33203
|
-
const visible = flights.filter((x) => getFlightKey(isOutbound ? x.outward.segments : x.return.segments) !== selectedKey);
|
|
33247
|
+
const availability = trajectFlightAvailability[line.guid];
|
|
33248
|
+
const status = availability?.status ?? 'loading';
|
|
33249
|
+
const flights = availability?.results ?? [];
|
|
33250
|
+
const selected = flights.find((x) => x.outwardGuid === availability?.selectedGuid) ?? null;
|
|
33251
|
+
const others = flights.filter((x) => x.outwardGuid !== availability?.selectedGuid);
|
|
33252
|
+
const isExpanded = !!expandedNodes[line.guid];
|
|
33253
|
+
const visible = isExpanded ? others : others.slice(0, 2);
|
|
33204
33254
|
return (React__default.createElement(React__default.Fragment, { key: line.guid },
|
|
33205
33255
|
React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
33206
33256
|
React__default.createElement("div", { className: "search__results__label__date" },
|
|
@@ -33210,42 +33260,37 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
33210
33260
|
React__default.createElement(Icon, { name: "ui-flight", height: 16 }),
|
|
33211
33261
|
React__default.createElement("h3", null,
|
|
33212
33262
|
translations.SRP.SELECT,
|
|
33213
|
-
|
|
33214
|
-
React__default.createElement("strong", null,
|
|
33215
|
-
|
|
33216
|
-
|
|
33217
|
-
|
|
33218
|
-
|
|
33219
|
-
|
|
33220
|
-
|
|
33221
|
-
|
|
33222
|
-
|
|
33223
|
-
|
|
33224
|
-
|
|
33225
|
-
|
|
33263
|
+
' ',
|
|
33264
|
+
React__default.createElement("strong", null,
|
|
33265
|
+
node.departureAirportCode,
|
|
33266
|
+
" - ",
|
|
33267
|
+
node.arrivalAirportCode)))),
|
|
33268
|
+
status === 'loading' && React__default.createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS }),
|
|
33269
|
+
status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
33270
|
+
status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
|
|
33271
|
+
React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
33272
|
+
React__default.createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price }),
|
|
33273
|
+
visible.map((result) => (React__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) })))),
|
|
33274
|
+
others.length > 2 && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
33275
|
+
React__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})`)))))));
|
|
33276
|
+
};
|
|
33226
33277
|
if (isLoading)
|
|
33227
33278
|
return React__default.createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
|
|
33228
33279
|
return (React__default.createElement(React__default.Fragment, null, trajectEntry.traject.days.map((day) => {
|
|
33229
33280
|
const dayNodes = nodesByDay.get(day.order) ?? [];
|
|
33230
33281
|
if (!dayNodes.length)
|
|
33231
33282
|
return null;
|
|
33232
|
-
return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` },
|
|
33233
|
-
|
|
33234
|
-
|
|
33235
|
-
|
|
33236
|
-
|
|
33237
|
-
|
|
33238
|
-
|
|
33239
|
-
|
|
33240
|
-
|
|
33241
|
-
|
|
33242
|
-
|
|
33243
|
-
return renderContextNode(node);
|
|
33244
|
-
const item = lineByNodeId.get(node.nodeId);
|
|
33245
|
-
if (!item)
|
|
33246
|
-
return renderContextNode(node);
|
|
33247
|
-
return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
|
|
33248
|
-
})));
|
|
33283
|
+
return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` }, dayNodes.map((node) => {
|
|
33284
|
+
// if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) return null;
|
|
33285
|
+
// if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE) return renderContextNode(node);
|
|
33286
|
+
if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE)
|
|
33287
|
+
return null;
|
|
33288
|
+
const item = lineByNodeId.get(node.nodeId);
|
|
33289
|
+
// if (!item) return renderContextNode(node);
|
|
33290
|
+
if (!item)
|
|
33291
|
+
return null;
|
|
33292
|
+
return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
|
|
33293
|
+
})));
|
|
33249
33294
|
})));
|
|
33250
33295
|
};
|
|
33251
33296
|
|
|
@@ -33253,7 +33298,6 @@ const useTrajectAvailability = () => {
|
|
|
33253
33298
|
const context = useContext(SearchResultsConfigurationContext);
|
|
33254
33299
|
const dispatch = useDispatch();
|
|
33255
33300
|
const trajectEntry = context?.trajectEntry;
|
|
33256
|
-
const selectedCombinationFlight = useSelector(selectSelectedCombinationFlight);
|
|
33257
33301
|
useEffect(() => {
|
|
33258
33302
|
if (!context || !trajectEntry)
|
|
33259
33303
|
return;
|
|
@@ -33273,31 +33317,40 @@ const useTrajectAvailability = () => {
|
|
|
33273
33317
|
language: context.languageCode ?? 'en-GB',
|
|
33274
33318
|
rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
|
|
33275
33319
|
};
|
|
33320
|
+
// Flight searches take passengers rather than rooms; the API buckets by age.
|
|
33321
|
+
const pax = trajectEntry.entry.pax ?? [];
|
|
33322
|
+
const ageOf = (p) => p.age ?? 30;
|
|
33323
|
+
const adults = pax.filter((p) => ageOf(p) >= 12).length;
|
|
33324
|
+
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
|
|
33325
|
+
const babies = pax.filter((p) => ageOf(p) < 2).length;
|
|
33326
|
+
const flightPax = 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 })));
|
|
33276
33327
|
const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
|
|
33277
33328
|
const resolveNode = async (item) => {
|
|
33278
33329
|
const lineGuid = item.line.guid;
|
|
33279
33330
|
const search = item.node.serviceType === EXCURSION_SERVICE_TYPE ? build.searchPackagingExcursions : build.searchPackagingAccommodations;
|
|
33280
33331
|
dispatch(setTrajectNodeLoading(lineGuid));
|
|
33281
33332
|
try {
|
|
33282
|
-
const
|
|
33283
|
-
|
|
33284
|
-
|
|
33285
|
-
|
|
33286
|
-
|
|
33287
|
-
const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, code), controller.signal);
|
|
33288
|
-
const hit = (attempt ?? []).find((result) => matchesCode(result, code));
|
|
33289
|
-
if (hit) {
|
|
33290
|
-
results = attempt;
|
|
33291
|
-
picked = hit;
|
|
33292
|
-
break;
|
|
33333
|
+
const candidates = getNodeCandidates(item.node);
|
|
33334
|
+
const attempts = await Promise.all(candidates.map(async (candidate) => {
|
|
33335
|
+
try {
|
|
33336
|
+
const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, candidate.code), controller.signal);
|
|
33337
|
+
return (attempt ?? []).find((result) => matchesCode(result, candidate.code)) ?? null;
|
|
33293
33338
|
}
|
|
33294
|
-
|
|
33295
|
-
|
|
33339
|
+
catch (error) {
|
|
33340
|
+
if (!controller.signal.aborted)
|
|
33341
|
+
console.error('Traject hotel unavailable', candidate.code, error);
|
|
33342
|
+
return null;
|
|
33343
|
+
}
|
|
33344
|
+
}));
|
|
33345
|
+
let results = attempts.filter((x) => !!x).filter((x, i, all) => all.findIndex((y) => y.code === x.code) === i);
|
|
33346
|
+
let picked = results[0] ?? null;
|
|
33347
|
+
const preferredCandidate = candidates.find((x) => x.isPreferred) ?? candidates[0];
|
|
33348
|
+
let preferredUnavailable = !!preferredCandidate && !results.some((x) => matchesCode(x, preferredCandidate.code));
|
|
33296
33349
|
// Nothing configured was available — fall back to the cheapest result in the destination.
|
|
33297
33350
|
if (!picked) {
|
|
33298
33351
|
results = (await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? [];
|
|
33299
33352
|
picked = pickCheapest(results);
|
|
33300
|
-
preferredUnavailable =
|
|
33353
|
+
preferredUnavailable = candidates.length > 0;
|
|
33301
33354
|
}
|
|
33302
33355
|
if (controller.signal.aborted)
|
|
33303
33356
|
return null;
|
|
@@ -33320,59 +33373,36 @@ const useTrajectAvailability = () => {
|
|
|
33320
33373
|
return lineGuid;
|
|
33321
33374
|
}
|
|
33322
33375
|
};
|
|
33323
|
-
const
|
|
33324
|
-
const
|
|
33325
|
-
if (!
|
|
33326
|
-
dispatch(
|
|
33327
|
-
return;
|
|
33376
|
+
const resolveFlightNode = async (item) => {
|
|
33377
|
+
const lineGuid = item.line.guid;
|
|
33378
|
+
if (!item.node.departureAirportCode || !item.node.arrivalAirportCode) {
|
|
33379
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: [], selectedGuid: null }));
|
|
33380
|
+
return lineGuid;
|
|
33328
33381
|
}
|
|
33329
|
-
dispatch(
|
|
33382
|
+
dispatch(setTrajectFlightLoading(lineGuid));
|
|
33330
33383
|
try {
|
|
33331
|
-
const
|
|
33332
|
-
const ageOf = (p) => p.age ?? 30;
|
|
33333
|
-
const adults = pax.filter((p) => ageOf(p) >= 12).length;
|
|
33334
|
-
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
|
|
33335
|
-
const babies = pax.filter((p) => ageOf(p) < 2).length;
|
|
33336
|
-
const request = {
|
|
33337
|
-
transactionId: trajectEntry.entry.transactionId,
|
|
33338
|
-
officeId: searchContext.officeId,
|
|
33339
|
-
catalogueId: searchContext.catalogueId,
|
|
33340
|
-
agentId: searchContext.agentId,
|
|
33341
|
-
language: searchContext.language,
|
|
33342
|
-
departureAirportCode: outbound.node.departureAirportCode ?? '',
|
|
33343
|
-
arrivalAirportCode: outbound.node.arrivalAirportCode ?? '',
|
|
33344
|
-
returnAirportCode: inbound?.node.arrivalAirportCode ?? outbound.node.departureAirportCode ?? null,
|
|
33345
|
-
luggageIncluded: null,
|
|
33346
|
-
maxStops: null,
|
|
33347
|
-
travelClass: null,
|
|
33348
|
-
pax: 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 }))),
|
|
33349
|
-
outward: { date: dateToDateStruct(new Date(outbound.line.from)) },
|
|
33350
|
-
return: { date: dateToDateStruct(new Date((inbound ?? outbound).line.from)) }
|
|
33351
|
-
};
|
|
33352
|
-
const flights = (await build.searchPackagingFlights(config, request, controller.signal)) ?? [];
|
|
33384
|
+
const flights = (await build.searchPackagingFlights(config, buildTrajectFlightRequest(item, searchContext, flightPax), controller.signal)) ?? [];
|
|
33353
33385
|
if (controller.signal.aborted)
|
|
33354
|
-
return;
|
|
33355
|
-
|
|
33356
|
-
|
|
33357
|
-
if (
|
|
33358
|
-
|
|
33359
|
-
|
|
33360
|
-
|
|
33386
|
+
return null;
|
|
33387
|
+
const picked = pickCheapestFlight(flights);
|
|
33388
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: flights, selectedGuid: picked?.outwardGuid ?? null }));
|
|
33389
|
+
if (!picked)
|
|
33390
|
+
return lineGuid;
|
|
33391
|
+
dispatch(updateEditableEntryLine(applyFlightToLine(item.line, picked)));
|
|
33392
|
+
return null;
|
|
33361
33393
|
}
|
|
33362
33394
|
catch (error) {
|
|
33363
|
-
if (
|
|
33364
|
-
|
|
33365
|
-
|
|
33366
|
-
|
|
33367
|
-
|
|
33368
|
-
dispatch(setFlightsLoading(false));
|
|
33369
|
-
dispatch(setTrajectFlightsResolved(true));
|
|
33370
|
-
}
|
|
33395
|
+
if (controller.signal.aborted)
|
|
33396
|
+
return null;
|
|
33397
|
+
console.error('Failed to resolve traject flight', item.node.name, error);
|
|
33398
|
+
dispatch(setTrajectFlightAvailability({ lineGuid, results: [], selectedGuid: null }));
|
|
33399
|
+
return lineGuid;
|
|
33371
33400
|
}
|
|
33372
33401
|
};
|
|
33373
33402
|
(async () => {
|
|
33374
33403
|
const searchable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node));
|
|
33375
|
-
const
|
|
33404
|
+
const flightNodes = nodesWithLines.filter((x) => isTrajectFlightNode(x.node));
|
|
33405
|
+
const unresolved = await Promise.all([...searchable.map(resolveNode), ...flightNodes.map(resolveFlightNode)]);
|
|
33376
33406
|
if (controller.signal.aborted)
|
|
33377
33407
|
return;
|
|
33378
33408
|
// A node with no availability anywhere cannot be priced or booked, so its line comes off
|
|
@@ -33383,16 +33413,6 @@ const useTrajectAvailability = () => {
|
|
|
33383
33413
|
})();
|
|
33384
33414
|
return () => controller.abort();
|
|
33385
33415
|
}, [trajectEntry]);
|
|
33386
|
-
// Keep the traject's own flight lines in step with whatever outward/return the user picks.
|
|
33387
|
-
useEffect(() => {
|
|
33388
|
-
if (!trajectEntry || !selectedCombinationFlight)
|
|
33389
|
-
return;
|
|
33390
|
-
const { outbound, inbound } = pairTrajectFlights(getTrajectNodesWithLines(trajectEntry));
|
|
33391
|
-
if (outbound)
|
|
33392
|
-
dispatch(updateEditableEntryLine(applyFlightToLine(outbound.line, selectedCombinationFlight, true)));
|
|
33393
|
-
if (inbound)
|
|
33394
|
-
dispatch(updateEditableEntryLine(applyFlightToLine(inbound.line, selectedCombinationFlight, false)));
|
|
33395
|
-
}, [trajectEntry, selectedCombinationFlight]);
|
|
33396
33416
|
};
|
|
33397
33417
|
|
|
33398
33418
|
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;
|