@qite/tide-components 1.0.14-preview.2 → 1.0.14-preview.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 +1323 -117
- package/build/build-cjs/src/content/agent-entries/agent-entries-services.d.ts +18 -0
- package/build/build-cjs/src/content/agent-entries/index.d.ts +4 -0
- package/build/build-cjs/src/content/agent-entries/types.d.ts +27 -0
- package/build/build-cjs/src/content/navbar/types.d.ts +1 -0
- package/build/build-cjs/src/index.d.ts +3 -1
- package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +16 -3
- package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +7 -1
- package/build/build-cjs/src/shared/booking/travelers-form.d.ts +12 -3
- package/build/build-esm/index.js +1323 -118
- package/build/build-esm/src/content/agent-entries/agent-entries-services.d.ts +18 -0
- package/build/build-esm/src/content/agent-entries/index.d.ts +4 -0
- package/build/build-esm/src/content/agent-entries/types.d.ts +27 -0
- package/build/build-esm/src/content/navbar/types.d.ts +1 -0
- package/build/build-esm/src/index.d.ts +3 -1
- package/build/build-esm/src/search-results/store/search-results-slice.d.ts +16 -3
- package/build/build-esm/src/search-results/utils/traject-utils.d.ts +7 -1
- package/build/build-esm/src/shared/booking/travelers-form.d.ts +12 -3
- package/package.json +2 -2
- package/styles/components/_agent-entries.scss +336 -0
- package/styles/content-blocks.scss +1 -0
package/build/build-esm/index.js
CHANGED
|
@@ -480,6 +480,39 @@ var FORM$f = {
|
|
|
480
480
|
YES: "نعم",
|
|
481
481
|
NO: "لا"
|
|
482
482
|
};
|
|
483
|
+
var AGENT_ENTRIES$f = {
|
|
484
|
+
TITLE: "الحجوزات",
|
|
485
|
+
MY_BOOKINGS: "حجوزاتي",
|
|
486
|
+
NUMBER: "الرقم",
|
|
487
|
+
DEPARTURE_DATE: "تاريخ المغادرة",
|
|
488
|
+
STATUS: "الحالة",
|
|
489
|
+
CUSTOM_STATUS: "حالة مخصصة",
|
|
490
|
+
RETURN_DATE: "تاريخ العودة",
|
|
491
|
+
PROFIT: "الربح",
|
|
492
|
+
NETTO_SELLING_PRICE: "صافي سعر البيع",
|
|
493
|
+
YOUR_SURCHARGE: "رسومك الإضافية",
|
|
494
|
+
CREATED: "تاريخ الإنشاء",
|
|
495
|
+
CONTACT: "جهة الاتصال",
|
|
496
|
+
MAIN_BOOKER: "الحاجز الرئيسي",
|
|
497
|
+
PRODUCT: "المنتج",
|
|
498
|
+
TRAVELERS: "المسافرون",
|
|
499
|
+
ACTIONS: "الإجراءات",
|
|
500
|
+
DETAILS: "التفاصيل",
|
|
501
|
+
HIDE_DETAILS: "إخفاء التفاصيل",
|
|
502
|
+
PRINTS: "المطبوعات",
|
|
503
|
+
ALL: "الكل",
|
|
504
|
+
X_ITEMS: "{0} عناصر",
|
|
505
|
+
PAGE_SIZE: "عناصر لكل صفحة",
|
|
506
|
+
PREVIOUS: "السابق",
|
|
507
|
+
NEXT: "التالي",
|
|
508
|
+
PAGE_X_OF_Y: "الصفحة {0} من {1}",
|
|
509
|
+
LOADING: "جارٍ التحميل...",
|
|
510
|
+
NO_ITEMS: "لم يتم العثور على حجوزات.",
|
|
511
|
+
ERROR: "حدث خطأ أثناء تحميل حجوزاتك.",
|
|
512
|
+
PRINT_ERROR: "فشلت الطباعة، يرجى المحاولة مرة أخرى.",
|
|
513
|
+
NOT_LOGGED_IN: "سجّل الدخول كوكيل لعرض حجوزاتك.",
|
|
514
|
+
SESSION_EXPIRED: "انتهت صلاحية جلستك، يرجى تسجيل الدخول مرة أخرى."
|
|
515
|
+
};
|
|
483
516
|
var arJson = {
|
|
484
517
|
STEPS: STEPS$f,
|
|
485
518
|
INPUT: INPUT$f,
|
|
@@ -500,7 +533,8 @@ var arJson = {
|
|
|
500
533
|
QSM: QSM$g,
|
|
501
534
|
SRP: SRP$f,
|
|
502
535
|
ITINERARY: ITINERARY$f,
|
|
503
|
-
FORM: FORM$f
|
|
536
|
+
FORM: FORM$f,
|
|
537
|
+
AGENT_ENTRIES: AGENT_ENTRIES$f
|
|
504
538
|
};
|
|
505
539
|
|
|
506
540
|
var STEPS$e = {
|
|
@@ -953,6 +987,39 @@ var FORM$e = {
|
|
|
953
987
|
YES: "Ja",
|
|
954
988
|
NO: "Nej"
|
|
955
989
|
};
|
|
990
|
+
var AGENT_ENTRIES$e = {
|
|
991
|
+
TITLE: "Bookinger",
|
|
992
|
+
MY_BOOKINGS: "Mine bookinger",
|
|
993
|
+
NUMBER: "Nummer",
|
|
994
|
+
DEPARTURE_DATE: "Afrejsedato",
|
|
995
|
+
STATUS: "Status",
|
|
996
|
+
CUSTOM_STATUS: "Tilpasset status",
|
|
997
|
+
RETURN_DATE: "Hjemrejsedato",
|
|
998
|
+
PROFIT: "Fortjeneste",
|
|
999
|
+
NETTO_SELLING_PRICE: "Netto salgspris",
|
|
1000
|
+
YOUR_SURCHARGE: "Dit tillæg",
|
|
1001
|
+
CREATED: "Oprettet",
|
|
1002
|
+
CONTACT: "Kontakt",
|
|
1003
|
+
MAIN_BOOKER: "Hovedbooker",
|
|
1004
|
+
PRODUCT: "Produkt",
|
|
1005
|
+
TRAVELERS: "Rejsende",
|
|
1006
|
+
ACTIONS: "Handlinger",
|
|
1007
|
+
DETAILS: "Detaljer",
|
|
1008
|
+
HIDE_DETAILS: "Skjul detaljer",
|
|
1009
|
+
PRINTS: "Udskrifter",
|
|
1010
|
+
ALL: "Alle",
|
|
1011
|
+
X_ITEMS: "{0} elementer",
|
|
1012
|
+
PAGE_SIZE: "Elementer pr. side",
|
|
1013
|
+
PREVIOUS: "Forrige",
|
|
1014
|
+
NEXT: "Næste",
|
|
1015
|
+
PAGE_X_OF_Y: "Side {0} af {1}",
|
|
1016
|
+
LOADING: "Indlæser...",
|
|
1017
|
+
NO_ITEMS: "Ingen bookinger fundet.",
|
|
1018
|
+
ERROR: "Der opstod en fejl under indlæsning af dine bookinger.",
|
|
1019
|
+
PRINT_ERROR: "Udskrivning mislykkedes, prøv igen.",
|
|
1020
|
+
NOT_LOGGED_IN: "Log ind som agent for at se dine bookinger.",
|
|
1021
|
+
SESSION_EXPIRED: "Din session er udløbet, log ind igen."
|
|
1022
|
+
};
|
|
956
1023
|
var daJson = {
|
|
957
1024
|
STEPS: STEPS$e,
|
|
958
1025
|
INPUT: INPUT$e,
|
|
@@ -973,7 +1040,8 @@ var daJson = {
|
|
|
973
1040
|
QSM: QSM$f,
|
|
974
1041
|
SRP: SRP$e,
|
|
975
1042
|
ITINERARY: ITINERARY$e,
|
|
976
|
-
FORM: FORM$e
|
|
1043
|
+
FORM: FORM$e,
|
|
1044
|
+
AGENT_ENTRIES: AGENT_ENTRIES$e
|
|
977
1045
|
};
|
|
978
1046
|
|
|
979
1047
|
var STEPS$d = {
|
|
@@ -1426,6 +1494,39 @@ var FORM$d = {
|
|
|
1426
1494
|
YES: "Ja",
|
|
1427
1495
|
NO: "Nein"
|
|
1428
1496
|
};
|
|
1497
|
+
var AGENT_ENTRIES$d = {
|
|
1498
|
+
TITLE: "Buchungen",
|
|
1499
|
+
MY_BOOKINGS: "Meine Buchungen",
|
|
1500
|
+
NUMBER: "Nummer",
|
|
1501
|
+
DEPARTURE_DATE: "Abreisedatum",
|
|
1502
|
+
STATUS: "Status",
|
|
1503
|
+
CUSTOM_STATUS: "Benutzerdefinierter Status",
|
|
1504
|
+
RETURN_DATE: "Rückreisedatum",
|
|
1505
|
+
PROFIT: "Gewinn",
|
|
1506
|
+
NETTO_SELLING_PRICE: "Netto-Verkaufspreis",
|
|
1507
|
+
YOUR_SURCHARGE: "Ihr Aufschlag",
|
|
1508
|
+
CREATED: "Erstellt",
|
|
1509
|
+
CONTACT: "Kontakt",
|
|
1510
|
+
MAIN_BOOKER: "Hauptbucher",
|
|
1511
|
+
PRODUCT: "Produkt",
|
|
1512
|
+
TRAVELERS: "Reisende",
|
|
1513
|
+
ACTIONS: "Aktionen",
|
|
1514
|
+
DETAILS: "Details",
|
|
1515
|
+
HIDE_DETAILS: "Details ausblenden",
|
|
1516
|
+
PRINTS: "Drucke",
|
|
1517
|
+
ALL: "Alle",
|
|
1518
|
+
X_ITEMS: "{0} Einträge",
|
|
1519
|
+
PAGE_SIZE: "Einträge pro Seite",
|
|
1520
|
+
PREVIOUS: "Zurück",
|
|
1521
|
+
NEXT: "Weiter",
|
|
1522
|
+
PAGE_X_OF_Y: "Seite {0} von {1}",
|
|
1523
|
+
LOADING: "Wird geladen...",
|
|
1524
|
+
NO_ITEMS: "Keine Buchungen gefunden.",
|
|
1525
|
+
ERROR: "Beim Laden Ihrer Buchungen ist ein Fehler aufgetreten.",
|
|
1526
|
+
PRINT_ERROR: "Drucken fehlgeschlagen, bitte versuchen Sie es erneut.",
|
|
1527
|
+
NOT_LOGGED_IN: "Melden Sie sich als Agent an, um Ihre Buchungen zu sehen.",
|
|
1528
|
+
SESSION_EXPIRED: "Ihre Sitzung ist abgelaufen, bitte melden Sie sich erneut an."
|
|
1529
|
+
};
|
|
1429
1530
|
var deJson = {
|
|
1430
1531
|
STEPS: STEPS$d,
|
|
1431
1532
|
INPUT: INPUT$d,
|
|
@@ -1446,7 +1547,8 @@ var deJson = {
|
|
|
1446
1547
|
QSM: QSM$e,
|
|
1447
1548
|
SRP: SRP$d,
|
|
1448
1549
|
ITINERARY: ITINERARY$d,
|
|
1449
|
-
FORM: FORM$d
|
|
1550
|
+
FORM: FORM$d,
|
|
1551
|
+
AGENT_ENTRIES: AGENT_ENTRIES$d
|
|
1450
1552
|
};
|
|
1451
1553
|
|
|
1452
1554
|
var STEPS$c = {
|
|
@@ -1903,6 +2005,39 @@ var FORM$c = {
|
|
|
1903
2005
|
YES: "Yes",
|
|
1904
2006
|
NO: "No"
|
|
1905
2007
|
};
|
|
2008
|
+
var AGENT_ENTRIES$c = {
|
|
2009
|
+
TITLE: "Bookings",
|
|
2010
|
+
MY_BOOKINGS: "My bookings",
|
|
2011
|
+
NUMBER: "Number",
|
|
2012
|
+
DEPARTURE_DATE: "Departure date",
|
|
2013
|
+
STATUS: "Status",
|
|
2014
|
+
CUSTOM_STATUS: "Custom status",
|
|
2015
|
+
RETURN_DATE: "Return date",
|
|
2016
|
+
PROFIT: "Profit",
|
|
2017
|
+
NETTO_SELLING_PRICE: "Netto selling price",
|
|
2018
|
+
YOUR_SURCHARGE: "Your surcharge",
|
|
2019
|
+
CREATED: "Created",
|
|
2020
|
+
CONTACT: "Contact",
|
|
2021
|
+
MAIN_BOOKER: "Main booker",
|
|
2022
|
+
PRODUCT: "Product",
|
|
2023
|
+
TRAVELERS: "Travellers",
|
|
2024
|
+
ACTIONS: "Actions",
|
|
2025
|
+
DETAILS: "Details",
|
|
2026
|
+
HIDE_DETAILS: "Hide details",
|
|
2027
|
+
PRINTS: "Prints",
|
|
2028
|
+
ALL: "All",
|
|
2029
|
+
X_ITEMS: "{0} items",
|
|
2030
|
+
PAGE_SIZE: "Items per page",
|
|
2031
|
+
PREVIOUS: "Previous",
|
|
2032
|
+
NEXT: "Next",
|
|
2033
|
+
PAGE_X_OF_Y: "Page {0} of {1}",
|
|
2034
|
+
LOADING: "Loading...",
|
|
2035
|
+
NO_ITEMS: "No bookings found.",
|
|
2036
|
+
ERROR: "Something went wrong while loading your bookings.",
|
|
2037
|
+
PRINT_ERROR: "Printing failed, please try again.",
|
|
2038
|
+
NOT_LOGGED_IN: "Log in as an agent to see your bookings.",
|
|
2039
|
+
SESSION_EXPIRED: "Your session has expired, please log in again."
|
|
2040
|
+
};
|
|
1906
2041
|
var enJson = {
|
|
1907
2042
|
STEPS: STEPS$c,
|
|
1908
2043
|
INPUT: INPUT$c,
|
|
@@ -1923,7 +2058,8 @@ var enJson = {
|
|
|
1923
2058
|
QSM: QSM$d,
|
|
1924
2059
|
SRP: SRP$c,
|
|
1925
2060
|
ITINERARY: ITINERARY$c,
|
|
1926
|
-
FORM: FORM$c
|
|
2061
|
+
FORM: FORM$c,
|
|
2062
|
+
AGENT_ENTRIES: AGENT_ENTRIES$c
|
|
1927
2063
|
};
|
|
1928
2064
|
|
|
1929
2065
|
var STEPS$b = {
|
|
@@ -2376,6 +2512,39 @@ var FORM$b = {
|
|
|
2376
2512
|
YES: "Sí",
|
|
2377
2513
|
NO: "No"
|
|
2378
2514
|
};
|
|
2515
|
+
var AGENT_ENTRIES$b = {
|
|
2516
|
+
TITLE: "Reservas",
|
|
2517
|
+
MY_BOOKINGS: "Mis reservas",
|
|
2518
|
+
NUMBER: "Número",
|
|
2519
|
+
DEPARTURE_DATE: "Fecha de salida",
|
|
2520
|
+
STATUS: "Estado",
|
|
2521
|
+
CUSTOM_STATUS: "Estado personalizado",
|
|
2522
|
+
RETURN_DATE: "Fecha de regreso",
|
|
2523
|
+
PROFIT: "Beneficio",
|
|
2524
|
+
NETTO_SELLING_PRICE: "Precio de venta neto",
|
|
2525
|
+
YOUR_SURCHARGE: "Su recargo",
|
|
2526
|
+
CREATED: "Creado",
|
|
2527
|
+
CONTACT: "Contacto",
|
|
2528
|
+
MAIN_BOOKER: "Titular de la reserva",
|
|
2529
|
+
PRODUCT: "Producto",
|
|
2530
|
+
TRAVELERS: "Viajeros",
|
|
2531
|
+
ACTIONS: "Acciones",
|
|
2532
|
+
DETAILS: "Detalles",
|
|
2533
|
+
HIDE_DETAILS: "Ocultar detalles",
|
|
2534
|
+
PRINTS: "Impresiones",
|
|
2535
|
+
ALL: "Todos",
|
|
2536
|
+
X_ITEMS: "{0} elementos",
|
|
2537
|
+
PAGE_SIZE: "Elementos por página",
|
|
2538
|
+
PREVIOUS: "Anterior",
|
|
2539
|
+
NEXT: "Siguiente",
|
|
2540
|
+
PAGE_X_OF_Y: "Página {0} de {1}",
|
|
2541
|
+
LOADING: "Cargando...",
|
|
2542
|
+
NO_ITEMS: "No se encontraron reservas.",
|
|
2543
|
+
ERROR: "Se produjo un error al cargar sus reservas.",
|
|
2544
|
+
PRINT_ERROR: "La impresión ha fallado, inténtelo de nuevo.",
|
|
2545
|
+
NOT_LOGGED_IN: "Inicie sesión como agente para ver sus reservas.",
|
|
2546
|
+
SESSION_EXPIRED: "Su sesión ha caducado, inicie sesión de nuevo."
|
|
2547
|
+
};
|
|
2379
2548
|
var esJson = {
|
|
2380
2549
|
STEPS: STEPS$b,
|
|
2381
2550
|
INPUT: INPUT$b,
|
|
@@ -2396,7 +2565,8 @@ var esJson = {
|
|
|
2396
2565
|
QSM: QSM$c,
|
|
2397
2566
|
SRP: SRP$b,
|
|
2398
2567
|
ITINERARY: ITINERARY$b,
|
|
2399
|
-
FORM: FORM$b
|
|
2568
|
+
FORM: FORM$b,
|
|
2569
|
+
AGENT_ENTRIES: AGENT_ENTRIES$b
|
|
2400
2570
|
};
|
|
2401
2571
|
|
|
2402
2572
|
var STEPS$a = {
|
|
@@ -2853,6 +3023,39 @@ var FORM$a = {
|
|
|
2853
3023
|
YES: "Oui",
|
|
2854
3024
|
NO: "Non"
|
|
2855
3025
|
};
|
|
3026
|
+
var AGENT_ENTRIES$a = {
|
|
3027
|
+
TITLE: "Réservations",
|
|
3028
|
+
MY_BOOKINGS: "Mes réservations",
|
|
3029
|
+
NUMBER: "Numéro",
|
|
3030
|
+
DEPARTURE_DATE: "Date de départ",
|
|
3031
|
+
STATUS: "Statut",
|
|
3032
|
+
CUSTOM_STATUS: "Statut personnalisé",
|
|
3033
|
+
RETURN_DATE: "Date de retour",
|
|
3034
|
+
PROFIT: "Bénéfice",
|
|
3035
|
+
NETTO_SELLING_PRICE: "Prix de vente net",
|
|
3036
|
+
YOUR_SURCHARGE: "Votre supplément",
|
|
3037
|
+
CREATED: "Créé le",
|
|
3038
|
+
CONTACT: "Contact",
|
|
3039
|
+
MAIN_BOOKER: "Réservant principal",
|
|
3040
|
+
PRODUCT: "Produit",
|
|
3041
|
+
TRAVELERS: "Voyageurs",
|
|
3042
|
+
ACTIONS: "Actions",
|
|
3043
|
+
DETAILS: "Détails",
|
|
3044
|
+
HIDE_DETAILS: "Masquer les détails",
|
|
3045
|
+
PRINTS: "Impressions",
|
|
3046
|
+
ALL: "Tous",
|
|
3047
|
+
X_ITEMS: "{0} éléments",
|
|
3048
|
+
PAGE_SIZE: "Éléments par page",
|
|
3049
|
+
PREVIOUS: "Précédent",
|
|
3050
|
+
NEXT: "Suivant",
|
|
3051
|
+
PAGE_X_OF_Y: "Page {0} sur {1}",
|
|
3052
|
+
LOADING: "Chargement...",
|
|
3053
|
+
NO_ITEMS: "Aucune réservation trouvée.",
|
|
3054
|
+
ERROR: "Une erreur est survenue lors du chargement de vos réservations.",
|
|
3055
|
+
PRINT_ERROR: "L'impression a échoué, veuillez réessayer.",
|
|
3056
|
+
NOT_LOGGED_IN: "Connectez-vous en tant qu'agent pour voir vos réservations.",
|
|
3057
|
+
SESSION_EXPIRED: "Votre session a expiré, veuillez vous reconnecter."
|
|
3058
|
+
};
|
|
2856
3059
|
var frBeJson = {
|
|
2857
3060
|
STEPS: STEPS$a,
|
|
2858
3061
|
INPUT: INPUT$a,
|
|
@@ -2873,7 +3076,8 @@ var frBeJson = {
|
|
|
2873
3076
|
QSM: QSM$b,
|
|
2874
3077
|
SRP: SRP$a,
|
|
2875
3078
|
ITINERARY: ITINERARY$a,
|
|
2876
|
-
FORM: FORM$a
|
|
3079
|
+
FORM: FORM$a,
|
|
3080
|
+
AGENT_ENTRIES: AGENT_ENTRIES$a
|
|
2877
3081
|
};
|
|
2878
3082
|
|
|
2879
3083
|
var STEPS$9 = {
|
|
@@ -3326,6 +3530,39 @@ var FORM$9 = {
|
|
|
3326
3530
|
YES: "Oui",
|
|
3327
3531
|
NO: "Non"
|
|
3328
3532
|
};
|
|
3533
|
+
var AGENT_ENTRIES$9 = {
|
|
3534
|
+
TITLE: "Réservations",
|
|
3535
|
+
MY_BOOKINGS: "Mes réservations",
|
|
3536
|
+
NUMBER: "Numéro",
|
|
3537
|
+
DEPARTURE_DATE: "Date de départ",
|
|
3538
|
+
STATUS: "Statut",
|
|
3539
|
+
CUSTOM_STATUS: "Statut personnalisé",
|
|
3540
|
+
RETURN_DATE: "Date de retour",
|
|
3541
|
+
PROFIT: "Bénéfice",
|
|
3542
|
+
NETTO_SELLING_PRICE: "Prix de vente net",
|
|
3543
|
+
YOUR_SURCHARGE: "Votre supplément",
|
|
3544
|
+
CREATED: "Créé le",
|
|
3545
|
+
CONTACT: "Contact",
|
|
3546
|
+
MAIN_BOOKER: "Réservant principal",
|
|
3547
|
+
PRODUCT: "Produit",
|
|
3548
|
+
TRAVELERS: "Voyageurs",
|
|
3549
|
+
ACTIONS: "Actions",
|
|
3550
|
+
DETAILS: "Détails",
|
|
3551
|
+
HIDE_DETAILS: "Masquer les détails",
|
|
3552
|
+
PRINTS: "Impressions",
|
|
3553
|
+
ALL: "Tous",
|
|
3554
|
+
X_ITEMS: "{0} éléments",
|
|
3555
|
+
PAGE_SIZE: "Éléments par page",
|
|
3556
|
+
PREVIOUS: "Précédent",
|
|
3557
|
+
NEXT: "Suivant",
|
|
3558
|
+
PAGE_X_OF_Y: "Page {0} sur {1}",
|
|
3559
|
+
LOADING: "Chargement...",
|
|
3560
|
+
NO_ITEMS: "Aucune réservation trouvée.",
|
|
3561
|
+
ERROR: "Une erreur est survenue lors du chargement de vos réservations.",
|
|
3562
|
+
PRINT_ERROR: "L'impression a échoué, veuillez réessayer.",
|
|
3563
|
+
NOT_LOGGED_IN: "Connectez-vous en tant qu'agent pour voir vos réservations.",
|
|
3564
|
+
SESSION_EXPIRED: "Votre session a expiré, veuillez vous reconnecter."
|
|
3565
|
+
};
|
|
3329
3566
|
var frFrJson = {
|
|
3330
3567
|
STEPS: STEPS$9,
|
|
3331
3568
|
INPUT: INPUT$9,
|
|
@@ -3346,7 +3583,8 @@ var frFrJson = {
|
|
|
3346
3583
|
QSM: QSM$a,
|
|
3347
3584
|
SRP: SRP$9,
|
|
3348
3585
|
ITINERARY: ITINERARY$9,
|
|
3349
|
-
FORM: FORM$9
|
|
3586
|
+
FORM: FORM$9,
|
|
3587
|
+
AGENT_ENTRIES: AGENT_ENTRIES$9
|
|
3350
3588
|
};
|
|
3351
3589
|
|
|
3352
3590
|
var STEPS$8 = {
|
|
@@ -3799,6 +4037,39 @@ var FORM$8 = {
|
|
|
3799
4037
|
YES: "Já",
|
|
3800
4038
|
NO: "Nei"
|
|
3801
4039
|
};
|
|
4040
|
+
var AGENT_ENTRIES$8 = {
|
|
4041
|
+
TITLE: "Bókanir",
|
|
4042
|
+
MY_BOOKINGS: "Mínar bókanir",
|
|
4043
|
+
NUMBER: "Númer",
|
|
4044
|
+
DEPARTURE_DATE: "Brottfarardagur",
|
|
4045
|
+
STATUS: "Staða",
|
|
4046
|
+
CUSTOM_STATUS: "Sérsniðin staða",
|
|
4047
|
+
RETURN_DATE: "Heimkomudagur",
|
|
4048
|
+
PROFIT: "Hagnaður",
|
|
4049
|
+
NETTO_SELLING_PRICE: "Nettó söluverð",
|
|
4050
|
+
YOUR_SURCHARGE: "Þitt álag",
|
|
4051
|
+
CREATED: "Stofnað",
|
|
4052
|
+
CONTACT: "Tengiliður",
|
|
4053
|
+
MAIN_BOOKER: "Aðalbókandi",
|
|
4054
|
+
PRODUCT: "Vara",
|
|
4055
|
+
TRAVELERS: "Ferðalangar",
|
|
4056
|
+
ACTIONS: "Aðgerðir",
|
|
4057
|
+
DETAILS: "Nánar",
|
|
4058
|
+
HIDE_DETAILS: "Fela nánar",
|
|
4059
|
+
PRINTS: "Útprentanir",
|
|
4060
|
+
ALL: "Allt",
|
|
4061
|
+
X_ITEMS: "{0} atriði",
|
|
4062
|
+
PAGE_SIZE: "Atriði á síðu",
|
|
4063
|
+
PREVIOUS: "Fyrri",
|
|
4064
|
+
NEXT: "Næsta",
|
|
4065
|
+
PAGE_X_OF_Y: "Síða {0} af {1}",
|
|
4066
|
+
LOADING: "Hleður...",
|
|
4067
|
+
NO_ITEMS: "Engar bókanir fundust.",
|
|
4068
|
+
ERROR: "Eitthvað fór úrskeiðis við að hlaða bókunum þínum.",
|
|
4069
|
+
PRINT_ERROR: "Prentun mistókst, reyndu aftur.",
|
|
4070
|
+
NOT_LOGGED_IN: "Skráðu þig inn sem umboðsaðili til að sjá bókanir þínar.",
|
|
4071
|
+
SESSION_EXPIRED: "Lotan þín er útrunnin, skráðu þig inn aftur."
|
|
4072
|
+
};
|
|
3802
4073
|
var isJson = {
|
|
3803
4074
|
STEPS: STEPS$8,
|
|
3804
4075
|
INPUT: INPUT$8,
|
|
@@ -3819,7 +4090,8 @@ var isJson = {
|
|
|
3819
4090
|
QSM: QSM$9,
|
|
3820
4091
|
SRP: SRP$8,
|
|
3821
4092
|
ITINERARY: ITINERARY$8,
|
|
3822
|
-
FORM: FORM$8
|
|
4093
|
+
FORM: FORM$8,
|
|
4094
|
+
AGENT_ENTRIES: AGENT_ENTRIES$8
|
|
3823
4095
|
};
|
|
3824
4096
|
|
|
3825
4097
|
var STEPS$7 = {
|
|
@@ -4272,6 +4544,39 @@ var FORM$7 = {
|
|
|
4272
4544
|
YES: "Sì",
|
|
4273
4545
|
NO: "No"
|
|
4274
4546
|
};
|
|
4547
|
+
var AGENT_ENTRIES$7 = {
|
|
4548
|
+
TITLE: "Prenotazioni",
|
|
4549
|
+
MY_BOOKINGS: "Le mie prenotazioni",
|
|
4550
|
+
NUMBER: "Numero",
|
|
4551
|
+
DEPARTURE_DATE: "Data di partenza",
|
|
4552
|
+
STATUS: "Stato",
|
|
4553
|
+
CUSTOM_STATUS: "Stato personalizzato",
|
|
4554
|
+
RETURN_DATE: "Data di ritorno",
|
|
4555
|
+
PROFIT: "Profitto",
|
|
4556
|
+
NETTO_SELLING_PRICE: "Prezzo di vendita netto",
|
|
4557
|
+
YOUR_SURCHARGE: "Il tuo supplemento",
|
|
4558
|
+
CREATED: "Creato",
|
|
4559
|
+
CONTACT: "Contatto",
|
|
4560
|
+
MAIN_BOOKER: "Prenotante principale",
|
|
4561
|
+
PRODUCT: "Prodotto",
|
|
4562
|
+
TRAVELERS: "Viaggiatori",
|
|
4563
|
+
ACTIONS: "Azioni",
|
|
4564
|
+
DETAILS: "Dettagli",
|
|
4565
|
+
HIDE_DETAILS: "Nascondi dettagli",
|
|
4566
|
+
PRINTS: "Stampe",
|
|
4567
|
+
ALL: "Tutti",
|
|
4568
|
+
X_ITEMS: "{0} elementi",
|
|
4569
|
+
PAGE_SIZE: "Elementi per pagina",
|
|
4570
|
+
PREVIOUS: "Precedente",
|
|
4571
|
+
NEXT: "Successivo",
|
|
4572
|
+
PAGE_X_OF_Y: "Pagina {0} di {1}",
|
|
4573
|
+
LOADING: "Caricamento...",
|
|
4574
|
+
NO_ITEMS: "Nessuna prenotazione trovata.",
|
|
4575
|
+
ERROR: "Si è verificato un errore durante il caricamento delle prenotazioni.",
|
|
4576
|
+
PRINT_ERROR: "Stampa non riuscita, riprova.",
|
|
4577
|
+
NOT_LOGGED_IN: "Accedi come agente per vedere le tue prenotazioni.",
|
|
4578
|
+
SESSION_EXPIRED: "La sessione è scaduta, accedi di nuovo."
|
|
4579
|
+
};
|
|
4275
4580
|
var itJson = {
|
|
4276
4581
|
STEPS: STEPS$7,
|
|
4277
4582
|
INPUT: INPUT$7,
|
|
@@ -4292,7 +4597,8 @@ var itJson = {
|
|
|
4292
4597
|
QSM: QSM$8,
|
|
4293
4598
|
SRP: SRP$7,
|
|
4294
4599
|
ITINERARY: ITINERARY$7,
|
|
4295
|
-
FORM: FORM$7
|
|
4600
|
+
FORM: FORM$7,
|
|
4601
|
+
AGENT_ENTRIES: AGENT_ENTRIES$7
|
|
4296
4602
|
};
|
|
4297
4603
|
|
|
4298
4604
|
var STEPS$6 = {
|
|
@@ -4749,6 +5055,39 @@ var FORM$6 = {
|
|
|
4749
5055
|
YES: "Ja",
|
|
4750
5056
|
NO: "Nee"
|
|
4751
5057
|
};
|
|
5058
|
+
var AGENT_ENTRIES$6 = {
|
|
5059
|
+
TITLE: "Boekingen",
|
|
5060
|
+
MY_BOOKINGS: "Mijn boekingen",
|
|
5061
|
+
NUMBER: "Nummer",
|
|
5062
|
+
DEPARTURE_DATE: "Vertrekdatum",
|
|
5063
|
+
STATUS: "Status",
|
|
5064
|
+
CUSTOM_STATUS: "Aangepaste status",
|
|
5065
|
+
RETURN_DATE: "Terugkeerdatum",
|
|
5066
|
+
PROFIT: "Winst",
|
|
5067
|
+
NETTO_SELLING_PRICE: "Netto verkoopprijs",
|
|
5068
|
+
YOUR_SURCHARGE: "Jouw toeslag",
|
|
5069
|
+
CREATED: "Aangemaakt",
|
|
5070
|
+
CONTACT: "Contact",
|
|
5071
|
+
MAIN_BOOKER: "Hoofdboeker",
|
|
5072
|
+
PRODUCT: "Product",
|
|
5073
|
+
TRAVELERS: "Reizigers",
|
|
5074
|
+
ACTIONS: "Acties",
|
|
5075
|
+
DETAILS: "Details",
|
|
5076
|
+
HIDE_DETAILS: "Details verbergen",
|
|
5077
|
+
PRINTS: "Afdrukken",
|
|
5078
|
+
ALL: "Alle",
|
|
5079
|
+
X_ITEMS: "{0} items",
|
|
5080
|
+
PAGE_SIZE: "Items per pagina",
|
|
5081
|
+
PREVIOUS: "Vorige",
|
|
5082
|
+
NEXT: "Volgende",
|
|
5083
|
+
PAGE_X_OF_Y: "Pagina {0} van {1}",
|
|
5084
|
+
LOADING: "Laden...",
|
|
5085
|
+
NO_ITEMS: "Geen boekingen gevonden.",
|
|
5086
|
+
ERROR: "Er ging iets mis bij het laden van je boekingen.",
|
|
5087
|
+
PRINT_ERROR: "Afdrukken mislukt, probeer het opnieuw.",
|
|
5088
|
+
NOT_LOGGED_IN: "Log in als agent om je boekingen te zien.",
|
|
5089
|
+
SESSION_EXPIRED: "Je sessie is verlopen, log opnieuw in."
|
|
5090
|
+
};
|
|
4752
5091
|
var nlBeJson = {
|
|
4753
5092
|
STEPS: STEPS$6,
|
|
4754
5093
|
INPUT: INPUT$6,
|
|
@@ -4769,7 +5108,8 @@ var nlBeJson = {
|
|
|
4769
5108
|
QSM: QSM$7,
|
|
4770
5109
|
SRP: SRP$6,
|
|
4771
5110
|
ITINERARY: ITINERARY$6,
|
|
4772
|
-
FORM: FORM$6
|
|
5111
|
+
FORM: FORM$6,
|
|
5112
|
+
AGENT_ENTRIES: AGENT_ENTRIES$6
|
|
4773
5113
|
};
|
|
4774
5114
|
|
|
4775
5115
|
var STEPS$5 = {
|
|
@@ -5222,6 +5562,39 @@ var FORM$5 = {
|
|
|
5222
5562
|
YES: "Ja",
|
|
5223
5563
|
NO: "Nee"
|
|
5224
5564
|
};
|
|
5565
|
+
var AGENT_ENTRIES$5 = {
|
|
5566
|
+
TITLE: "Boekingen",
|
|
5567
|
+
MY_BOOKINGS: "Mijn boekingen",
|
|
5568
|
+
NUMBER: "Nummer",
|
|
5569
|
+
DEPARTURE_DATE: "Vertrekdatum",
|
|
5570
|
+
STATUS: "Status",
|
|
5571
|
+
CUSTOM_STATUS: "Aangepaste status",
|
|
5572
|
+
RETURN_DATE: "Terugkeerdatum",
|
|
5573
|
+
PROFIT: "Winst",
|
|
5574
|
+
NETTO_SELLING_PRICE: "Netto verkoopprijs",
|
|
5575
|
+
YOUR_SURCHARGE: "Jouw toeslag",
|
|
5576
|
+
CREATED: "Aangemaakt",
|
|
5577
|
+
CONTACT: "Contact",
|
|
5578
|
+
MAIN_BOOKER: "Hoofdboeker",
|
|
5579
|
+
PRODUCT: "Product",
|
|
5580
|
+
TRAVELERS: "Reizigers",
|
|
5581
|
+
ACTIONS: "Acties",
|
|
5582
|
+
DETAILS: "Details",
|
|
5583
|
+
HIDE_DETAILS: "Details verbergen",
|
|
5584
|
+
PRINTS: "Afdrukken",
|
|
5585
|
+
ALL: "Alle",
|
|
5586
|
+
X_ITEMS: "{0} items",
|
|
5587
|
+
PAGE_SIZE: "Items per pagina",
|
|
5588
|
+
PREVIOUS: "Vorige",
|
|
5589
|
+
NEXT: "Volgende",
|
|
5590
|
+
PAGE_X_OF_Y: "Pagina {0} van {1}",
|
|
5591
|
+
LOADING: "Laden...",
|
|
5592
|
+
NO_ITEMS: "Geen boekingen gevonden.",
|
|
5593
|
+
ERROR: "Er ging iets mis bij het laden van je boekingen.",
|
|
5594
|
+
PRINT_ERROR: "Afdrukken mislukt, probeer het opnieuw.",
|
|
5595
|
+
NOT_LOGGED_IN: "Log in als agent om je boekingen te zien.",
|
|
5596
|
+
SESSION_EXPIRED: "Je sessie is verlopen, log opnieuw in."
|
|
5597
|
+
};
|
|
5225
5598
|
var nlNlJson = {
|
|
5226
5599
|
STEPS: STEPS$5,
|
|
5227
5600
|
INPUT: INPUT$5,
|
|
@@ -5242,7 +5615,8 @@ var nlNlJson = {
|
|
|
5242
5615
|
QSM: QSM$6,
|
|
5243
5616
|
SRP: SRP$5,
|
|
5244
5617
|
ITINERARY: ITINERARY$5,
|
|
5245
|
-
FORM: FORM$5
|
|
5618
|
+
FORM: FORM$5,
|
|
5619
|
+
AGENT_ENTRIES: AGENT_ENTRIES$5
|
|
5246
5620
|
};
|
|
5247
5621
|
|
|
5248
5622
|
var STEPS$4 = {
|
|
@@ -5695,6 +6069,39 @@ var FORM$4 = {
|
|
|
5695
6069
|
YES: "Ja",
|
|
5696
6070
|
NO: "Nei"
|
|
5697
6071
|
};
|
|
6072
|
+
var AGENT_ENTRIES$4 = {
|
|
6073
|
+
TITLE: "Bestillinger",
|
|
6074
|
+
MY_BOOKINGS: "Mine bestillinger",
|
|
6075
|
+
NUMBER: "Nummer",
|
|
6076
|
+
DEPARTURE_DATE: "Avreisedato",
|
|
6077
|
+
STATUS: "Status",
|
|
6078
|
+
CUSTOM_STATUS: "Egendefinert status",
|
|
6079
|
+
RETURN_DATE: "Returdato",
|
|
6080
|
+
PROFIT: "Fortjeneste",
|
|
6081
|
+
NETTO_SELLING_PRICE: "Netto salgspris",
|
|
6082
|
+
YOUR_SURCHARGE: "Ditt tillegg",
|
|
6083
|
+
CREATED: "Opprettet",
|
|
6084
|
+
CONTACT: "Kontakt",
|
|
6085
|
+
MAIN_BOOKER: "Hovedbestiller",
|
|
6086
|
+
PRODUCT: "Produkt",
|
|
6087
|
+
TRAVELERS: "Reisende",
|
|
6088
|
+
ACTIONS: "Handlinger",
|
|
6089
|
+
DETAILS: "Detaljer",
|
|
6090
|
+
HIDE_DETAILS: "Skjul detaljer",
|
|
6091
|
+
PRINTS: "Utskrifter",
|
|
6092
|
+
ALL: "Alle",
|
|
6093
|
+
X_ITEMS: "{0} elementer",
|
|
6094
|
+
PAGE_SIZE: "Elementer per side",
|
|
6095
|
+
PREVIOUS: "Forrige",
|
|
6096
|
+
NEXT: "Neste",
|
|
6097
|
+
PAGE_X_OF_Y: "Side {0} av {1}",
|
|
6098
|
+
LOADING: "Laster...",
|
|
6099
|
+
NO_ITEMS: "Ingen bestillinger funnet.",
|
|
6100
|
+
ERROR: "Noe gikk galt under lasting av bestillingene dine.",
|
|
6101
|
+
PRINT_ERROR: "Utskrift mislyktes, prøv igjen.",
|
|
6102
|
+
NOT_LOGGED_IN: "Logg inn som agent for å se bestillingene dine.",
|
|
6103
|
+
SESSION_EXPIRED: "Økten din er utløpt, logg inn på nytt."
|
|
6104
|
+
};
|
|
5698
6105
|
var noJson = {
|
|
5699
6106
|
STEPS: STEPS$4,
|
|
5700
6107
|
INPUT: INPUT$4,
|
|
@@ -5715,7 +6122,8 @@ var noJson = {
|
|
|
5715
6122
|
QSM: QSM$5,
|
|
5716
6123
|
SRP: SRP$4,
|
|
5717
6124
|
ITINERARY: ITINERARY$4,
|
|
5718
|
-
FORM: FORM$4
|
|
6125
|
+
FORM: FORM$4,
|
|
6126
|
+
AGENT_ENTRIES: AGENT_ENTRIES$4
|
|
5719
6127
|
};
|
|
5720
6128
|
|
|
5721
6129
|
var STEPS$3 = {
|
|
@@ -6168,6 +6576,39 @@ var FORM$3 = {
|
|
|
6168
6576
|
YES: "Tak",
|
|
6169
6577
|
NO: "Nie"
|
|
6170
6578
|
};
|
|
6579
|
+
var AGENT_ENTRIES$3 = {
|
|
6580
|
+
TITLE: "Rezerwacje",
|
|
6581
|
+
MY_BOOKINGS: "Moje rezerwacje",
|
|
6582
|
+
NUMBER: "Numer",
|
|
6583
|
+
DEPARTURE_DATE: "Data wyjazdu",
|
|
6584
|
+
STATUS: "Status",
|
|
6585
|
+
CUSTOM_STATUS: "Status niestandardowy",
|
|
6586
|
+
RETURN_DATE: "Data powrotu",
|
|
6587
|
+
PROFIT: "Zysk",
|
|
6588
|
+
NETTO_SELLING_PRICE: "Cena sprzedaży netto",
|
|
6589
|
+
YOUR_SURCHARGE: "Twoja dopłata",
|
|
6590
|
+
CREATED: "Utworzono",
|
|
6591
|
+
CONTACT: "Kontakt",
|
|
6592
|
+
MAIN_BOOKER: "Główny rezerwujący",
|
|
6593
|
+
PRODUCT: "Produkt",
|
|
6594
|
+
TRAVELERS: "Podróżni",
|
|
6595
|
+
ACTIONS: "Akcje",
|
|
6596
|
+
DETAILS: "Szczegóły",
|
|
6597
|
+
HIDE_DETAILS: "Ukryj szczegóły",
|
|
6598
|
+
PRINTS: "Wydruki",
|
|
6599
|
+
ALL: "Wszystkie",
|
|
6600
|
+
X_ITEMS: "{0} pozycji",
|
|
6601
|
+
PAGE_SIZE: "Pozycji na stronę",
|
|
6602
|
+
PREVIOUS: "Poprzednia",
|
|
6603
|
+
NEXT: "Następna",
|
|
6604
|
+
PAGE_X_OF_Y: "Strona {0} z {1}",
|
|
6605
|
+
LOADING: "Ładowanie...",
|
|
6606
|
+
NO_ITEMS: "Nie znaleziono rezerwacji.",
|
|
6607
|
+
ERROR: "Wystąpił błąd podczas ładowania rezerwacji.",
|
|
6608
|
+
PRINT_ERROR: "Drukowanie nie powiodło się, spróbuj ponownie.",
|
|
6609
|
+
NOT_LOGGED_IN: "Zaloguj się jako agent, aby zobaczyć swoje rezerwacje.",
|
|
6610
|
+
SESSION_EXPIRED: "Twoja sesja wygasła, zaloguj się ponownie."
|
|
6611
|
+
};
|
|
6171
6612
|
var plJson = {
|
|
6172
6613
|
STEPS: STEPS$3,
|
|
6173
6614
|
INPUT: INPUT$3,
|
|
@@ -6188,7 +6629,8 @@ var plJson = {
|
|
|
6188
6629
|
QSM: QSM$4,
|
|
6189
6630
|
SRP: SRP$3,
|
|
6190
6631
|
ITINERARY: ITINERARY$3,
|
|
6191
|
-
FORM: FORM$3
|
|
6632
|
+
FORM: FORM$3,
|
|
6633
|
+
AGENT_ENTRIES: AGENT_ENTRIES$3
|
|
6192
6634
|
};
|
|
6193
6635
|
|
|
6194
6636
|
var STEPS$2 = {
|
|
@@ -6641,6 +7083,39 @@ var FORM$2 = {
|
|
|
6641
7083
|
YES: "Sim",
|
|
6642
7084
|
NO: "Não"
|
|
6643
7085
|
};
|
|
7086
|
+
var AGENT_ENTRIES$2 = {
|
|
7087
|
+
TITLE: "Reservas",
|
|
7088
|
+
MY_BOOKINGS: "As minhas reservas",
|
|
7089
|
+
NUMBER: "Número",
|
|
7090
|
+
DEPARTURE_DATE: "Data de partida",
|
|
7091
|
+
STATUS: "Estado",
|
|
7092
|
+
CUSTOM_STATUS: "Estado personalizado",
|
|
7093
|
+
RETURN_DATE: "Data de regresso",
|
|
7094
|
+
PROFIT: "Lucro",
|
|
7095
|
+
NETTO_SELLING_PRICE: "Preço de venda líquido",
|
|
7096
|
+
YOUR_SURCHARGE: "A sua sobretaxa",
|
|
7097
|
+
CREATED: "Criado",
|
|
7098
|
+
CONTACT: "Contacto",
|
|
7099
|
+
MAIN_BOOKER: "Titular da reserva",
|
|
7100
|
+
PRODUCT: "Produto",
|
|
7101
|
+
TRAVELERS: "Viajantes",
|
|
7102
|
+
ACTIONS: "Ações",
|
|
7103
|
+
DETAILS: "Detalhes",
|
|
7104
|
+
HIDE_DETAILS: "Ocultar detalhes",
|
|
7105
|
+
PRINTS: "Impressões",
|
|
7106
|
+
ALL: "Todos",
|
|
7107
|
+
X_ITEMS: "{0} itens",
|
|
7108
|
+
PAGE_SIZE: "Itens por página",
|
|
7109
|
+
PREVIOUS: "Anterior",
|
|
7110
|
+
NEXT: "Seguinte",
|
|
7111
|
+
PAGE_X_OF_Y: "Página {0} de {1}",
|
|
7112
|
+
LOADING: "A carregar...",
|
|
7113
|
+
NO_ITEMS: "Nenhuma reserva encontrada.",
|
|
7114
|
+
ERROR: "Ocorreu um erro ao carregar as suas reservas.",
|
|
7115
|
+
PRINT_ERROR: "A impressão falhou, tente novamente.",
|
|
7116
|
+
NOT_LOGGED_IN: "Inicie sessão como agente para ver as suas reservas.",
|
|
7117
|
+
SESSION_EXPIRED: "A sua sessão expirou, inicie sessão novamente."
|
|
7118
|
+
};
|
|
6644
7119
|
var ptJson = {
|
|
6645
7120
|
STEPS: STEPS$2,
|
|
6646
7121
|
INPUT: INPUT$2,
|
|
@@ -6661,7 +7136,8 @@ var ptJson = {
|
|
|
6661
7136
|
QSM: QSM$3,
|
|
6662
7137
|
SRP: SRP$2,
|
|
6663
7138
|
ITINERARY: ITINERARY$2,
|
|
6664
|
-
FORM: FORM$2
|
|
7139
|
+
FORM: FORM$2,
|
|
7140
|
+
AGENT_ENTRIES: AGENT_ENTRIES$2
|
|
6665
7141
|
};
|
|
6666
7142
|
|
|
6667
7143
|
var STEPS$1 = {
|
|
@@ -7114,6 +7590,39 @@ var FORM$1 = {
|
|
|
7114
7590
|
YES: "Ja",
|
|
7115
7591
|
NO: "Nej"
|
|
7116
7592
|
};
|
|
7593
|
+
var AGENT_ENTRIES$1 = {
|
|
7594
|
+
TITLE: "Bokningar",
|
|
7595
|
+
MY_BOOKINGS: "Mina bokningar",
|
|
7596
|
+
NUMBER: "Nummer",
|
|
7597
|
+
DEPARTURE_DATE: "Avresedatum",
|
|
7598
|
+
STATUS: "Status",
|
|
7599
|
+
CUSTOM_STATUS: "Anpassad status",
|
|
7600
|
+
RETURN_DATE: "Returdatum",
|
|
7601
|
+
PROFIT: "Vinst",
|
|
7602
|
+
NETTO_SELLING_PRICE: "Nettoförsäljningspris",
|
|
7603
|
+
YOUR_SURCHARGE: "Ditt tillägg",
|
|
7604
|
+
CREATED: "Skapad",
|
|
7605
|
+
CONTACT: "Kontakt",
|
|
7606
|
+
MAIN_BOOKER: "Huvudbokare",
|
|
7607
|
+
PRODUCT: "Produkt",
|
|
7608
|
+
TRAVELERS: "Resenärer",
|
|
7609
|
+
ACTIONS: "Åtgärder",
|
|
7610
|
+
DETAILS: "Detaljer",
|
|
7611
|
+
HIDE_DETAILS: "Dölj detaljer",
|
|
7612
|
+
PRINTS: "Utskrifter",
|
|
7613
|
+
ALL: "Alla",
|
|
7614
|
+
X_ITEMS: "{0} objekt",
|
|
7615
|
+
PAGE_SIZE: "Objekt per sida",
|
|
7616
|
+
PREVIOUS: "Föregående",
|
|
7617
|
+
NEXT: "Nästa",
|
|
7618
|
+
PAGE_X_OF_Y: "Sida {0} av {1}",
|
|
7619
|
+
LOADING: "Laddar...",
|
|
7620
|
+
NO_ITEMS: "Inga bokningar hittades.",
|
|
7621
|
+
ERROR: "Något gick fel när dina bokningar laddades.",
|
|
7622
|
+
PRINT_ERROR: "Utskriften misslyckades, försök igen.",
|
|
7623
|
+
NOT_LOGGED_IN: "Logga in som agent för att se dina bokningar.",
|
|
7624
|
+
SESSION_EXPIRED: "Din session har gått ut, logga in igen."
|
|
7625
|
+
};
|
|
7117
7626
|
var svJson = {
|
|
7118
7627
|
STEPS: STEPS$1,
|
|
7119
7628
|
INPUT: INPUT$1,
|
|
@@ -7134,7 +7643,8 @@ var svJson = {
|
|
|
7134
7643
|
QSM: QSM$2,
|
|
7135
7644
|
SRP: SRP$1,
|
|
7136
7645
|
ITINERARY: ITINERARY$1,
|
|
7137
|
-
FORM: FORM$1
|
|
7646
|
+
FORM: FORM$1,
|
|
7647
|
+
AGENT_ENTRIES: AGENT_ENTRIES$1
|
|
7138
7648
|
};
|
|
7139
7649
|
|
|
7140
7650
|
var STEPS = {
|
|
@@ -7587,6 +8097,39 @@ var FORM = {
|
|
|
7587
8097
|
YES: "はい",
|
|
7588
8098
|
NO: "いいえ"
|
|
7589
8099
|
};
|
|
8100
|
+
var AGENT_ENTRIES = {
|
|
8101
|
+
TITLE: "予約",
|
|
8102
|
+
MY_BOOKINGS: "マイ予約",
|
|
8103
|
+
NUMBER: "番号",
|
|
8104
|
+
DEPARTURE_DATE: "出発日",
|
|
8105
|
+
STATUS: "ステータス",
|
|
8106
|
+
CUSTOM_STATUS: "カスタムステータス",
|
|
8107
|
+
RETURN_DATE: "帰着日",
|
|
8108
|
+
PROFIT: "利益",
|
|
8109
|
+
NETTO_SELLING_PRICE: "正味販売価格",
|
|
8110
|
+
YOUR_SURCHARGE: "手数料",
|
|
8111
|
+
CREATED: "作成日",
|
|
8112
|
+
CONTACT: "連絡先",
|
|
8113
|
+
MAIN_BOOKER: "代表予約者",
|
|
8114
|
+
PRODUCT: "商品",
|
|
8115
|
+
TRAVELERS: "旅行者",
|
|
8116
|
+
ACTIONS: "操作",
|
|
8117
|
+
DETAILS: "詳細",
|
|
8118
|
+
HIDE_DETAILS: "詳細を隠す",
|
|
8119
|
+
PRINTS: "印刷",
|
|
8120
|
+
ALL: "すべて",
|
|
8121
|
+
X_ITEMS: "{0} 件",
|
|
8122
|
+
PAGE_SIZE: "1ページあたりの件数",
|
|
8123
|
+
PREVIOUS: "前へ",
|
|
8124
|
+
NEXT: "次へ",
|
|
8125
|
+
PAGE_X_OF_Y: "{0} / {1} ページ",
|
|
8126
|
+
LOADING: "読み込み中...",
|
|
8127
|
+
NO_ITEMS: "予約が見つかりません。",
|
|
8128
|
+
ERROR: "予約の読み込み中にエラーが発生しました。",
|
|
8129
|
+
PRINT_ERROR: "印刷に失敗しました。もう一度お試しください。",
|
|
8130
|
+
NOT_LOGGED_IN: "予約を表示するにはエージェントとしてログインしてください。",
|
|
8131
|
+
SESSION_EXPIRED: "セッションの有効期限が切れました。再度ログインしてください。"
|
|
8132
|
+
};
|
|
7590
8133
|
var jaJson = {
|
|
7591
8134
|
STEPS: STEPS,
|
|
7592
8135
|
INPUT: INPUT,
|
|
@@ -7607,7 +8150,8 @@ var jaJson = {
|
|
|
7607
8150
|
QSM: QSM$1,
|
|
7608
8151
|
SRP: SRP,
|
|
7609
8152
|
ITINERARY: ITINERARY,
|
|
7610
|
-
FORM: FORM
|
|
8153
|
+
FORM: FORM,
|
|
8154
|
+
AGENT_ENTRIES: AGENT_ENTRIES
|
|
7611
8155
|
};
|
|
7612
8156
|
|
|
7613
8157
|
var DepartureRange;
|
|
@@ -15560,6 +16104,7 @@ var ENDPOINT$1 = "/api/web/packaging";
|
|
|
15560
16104
|
var ENDPOINT_START_TRANSACTION = ENDPOINT$1 + "/start";
|
|
15561
16105
|
var ENDPOINT_ACCOMMODATIONS = ENDPOINT$1 + "/accommodations";
|
|
15562
16106
|
var ENDPOINT_EXCURSIONS = ENDPOINT$1 + "/excursions";
|
|
16107
|
+
var ENDPOINT_TRANSFERS = ENDPOINT$1 + "/transfers";
|
|
15563
16108
|
var ENDPOINT_FLIGHTS = ENDPOINT$1 + "/flights";
|
|
15564
16109
|
var ENDPOINT_PRICE_DETAILS = ENDPOINT$1 + "/price-details";
|
|
15565
16110
|
var ENDPOINT_BOOK = ENDPOINT$1 + "/book";
|
|
@@ -15592,6 +16137,12 @@ var searchPackagingExcursions = function (config, request, signal) {
|
|
|
15592
16137
|
var body = JSON.stringify(request);
|
|
15593
16138
|
return post(url, apiKey, body, config.token, signal, true);
|
|
15594
16139
|
};
|
|
16140
|
+
var searchPackagingTransfers = function (config, request, signal) {
|
|
16141
|
+
var url = "" + config.host + ENDPOINT_TRANSFERS;
|
|
16142
|
+
var apiKey = config.apiKey;
|
|
16143
|
+
var body = JSON.stringify(request);
|
|
16144
|
+
return post(url, apiKey, body, config.token, signal, true);
|
|
16145
|
+
};
|
|
15595
16146
|
var getEntry = function (config, magicLinkCode, signal) {
|
|
15596
16147
|
var apiKey = config.apiKey;
|
|
15597
16148
|
var url = "" + config.host + ENDPOINT_ENTRY(magicLinkCode);
|
|
@@ -15769,6 +16320,7 @@ exports.searchOords = searchOords;
|
|
|
15769
16320
|
exports.searchPackagingAccommodations = searchPackagingAccommodations;
|
|
15770
16321
|
exports.searchPackagingExcursions = searchPackagingExcursions;
|
|
15771
16322
|
exports.searchPackagingFlights = searchPackagingFlights;
|
|
16323
|
+
exports.searchPackagingTransfers = searchPackagingTransfers;
|
|
15772
16324
|
exports.searchRegions = searchRegions;
|
|
15773
16325
|
exports.searchWithErrorMapping = searchWithErrorMapping;
|
|
15774
16326
|
exports.sendContactForm = sendContactForm;
|
|
@@ -19261,10 +19813,30 @@ function formatBirthDate$1(birthDate) {
|
|
|
19261
19813
|
// A field can have separate "main-booker"/other-pax variants sharing the same identity
|
|
19262
19814
|
// (customFieldConfigurationId for custom fields, fieldName for built-in fields).
|
|
19263
19815
|
const MAIN_BOOKER_GROUP = 'main-booker';
|
|
19816
|
+
const MAIN_BOOKER_FIELD_PREFIX = 'mainBooker';
|
|
19264
19817
|
const isCustomPaxField = (field) => field.customFieldConfigurationId != null;
|
|
19818
|
+
// Tide names the built-in main-booker fields with a prefix ('mainBookerGender', 'mainBookerCountryId', ...),
|
|
19819
|
+
// the other-pax ones without ('gender', 'countryId'). Strip it so both are variants of the same field.
|
|
19820
|
+
function normalizeBuiltInFieldName(field) {
|
|
19821
|
+
if (isCustomPaxField(field) || !field.fieldName?.startsWith(MAIN_BOOKER_FIELD_PREFIX))
|
|
19822
|
+
return field;
|
|
19823
|
+
const stripped = field.fieldName.slice(MAIN_BOOKER_FIELD_PREFIX.length);
|
|
19824
|
+
if (!stripped)
|
|
19825
|
+
return field;
|
|
19826
|
+
return { ...field, fieldName: stripped.charAt(0).toLowerCase() + stripped.slice(1) };
|
|
19827
|
+
}
|
|
19828
|
+
// Once Tide sends built-in fields, that configuration decides which built-in fields are shown/required;
|
|
19829
|
+
// the hardcoded formFields / core defaults are only the fallback for when it doesn't.
|
|
19830
|
+
function hasConfiguredBuiltInPaxFields(paxFields = []) {
|
|
19831
|
+
return paxFields.some((f) => !isCustomPaxField(f));
|
|
19832
|
+
}
|
|
19833
|
+
// The main booker's address/contact details are then asked on the main booker's own traveler block.
|
|
19834
|
+
function hasConfiguredMainBookerFields(paxFields = []) {
|
|
19835
|
+
return paxFields.some((f) => !isCustomPaxField(f) && f.group === MAIN_BOOKER_GROUP);
|
|
19836
|
+
}
|
|
19265
19837
|
function resolveApplicablePaxFields(fields, isMainBooker) {
|
|
19266
19838
|
const variantsByKey = new Map();
|
|
19267
|
-
fields.forEach((field) => {
|
|
19839
|
+
fields.map(normalizeBuiltInFieldName).forEach((field) => {
|
|
19268
19840
|
const key = field.customFieldConfigurationId ?? field.fieldName;
|
|
19269
19841
|
const variants = variantsByKey.get(key) ?? [];
|
|
19270
19842
|
variants.push(field);
|
|
@@ -19326,11 +19898,50 @@ const BUILT_IN_FIELD_PATHS = {
|
|
|
19326
19898
|
// The 4 fields that always render/validate regardless of paxFields config (fallback behavior).
|
|
19327
19899
|
const CORE_FIELD_NAMES = new Set(['gender', 'firstName', 'lastName', 'dateOfBirth']);
|
|
19328
19900
|
const ADDRESS_FIELD_NAMES = ['street', 'location', 'countryId', 'postalCode', 'number'];
|
|
19901
|
+
// Built-in fields have no dataType from Tide; their control type and label follow from the fieldName.
|
|
19902
|
+
// gender, hasInsurance, countryId, weight and height have a dedicated control and only need a label here.
|
|
19903
|
+
function getBuiltInFieldControlMeta(translations) {
|
|
19904
|
+
return {
|
|
19905
|
+
gender: { label: translations.TRAVELERS_FORM.GENDER_ID },
|
|
19906
|
+
firstName: { label: translations.TRAVELERS_FORM.FIRST_NAME },
|
|
19907
|
+
lastName: { label: translations.TRAVELERS_FORM.LAST_NAME },
|
|
19908
|
+
dateOfBirth: { type: 'date', label: translations.TRAVELERS_FORM.BIRTHDATE },
|
|
19909
|
+
nickname: { label: translations.TRAVELERS_FORM.NICKNAME },
|
|
19910
|
+
birthplace: { label: translations.TRAVELERS_FORM.BIRTHPLACE },
|
|
19911
|
+
nationality: { label: translations.TRAVELERS_FORM.NATIONALITY },
|
|
19912
|
+
preferredLanguageId: { type: 'number', label: translations.TRAVELERS_FORM.PREFERRED_LANGUAGE },
|
|
19913
|
+
email: { type: 'email', label: translations.TRAVELERS_FORM.TRAVELER_EMAIL },
|
|
19914
|
+
phone: { type: 'tel', label: translations.TRAVELERS_FORM.TRAVELER_PHONE },
|
|
19915
|
+
mobile: { type: 'tel', label: translations.TRAVELERS_FORM.TRAVELER_MOBILE },
|
|
19916
|
+
passportNumber: { label: translations.TRAVELERS_FORM.PASSPORT_NUMBER },
|
|
19917
|
+
passportIssueDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_ISSUE_DATE },
|
|
19918
|
+
passportIssuedLocation: { label: translations.TRAVELERS_FORM.PASSPORT_ISSUED_LOCATION },
|
|
19919
|
+
passportExpiryDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_EXPIRY_DATE },
|
|
19920
|
+
emergencyNumber: { type: 'tel', label: translations.TRAVELERS_FORM.EMERGENCY_NUMBER },
|
|
19921
|
+
hasInsurance: { label: translations.TRAVELERS_FORM.HAS_INSURANCE },
|
|
19922
|
+
insuranceName: { label: translations.TRAVELERS_FORM.INSURANCE_NAME },
|
|
19923
|
+
info: { label: translations.TRAVELERS_FORM.INFO },
|
|
19924
|
+
weight: { label: translations.TRAVELERS_FORM.WEIGHT },
|
|
19925
|
+
height: { label: translations.TRAVELERS_FORM.HEIGHT },
|
|
19926
|
+
street: { label: translations.TRAVELERS_FORM.STREET },
|
|
19927
|
+
location: { label: translations.TRAVELERS_FORM.CITY },
|
|
19928
|
+
countryId: { label: translations.TRAVELERS_FORM.COUNTRY },
|
|
19929
|
+
postalCode: { label: translations.TRAVELERS_FORM.ZIPCODE },
|
|
19930
|
+
number: { label: translations.TRAVELERS_FORM.HOUSE_NUMBER }
|
|
19931
|
+
};
|
|
19932
|
+
}
|
|
19933
|
+
// The form's gender radio values ('m'/'f'/'x') <-> Tide's Gender enum.
|
|
19934
|
+
const GENDER_BY_FORM_VALUE = { m: build.Gender.male, f: build.Gender.female, x: build.Gender.other };
|
|
19935
|
+
function formValueFromGender(gender) {
|
|
19936
|
+
return Object.keys(GENDER_BY_FORM_VALUE).find((key) => GENDER_BY_FORM_VALUE[key] === gender) ?? '';
|
|
19937
|
+
}
|
|
19329
19938
|
// Shared by buildPax (new-booking) and applyTravelersFormValuesToEditablePackagingEntry
|
|
19330
19939
|
// (edit-booking), now that PackagingEntryPax and BookingPackagePax have the same shape.
|
|
19331
19940
|
function applyTravelerToPax(pax, traveler, mainBookerId) {
|
|
19332
19941
|
return {
|
|
19333
19942
|
...pax,
|
|
19943
|
+
// Unanswered (optional) gender keeps whatever the pax already had.
|
|
19944
|
+
gender: GENDER_BY_FORM_VALUE[traveler.gender] ?? pax.gender,
|
|
19334
19945
|
firstName: traveler.firstName ?? '',
|
|
19335
19946
|
lastName: traveler.lastName ?? '',
|
|
19336
19947
|
dateOfBirth: traveler.birthDate || null,
|
|
@@ -19490,7 +20101,13 @@ function mapPackagingEntryPaxToTraveler(roomTraveler) {
|
|
|
19490
20101
|
customFields: roomTraveler.customFields ?? []
|
|
19491
20102
|
};
|
|
19492
20103
|
}
|
|
19493
|
-
|
|
20104
|
+
// Keeps the values already on the entry's pax and adds an empty slot for every configured custom field it lacks,
|
|
20105
|
+
// so the form renders/validates the same set as createTraveler does for a new booking.
|
|
20106
|
+
function mergeCustomFields(existing = [], paxFields) {
|
|
20107
|
+
const missing = buildEmptyCustomFields(paxFields).filter((empty) => !existing.some((c) => c.customFieldConfigurationId === empty.customFieldConfigurationId));
|
|
20108
|
+
return [...existing, ...missing];
|
|
20109
|
+
}
|
|
20110
|
+
function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, agentAdressId, paxFields = editablePackagingEntry?.paxFields ?? []) {
|
|
19494
20111
|
const pax = editablePackagingEntry?.pax ?? [];
|
|
19495
20112
|
const rooms = editablePackagingEntry.rooms.map((room) => {
|
|
19496
20113
|
const roomPax = pax.filter((x) => room.paxIds.includes(x.id));
|
|
@@ -19503,8 +20120,9 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
|
|
|
19503
20120
|
firstName: roomTraveler.firstName ?? '',
|
|
19504
20121
|
lastName: roomTraveler.lastName ?? '',
|
|
19505
20122
|
birthDate: roomTraveler.dateOfBirth ? format$2(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
19506
|
-
gender:
|
|
19507
|
-
...mapPackagingEntryPaxToTraveler(roomTraveler)
|
|
20123
|
+
gender: formValueFromGender(roomTraveler.gender),
|
|
20124
|
+
...mapPackagingEntryPaxToTraveler(roomTraveler),
|
|
20125
|
+
customFields: mergeCustomFields(roomTraveler.customFields, paxFields)
|
|
19508
20126
|
};
|
|
19509
20127
|
}),
|
|
19510
20128
|
children: children.map((roomTraveler) => {
|
|
@@ -19513,9 +20131,10 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
|
|
|
19513
20131
|
firstName: roomTraveler.firstName ?? '',
|
|
19514
20132
|
lastName: roomTraveler.lastName ?? '',
|
|
19515
20133
|
birthDate: roomTraveler.dateOfBirth ? format$2(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
19516
|
-
gender:
|
|
20134
|
+
gender: formValueFromGender(roomTraveler.gender),
|
|
19517
20135
|
isBaby: isBabyAge(roomTraveler.age),
|
|
19518
|
-
...mapPackagingEntryPaxToTraveler(roomTraveler)
|
|
20136
|
+
...mapPackagingEntryPaxToTraveler(roomTraveler),
|
|
20137
|
+
customFields: mergeCustomFields(roomTraveler.customFields, paxFields)
|
|
19519
20138
|
};
|
|
19520
20139
|
})
|
|
19521
20140
|
};
|
|
@@ -19540,7 +20159,8 @@ function applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry
|
|
|
19540
20159
|
const travelers = values.rooms.flatMap((room) => [...room.adults, ...room.children]);
|
|
19541
20160
|
// The backend treats the main booker's per-pax address as authoritative, so keep the
|
|
19542
20161
|
// booking-level address in sync with it rather than sending two independent values.
|
|
19543
|
-
const
|
|
20162
|
+
const mainBookerTraveler = travelers.find((x) => x.id === values.mainBookerId);
|
|
20163
|
+
const mainBookerAddress = mainBookerTraveler?.address;
|
|
19544
20164
|
return {
|
|
19545
20165
|
...editablePackagingEntry,
|
|
19546
20166
|
pax: (editablePackagingEntry.pax ?? []).map((pax) => {
|
|
@@ -19556,8 +20176,9 @@ function applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry
|
|
|
19556
20176
|
place: mainBookerAddress?.location || values.place,
|
|
19557
20177
|
country: mainBookerAddress?.country || values.country,
|
|
19558
20178
|
travelAgentId: values.travelAgentId,
|
|
19559
|
-
|
|
19560
|
-
|
|
20179
|
+
// When Tide configures the main-booker fields, contact details live on the main booker's traveler block.
|
|
20180
|
+
phone: values.phone || mainBookerTraveler?.mobile || mainBookerTraveler?.phone,
|
|
20181
|
+
email: values.email || mainBookerTraveler?.email
|
|
19561
20182
|
}
|
|
19562
20183
|
};
|
|
19563
20184
|
}
|
|
@@ -19714,30 +20335,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19714
20335
|
return (React__default.createElement("div", { key: field.customFieldConfigurationId, style: { gridColumn: `span ${field.col || 12}` } }, getCustomFieldControl(field, value, name)));
|
|
19715
20336
|
})));
|
|
19716
20337
|
};
|
|
19717
|
-
|
|
19718
|
-
const BUILT_IN_FIELD_CONTROL_META = {
|
|
19719
|
-
firstName: { label: translations.TRAVELERS_FORM.FIRST_NAME },
|
|
19720
|
-
lastName: { label: translations.TRAVELERS_FORM.LAST_NAME },
|
|
19721
|
-
dateOfBirth: { type: 'date', label: translations.TRAVELERS_FORM.BIRTHDATE },
|
|
19722
|
-
nickname: { label: translations.TRAVELERS_FORM.NICKNAME },
|
|
19723
|
-
birthplace: { label: translations.TRAVELERS_FORM.BIRTHPLACE },
|
|
19724
|
-
nationality: { label: translations.TRAVELERS_FORM.NATIONALITY },
|
|
19725
|
-
preferredLanguageId: { type: 'number', label: translations.TRAVELERS_FORM.PREFERRED_LANGUAGE },
|
|
19726
|
-
email: { type: 'email', label: translations.TRAVELERS_FORM.TRAVELER_EMAIL },
|
|
19727
|
-
phone: { label: translations.TRAVELERS_FORM.TRAVELER_PHONE },
|
|
19728
|
-
mobile: { label: translations.TRAVELERS_FORM.TRAVELER_MOBILE },
|
|
19729
|
-
passportNumber: { label: translations.TRAVELERS_FORM.PASSPORT_NUMBER },
|
|
19730
|
-
passportIssueDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_ISSUE_DATE },
|
|
19731
|
-
passportIssuedLocation: { label: translations.TRAVELERS_FORM.PASSPORT_ISSUED_LOCATION },
|
|
19732
|
-
passportExpiryDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_EXPIRY_DATE },
|
|
19733
|
-
emergencyNumber: { label: translations.TRAVELERS_FORM.EMERGENCY_NUMBER },
|
|
19734
|
-
insuranceName: { label: translations.TRAVELERS_FORM.INSURANCE_NAME },
|
|
19735
|
-
info: { label: translations.TRAVELERS_FORM.INFO },
|
|
19736
|
-
street: { label: translations.TRAVELERS_FORM.STREET },
|
|
19737
|
-
location: { label: translations.TRAVELERS_FORM.CITY },
|
|
19738
|
-
postalCode: { label: translations.TRAVELERS_FORM.ZIPCODE },
|
|
19739
|
-
number: { label: translations.TRAVELERS_FORM.HOUSE_NUMBER }
|
|
19740
|
-
};
|
|
20338
|
+
const BUILT_IN_FIELD_CONTROL_META = getBuiltInFieldControlMeta(translations);
|
|
19741
20339
|
const renderBuiltInFieldControl = (fieldName, isRequired, travelerValues, namePrefix) => {
|
|
19742
20340
|
const path = BUILT_IN_FIELD_PATHS[fieldName] ?? fieldName;
|
|
19743
20341
|
const name = `${namePrefix}.${path}`;
|
|
@@ -19772,7 +20370,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19772
20370
|
const resolveBuiltInField = (fieldName, travelerValues) => {
|
|
19773
20371
|
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
19774
20372
|
const configured = getBuiltInPaxField(paxFields, fieldName, isMainBooker);
|
|
19775
|
-
const fallback = CORE_FIELD_DEFAULTS[fieldName];
|
|
20373
|
+
const fallback = hasConfiguredBuiltInPaxFields(paxFields) ? undefined : CORE_FIELD_DEFAULTS[fieldName];
|
|
19776
20374
|
if (!configured && !fallback)
|
|
19777
20375
|
return undefined;
|
|
19778
20376
|
return { isRequired: configured?.isRequired ?? fallback.isRequired, col: configured?.col ?? fallback.col };
|
|
@@ -19784,7 +20382,14 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19784
20382
|
return (React__default.createElement("div", { key: fieldName, style: { gridColumn: `span ${resolved.col || 12}` } }, renderBuiltInFieldControl(fieldName, resolved.isRequired, travelerValues, namePrefix)));
|
|
19785
20383
|
};
|
|
19786
20384
|
const renderTravelerAddressFields = (travelerValues, namePrefix) => {
|
|
19787
|
-
const
|
|
20385
|
+
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
20386
|
+
// Configured order when Tide sends one, so the configured col widths line up as intended.
|
|
20387
|
+
const fieldNames = hasConfiguredBuiltInPaxFields(paxFields)
|
|
20388
|
+
? getApplicableBuiltInPaxFields(paxFields, isMainBooker)
|
|
20389
|
+
.map((field) => field.fieldName)
|
|
20390
|
+
.filter((fieldName) => ADDRESS_FIELD_NAMES.includes(fieldName))
|
|
20391
|
+
: ADDRESS_FIELD_NAMES;
|
|
20392
|
+
const fields = fieldNames.map((fieldName) => renderBuiltInField(fieldName, travelerValues, namePrefix)).filter(Boolean);
|
|
19788
20393
|
if (!fields.length)
|
|
19789
20394
|
return null;
|
|
19790
20395
|
return React__default.createElement("div", { className: "travelers-form__custom-fields-grid" }, fields);
|
|
@@ -19827,15 +20432,18 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19827
20432
|
return (React__default.createElement("div", { className: "form__row" },
|
|
19828
20433
|
React__default.createElement(LabeledInput, { hasError: hasVisibleError(`${namePrefix}.age`), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.AGE, required: true, name: `${namePrefix}.age`, onChange: formik.handleChange, onBlur: formik.handleBlur, value: travelerValues.age })));
|
|
19829
20434
|
}
|
|
19830
|
-
// 'birthDate' (the legacy formFields type string) is normalized to the paxFields catalog's
|
|
19831
|
-
// 'dateOfBirth' fieldName for config lookups.
|
|
19832
|
-
const baseFieldNames = (travellersSettings?.formFields?.length ? travellersSettings.formFields.map((field) => field.type) : ['gender', 'firstName', 'lastName', 'dateOfBirth']).map((fieldName) => (fieldName === 'birthDate' ? 'dateOfBirth' : fieldName));
|
|
19833
20435
|
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
19834
|
-
|
|
19835
|
-
|
|
19836
|
-
|
|
20436
|
+
// With a Tide field configuration, exactly the configured fields render, in their configured order.
|
|
20437
|
+
// Without one, fall back to formFields ('birthDate', the legacy type string, maps to 'dateOfBirth').
|
|
20438
|
+
const fieldNames = hasConfiguredBuiltInPaxFields(paxFields)
|
|
20439
|
+
? getApplicableBuiltInPaxFields(paxFields, isMainBooker)
|
|
20440
|
+
.map((field) => field.fieldName)
|
|
20441
|
+
.filter((fieldName) => !ADDRESS_FIELD_NAMES.includes(fieldName))
|
|
20442
|
+
: (travellersSettings?.formFields?.length
|
|
20443
|
+
? travellersSettings.formFields.map((field) => field.type)
|
|
20444
|
+
: ['gender', 'firstName', 'lastName', 'dateOfBirth']).map((fieldName) => (fieldName === 'birthDate' ? 'dateOfBirth' : fieldName));
|
|
19837
20445
|
return (React__default.createElement(React__default.Fragment, null,
|
|
19838
|
-
React__default.createElement("div", { className: "travelers-form__custom-fields-grid" },
|
|
20446
|
+
React__default.createElement("div", { className: "travelers-form__custom-fields-grid" }, fieldNames.map((fieldName) => renderBuiltInField(fieldName, travelerValues, namePrefix))),
|
|
19839
20447
|
renderTravelerAddressFields(travelerValues, namePrefix),
|
|
19840
20448
|
renderCustomFields(travelerValues, namePrefix),
|
|
19841
20449
|
travelersFirstStep && isAdult && formik.values.rooms[roomIndex].adults.length > 1 && (React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleRemoveTraveler(roomIndex, travelerIndex) }, translations.TRAVELERS_FORM.REMOVE_TRAVELER))));
|
|
@@ -19873,7 +20481,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19873
20481
|
renderTravelerFields(travelerValues, `rooms[${roomIndex}].children[${index}]`, false, roomIndex, index)))),
|
|
19874
20482
|
!useCompactForm && travelersFirstStep && (React__default.createElement("div", { className: "form__region" },
|
|
19875
20483
|
React__default.createElement("button", { type: "button", className: "cta cta--select", onClick: () => handleAddTraveler(roomIndex) }, translations.TRAVELERS_FORM.ADD_TRAVELER)))))),
|
|
19876
|
-
|
|
20484
|
+
useCompactForm || hasConfiguredMainBookerFields(paxFields) ? null : bookingType !== 'b2b' || travellersSettings?.mainBookerFormFields?.length ? (React__default.createElement("div", { className: "form__region" },
|
|
19877
20485
|
React__default.createElement("div", { className: "form__region-header" },
|
|
19878
20486
|
React__default.createElement("h5", { className: "form__region-heading" }, translations.TRAVELERS_FORM.MAIN_BOOKER),
|
|
19879
20487
|
React__default.createElement("p", { className: "form__region-label" }, compact([compact([mainBooker?.firstName, mainBooker?.lastName]).join(' '), formatBirthDate$1(mainBooker?.birthDate)]).join(', '))),
|
|
@@ -19892,9 +20500,9 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19892
20500
|
React__default.createElement("div", { className: "form__row" },
|
|
19893
20501
|
React__default.createElement(LabeledInput, { hasError: hasVisibleError('phone'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.PHONE, required: true, name: "phone", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.phone }),
|
|
19894
20502
|
React__default.createElement(LabeledInput, { type: "email", hasError: hasVisibleError('email'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.EMAIL, required: true, name: "email", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.email }),
|
|
19895
|
-
React__default.createElement(LabeledInput, { type: "email", hasError: hasVisibleError('emailConfirmation'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.REPEAT_EMAIL, required: true, name: "emailConfirmation", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.emailConfirmation })))))) :
|
|
20503
|
+
React__default.createElement(LabeledInput, { type: "email", hasError: hasVisibleError('emailConfirmation'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.REPEAT_EMAIL, required: true, name: "emailConfirmation", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.emailConfirmation })))))) : (React__default.createElement("div", { className: "form__region" },
|
|
19896
20504
|
React__default.createElement("div", { className: "form__row" },
|
|
19897
|
-
React__default.createElement(LabeledInput, { hasError: hasVisibleError('phone'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.PHONE, required: true, name: "phone", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.phone }))))
|
|
20505
|
+
React__default.createElement(LabeledInput, { hasError: hasVisibleError('phone'), extraClassName: "form__group--md-33", label: translations.TRAVELERS_FORM.PHONE, required: true, name: "phone", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.phone })))),
|
|
19898
20506
|
!useCompactForm && showAgentSelection && (React__default.createElement("div", { className: "form__region" },
|
|
19899
20507
|
React__default.createElement("div", { className: "form__region-header" },
|
|
19900
20508
|
React__default.createElement("h5", { className: "form__region-heading" }, translations.TRAVELERS_FORM.BOOK_WITH_AGENT),
|
|
@@ -20505,8 +21113,9 @@ const selectBookingPackagePax = createSelector(selectTravelersFormValues, (formV
|
|
|
20505
21113
|
formValues?.rooms.forEach((r) => r.adults.forEach((x) => {
|
|
20506
21114
|
const adultPax = buildPax(x, formValues?.mainBookerId);
|
|
20507
21115
|
if (adultPax.isMainBooker) {
|
|
20508
|
-
|
|
20509
|
-
adultPax.
|
|
21116
|
+
// Without the main booker block (Tide configures main-booker fields), keep the traveler's own details.
|
|
21117
|
+
adultPax.mobilePhone = formValues?.phone || adultPax.mobilePhone;
|
|
21118
|
+
adultPax.email = formValues?.email || adultPax.email;
|
|
20510
21119
|
}
|
|
20511
21120
|
pax.push(adultPax);
|
|
20512
21121
|
}));
|
|
@@ -20530,8 +21139,8 @@ const selectBookingAddress = createSelector(selectTravelersFormValues, selectBoo
|
|
|
20530
21139
|
postalCode: mainBookerAddress?.postalCode || formValues?.zipCode,
|
|
20531
21140
|
location: mainBookerAddress?.location || formValues?.place,
|
|
20532
21141
|
country: mainBookerAddress?.country || formValues?.country,
|
|
20533
|
-
mobilePhone:
|
|
20534
|
-
email:
|
|
21142
|
+
mobilePhone: mainBooker.mobilePhone,
|
|
21143
|
+
email: mainBooker.email
|
|
20535
21144
|
};
|
|
20536
21145
|
});
|
|
20537
21146
|
const selectSubFormAnswers = (state) => state.booking.subFormAnswers;
|
|
@@ -25668,6 +26277,10 @@ const Summary = () => {
|
|
|
25668
26277
|
React__default.createElement("button", { title: settings.isOffer ? translations.STEPS.SUBMIT_OFFER : translations.STEPS.SUBMIT_BOOKING, className: buildClassName(['cta', !userValidated && 'cta--disabled']), disabled: !userValidated, name: "default" }, settings.isOffer ? translations.STEPS.SUBMIT_OFFER : translations.STEPS.SUBMIT_BOOKING))))));
|
|
25669
26278
|
};
|
|
25670
26279
|
|
|
26280
|
+
// lodash isEmpty is true for every number, which would flag a filled-in preferredLanguageId as missing.
|
|
26281
|
+
function isBlank(value) {
|
|
26282
|
+
return value === null || value === undefined || (typeof value === 'string' && value.trim() === '');
|
|
26283
|
+
}
|
|
25671
26284
|
function isValidEmail(email) {
|
|
25672
26285
|
return !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,24}$/i.test(email);
|
|
25673
26286
|
}
|
|
@@ -25691,9 +26304,14 @@ function getAge(birthDateText, startDateText) {
|
|
|
25691
26304
|
}
|
|
25692
26305
|
const validateForm = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE, maxBabyAge = BABY_MAX_AGE, paxFields = []) => {
|
|
25693
26306
|
const errors = {};
|
|
26307
|
+
const usesFieldConfiguration = hasConfiguredBuiltInPaxFields(paxFields);
|
|
26308
|
+
const builtInFieldMeta = getBuiltInFieldControlMeta(translations);
|
|
25694
26309
|
const isFormFieldPresent = (type) => {
|
|
25695
26310
|
return formFields?.some((f) => f.type === type) ?? true;
|
|
25696
26311
|
};
|
|
26312
|
+
// The 4 core fields: with a Tide field configuration they're required only when configured so for the
|
|
26313
|
+
// traveler's role (main booker / other pax); without one, whenever formFields lists them (legacy behavior).
|
|
26314
|
+
const isCoreFieldRequired = (traveler, legacyType, fieldName = legacyType) => usesFieldConfiguration ? !!getBuiltInPaxField(paxFields, fieldName, traveler.id === values.mainBookerId)?.isRequired : isFormFieldPresent(legacyType);
|
|
25697
26315
|
const isMainBookerFormFieldPresent = (type) => {
|
|
25698
26316
|
return mainBookerFormFields?.some((f) => f.type === type) ?? true;
|
|
25699
26317
|
};
|
|
@@ -25745,16 +26363,16 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25745
26363
|
const fieldPath = BUILT_IN_FIELD_PATHS[field.fieldName];
|
|
25746
26364
|
if (!fieldPath)
|
|
25747
26365
|
return;
|
|
25748
|
-
if (
|
|
25749
|
-
set(errors, `${path}.${fieldPath}`, formatTravelerField(room, pax, field.fieldName));
|
|
26366
|
+
if (isBlank(get(traveler, fieldPath))) {
|
|
26367
|
+
set(errors, `${path}.${fieldPath}`, formatTravelerField(room, pax, builtInFieldMeta[field.fieldName]?.label ?? field.fieldName));
|
|
25750
26368
|
}
|
|
25751
26369
|
});
|
|
25752
26370
|
};
|
|
25753
26371
|
values.rooms.forEach((r, rIndex) => r.adults.forEach((adult, index) => {
|
|
25754
|
-
if (isEmpty$1(adult.gender) &&
|
|
26372
|
+
if (isEmpty$1(adult.gender) && isCoreFieldRequired(adult, 'gender')) {
|
|
25755
26373
|
set(errors, `rooms[${rIndex}].adults[${index}].gender`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.GENDER));
|
|
25756
26374
|
}
|
|
25757
|
-
if (
|
|
26375
|
+
if (isCoreFieldRequired(adult, 'firstName') || !isEmpty$1(adult.firstName)) {
|
|
25758
26376
|
if (isEmpty$1(adult.firstName)) {
|
|
25759
26377
|
set(errors, `rooms[${rIndex}].adults[${index}].firstName`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25760
26378
|
}
|
|
@@ -25762,7 +26380,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25762
26380
|
set(errors, `rooms[${rIndex}].adults[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25763
26381
|
}
|
|
25764
26382
|
}
|
|
25765
|
-
if (
|
|
26383
|
+
if (isCoreFieldRequired(adult, 'lastName') || !isEmpty$1(adult.lastName)) {
|
|
25766
26384
|
if (isEmpty$1(adult.lastName)) {
|
|
25767
26385
|
set(errors, `rooms[${rIndex}].adults[${index}].lastName`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25768
26386
|
}
|
|
@@ -25770,7 +26388,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25770
26388
|
set(errors, `rooms[${rIndex}].adults[${index}].lastName`, formatTravelerFieldInvalidCharacters(rIndex + 1, index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25771
26389
|
}
|
|
25772
26390
|
}
|
|
25773
|
-
if (
|
|
26391
|
+
if (isCoreFieldRequired(adult, 'birthDate', 'dateOfBirth') || !isEmpty$1(adult.birthDate)) {
|
|
25774
26392
|
if (isEmpty$1(adult.birthDate) || !isValidBirthDate(adult.birthDate)) {
|
|
25775
26393
|
set(errors, `rooms[${rIndex}].adults[${index}].birthDate`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
|
|
25776
26394
|
}
|
|
@@ -25786,10 +26404,10 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25786
26404
|
validateRequiredBuiltInFields(adult, `rooms[${rIndex}].adults[${index}]`, rIndex + 1, index + 1);
|
|
25787
26405
|
}));
|
|
25788
26406
|
values.rooms.forEach((r, rIndex) => r.children.forEach((child, index) => {
|
|
25789
|
-
if (isEmpty$1(child.gender) &&
|
|
26407
|
+
if (isEmpty$1(child.gender) && isCoreFieldRequired(child, 'gender')) {
|
|
25790
26408
|
set(errors, `rooms[${rIndex}].children[${index}].gender`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.GENDER));
|
|
25791
26409
|
}
|
|
25792
|
-
if (
|
|
26410
|
+
if (isCoreFieldRequired(child, 'firstName') || !isEmpty$1(child.firstName)) {
|
|
25793
26411
|
if (isEmpty$1(child.firstName)) {
|
|
25794
26412
|
set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25795
26413
|
}
|
|
@@ -25797,7 +26415,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25797
26415
|
set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25798
26416
|
}
|
|
25799
26417
|
}
|
|
25800
|
-
if (
|
|
26418
|
+
if (isCoreFieldRequired(child, 'lastName') || !isEmpty$1(child.lastName)) {
|
|
25801
26419
|
if (isEmpty$1(child.lastName)) {
|
|
25802
26420
|
set(errors, `rooms[${rIndex}].children[${index}].lastName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25803
26421
|
}
|
|
@@ -25805,7 +26423,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25805
26423
|
set(errors, `rooms[${rIndex}].children[${index}].lastName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25806
26424
|
}
|
|
25807
26425
|
}
|
|
25808
|
-
if (
|
|
26426
|
+
if (isCoreFieldRequired(child, 'birthDate', 'dateOfBirth') || !isEmpty$1(child.birthDate)) {
|
|
25809
26427
|
if (isEmpty$1(child.birthDate) || !isValidBirthDate(child.birthDate)) {
|
|
25810
26428
|
set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
|
|
25811
26429
|
}
|
|
@@ -25831,7 +26449,8 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25831
26449
|
if (values.mainBookerId < 0) {
|
|
25832
26450
|
errors.mainBookerId = translations.TRAVELERS_FORM.VALIDATION.NO_MAIN_BOOKER_SELECTED;
|
|
25833
26451
|
}
|
|
25834
|
-
if (
|
|
26452
|
+
if (hasConfiguredMainBookerFields(paxFields)) ;
|
|
26453
|
+
else if (bookingType != 'b2b' || mainBookerFormFields?.length) {
|
|
25835
26454
|
if (isEmpty$1(values.street) && isMainBookerFormFieldPresent('street')) {
|
|
25836
26455
|
errors.street = format$1(translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD, [translations.TRAVELERS_FORM.STREET]);
|
|
25837
26456
|
}
|
|
@@ -26526,7 +27145,7 @@ const LanguageSwitcher = ({ value = 'EN', languages = DEFAULT_LANGUAGES, onChang
|
|
|
26526
27145
|
React__default.createElement("span", { className: "nav__subnav__languages__option__label" }, l.label)))))));
|
|
26527
27146
|
};
|
|
26528
27147
|
|
|
26529
|
-
const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, languages, onLanguageChange, onSearch, member, onLogin, onLogout }) => {
|
|
27148
|
+
const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, languages, onLanguageChange, onSearch, member, onLogin, onLogout, onMyBookings }) => {
|
|
26530
27149
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
26531
27150
|
const [query, setQuery] = useState('');
|
|
26532
27151
|
const [activeMobileGroup, setActiveMobileGroup] = useState();
|
|
@@ -26620,6 +27239,12 @@ const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, lan
|
|
|
26620
27239
|
onLogout();
|
|
26621
27240
|
}
|
|
26622
27241
|
};
|
|
27242
|
+
const handleMyBookings = (event) => {
|
|
27243
|
+
event.preventDefault();
|
|
27244
|
+
if (onMyBookings) {
|
|
27245
|
+
onMyBookings();
|
|
27246
|
+
}
|
|
27247
|
+
};
|
|
26623
27248
|
const handleLogin = (event) => {
|
|
26624
27249
|
event.preventDefault();
|
|
26625
27250
|
if (onLogin) {
|
|
@@ -26633,7 +27258,9 @@ const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, lan
|
|
|
26633
27258
|
member && (React__default.createElement("span", { className: "nav__subnav__member" },
|
|
26634
27259
|
translations.LOGIN.WELCOME_X,
|
|
26635
27260
|
member.name)),
|
|
26636
|
-
member ? (React__default.createElement(React__default.Fragment, null,
|
|
27261
|
+
member ? (React__default.createElement(React__default.Fragment, null,
|
|
27262
|
+
onMyBookings && (React__default.createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleMyBookings }, translations.AGENT_ENTRIES.MY_BOOKINGS)),
|
|
27263
|
+
onLogout && (React__default.createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleLogout }, translations.LOGIN.LOGOUT)))) : (React__default.createElement(React__default.Fragment, null, onLogin && (React__default.createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleLogin }, translations.LOGIN.LOGIN)))),
|
|
26637
27264
|
React__default.createElement(LanguageSwitcher, { value: language.code, languages: languages, onChange: (lang) => {
|
|
26638
27265
|
console.log('Selected language:', lang);
|
|
26639
27266
|
onLanguageChange(lang);
|
|
@@ -28602,6 +29229,7 @@ const initialState$1 = {
|
|
|
28602
29229
|
bookingNumber: undefined,
|
|
28603
29230
|
trajectNodeAvailability: {},
|
|
28604
29231
|
trajectFlightAvailability: {},
|
|
29232
|
+
trajectTransferAvailability: {},
|
|
28605
29233
|
trajectDaySuggestions: {},
|
|
28606
29234
|
trajectEditLineGuid: null,
|
|
28607
29235
|
trajectActivitiesDayOrder: null,
|
|
@@ -28814,6 +29442,12 @@ const searchResultsSlice = createSlice({
|
|
|
28814
29442
|
node.selectedCode = code;
|
|
28815
29443
|
node.status = 'resolved';
|
|
28816
29444
|
},
|
|
29445
|
+
clearTrajectNodeSelection(state, action) {
|
|
29446
|
+
const node = state.trajectNodeAvailability[action.payload];
|
|
29447
|
+
if (!node)
|
|
29448
|
+
return;
|
|
29449
|
+
node.selectedCode = null;
|
|
29450
|
+
},
|
|
28817
29451
|
updateEditableEntryLine(state, action) {
|
|
28818
29452
|
if (!state.editablePackagingEntry)
|
|
28819
29453
|
return;
|
|
@@ -28827,6 +29461,32 @@ const searchResultsSlice = createSlice({
|
|
|
28827
29461
|
return;
|
|
28828
29462
|
state.editablePackagingEntry.lines = [...(state.editablePackagingEntry.lines ?? []), ...action.payload];
|
|
28829
29463
|
},
|
|
29464
|
+
upsertEditableEntryLines(state, action) {
|
|
29465
|
+
if (!state.editablePackagingEntry)
|
|
29466
|
+
return;
|
|
29467
|
+
const lines = [...(state.editablePackagingEntry.lines ?? [])];
|
|
29468
|
+
action.payload.forEach((line) => {
|
|
29469
|
+
const index = lines.findIndex((x) => x.guid === line.guid);
|
|
29470
|
+
if (index === -1)
|
|
29471
|
+
lines.push(line);
|
|
29472
|
+
else
|
|
29473
|
+
lines[index] = line;
|
|
29474
|
+
});
|
|
29475
|
+
state.editablePackagingEntry.lines = lines;
|
|
29476
|
+
const restored = new Set(action.payload.map((line) => line.trajectNodeId).filter((x) => x != null));
|
|
29477
|
+
if (restored.size && state.editablePackagingEntry.removedTrajectNodeIds?.length) {
|
|
29478
|
+
state.editablePackagingEntry.removedTrajectNodeIds = state.editablePackagingEntry.removedTrajectNodeIds.filter((x) => !restored.has(x));
|
|
29479
|
+
}
|
|
29480
|
+
},
|
|
29481
|
+
removeTrajectNode(state, action) {
|
|
29482
|
+
if (!state.editablePackagingEntry)
|
|
29483
|
+
return;
|
|
29484
|
+
const guids = new Set(action.payload.lineGuids);
|
|
29485
|
+
state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
|
|
29486
|
+
const removed = state.editablePackagingEntry.removedTrajectNodeIds ?? [];
|
|
29487
|
+
if (!removed.includes(action.payload.nodeId))
|
|
29488
|
+
state.editablePackagingEntry.removedTrajectNodeIds = [...removed, action.payload.nodeId];
|
|
29489
|
+
},
|
|
28830
29490
|
removeEditableEntryLines(state, action) {
|
|
28831
29491
|
if (!state.editablePackagingEntry)
|
|
28832
29492
|
return;
|
|
@@ -28858,6 +29518,19 @@ const searchResultsSlice = createSlice({
|
|
|
28858
29518
|
flight.selectedGuid = action.payload.guid;
|
|
28859
29519
|
flight.status = 'resolved';
|
|
28860
29520
|
},
|
|
29521
|
+
clearTrajectFlightSelection(state, action) {
|
|
29522
|
+
const flight = state.trajectFlightAvailability[action.payload];
|
|
29523
|
+
if (!flight)
|
|
29524
|
+
return;
|
|
29525
|
+
flight.selectedGuid = null;
|
|
29526
|
+
},
|
|
29527
|
+
setTrajectTransferLoading(state, action) {
|
|
29528
|
+
state.trajectTransferAvailability[action.payload] = { nodeId: action.payload, status: 'loading', result: null };
|
|
29529
|
+
},
|
|
29530
|
+
setTrajectTransferAvailability(state, action) {
|
|
29531
|
+
const { nodeId, result } = action.payload;
|
|
29532
|
+
state.trajectTransferAvailability[nodeId] = { nodeId, status: result ? 'resolved' : 'unavailable', result };
|
|
29533
|
+
},
|
|
28861
29534
|
setTrajectDaySuggestionsLoading(state, action) {
|
|
28862
29535
|
const dayOrder = action.payload;
|
|
28863
29536
|
state.trajectDaySuggestions[dayOrder] = {
|
|
@@ -28894,6 +29567,7 @@ const searchResultsSlice = createSlice({
|
|
|
28894
29567
|
resetTrajectAvailability(state) {
|
|
28895
29568
|
state.trajectNodeAvailability = {};
|
|
28896
29569
|
state.trajectFlightAvailability = {};
|
|
29570
|
+
state.trajectTransferAvailability = {};
|
|
28897
29571
|
state.trajectDaySuggestions = {};
|
|
28898
29572
|
state.trajectEditLineGuid = null;
|
|
28899
29573
|
state.trajectActivitiesDayOrder = null;
|
|
@@ -28902,7 +29576,7 @@ const searchResultsSlice = createSlice({
|
|
|
28902
29576
|
}
|
|
28903
29577
|
}
|
|
28904
29578
|
});
|
|
28905
|
-
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, setTrajectResolving, setTrajectItineraryView, setTrajectFlightLoading, setTrajectFlightAvailability, setTrajectFlightSelection, setTrajectEditLineGuid, setTrajectActivitiesDayOrder, setTrajectDaySuggestionsLoading, setTrajectDaySuggestions, addEditableEntryLines, updateTrajectNodeResult, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
|
|
29579
|
+
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, clearTrajectNodeSelection, setTrajectResolving, setTrajectItineraryView, setTrajectFlightLoading, setTrajectFlightAvailability, setTrajectFlightSelection, clearTrajectFlightSelection, setTrajectTransferLoading, setTrajectTransferAvailability, setTrajectEditLineGuid, setTrajectActivitiesDayOrder, setTrajectDaySuggestionsLoading, setTrajectDaySuggestions, addEditableEntryLines, upsertEditableEntryLines, removeTrajectNode, updateTrajectNodeResult, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
|
|
28906
29580
|
var searchResultsReducer = searchResultsSlice.reducer;
|
|
28907
29581
|
|
|
28908
29582
|
const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
|
|
@@ -29117,7 +29791,7 @@ const numberOfNights = (segment) => {
|
|
|
29117
29791
|
const CHARTER_SERVICE_TYPE = 10;
|
|
29118
29792
|
const CRUISE_SERVICE_TYPE = 11;
|
|
29119
29793
|
const FERRY_SERVICE_TYPE = 12;
|
|
29120
|
-
const TRANSFER_SERVICE_TYPE = 13;
|
|
29794
|
+
const TRANSFER_SERVICE_TYPE$1 = 13;
|
|
29121
29795
|
const BUS_SERVICE_TYPE = 14;
|
|
29122
29796
|
const CAR_SERVICE_TYPE = 17;
|
|
29123
29797
|
const CAMPER_SERVICE_TYPE = 18;
|
|
@@ -29149,7 +29823,7 @@ const getServiceTypeIcon = (serviceType) => {
|
|
|
29149
29823
|
return 'ui-bus';
|
|
29150
29824
|
case TRAIN_SERVICE_TYPE:
|
|
29151
29825
|
return 'ui-train';
|
|
29152
|
-
case TRANSFER_SERVICE_TYPE:
|
|
29826
|
+
case TRANSFER_SERVICE_TYPE$1:
|
|
29153
29827
|
return 'ui-transfer';
|
|
29154
29828
|
case EVENT_SERVICE_TYPE:
|
|
29155
29829
|
return 'ui-ticket';
|
|
@@ -29285,6 +29959,81 @@ const getTrajectNodesWithLines = (trajectEntry) => {
|
|
|
29285
29959
|
})
|
|
29286
29960
|
.filter((x) => !!x.line);
|
|
29287
29961
|
};
|
|
29962
|
+
// Qite.Offer.Enums.ServiceType.Transfer: a traject's connecting node is booked as one.
|
|
29963
|
+
const TRANSFER_SERVICE_TYPE = 13;
|
|
29964
|
+
// Qite.Offer.Enums.RequirementType. A Mandatory (0) stop, and one RequiredInGroup (3) — one of the node's
|
|
29965
|
+
// alternatives has to be booked — always keep a selection; only these two may be taken off the trip.
|
|
29966
|
+
const OPTIONAL_REQUIREMENT_TYPE = 1;
|
|
29967
|
+
const OPTIONAL_IN_GROUP_REQUIREMENT_TYPE = 2;
|
|
29968
|
+
const canRemoveTrajectNode = (node) => node.requirementType === OPTIONAL_REQUIREMENT_TYPE || node.requirementType === OPTIONAL_IN_GROUP_REQUIREMENT_TYPE;
|
|
29969
|
+
const getDroppedTrajectNodeIds = (trajectEntry, entry) => {
|
|
29970
|
+
const dropped = new Set();
|
|
29971
|
+
if (!entry || !!trajectEntry.entry.magicLink)
|
|
29972
|
+
return dropped;
|
|
29973
|
+
const removed = new Set(entry.removedTrajectNodeIds ?? []);
|
|
29974
|
+
if (!removed.size)
|
|
29975
|
+
return dropped;
|
|
29976
|
+
const byDay = new Map();
|
|
29977
|
+
[...(trajectEntry.nodes ?? [])]
|
|
29978
|
+
.sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
|
|
29979
|
+
.forEach((node) => byDay.set(node.dayOrder, [...(byDay.get(node.dayOrder) ?? []), node]));
|
|
29980
|
+
byDay.forEach((nodes) => nodes.forEach((node, index) => {
|
|
29981
|
+
if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE || !canRemoveTrajectNode(node) || !removed.has(node.nodeId))
|
|
29982
|
+
return;
|
|
29983
|
+
dropped.add(node.nodeId);
|
|
29984
|
+
[nodes[index - 1], nodes[index + 1]]
|
|
29985
|
+
.filter((x) => !!x && x.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE)
|
|
29986
|
+
.forEach((x) => dropped.add(x.nodeId));
|
|
29987
|
+
}));
|
|
29988
|
+
return dropped;
|
|
29989
|
+
};
|
|
29990
|
+
const isTrajectTransferNode = (node) => node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE && !!node.pickUp && !!node.dropOff;
|
|
29991
|
+
const buildTrajectTransferRequest = (node, context) => ({
|
|
29992
|
+
transactionId: context.transactionId,
|
|
29993
|
+
officeId: context.officeId,
|
|
29994
|
+
agentId: context.agentId ?? null,
|
|
29995
|
+
catalogueId: context.catalogueId,
|
|
29996
|
+
searchConfigurationId: context.searchConfigurationId,
|
|
29997
|
+
language: context.language,
|
|
29998
|
+
date: node.from,
|
|
29999
|
+
pickUp: node.pickUp,
|
|
30000
|
+
dropOff: node.dropOff,
|
|
30001
|
+
travellers: context.rooms.flatMap((room) => room.travellers)
|
|
30002
|
+
});
|
|
30003
|
+
const buildTrajectTransferLine = (node, result) => {
|
|
30004
|
+
const option = result.rooms?.[0]?.options?.find((x) => x.isSelected) ?? result.rooms?.[0]?.options?.[0];
|
|
30005
|
+
if (!option?.guid)
|
|
30006
|
+
return null;
|
|
30007
|
+
return {
|
|
30008
|
+
guid: option.guid,
|
|
30009
|
+
parentGuid: null,
|
|
30010
|
+
order: 0,
|
|
30011
|
+
trajectNodeId: node.nodeId,
|
|
30012
|
+
isChanged: true,
|
|
30013
|
+
from: result.fromDate ?? node.from,
|
|
30014
|
+
to: result.toDate ?? node.to,
|
|
30015
|
+
moment: node.moment ?? '',
|
|
30016
|
+
serviceType: TRANSFER_SERVICE_TYPE,
|
|
30017
|
+
productName: result.name,
|
|
30018
|
+
productCode: result.code,
|
|
30019
|
+
accommodationName: option.accommodationName,
|
|
30020
|
+
accommodationCode: option.accommodationCode,
|
|
30021
|
+
regimeName: option.regimeName,
|
|
30022
|
+
regimeCode: option.regimeCode,
|
|
30023
|
+
vendor: result.vendorType ?? null,
|
|
30024
|
+
externalVendorId: result.vendorId ?? null,
|
|
30025
|
+
groupKey: '',
|
|
30026
|
+
isActive: true,
|
|
30027
|
+
country: result.countryId ? { id: result.countryId, name: result.countryName, localizations: [] } : null,
|
|
30028
|
+
region: result.regionId ? { id: result.regionId, name: result.regionName, localizations: [] } : null,
|
|
30029
|
+
oord: result.oordId ? { id: result.oordId, name: result.oordName, localizations: [] } : null,
|
|
30030
|
+
location: result.locationId ? { id: result.locationId, name: result.locationName, localizations: [] } : null,
|
|
30031
|
+
longitude: result.longitude ?? null,
|
|
30032
|
+
latitude: result.latitude ?? null,
|
|
30033
|
+
pax: (option.paxIds ?? []).map((paxId, paxIndex) => ({ paxId, room: 0, order: paxIndex })),
|
|
30034
|
+
flightInformation: null
|
|
30035
|
+
};
|
|
30036
|
+
};
|
|
29288
30037
|
const getCoordinates = (line, node, result) => {
|
|
29289
30038
|
const sources = [
|
|
29290
30039
|
...(result ? [result] : []),
|
|
@@ -29712,9 +30461,15 @@ const nightsOf = (node, line) => differenceInCalendarDays(new Date(line?.to ?? n
|
|
|
29712
30461
|
const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
29713
30462
|
const timeline = useMemo(() => {
|
|
29714
30463
|
const linesByGuid = new Map((packagingEntry.lines ?? []).map((line) => [line.guid, line]));
|
|
30464
|
+
const dropped = getDroppedTrajectNodeIds(trajectEntry, packagingEntry);
|
|
29715
30465
|
const nodes = [...(trajectEntry.nodes ?? [])]
|
|
30466
|
+
.filter((node) => !dropped.has(node.nodeId))
|
|
29716
30467
|
.sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
|
|
29717
30468
|
.map((node) => {
|
|
30469
|
+
// A connecting node has no line of its own; the transfer found for it carries its node id.
|
|
30470
|
+
if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) {
|
|
30471
|
+
return { node, lines: (packagingEntry.lines ?? []).filter((line) => line.trajectNodeId === node.nodeId) };
|
|
30472
|
+
}
|
|
29718
30473
|
const guids = node.lineGuids?.length ? node.lineGuids : [node.lineGuid];
|
|
29719
30474
|
const lines = guids.map((guid) => linesByGuid.get(guid)).filter((x) => !!x);
|
|
29720
30475
|
const groupKey = lines.length ? getLineGroupKey(lines[0]) : '';
|
|
@@ -29784,10 +30539,11 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
|
29784
30539
|
React__default.createElement("p", { className: "search__filter__itinerary__transport-date-date" },
|
|
29785
30540
|
React__default.createElement("strong", null, format$2(new Date(value), 'd'))),
|
|
29786
30541
|
React__default.createElement("p", null, format$2(new Date(value), 'MMM'))));
|
|
29787
|
-
const renderConnectingNode = ({ node }) => {
|
|
30542
|
+
const renderConnectingNode = ({ node, lines }) => {
|
|
29788
30543
|
const distance = node.distanceInKm ? `${Math.round(node.distanceInKm)} km` : '';
|
|
29789
30544
|
// How long the hop takes and how far it is, the way the traject editor puts them.
|
|
29790
30545
|
const journey = [getTrajectNodeDuration(node), distance].filter(Boolean).join(' · ');
|
|
30546
|
+
const title = lines[0]?.productName || node.name;
|
|
29791
30547
|
return (React__default.createElement("div", { className: "search__filter__itinerary__transport", key: `connect-${node.nodeId}` },
|
|
29792
30548
|
React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline" },
|
|
29793
30549
|
React__default.createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
|
|
@@ -29796,8 +30552,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
|
29796
30552
|
React__default.createElement("div", { className: badgeClass('transport', getTrajectNodeBadgeModifier(node)) },
|
|
29797
30553
|
React__default.createElement(Icon, { name: getTrajectNodeIcon(node), height: 15 })),
|
|
29798
30554
|
React__default.createElement("div", { className: "search__filter__itinerary__transport-details" },
|
|
29799
|
-
React__default.createElement("h6", null,
|
|
29800
|
-
!!
|
|
30555
|
+
React__default.createElement("h6", null, title || journey),
|
|
30556
|
+
!!title && !!journey && React__default.createElement("p", { className: "search__filter__itinerary__transport-details-time" }, journey)))));
|
|
29801
30557
|
};
|
|
29802
30558
|
const renderOvernight = (item, index) => {
|
|
29803
30559
|
const { dayOrder } = item.node;
|
|
@@ -33048,7 +33804,7 @@ const TrajectResultsFlyIn = ({ isLoading }) => {
|
|
|
33048
33804
|
if (!result)
|
|
33049
33805
|
return;
|
|
33050
33806
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
|
|
33051
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
33807
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
33052
33808
|
dispatch(setTrajectEditLineGuid(null));
|
|
33053
33809
|
dispatch(setFlyInIsOpen(false));
|
|
33054
33810
|
};
|
|
@@ -33093,7 +33849,7 @@ const TrajectFlightsFlyIn = ({ isLoading }) => {
|
|
|
33093
33849
|
if (!flight)
|
|
33094
33850
|
return;
|
|
33095
33851
|
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
33096
|
-
dispatch(
|
|
33852
|
+
dispatch(upsertEditableEntryLines([applyFlightToLine(item.line, flight)]));
|
|
33097
33853
|
dispatch(setTrajectEditLineGuid(null));
|
|
33098
33854
|
dispatch(setFlyInIsOpen(false));
|
|
33099
33855
|
};
|
|
@@ -33156,10 +33912,16 @@ const TrajectDayActivitiesFlyIn = ({ isLoading }) => {
|
|
|
33156
33912
|
if (!item)
|
|
33157
33913
|
return;
|
|
33158
33914
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code: result.code }));
|
|
33159
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
33915
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
33160
33916
|
dispatch(setTrajectActivitiesDayOrder(null));
|
|
33161
33917
|
dispatch(setFlyInIsOpen(false));
|
|
33162
33918
|
};
|
|
33919
|
+
const handleRemove = ({ item }) => {
|
|
33920
|
+
if (!item)
|
|
33921
|
+
return;
|
|
33922
|
+
dispatch(clearTrajectNodeSelection(item.line.guid));
|
|
33923
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
33924
|
+
};
|
|
33163
33925
|
if (isLoading || suggestions?.status === 'loading') {
|
|
33164
33926
|
return React__default.createElement(React__default.Fragment, null, context.customSpinner ?? React__default.createElement(Spinner, { label: translations.SRP.LOADING_ACTIVITIES }));
|
|
33165
33927
|
}
|
|
@@ -33173,7 +33935,8 @@ const TrajectDayActivitiesFlyIn = ({ isLoading }) => {
|
|
|
33173
33935
|
const { result, item } = card;
|
|
33174
33936
|
const isSelected = item ? trajectNodeAvailability[item.line.guid]?.selectedCode === result.code : getAddedLines(result).length > 0;
|
|
33175
33937
|
const isBookedCard = !!item && bookedMode && matchesCode(result, item.node.code ?? '');
|
|
33176
|
-
|
|
33938
|
+
const canRemove = !!item && isSelected && !bookedMode && canRemoveTrajectNode(item.node);
|
|
33939
|
+
return (React__default.createElement(TrajectNodeCard, { key: `activity-${result.code}`, node: item?.node, result: result, isSelected: isSelected, languageCode: context.languageCode, translations: translations, onSelect: () => (!item ? handleToggle(result) : canRemove ? handleRemove(card) : handleSelect(card)), selectLabel: item ? undefined : translations.SRP.ADD, selectedLabel: item && !canRemove ? (isBookedCard ? translations.SHARED.BOOKED : undefined) : translations.SRP.REMOVE }));
|
|
33177
33940
|
})))));
|
|
33178
33941
|
};
|
|
33179
33942
|
|
|
@@ -35567,16 +36330,18 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
|
|
|
35567
36330
|
apiKey: context.tideConnection.apiKey
|
|
35568
36331
|
};
|
|
35569
36332
|
}, [context]);
|
|
36333
|
+
// The field configuration on the entry is leading for which traveler fields are shown and required.
|
|
36334
|
+
const paxFields = editablePackagingEntry?.paxFields ?? [];
|
|
35570
36335
|
const initialValues = useMemo(() => {
|
|
35571
36336
|
if (!editablePackagingEntry) {
|
|
35572
36337
|
return {};
|
|
35573
36338
|
}
|
|
35574
|
-
return createInitialValuesFromEditablePackagingEntry(editablePackagingEntry);
|
|
36339
|
+
return createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, undefined, paxFields);
|
|
35575
36340
|
}, [editablePackagingEntry?.transactionId]);
|
|
35576
36341
|
const formik = useFormik({
|
|
35577
36342
|
initialValues,
|
|
35578
36343
|
enableReinitialize: true,
|
|
35579
|
-
validate: (values) => validateForm(values, false, 'b2c', translations, travellersSettings.formFields, travellersSettings.mainBookerFormFields, undefined, undefined,
|
|
36344
|
+
validate: (values) => validateForm(values, false, 'b2c', translations, travellersSettings.formFields, travellersSettings.mainBookerFormFields, undefined, undefined, paxFields),
|
|
35580
36345
|
onSubmit: (values) => {
|
|
35581
36346
|
if (!editablePackagingEntry)
|
|
35582
36347
|
return;
|
|
@@ -35661,7 +36426,7 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
|
|
|
35661
36426
|
".\u00A0",
|
|
35662
36427
|
stepLabels[step])) },
|
|
35663
36428
|
isConfirmationPage && isLoading && React__default.createElement(Spinner, { label: translations.SUMMARY.PROCESS_BOOKING }),
|
|
35664
|
-
currentStep === 0 && (React__default.createElement(SharedTravelersForm, { formik: formik, translations: translations, travellersSettings: travellersSettings, countries: countries, travelersFirstStep: false, isUnavailable: false, useCompactForm: false, showAgentSelection: false, paxFields:
|
|
36429
|
+
currentStep === 0 && (React__default.createElement(SharedTravelersForm, { formik: formik, translations: translations, travellersSettings: travellersSettings, countries: countries, travelersFirstStep: false, isUnavailable: false, useCompactForm: false, showAgentSelection: false, paxFields: paxFields })),
|
|
35665
36430
|
currentStep === 1 && (React__default.createElement(SharedSummary, { translations: translations, travelerFormValues: formik.values, isSubmitting: isSubmitting, skipPayment: !context.generatePaymentUrl, userValidated: userValidated, remarks: remarks, enableVoucher: false, allowOption: false, isOffer: false, onUserValidatedChange: setUserValidated, onRemarksChange: setRemarks, onSubmit: handleSummarySubmit, renderOptions: () => renderEditablePackagingEntrySummaryOptions(editablePackagingEntry, priceDetails, translations, selectedPackagingAccoResult?.currencyCode), renderPreviousButton: () => (React__default.createElement("button", { type: "button", title: translations.STEPS.PREVIOUS, onClick: () => dispatch(setCurrentStep(0)), className: "cta cta--secondary" }, translations.STEPS.PREVIOUS)) })),
|
|
35666
36431
|
currentStep === 2 && (React__default.createElement(SharedConfirmation, { bookingNumber: bookingNumber ?? editablePackagingEntry?.dossierNumber ?? '', isOption: false, isOffer: false, translations: translations.CONFIRMATION })),
|
|
35667
36432
|
currentStep === 3 && React__default.createElement("div", null))),
|
|
@@ -35761,11 +36526,13 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35761
36526
|
});
|
|
35762
36527
|
return map;
|
|
35763
36528
|
}, [trajectEntry]);
|
|
36529
|
+
const droppedNodeIds = trajectEntry ? getDroppedTrajectNodeIds(trajectEntry, editablePackagingEntry) : new Set();
|
|
36530
|
+
const droppedKey = [...droppedNodeIds].sort((a, b) => a - b).join(',');
|
|
35764
36531
|
const { stayByDay, stayStartByNodeId } = useMemo(() => {
|
|
35765
36532
|
const byDay = new Map();
|
|
35766
36533
|
const byNodeId = new Map();
|
|
35767
36534
|
nodesWithLines
|
|
35768
|
-
.filter((x) => x.node.serviceType === ACCOMMODATION_SERVICE_TYPE)
|
|
36535
|
+
.filter((x) => x.node.serviceType === ACCOMMODATION_SERVICE_TYPE && !droppedNodeIds.has(x.node.nodeId))
|
|
35769
36536
|
.forEach((item) => {
|
|
35770
36537
|
const nights = Math.max(differenceInCalendarDays(new Date(item.line.to), new Date(item.line.from)), 1);
|
|
35771
36538
|
byNodeId.set(item.node.nodeId, { item, night: 0, nights });
|
|
@@ -35774,7 +36541,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35774
36541
|
}
|
|
35775
36542
|
});
|
|
35776
36543
|
return { stayByDay: byDay, stayStartByNodeId: byNodeId };
|
|
35777
|
-
}, [nodesWithLines]);
|
|
36544
|
+
}, [nodesWithLines, droppedKey]);
|
|
35778
36545
|
/** Whether every node of the trip has an answer, one way or the other. */
|
|
35779
36546
|
const tripResolved = useMemo(() => nodesWithLines
|
|
35780
36547
|
.filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node))
|
|
@@ -35801,7 +36568,20 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35801
36568
|
if (!result)
|
|
35802
36569
|
return;
|
|
35803
36570
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
|
|
35804
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
36571
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
36572
|
+
};
|
|
36573
|
+
/**
|
|
36574
|
+
* An optional stop can be taken off the trip; a mandatory one, or one of which the group needs a pick,
|
|
36575
|
+
* only swapped. A booked entry's services are never taken off here.
|
|
36576
|
+
*/
|
|
36577
|
+
const canRemove = (item) => !bookedMode && canRemoveTrajectNode(item.node);
|
|
36578
|
+
const handleRemoveNode = (item) => {
|
|
36579
|
+
dispatch(clearTrajectNodeSelection(item.line.guid));
|
|
36580
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
36581
|
+
};
|
|
36582
|
+
const handleRemoveFlight = (item) => {
|
|
36583
|
+
dispatch(clearTrajectFlightSelection(item.line.guid));
|
|
36584
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
35805
36585
|
};
|
|
35806
36586
|
/** The remaining legs for a flight node open in the fly-in, as the regular flight results do. */
|
|
35807
36587
|
const handleShowMoreFlights = (item) => {
|
|
@@ -35869,9 +36649,17 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35869
36649
|
// A hotel row holds the hotels configured on the node; a portal can also let it fill up with
|
|
35870
36650
|
// non-preferred hotels found in the area, the rest staying behind "show more".
|
|
35871
36651
|
const fill = showNonPreferredHotels && node.serviceType === ACCOMMODATION_SERVICE_TYPE ? others.slice(0, Math.max(MAX_HOTEL_RESULTS - 1 - configured.length, 0)) : [];
|
|
35872
|
-
const remaining = others.length - fill.length;
|
|
35873
36652
|
// No entry yet means the node's search has been queued but not dispatched — still loading.
|
|
35874
36653
|
const status = availability?.status ?? 'loading';
|
|
36654
|
+
// A stop taken off the trip keeps its results in view, to pick one back.
|
|
36655
|
+
const isRemoved = status === 'resolved' && !selected && results.length > 0;
|
|
36656
|
+
const removable = canRemove(item);
|
|
36657
|
+
const shown = selected
|
|
36658
|
+
? [selected, ...configured, ...fill]
|
|
36659
|
+
: configured.length || fill.length
|
|
36660
|
+
? [...configured, ...fill]
|
|
36661
|
+
: others.slice(0, MAX_HOTEL_RESULTS);
|
|
36662
|
+
const remaining = results.length - shown.length;
|
|
35875
36663
|
return (React__default.createElement(React__default.Fragment, { key: line.guid },
|
|
35876
36664
|
showHeader && (React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
35877
36665
|
React__default.createElement("div", { className: "search__results__label__date" },
|
|
@@ -35883,13 +36671,18 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35883
36671
|
React__default.createElement("strong", null, headerTitle || node.name))))),
|
|
35884
36672
|
status === 'loading' && React__default.createElement(Spinner, { label: translations.SRP.LOADING_ACCOMMODATIONS }),
|
|
35885
36673
|
status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
35886
|
-
status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
|
|
35887
|
-
availability.preferredUnavailable && node.preferredAccommodationName && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
36674
|
+
status === 'resolved' && (selected || isRemoved) && (React__default.createElement(React__default.Fragment, null,
|
|
36675
|
+
selected && availability.preferredUnavailable && node.preferredAccommodationName && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
35888
36676
|
React__default.createElement("span", null,
|
|
35889
36677
|
node.preferredAccommodationName,
|
|
35890
36678
|
" \u2014 ",
|
|
35891
36679
|
translations.SRP.NO_RESULTS))),
|
|
35892
|
-
React__default.createElement(TrajectCardRow, { selectionKey: selected
|
|
36680
|
+
React__default.createElement(TrajectCardRow, { selectionKey: selected?.code ?? '' }, shown.map((result) => {
|
|
36681
|
+
const isSelected = result.code === selected?.code;
|
|
36682
|
+
return (React__default.createElement(TrajectNodeCard, { key: result.code, node: node, result: result, isSelected: isSelected, languageCode: context.languageCode, translations: translations, onSelect: () => (isSelected && removable ? handleRemoveNode(item) : handleSelect(item, result.code)), onEditOptions: node.serviceType === ACCOMMODATION_SERVICE_TYPE ? () => handleEditOptions(item) : undefined, showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE,
|
|
36683
|
+
// selectedLabel={bookedMode && matchesCode(result, node.code ?? '') ? translations.SHARED.BOOKED : undefined}
|
|
36684
|
+
selectedLabel: removable ? translations.SRP.REMOVE : undefined }));
|
|
36685
|
+
})),
|
|
35893
36686
|
remaining > 0 && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
35894
36687
|
React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMore(item) },
|
|
35895
36688
|
translations.SRP.SHOW_MORE,
|
|
@@ -35899,7 +36692,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35899
36692
|
};
|
|
35900
36693
|
const handleSelectFlight = (item, flight) => {
|
|
35901
36694
|
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
35902
|
-
dispatch(
|
|
36695
|
+
dispatch(upsertEditableEntryLines([buildFlightSelectionLine(item, flight, bookedMode)]));
|
|
35903
36696
|
};
|
|
35904
36697
|
const renderFlightNode = (item) => {
|
|
35905
36698
|
const { node, line } = item;
|
|
@@ -35908,7 +36701,9 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35908
36701
|
const flights = availability?.results ?? [];
|
|
35909
36702
|
const selected = flights.find((x) => x.outwardGuid === availability?.selectedGuid) ?? null;
|
|
35910
36703
|
const others = flights.filter((x) => x.outwardGuid !== availability?.selectedGuid);
|
|
35911
|
-
const
|
|
36704
|
+
const isRemoved = status === 'resolved' && !selected && flights.length > 0;
|
|
36705
|
+
const removable = canRemove(item);
|
|
36706
|
+
const visible = others.slice(0, selected ? 2 : 3);
|
|
35912
36707
|
return (React__default.createElement(React__default.Fragment, { key: line.guid },
|
|
35913
36708
|
React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
35914
36709
|
React__default.createElement("div", { className: "search__results__label__date" },
|
|
@@ -35923,15 +36718,15 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35923
36718
|
node.arrivalAirportCode)))),
|
|
35924
36719
|
status === 'loading' && React__default.createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS }),
|
|
35925
36720
|
status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
35926
|
-
status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
|
|
36721
|
+
status === 'resolved' && (selected || isRemoved) && (React__default.createElement(React__default.Fragment, null,
|
|
35927
36722
|
React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
35928
|
-
React__default.createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price, selectedLabel: bookedMode && selected.outwardGuid === line.guid ? translations.SHARED.BOOKED : undefined }),
|
|
35929
|
-
visible.map((result) => (React__default.createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, isOutward: true, price: result.price, currentSelectedPrice: selected
|
|
35930
|
-
others.length >
|
|
36723
|
+
selected && (React__default.createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price, onSelect: removable ? () => handleRemoveFlight(item) : undefined, selectedLabel: bookedMode && selected.outwardGuid === line.guid ? translations.SHARED.BOOKED : removable ? translations.SRP.REMOVE : undefined })),
|
|
36724
|
+
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) })))),
|
|
36725
|
+
others.length > visible.length && !hideShowMoreResults && (React__default.createElement("div", { className: "search__results__cards__actions" },
|
|
35931
36726
|
React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreFlights(item) },
|
|
35932
36727
|
translations.SRP.SHOW_MORE,
|
|
35933
36728
|
" (",
|
|
35934
|
-
others.length -
|
|
36729
|
+
others.length - visible.length,
|
|
35935
36730
|
")")))))));
|
|
35936
36731
|
};
|
|
35937
36732
|
/** The lines a suggested activity put on the entry, which is also how we know it was added. */
|
|
@@ -36007,13 +36802,21 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
36007
36802
|
")")))));
|
|
36008
36803
|
};
|
|
36009
36804
|
/**
|
|
36010
|
-
* An activity the traject books is swapped for another, the way a hotel is
|
|
36011
|
-
* found for themselves is added to the trip or taken back off it.
|
|
36805
|
+
* An activity the traject books is swapped for another, the way a hotel is, or - when it is optional -
|
|
36806
|
+
* taken off the trip; one the traveller found for themselves is added to the trip or taken back off it.
|
|
36012
36807
|
*/
|
|
36013
36808
|
const renderActivityCard = ({ result, item }) => {
|
|
36014
36809
|
const isSelected = isActivitySelected({ result, item });
|
|
36015
36810
|
const isBookedCard = !!item && bookedMode && matchesCode(result, item.node.code ?? '');
|
|
36016
|
-
|
|
36811
|
+
const removable = !!item && canRemove(item);
|
|
36812
|
+
const handleClick = () => {
|
|
36813
|
+
if (!item)
|
|
36814
|
+
return handleToggleActivity(result);
|
|
36815
|
+
if (isSelected && removable)
|
|
36816
|
+
return handleRemoveNode(item);
|
|
36817
|
+
handleSelect(item, result.code);
|
|
36818
|
+
};
|
|
36819
|
+
return (React__default.createElement(TrajectNodeCard, { key: `activity-${result.code}`, node: item?.node, result: result, isSelected: isSelected, languageCode: context.languageCode, translations: translations, onSelect: handleClick, selectLabel: item ? undefined : translations.SRP.ADD, selectedLabel: item && !removable ? (isBookedCard ? translations.SHARED.BOOKED : undefined) : translations.SRP.REMOVE }));
|
|
36017
36820
|
};
|
|
36018
36821
|
if (isLoading)
|
|
36019
36822
|
return React__default.createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
|
|
@@ -36048,6 +36851,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
36048
36851
|
const useTrajectAvailability = () => {
|
|
36049
36852
|
const context = useContext(SearchResultsConfigurationContext);
|
|
36050
36853
|
const dispatch = useDispatch();
|
|
36854
|
+
const { editablePackagingEntry, trajectTransferAvailability } = useSelector((state) => state.searchResults);
|
|
36051
36855
|
const trajectEntry = context?.trajectEntry;
|
|
36052
36856
|
const showApiItems = !!context?.showApiItems;
|
|
36053
36857
|
const hideShowMoreResults = !!context?.hideShowMoreResults;
|
|
@@ -36073,12 +36877,14 @@ const useTrajectAvailability = () => {
|
|
|
36073
36877
|
rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
|
|
36074
36878
|
};
|
|
36075
36879
|
// Flight searches take passengers rather than rooms; the API buckets by age.
|
|
36880
|
+
// The ids must be the entry's own pax ids: the flight lines this search caches carry them as
|
|
36881
|
+
// EntryLinePax.PaxId, and booking maps those onto the entry's travelers (PackagingService.SyncPaxIds).
|
|
36076
36882
|
const pax = trajectEntry.entry.pax ?? [];
|
|
36077
36883
|
const ageOf = (p) => p.age ?? 30;
|
|
36078
|
-
const adults = pax.filter((p) => ageOf(p) >= 12)
|
|
36079
|
-
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12)
|
|
36080
|
-
const babies = pax.filter((p) => ageOf(p) < 2)
|
|
36081
|
-
const flightPax = concat(
|
|
36884
|
+
const adults = pax.filter((p) => ageOf(p) >= 12);
|
|
36885
|
+
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12);
|
|
36886
|
+
const babies = pax.filter((p) => ageOf(p) < 2);
|
|
36887
|
+
const flightPax = concat(adults.map((p) => ({ id: p.id, age: 31 })), kids.map((p) => ({ id: p.id, age: 8 })), babies.map((p) => ({ id: p.id, age: 1 })));
|
|
36082
36888
|
const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
|
|
36083
36889
|
// The other members of a line group are alternatives whether or not a search still finds
|
|
36084
36890
|
// them; the ones it does not are drawn from their lines, as the booked service itself is.
|
|
@@ -36209,9 +37015,30 @@ const useTrajectAvailability = () => {
|
|
|
36209
37015
|
return item.lines.map((x) => x.guid);
|
|
36210
37016
|
}
|
|
36211
37017
|
};
|
|
37018
|
+
const resolveTransferNode = async (node) => {
|
|
37019
|
+
dispatch(setTrajectTransferLoading(node.nodeId));
|
|
37020
|
+
try {
|
|
37021
|
+
const results = (await build.searchPackagingTransfers(config, buildTrajectTransferRequest(node, searchContext), controller.signal)) ?? [];
|
|
37022
|
+
if (controller.signal.aborted)
|
|
37023
|
+
return [];
|
|
37024
|
+
const result = results[0] ?? null;
|
|
37025
|
+
dispatch(setTrajectTransferAvailability({ nodeId: node.nodeId, result: result && buildTrajectTransferLine(node, result) ? result : null }));
|
|
37026
|
+
}
|
|
37027
|
+
catch (error) {
|
|
37028
|
+
if (controller.signal.aborted)
|
|
37029
|
+
return [];
|
|
37030
|
+
console.error('Failed to resolve traject transfer', node.name, error);
|
|
37031
|
+
dispatch(setTrajectTransferAvailability({ nodeId: node.nodeId, result: null }));
|
|
37032
|
+
}
|
|
37033
|
+
return [];
|
|
37034
|
+
};
|
|
36212
37035
|
(async () => {
|
|
36213
37036
|
const resolvable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node));
|
|
36214
|
-
const
|
|
37037
|
+
const transfers = bookedMode ? [] : (trajectEntry.nodes ?? []).filter(isTrajectTransferNode);
|
|
37038
|
+
const unresolved = (await Promise.all([
|
|
37039
|
+
...resolvable.map((item) => (isTrajectFlightNode(item.node) ? resolveFlightNode(item) : resolveNode(item))),
|
|
37040
|
+
...transfers.map(resolveTransferNode)
|
|
37041
|
+
])).flat();
|
|
36215
37042
|
if (controller.signal.aborted)
|
|
36216
37043
|
return;
|
|
36217
37044
|
dispatch(setTrajectResolving(false));
|
|
@@ -36223,6 +37050,28 @@ const useTrajectAvailability = () => {
|
|
|
36223
37050
|
})();
|
|
36224
37051
|
return () => controller.abort();
|
|
36225
37052
|
}, [trajectEntry, showApiItems, hideShowMoreResults]);
|
|
37053
|
+
useEffect(() => {
|
|
37054
|
+
if (!trajectEntry || !editablePackagingEntry || isBookedEntryTraject(trajectEntry))
|
|
37055
|
+
return;
|
|
37056
|
+
const dropped = getDroppedTrajectNodeIds(trajectEntry, editablePackagingEntry);
|
|
37057
|
+
const guids = new Set((editablePackagingEntry.lines ?? []).map((line) => line.guid));
|
|
37058
|
+
const toAdd = [];
|
|
37059
|
+
const toRemove = [];
|
|
37060
|
+
(trajectEntry.nodes ?? []).filter(isTrajectTransferNode).forEach((node) => {
|
|
37061
|
+
const result = trajectTransferAvailability[node.nodeId]?.result;
|
|
37062
|
+
const line = result ? buildTrajectTransferLine(node, result) : null;
|
|
37063
|
+
if (!line)
|
|
37064
|
+
return;
|
|
37065
|
+
if (dropped.has(node.nodeId) && guids.has(line.guid))
|
|
37066
|
+
toRemove.push(line.guid);
|
|
37067
|
+
if (!dropped.has(node.nodeId) && !guids.has(line.guid))
|
|
37068
|
+
toAdd.push(line);
|
|
37069
|
+
});
|
|
37070
|
+
if (toRemove.length)
|
|
37071
|
+
dispatch(removeEditableEntryLines(toRemove));
|
|
37072
|
+
if (toAdd.length)
|
|
37073
|
+
dispatch(addEditableEntryLines(toAdd));
|
|
37074
|
+
}, [trajectEntry, editablePackagingEntry, trajectTransferAvailability]);
|
|
36226
37075
|
};
|
|
36227
37076
|
|
|
36228
37077
|
const SearchResultsContainer = ({ onBookingStarted }) => {
|
|
@@ -36527,10 +37376,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
|
|
|
36527
37376
|
const item = getTrajectNodesWithLines(context.trajectEntry).find((x) => x.line.guid === trajectEditLineGuid);
|
|
36528
37377
|
const result = packagingAccoSearchDetails.find((x) => x.code === selectedPackagingAccoResultCode);
|
|
36529
37378
|
if (item && result) {
|
|
36530
|
-
|
|
36531
|
-
|
|
36532
|
-
|
|
36533
|
-
applyResultToLines(currentLines, result).forEach((line) => dispatch(updateEditableEntryLine(line)));
|
|
37379
|
+
// A stop the traveller took off has no lines left on the entry: the traject's own put it back.
|
|
37380
|
+
const currentLines = item.lines.map((line) => editablePackagingEntry?.lines?.find((x) => x.guid === line.guid) ?? line);
|
|
37381
|
+
dispatch(upsertEditableEntryLines(applyResultToLines(currentLines, result)));
|
|
36534
37382
|
dispatch(updateTrajectNodeResult({ lineGuid: trajectEditLineGuid, result }));
|
|
36535
37383
|
}
|
|
36536
37384
|
dispatch(setTrajectEditLineGuid(null));
|
|
@@ -40155,6 +41003,363 @@ const Login = ({ tideClientConfig, portalId, languageCode, imageSrc, logo, isMem
|
|
|
40155
41003
|
isMemberConfirmation && (React__default.createElement(ConfirmComponent, { tideClientConfig: tideClientConfig, portalId: portalId, languageCode: languageCode, member: member, setMember: setMember, handleBackToHome: handleBackToHome, handleBackToLogin: handleBackToLogin }))))));
|
|
40156
41004
|
};
|
|
40157
41005
|
|
|
41006
|
+
/** Agent endpoints need the member token, fall back to the one the Login component stored. */
|
|
41007
|
+
const withAgentToken = (config) => ({
|
|
41008
|
+
...config,
|
|
41009
|
+
token: config.token ?? selectAgentToken()
|
|
41010
|
+
});
|
|
41011
|
+
/** False when the token is not a JWT or has expired. */
|
|
41012
|
+
const isAgentTokenValid = (token) => {
|
|
41013
|
+
if (!token)
|
|
41014
|
+
return false;
|
|
41015
|
+
try {
|
|
41016
|
+
const { exp } = jwtDecode(token);
|
|
41017
|
+
return !exp || exp * 1000 > Date.now();
|
|
41018
|
+
}
|
|
41019
|
+
catch {
|
|
41020
|
+
return false;
|
|
41021
|
+
}
|
|
41022
|
+
};
|
|
41023
|
+
// tide-client throws Error(statusText) without the status, and statusText is empty over HTTP/2,
|
|
41024
|
+
// so also treat any failure with an invalid/expired token as unauthorized.
|
|
41025
|
+
const isUnauthorizedError = (error, token) => (error instanceof Error && /unauthori[sz]ed|forbidden/i.test(error.message)) || !isAgentTokenValid(token);
|
|
41026
|
+
const fetchLookups = async (config, languageCode, signal) => {
|
|
41027
|
+
// A failing lookup should not block the list itself.
|
|
41028
|
+
const [entryStatuses, customEntryStatuses, printActions] = await Promise.allSettled([
|
|
41029
|
+
build.getEntryStatus(config, signal, languageCode),
|
|
41030
|
+
build.getCustomEntryStatus(config, signal, languageCode),
|
|
41031
|
+
build.getPrintActions(config, build.PrintActionGroup.Dossier, signal)
|
|
41032
|
+
]);
|
|
41033
|
+
return {
|
|
41034
|
+
entryStatuses: entryStatuses.status === 'fulfilled' ? entryStatuses.value ?? [] : [],
|
|
41035
|
+
customEntryStatuses: customEntryStatuses.status === 'fulfilled' ? customEntryStatuses.value ?? [] : [],
|
|
41036
|
+
printActions: printActions.status === 'fulfilled' ? printActions.value ?? [] : []
|
|
41037
|
+
};
|
|
41038
|
+
};
|
|
41039
|
+
/** Converts the raw filter inputs to the OData column filters understood by tide-client's createParams. */
|
|
41040
|
+
const buildFilterItem = (columns, filterValues, sort, page, take) => {
|
|
41041
|
+
const filterColumns = {};
|
|
41042
|
+
columns.forEach((column) => {
|
|
41043
|
+
const raw = filterValues[column.id]?.trim();
|
|
41044
|
+
if (!raw)
|
|
41045
|
+
return;
|
|
41046
|
+
switch (column.kind) {
|
|
41047
|
+
case 'text':
|
|
41048
|
+
filterColumns[column.id] = { type: 'text', value: raw };
|
|
41049
|
+
break;
|
|
41050
|
+
case 'number': {
|
|
41051
|
+
const value = parseFloat(raw.replace(',', '.'));
|
|
41052
|
+
if (!isNaN(value))
|
|
41053
|
+
filterColumns[column.id] = { type: 'number', value };
|
|
41054
|
+
break;
|
|
41055
|
+
}
|
|
41056
|
+
case 'date': {
|
|
41057
|
+
// <input type="date"> value: yyyy-MM-dd, createParams expects a 1-based month.
|
|
41058
|
+
const [year, month, day] = raw.split('-').map((x) => parseInt(x, 10));
|
|
41059
|
+
if (year && month && day)
|
|
41060
|
+
filterColumns[column.id] = { type: 'date', value: { year, month, day } };
|
|
41061
|
+
break;
|
|
41062
|
+
}
|
|
41063
|
+
case 'status':
|
|
41064
|
+
case 'customStatus':
|
|
41065
|
+
filterColumns[column.id] = { type: 'enum', value: parseInt(raw, 10) };
|
|
41066
|
+
break;
|
|
41067
|
+
}
|
|
41068
|
+
});
|
|
41069
|
+
return { take, page, sort, columns: filterColumns };
|
|
41070
|
+
};
|
|
41071
|
+
const fetchEntries = (config, filter, signal) => build.getEntryList(config, filter, undefined, signal);
|
|
41072
|
+
/** Prints the entry and returns an object url to the resulting pdf. */
|
|
41073
|
+
const printEntry = async (config, printActionId, entryId) => {
|
|
41074
|
+
// Same request as the agent portal: the print action and the entry (version) id.
|
|
41075
|
+
const request = { id: printActionId, entryId };
|
|
41076
|
+
const response = await build.print(config, request);
|
|
41077
|
+
if (!response.ok)
|
|
41078
|
+
throw new Error(response.statusText);
|
|
41079
|
+
const buffer = await response.arrayBuffer();
|
|
41080
|
+
return URL.createObjectURL(new Blob([buffer], { type: 'application/pdf' }));
|
|
41081
|
+
};
|
|
41082
|
+
|
|
41083
|
+
const PAGE_SIZES = [10, 20, 50, 100];
|
|
41084
|
+
const FILTER_DEBOUNCE_MS = 400;
|
|
41085
|
+
const EyeIcon = () => (React__default.createElement("svg", { className: "agent-entries__icon", viewBox: "0 0 576 512", fill: "currentColor", "aria-hidden": "true" },
|
|
41086
|
+
React__default.createElement("path", { d: "M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4 142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1 3.3-7.9 3.3-16.7 0-24.6-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1-288 0zm144-64c0 35.3-28.7 64-64 64-7.1 0-13.9-1.2-20.3-3.3-5.5-1.8-11.9 1.6-11.7 7.4.3 6.9 1.3 13.8 3.2 20.7 13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1-5.8-.2-9.2 6.1-7.4 11.7 2.1 6.4 3.3 13.2 3.3 20.3z" })));
|
|
41087
|
+
const PrintIcon = () => (React__default.createElement("svg", { className: "agent-entries__icon", viewBox: "0 0 512 512", fill: "currentColor", "aria-hidden": "true" },
|
|
41088
|
+
React__default.createElement("path", { d: "M128 0C92.7 0 64 28.7 64 64v96h64V64h226.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zm256 352v96H128v-96h256zm64 32h32c17.7 0 32-14.3 32-32v-96c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32h32v64c0 35.3 28.7 64 64 64h256c35.3 0 64-28.7 64-64v-64zm-16-136a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" })));
|
|
41089
|
+
const SortIcon = ({ asc }) => (React__default.createElement("svg", { className: buildClassName(['agent-entries__sort-icon', !asc && 'agent-entries__sort-icon--desc']), viewBox: "0 0 320 512", fill: "currentColor", "aria-hidden": "true" },
|
|
41090
|
+
React__default.createElement("path", { d: "M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9S19 320 32 320h256c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z" })));
|
|
41091
|
+
const AgentEntries = ({ tideClientConfig, languageCode, title, pageSize, customTranslations, onLogin, onUnauthorized }) => {
|
|
41092
|
+
const translations = useMemo(() => getTranslations(languageCode ?? 'en-GB', customTranslations), [languageCode, customTranslations]);
|
|
41093
|
+
const t = translations.AGENT_ENTRIES;
|
|
41094
|
+
const config = useMemo(() => withAgentToken(tideClientConfig), [tideClientConfig.host, tideClientConfig.apiKey, tideClientConfig.token]);
|
|
41095
|
+
const isLoggedIn = !!config.token;
|
|
41096
|
+
const hasValidToken = isLoggedIn && isAgentTokenValid(config.token);
|
|
41097
|
+
const columns = useMemo(() => [
|
|
41098
|
+
{ id: 'number', kind: 'text', label: t.NUMBER },
|
|
41099
|
+
{ id: 'departureDate', kind: 'date', label: t.DEPARTURE_DATE },
|
|
41100
|
+
{ id: 'status', kind: 'status', label: t.STATUS },
|
|
41101
|
+
{ id: 'customEntryStatusId', kind: 'customStatus', label: t.CUSTOM_STATUS },
|
|
41102
|
+
{ id: 'returnDate', kind: 'date', label: t.RETURN_DATE },
|
|
41103
|
+
{ id: 'profit', kind: 'number', label: t.PROFIT },
|
|
41104
|
+
{ id: 'totalPrice', kind: 'number', label: t.NETTO_SELLING_PRICE },
|
|
41105
|
+
{ id: 'calculatedAgentSurchargeAmount', kind: 'number', label: t.YOUR_SURCHARGE },
|
|
41106
|
+
{ id: 'createdDate', kind: 'date', label: t.CREATED },
|
|
41107
|
+
{ id: 'contact', kind: 'text', label: t.CONTACT },
|
|
41108
|
+
{ id: 'travelerAddress', kind: 'text', label: t.MAIN_BOOKER }
|
|
41109
|
+
], [t]);
|
|
41110
|
+
const [lookups, setLookups] = useState({ entryStatuses: [], customEntryStatuses: [], printActions: [] });
|
|
41111
|
+
const [entries, setEntries] = useState([]);
|
|
41112
|
+
const [count, setCount] = useState();
|
|
41113
|
+
const [loadState, setLoadState] = useState('idle');
|
|
41114
|
+
const [filterInputs, setFilterInputs] = useState({});
|
|
41115
|
+
const [filterValues, setFilterValues] = useState({});
|
|
41116
|
+
const [sort, setSort] = useState({ name: 'number', asc: true });
|
|
41117
|
+
const [page, setPage] = useState(1);
|
|
41118
|
+
const [take, setTake] = useState(pageSize ?? 20);
|
|
41119
|
+
const [expandedId, setExpandedId] = useState();
|
|
41120
|
+
const [printingKey, setPrintingKey] = useState();
|
|
41121
|
+
const [printError, setPrintError] = useState(false);
|
|
41122
|
+
const handleError = (error) => {
|
|
41123
|
+
if (error instanceof DOMException && error.name === 'AbortError')
|
|
41124
|
+
return;
|
|
41125
|
+
if (isUnauthorizedError(error, config.token)) {
|
|
41126
|
+
setLoadState('unauthorized');
|
|
41127
|
+
onUnauthorized?.();
|
|
41128
|
+
}
|
|
41129
|
+
else {
|
|
41130
|
+
console.error(error);
|
|
41131
|
+
setLoadState('error');
|
|
41132
|
+
}
|
|
41133
|
+
};
|
|
41134
|
+
useEffect(() => {
|
|
41135
|
+
if (isLoggedIn && !hasValidToken)
|
|
41136
|
+
onUnauthorized?.();
|
|
41137
|
+
}, [isLoggedIn, hasValidToken]);
|
|
41138
|
+
// Lookups (statuses & print actions) only need to be fetched once.
|
|
41139
|
+
useEffect(() => {
|
|
41140
|
+
if (!hasValidToken)
|
|
41141
|
+
return;
|
|
41142
|
+
const controller = new AbortController();
|
|
41143
|
+
fetchLookups(config, languageCode, controller.signal)
|
|
41144
|
+
.then(setLookups)
|
|
41145
|
+
.catch(() => { });
|
|
41146
|
+
return () => controller.abort();
|
|
41147
|
+
}, [config, languageCode, hasValidToken]);
|
|
41148
|
+
// Debounce the typed filters, a selected dropdown/date is applied immediately.
|
|
41149
|
+
useEffect(() => {
|
|
41150
|
+
const handle = setTimeout(() => {
|
|
41151
|
+
if (isEqual$1(filterInputs, filterValues))
|
|
41152
|
+
return;
|
|
41153
|
+
setFilterValues(filterInputs);
|
|
41154
|
+
setPage(1);
|
|
41155
|
+
}, FILTER_DEBOUNCE_MS);
|
|
41156
|
+
return () => clearTimeout(handle);
|
|
41157
|
+
}, [filterInputs]);
|
|
41158
|
+
useEffect(() => {
|
|
41159
|
+
if (!hasValidToken)
|
|
41160
|
+
return;
|
|
41161
|
+
const controller = new AbortController();
|
|
41162
|
+
setLoadState('loading');
|
|
41163
|
+
fetchEntries(config, buildFilterItem(columns, filterValues, sort, page, take), controller.signal)
|
|
41164
|
+
.then((result) => {
|
|
41165
|
+
setEntries(result?.items ?? []);
|
|
41166
|
+
setCount(result?.count ?? undefined);
|
|
41167
|
+
setLoadState('loaded');
|
|
41168
|
+
})
|
|
41169
|
+
.catch(handleError);
|
|
41170
|
+
return () => controller.abort();
|
|
41171
|
+
}, [config, hasValidToken, columns, filterValues, sort, page, take]);
|
|
41172
|
+
const totalPages = count !== undefined ? Math.max(1, Math.ceil(count / take)) : undefined;
|
|
41173
|
+
const hasNextPage = totalPages !== undefined ? page < totalPages : entries.length === take;
|
|
41174
|
+
const handleSort = (columnId) => {
|
|
41175
|
+
setSort((current) => (current.name === columnId ? { name: columnId, asc: !current.asc } : { name: columnId, asc: true }));
|
|
41176
|
+
setPage(1);
|
|
41177
|
+
};
|
|
41178
|
+
const handleFilterChange = (columnId, value, immediate) => {
|
|
41179
|
+
const next = { ...filterInputs, [columnId]: value };
|
|
41180
|
+
setFilterInputs(next);
|
|
41181
|
+
if (immediate) {
|
|
41182
|
+
setFilterValues(next);
|
|
41183
|
+
setPage(1);
|
|
41184
|
+
}
|
|
41185
|
+
};
|
|
41186
|
+
const handlePrint = async (entry, printAction) => {
|
|
41187
|
+
// Open the tab synchronously, otherwise the popup blocker kicks in once the pdf arrives.
|
|
41188
|
+
const printWindow = window.open('', '_blank');
|
|
41189
|
+
setPrintingKey(`${entry.id}-${printAction.id}`);
|
|
41190
|
+
setPrintError(false);
|
|
41191
|
+
try {
|
|
41192
|
+
const url = await printEntry(config, printAction.id, entry.id);
|
|
41193
|
+
if (printWindow) {
|
|
41194
|
+
printWindow.location.href = url;
|
|
41195
|
+
}
|
|
41196
|
+
else {
|
|
41197
|
+
window.open(url, '_blank');
|
|
41198
|
+
}
|
|
41199
|
+
setTimeout(() => URL.revokeObjectURL(url), 60000);
|
|
41200
|
+
}
|
|
41201
|
+
catch (error) {
|
|
41202
|
+
printWindow?.close();
|
|
41203
|
+
if (isUnauthorizedError(error, config.token)) {
|
|
41204
|
+
handleError(error);
|
|
41205
|
+
}
|
|
41206
|
+
else {
|
|
41207
|
+
console.error(error);
|
|
41208
|
+
setPrintError(true);
|
|
41209
|
+
}
|
|
41210
|
+
}
|
|
41211
|
+
finally {
|
|
41212
|
+
setPrintingKey(undefined);
|
|
41213
|
+
}
|
|
41214
|
+
};
|
|
41215
|
+
const formatDate = (value) => {
|
|
41216
|
+
if (!value)
|
|
41217
|
+
return '';
|
|
41218
|
+
const date = new Date(value);
|
|
41219
|
+
if (isNaN(date.getTime()))
|
|
41220
|
+
return '';
|
|
41221
|
+
return new Intl.DateTimeFormat(languageCode, { day: '2-digit', month: '2-digit', year: 'numeric' }).format(date);
|
|
41222
|
+
};
|
|
41223
|
+
const formatNumber = (value) => {
|
|
41224
|
+
if (value === undefined || value === null)
|
|
41225
|
+
return '';
|
|
41226
|
+
return new Intl.NumberFormat(languageCode, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value);
|
|
41227
|
+
};
|
|
41228
|
+
const getEntryStatusLabel = (status) => lookups.entryStatuses.find((x) => x.key === status)?.value ?? '';
|
|
41229
|
+
const getCustomEntryStatusLabel = (id) => lookups.customEntryStatuses.find((x) => x.id === id)?.name ?? '';
|
|
41230
|
+
const getPrintActionsForEntry = (entry) => lookups.printActions.filter((x) => x.validEntryStatuses?.includes(entry.status));
|
|
41231
|
+
const renderCell = (entry, column) => {
|
|
41232
|
+
const value = entry[column.id];
|
|
41233
|
+
switch (column.kind) {
|
|
41234
|
+
case 'date':
|
|
41235
|
+
return formatDate(value);
|
|
41236
|
+
case 'number':
|
|
41237
|
+
return formatNumber(value);
|
|
41238
|
+
case 'status':
|
|
41239
|
+
return getEntryStatusLabel(value);
|
|
41240
|
+
case 'customStatus':
|
|
41241
|
+
return getCustomEntryStatusLabel(value);
|
|
41242
|
+
default:
|
|
41243
|
+
return value ?? '';
|
|
41244
|
+
}
|
|
41245
|
+
};
|
|
41246
|
+
const renderFilter = (column) => {
|
|
41247
|
+
const value = filterInputs[column.id] ?? '';
|
|
41248
|
+
const className = 'agent-entries__filter';
|
|
41249
|
+
switch (column.kind) {
|
|
41250
|
+
case 'date':
|
|
41251
|
+
return (React__default.createElement("input", { type: "date", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value, true) }));
|
|
41252
|
+
case 'status':
|
|
41253
|
+
case 'customStatus': {
|
|
41254
|
+
const options = column.kind === 'status'
|
|
41255
|
+
? lookups.entryStatuses.filter((x) => x.key !== undefined && x.key !== null).map((x) => ({ key: x.key, value: x.value }))
|
|
41256
|
+
: lookups.customEntryStatuses.map((x) => ({ key: x.id, value: x.name }));
|
|
41257
|
+
return (React__default.createElement("select", { className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value, true) },
|
|
41258
|
+
React__default.createElement("option", { value: "" }, t.ALL),
|
|
41259
|
+
options.map((option) => (React__default.createElement("option", { key: option.key, value: option.key }, option.value)))));
|
|
41260
|
+
}
|
|
41261
|
+
case 'number':
|
|
41262
|
+
return (React__default.createElement("input", { type: "number", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value) }));
|
|
41263
|
+
default:
|
|
41264
|
+
return (React__default.createElement("input", { type: "text", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value) }));
|
|
41265
|
+
}
|
|
41266
|
+
};
|
|
41267
|
+
const renderDetails = (entry) => {
|
|
41268
|
+
const printActions = getPrintActionsForEntry(entry);
|
|
41269
|
+
const travelers = entry.pax?.length ? entry.pax.map((p) => (p.isMainBooker ? `${p.name} (${t.MAIN_BOOKER.toLowerCase()})` : p.name)).join(', ') : '';
|
|
41270
|
+
const details = [
|
|
41271
|
+
{ label: t.NUMBER, value: entry.number },
|
|
41272
|
+
{ label: t.PRODUCT, value: entry.firstProductName },
|
|
41273
|
+
{ label: t.STATUS, value: getEntryStatusLabel(entry.status) },
|
|
41274
|
+
{ label: t.CUSTOM_STATUS, value: getCustomEntryStatusLabel(entry.customEntryStatusId) },
|
|
41275
|
+
{ label: t.DEPARTURE_DATE, value: formatDate(entry.departureDate) },
|
|
41276
|
+
{ label: t.RETURN_DATE, value: formatDate(entry.returnDate) },
|
|
41277
|
+
{ label: t.CREATED, value: formatDate(entry.createdDate) },
|
|
41278
|
+
{ label: t.CONTACT, value: entry.contact },
|
|
41279
|
+
{ label: t.MAIN_BOOKER, value: entry.travelerAddress },
|
|
41280
|
+
{ label: t.TRAVELERS, value: travelers || (entry.paxCount ? entry.paxCount : '') },
|
|
41281
|
+
{ label: t.NETTO_SELLING_PRICE, value: formatNumber(entry.totalPrice) },
|
|
41282
|
+
{ label: t.YOUR_SURCHARGE, value: formatNumber(entry.calculatedAgentSurchargeAmount) },
|
|
41283
|
+
{ label: t.PROFIT, value: formatNumber(entry.profit) }
|
|
41284
|
+
];
|
|
41285
|
+
return (React__default.createElement("div", { className: "agent-entries__details" },
|
|
41286
|
+
React__default.createElement("dl", { className: "agent-entries__details__list" }, details
|
|
41287
|
+
.filter((detail) => detail.value !== undefined && detail.value !== null && detail.value !== '')
|
|
41288
|
+
.map((detail) => (React__default.createElement("div", { className: "agent-entries__details__item", key: detail.label },
|
|
41289
|
+
React__default.createElement("dt", null, detail.label),
|
|
41290
|
+
React__default.createElement("dd", null, detail.value))))),
|
|
41291
|
+
printActions.length > 0 && (React__default.createElement("div", { className: "agent-entries__details__prints" },
|
|
41292
|
+
React__default.createElement("span", { className: "agent-entries__details__prints__title" }, t.PRINTS),
|
|
41293
|
+
React__default.createElement("div", { className: "agent-entries__details__prints__buttons" }, printActions.map((printAction) => (React__default.createElement("button", { type: "button", key: printAction.id, className: "agent-entries__print-button", disabled: printingKey === `${entry.id}-${printAction.id}`, onClick: () => handlePrint(entry, printAction) },
|
|
41294
|
+
React__default.createElement(PrintIcon, null),
|
|
41295
|
+
printAction.label))))))));
|
|
41296
|
+
};
|
|
41297
|
+
const renderLoginMessage = (message) => (React__default.createElement("div", { className: "agent-entries__message" },
|
|
41298
|
+
React__default.createElement("p", null, message),
|
|
41299
|
+
onLogin && (React__default.createElement("button", { type: "button", className: "cta cta--primary", onClick: onLogin }, translations.LOGIN.LOGIN))));
|
|
41300
|
+
if (!isLoggedIn) {
|
|
41301
|
+
return (React__default.createElement("div", { className: "agent-entries" },
|
|
41302
|
+
React__default.createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41303
|
+
renderLoginMessage(t.NOT_LOGGED_IN)));
|
|
41304
|
+
}
|
|
41305
|
+
if (!hasValidToken || loadState === 'unauthorized') {
|
|
41306
|
+
return (React__default.createElement("div", { className: "agent-entries" },
|
|
41307
|
+
React__default.createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41308
|
+
renderLoginMessage(t.SESSION_EXPIRED)));
|
|
41309
|
+
}
|
|
41310
|
+
const columnCount = columns.length + 1;
|
|
41311
|
+
return (React__default.createElement("div", { className: "agent-entries" },
|
|
41312
|
+
React__default.createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41313
|
+
printError && (React__default.createElement("div", { className: "agent-entries__error", role: "alert" },
|
|
41314
|
+
t.PRINT_ERROR,
|
|
41315
|
+
React__default.createElement("button", { type: "button", className: "agent-entries__error__close", "aria-label": "close", onClick: () => setPrintError(false) }, "\u00D7"))),
|
|
41316
|
+
React__default.createElement("div", { className: buildClassName(['agent-entries__card', loadState === 'loading' && 'agent-entries__card--loading']) },
|
|
41317
|
+
React__default.createElement("div", { className: "agent-entries__table-wrapper" },
|
|
41318
|
+
React__default.createElement("table", { className: "agent-entries__table" },
|
|
41319
|
+
React__default.createElement("thead", null,
|
|
41320
|
+
React__default.createElement("tr", null,
|
|
41321
|
+
React__default.createElement("th", { className: "agent-entries__actions-header" },
|
|
41322
|
+
React__default.createElement("span", { className: "agent-entries__sr-only" }, t.ACTIONS)),
|
|
41323
|
+
columns.map((column) => (React__default.createElement("th", { key: column.id, "aria-sort": sort.name === column.id ? (sort.asc ? 'ascending' : 'descending') : undefined },
|
|
41324
|
+
React__default.createElement("button", { type: "button", className: "agent-entries__sort", onClick: () => handleSort(column.id) },
|
|
41325
|
+
column.label,
|
|
41326
|
+
sort.name === column.id && React__default.createElement(SortIcon, { asc: sort.asc })))))),
|
|
41327
|
+
React__default.createElement("tr", { className: "agent-entries__filter-row" },
|
|
41328
|
+
React__default.createElement("th", null),
|
|
41329
|
+
columns.map((column) => (React__default.createElement("th", { key: column.id }, renderFilter(column)))))),
|
|
41330
|
+
React__default.createElement("tbody", null,
|
|
41331
|
+
loadState === 'error' && (React__default.createElement("tr", null,
|
|
41332
|
+
React__default.createElement("td", { colSpan: columnCount, className: "agent-entries__empty" }, t.ERROR))),
|
|
41333
|
+
loadState !== 'error' && entries.length === 0 && (React__default.createElement("tr", null,
|
|
41334
|
+
React__default.createElement("td", { colSpan: columnCount, className: "agent-entries__empty" }, loadState === 'loading' ? t.LOADING : t.NO_ITEMS))),
|
|
41335
|
+
loadState !== 'error' &&
|
|
41336
|
+
entries.map((entry) => {
|
|
41337
|
+
const isExpanded = expandedId === entry.id;
|
|
41338
|
+
return (React__default.createElement(React__default.Fragment, { key: entry.id },
|
|
41339
|
+
React__default.createElement("tr", { className: buildClassName(['agent-entries__row', isExpanded && 'agent-entries__row--expanded']) },
|
|
41340
|
+
React__default.createElement("td", { className: "agent-entries__actions" },
|
|
41341
|
+
React__default.createElement("button", { type: "button", className: "agent-entries__action agent-entries__action--primary", title: isExpanded ? t.HIDE_DETAILS : t.DETAILS, "aria-label": isExpanded ? t.HIDE_DETAILS : t.DETAILS, "aria-expanded": isExpanded, onClick: () => setExpandedId(isExpanded ? undefined : entry.id) },
|
|
41342
|
+
React__default.createElement(EyeIcon, null)),
|
|
41343
|
+
getPrintActionsForEntry(entry).map((printAction) => (React__default.createElement("button", { type: "button", key: printAction.id, className: "agent-entries__action", title: printAction.label, "aria-label": printAction.label, disabled: printingKey === `${entry.id}-${printAction.id}`, onClick: () => handlePrint(entry, printAction) },
|
|
41344
|
+
React__default.createElement(PrintIcon, null))))),
|
|
41345
|
+
columns.map((column) => (React__default.createElement("td", { key: column.id, className: `agent-entries__cell agent-entries__cell--${column.kind}` }, renderCell(entry, column))))),
|
|
41346
|
+
isExpanded && (React__default.createElement("tr", { className: "agent-entries__details-row" },
|
|
41347
|
+
React__default.createElement("td", { colSpan: columnCount }, renderDetails(entry))))));
|
|
41348
|
+
})))),
|
|
41349
|
+
React__default.createElement("div", { className: "agent-entries__footer" },
|
|
41350
|
+
React__default.createElement("select", { className: "agent-entries__page-size", value: take, "aria-label": t.PAGE_SIZE, onChange: (e) => {
|
|
41351
|
+
setTake(parseInt(e.target.value, 10));
|
|
41352
|
+
setPage(1);
|
|
41353
|
+
} }, Array.from(new Set([...PAGE_SIZES, take]))
|
|
41354
|
+
.sort((a, b) => a - b)
|
|
41355
|
+
.map((size) => (React__default.createElement("option", { key: size, value: size }, size)))),
|
|
41356
|
+
count !== undefined && React__default.createElement("span", { className: "agent-entries__count" }, format$1(t.X_ITEMS, [count])),
|
|
41357
|
+
React__default.createElement("div", { className: "agent-entries__pager" },
|
|
41358
|
+
React__default.createElement("button", { type: "button", className: "agent-entries__pager__button", disabled: page <= 1, onClick: () => setPage(page - 1) }, t.PREVIOUS),
|
|
41359
|
+
React__default.createElement("span", { className: "agent-entries__pager__info" }, totalPages !== undefined ? format$1(t.PAGE_X_OF_Y, [page, totalPages]) : page),
|
|
41360
|
+
React__default.createElement("button", { type: "button", className: "agent-entries__pager__button", disabled: !hasNextPage, onClick: () => setPage(page + 1) }, t.NEXT))))));
|
|
41361
|
+
};
|
|
41362
|
+
|
|
40158
41363
|
const ImageWithTextCard = ({ noCard, fullImage, reverse, imageSrc, imageAlt, title, section1Title, section1Text, section2Title, section2Text, buttonText, onButtonClick }) => {
|
|
40159
41364
|
let cardClassName = 'image-with-text__card';
|
|
40160
41365
|
if (noCard) {
|
|
@@ -44613,4 +45818,4 @@ var signalR = /*#__PURE__*/_mergeNamespaces({
|
|
|
44613
45818
|
'default': signalR$1
|
|
44614
45819
|
}, [signalR$1]);
|
|
44615
45820
|
|
|
44616
|
-
export { BookingProduct, BookingWizard, Breadcrumbs, DepartureRange, FAQ, FeaturedTrips, Footer, Header, ImageCardGrid, ImageWithTextSection, ItineraryMapView, Login, Navbar, PhotoGallery, QSM, SearchResults, Slider, Spinner, TideForm };
|
|
45821
|
+
export { AgentEntries, BookingProduct, BookingWizard, Breadcrumbs, DepartureRange, FAQ, FeaturedTrips, Footer, Header, ImageCardGrid, ImageWithTextSection, ItineraryMapView, Login, Navbar, PhotoGallery, QSM, SearchResults, Slider, Spinner, TideForm };
|