@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-cjs/index.js
CHANGED
|
@@ -509,6 +509,39 @@ var FORM$f = {
|
|
|
509
509
|
YES: "نعم",
|
|
510
510
|
NO: "لا"
|
|
511
511
|
};
|
|
512
|
+
var AGENT_ENTRIES$f = {
|
|
513
|
+
TITLE: "الحجوزات",
|
|
514
|
+
MY_BOOKINGS: "حجوزاتي",
|
|
515
|
+
NUMBER: "الرقم",
|
|
516
|
+
DEPARTURE_DATE: "تاريخ المغادرة",
|
|
517
|
+
STATUS: "الحالة",
|
|
518
|
+
CUSTOM_STATUS: "حالة مخصصة",
|
|
519
|
+
RETURN_DATE: "تاريخ العودة",
|
|
520
|
+
PROFIT: "الربح",
|
|
521
|
+
NETTO_SELLING_PRICE: "صافي سعر البيع",
|
|
522
|
+
YOUR_SURCHARGE: "رسومك الإضافية",
|
|
523
|
+
CREATED: "تاريخ الإنشاء",
|
|
524
|
+
CONTACT: "جهة الاتصال",
|
|
525
|
+
MAIN_BOOKER: "الحاجز الرئيسي",
|
|
526
|
+
PRODUCT: "المنتج",
|
|
527
|
+
TRAVELERS: "المسافرون",
|
|
528
|
+
ACTIONS: "الإجراءات",
|
|
529
|
+
DETAILS: "التفاصيل",
|
|
530
|
+
HIDE_DETAILS: "إخفاء التفاصيل",
|
|
531
|
+
PRINTS: "المطبوعات",
|
|
532
|
+
ALL: "الكل",
|
|
533
|
+
X_ITEMS: "{0} عناصر",
|
|
534
|
+
PAGE_SIZE: "عناصر لكل صفحة",
|
|
535
|
+
PREVIOUS: "السابق",
|
|
536
|
+
NEXT: "التالي",
|
|
537
|
+
PAGE_X_OF_Y: "الصفحة {0} من {1}",
|
|
538
|
+
LOADING: "جارٍ التحميل...",
|
|
539
|
+
NO_ITEMS: "لم يتم العثور على حجوزات.",
|
|
540
|
+
ERROR: "حدث خطأ أثناء تحميل حجوزاتك.",
|
|
541
|
+
PRINT_ERROR: "فشلت الطباعة، يرجى المحاولة مرة أخرى.",
|
|
542
|
+
NOT_LOGGED_IN: "سجّل الدخول كوكيل لعرض حجوزاتك.",
|
|
543
|
+
SESSION_EXPIRED: "انتهت صلاحية جلستك، يرجى تسجيل الدخول مرة أخرى."
|
|
544
|
+
};
|
|
512
545
|
var arJson = {
|
|
513
546
|
STEPS: STEPS$f,
|
|
514
547
|
INPUT: INPUT$f,
|
|
@@ -529,7 +562,8 @@ var arJson = {
|
|
|
529
562
|
QSM: QSM$g,
|
|
530
563
|
SRP: SRP$f,
|
|
531
564
|
ITINERARY: ITINERARY$f,
|
|
532
|
-
FORM: FORM$f
|
|
565
|
+
FORM: FORM$f,
|
|
566
|
+
AGENT_ENTRIES: AGENT_ENTRIES$f
|
|
533
567
|
};
|
|
534
568
|
|
|
535
569
|
var STEPS$e = {
|
|
@@ -982,6 +1016,39 @@ var FORM$e = {
|
|
|
982
1016
|
YES: "Ja",
|
|
983
1017
|
NO: "Nej"
|
|
984
1018
|
};
|
|
1019
|
+
var AGENT_ENTRIES$e = {
|
|
1020
|
+
TITLE: "Bookinger",
|
|
1021
|
+
MY_BOOKINGS: "Mine bookinger",
|
|
1022
|
+
NUMBER: "Nummer",
|
|
1023
|
+
DEPARTURE_DATE: "Afrejsedato",
|
|
1024
|
+
STATUS: "Status",
|
|
1025
|
+
CUSTOM_STATUS: "Tilpasset status",
|
|
1026
|
+
RETURN_DATE: "Hjemrejsedato",
|
|
1027
|
+
PROFIT: "Fortjeneste",
|
|
1028
|
+
NETTO_SELLING_PRICE: "Netto salgspris",
|
|
1029
|
+
YOUR_SURCHARGE: "Dit tillæg",
|
|
1030
|
+
CREATED: "Oprettet",
|
|
1031
|
+
CONTACT: "Kontakt",
|
|
1032
|
+
MAIN_BOOKER: "Hovedbooker",
|
|
1033
|
+
PRODUCT: "Produkt",
|
|
1034
|
+
TRAVELERS: "Rejsende",
|
|
1035
|
+
ACTIONS: "Handlinger",
|
|
1036
|
+
DETAILS: "Detaljer",
|
|
1037
|
+
HIDE_DETAILS: "Skjul detaljer",
|
|
1038
|
+
PRINTS: "Udskrifter",
|
|
1039
|
+
ALL: "Alle",
|
|
1040
|
+
X_ITEMS: "{0} elementer",
|
|
1041
|
+
PAGE_SIZE: "Elementer pr. side",
|
|
1042
|
+
PREVIOUS: "Forrige",
|
|
1043
|
+
NEXT: "Næste",
|
|
1044
|
+
PAGE_X_OF_Y: "Side {0} af {1}",
|
|
1045
|
+
LOADING: "Indlæser...",
|
|
1046
|
+
NO_ITEMS: "Ingen bookinger fundet.",
|
|
1047
|
+
ERROR: "Der opstod en fejl under indlæsning af dine bookinger.",
|
|
1048
|
+
PRINT_ERROR: "Udskrivning mislykkedes, prøv igen.",
|
|
1049
|
+
NOT_LOGGED_IN: "Log ind som agent for at se dine bookinger.",
|
|
1050
|
+
SESSION_EXPIRED: "Din session er udløbet, log ind igen."
|
|
1051
|
+
};
|
|
985
1052
|
var daJson = {
|
|
986
1053
|
STEPS: STEPS$e,
|
|
987
1054
|
INPUT: INPUT$e,
|
|
@@ -1002,7 +1069,8 @@ var daJson = {
|
|
|
1002
1069
|
QSM: QSM$f,
|
|
1003
1070
|
SRP: SRP$e,
|
|
1004
1071
|
ITINERARY: ITINERARY$e,
|
|
1005
|
-
FORM: FORM$e
|
|
1072
|
+
FORM: FORM$e,
|
|
1073
|
+
AGENT_ENTRIES: AGENT_ENTRIES$e
|
|
1006
1074
|
};
|
|
1007
1075
|
|
|
1008
1076
|
var STEPS$d = {
|
|
@@ -1455,6 +1523,39 @@ var FORM$d = {
|
|
|
1455
1523
|
YES: "Ja",
|
|
1456
1524
|
NO: "Nein"
|
|
1457
1525
|
};
|
|
1526
|
+
var AGENT_ENTRIES$d = {
|
|
1527
|
+
TITLE: "Buchungen",
|
|
1528
|
+
MY_BOOKINGS: "Meine Buchungen",
|
|
1529
|
+
NUMBER: "Nummer",
|
|
1530
|
+
DEPARTURE_DATE: "Abreisedatum",
|
|
1531
|
+
STATUS: "Status",
|
|
1532
|
+
CUSTOM_STATUS: "Benutzerdefinierter Status",
|
|
1533
|
+
RETURN_DATE: "Rückreisedatum",
|
|
1534
|
+
PROFIT: "Gewinn",
|
|
1535
|
+
NETTO_SELLING_PRICE: "Netto-Verkaufspreis",
|
|
1536
|
+
YOUR_SURCHARGE: "Ihr Aufschlag",
|
|
1537
|
+
CREATED: "Erstellt",
|
|
1538
|
+
CONTACT: "Kontakt",
|
|
1539
|
+
MAIN_BOOKER: "Hauptbucher",
|
|
1540
|
+
PRODUCT: "Produkt",
|
|
1541
|
+
TRAVELERS: "Reisende",
|
|
1542
|
+
ACTIONS: "Aktionen",
|
|
1543
|
+
DETAILS: "Details",
|
|
1544
|
+
HIDE_DETAILS: "Details ausblenden",
|
|
1545
|
+
PRINTS: "Drucke",
|
|
1546
|
+
ALL: "Alle",
|
|
1547
|
+
X_ITEMS: "{0} Einträge",
|
|
1548
|
+
PAGE_SIZE: "Einträge pro Seite",
|
|
1549
|
+
PREVIOUS: "Zurück",
|
|
1550
|
+
NEXT: "Weiter",
|
|
1551
|
+
PAGE_X_OF_Y: "Seite {0} von {1}",
|
|
1552
|
+
LOADING: "Wird geladen...",
|
|
1553
|
+
NO_ITEMS: "Keine Buchungen gefunden.",
|
|
1554
|
+
ERROR: "Beim Laden Ihrer Buchungen ist ein Fehler aufgetreten.",
|
|
1555
|
+
PRINT_ERROR: "Drucken fehlgeschlagen, bitte versuchen Sie es erneut.",
|
|
1556
|
+
NOT_LOGGED_IN: "Melden Sie sich als Agent an, um Ihre Buchungen zu sehen.",
|
|
1557
|
+
SESSION_EXPIRED: "Ihre Sitzung ist abgelaufen, bitte melden Sie sich erneut an."
|
|
1558
|
+
};
|
|
1458
1559
|
var deJson = {
|
|
1459
1560
|
STEPS: STEPS$d,
|
|
1460
1561
|
INPUT: INPUT$d,
|
|
@@ -1475,7 +1576,8 @@ var deJson = {
|
|
|
1475
1576
|
QSM: QSM$e,
|
|
1476
1577
|
SRP: SRP$d,
|
|
1477
1578
|
ITINERARY: ITINERARY$d,
|
|
1478
|
-
FORM: FORM$d
|
|
1579
|
+
FORM: FORM$d,
|
|
1580
|
+
AGENT_ENTRIES: AGENT_ENTRIES$d
|
|
1479
1581
|
};
|
|
1480
1582
|
|
|
1481
1583
|
var STEPS$c = {
|
|
@@ -1932,6 +2034,39 @@ var FORM$c = {
|
|
|
1932
2034
|
YES: "Yes",
|
|
1933
2035
|
NO: "No"
|
|
1934
2036
|
};
|
|
2037
|
+
var AGENT_ENTRIES$c = {
|
|
2038
|
+
TITLE: "Bookings",
|
|
2039
|
+
MY_BOOKINGS: "My bookings",
|
|
2040
|
+
NUMBER: "Number",
|
|
2041
|
+
DEPARTURE_DATE: "Departure date",
|
|
2042
|
+
STATUS: "Status",
|
|
2043
|
+
CUSTOM_STATUS: "Custom status",
|
|
2044
|
+
RETURN_DATE: "Return date",
|
|
2045
|
+
PROFIT: "Profit",
|
|
2046
|
+
NETTO_SELLING_PRICE: "Netto selling price",
|
|
2047
|
+
YOUR_SURCHARGE: "Your surcharge",
|
|
2048
|
+
CREATED: "Created",
|
|
2049
|
+
CONTACT: "Contact",
|
|
2050
|
+
MAIN_BOOKER: "Main booker",
|
|
2051
|
+
PRODUCT: "Product",
|
|
2052
|
+
TRAVELERS: "Travellers",
|
|
2053
|
+
ACTIONS: "Actions",
|
|
2054
|
+
DETAILS: "Details",
|
|
2055
|
+
HIDE_DETAILS: "Hide details",
|
|
2056
|
+
PRINTS: "Prints",
|
|
2057
|
+
ALL: "All",
|
|
2058
|
+
X_ITEMS: "{0} items",
|
|
2059
|
+
PAGE_SIZE: "Items per page",
|
|
2060
|
+
PREVIOUS: "Previous",
|
|
2061
|
+
NEXT: "Next",
|
|
2062
|
+
PAGE_X_OF_Y: "Page {0} of {1}",
|
|
2063
|
+
LOADING: "Loading...",
|
|
2064
|
+
NO_ITEMS: "No bookings found.",
|
|
2065
|
+
ERROR: "Something went wrong while loading your bookings.",
|
|
2066
|
+
PRINT_ERROR: "Printing failed, please try again.",
|
|
2067
|
+
NOT_LOGGED_IN: "Log in as an agent to see your bookings.",
|
|
2068
|
+
SESSION_EXPIRED: "Your session has expired, please log in again."
|
|
2069
|
+
};
|
|
1935
2070
|
var enJson = {
|
|
1936
2071
|
STEPS: STEPS$c,
|
|
1937
2072
|
INPUT: INPUT$c,
|
|
@@ -1952,7 +2087,8 @@ var enJson = {
|
|
|
1952
2087
|
QSM: QSM$d,
|
|
1953
2088
|
SRP: SRP$c,
|
|
1954
2089
|
ITINERARY: ITINERARY$c,
|
|
1955
|
-
FORM: FORM$c
|
|
2090
|
+
FORM: FORM$c,
|
|
2091
|
+
AGENT_ENTRIES: AGENT_ENTRIES$c
|
|
1956
2092
|
};
|
|
1957
2093
|
|
|
1958
2094
|
var STEPS$b = {
|
|
@@ -2405,6 +2541,39 @@ var FORM$b = {
|
|
|
2405
2541
|
YES: "Sí",
|
|
2406
2542
|
NO: "No"
|
|
2407
2543
|
};
|
|
2544
|
+
var AGENT_ENTRIES$b = {
|
|
2545
|
+
TITLE: "Reservas",
|
|
2546
|
+
MY_BOOKINGS: "Mis reservas",
|
|
2547
|
+
NUMBER: "Número",
|
|
2548
|
+
DEPARTURE_DATE: "Fecha de salida",
|
|
2549
|
+
STATUS: "Estado",
|
|
2550
|
+
CUSTOM_STATUS: "Estado personalizado",
|
|
2551
|
+
RETURN_DATE: "Fecha de regreso",
|
|
2552
|
+
PROFIT: "Beneficio",
|
|
2553
|
+
NETTO_SELLING_PRICE: "Precio de venta neto",
|
|
2554
|
+
YOUR_SURCHARGE: "Su recargo",
|
|
2555
|
+
CREATED: "Creado",
|
|
2556
|
+
CONTACT: "Contacto",
|
|
2557
|
+
MAIN_BOOKER: "Titular de la reserva",
|
|
2558
|
+
PRODUCT: "Producto",
|
|
2559
|
+
TRAVELERS: "Viajeros",
|
|
2560
|
+
ACTIONS: "Acciones",
|
|
2561
|
+
DETAILS: "Detalles",
|
|
2562
|
+
HIDE_DETAILS: "Ocultar detalles",
|
|
2563
|
+
PRINTS: "Impresiones",
|
|
2564
|
+
ALL: "Todos",
|
|
2565
|
+
X_ITEMS: "{0} elementos",
|
|
2566
|
+
PAGE_SIZE: "Elementos por página",
|
|
2567
|
+
PREVIOUS: "Anterior",
|
|
2568
|
+
NEXT: "Siguiente",
|
|
2569
|
+
PAGE_X_OF_Y: "Página {0} de {1}",
|
|
2570
|
+
LOADING: "Cargando...",
|
|
2571
|
+
NO_ITEMS: "No se encontraron reservas.",
|
|
2572
|
+
ERROR: "Se produjo un error al cargar sus reservas.",
|
|
2573
|
+
PRINT_ERROR: "La impresión ha fallado, inténtelo de nuevo.",
|
|
2574
|
+
NOT_LOGGED_IN: "Inicie sesión como agente para ver sus reservas.",
|
|
2575
|
+
SESSION_EXPIRED: "Su sesión ha caducado, inicie sesión de nuevo."
|
|
2576
|
+
};
|
|
2408
2577
|
var esJson = {
|
|
2409
2578
|
STEPS: STEPS$b,
|
|
2410
2579
|
INPUT: INPUT$b,
|
|
@@ -2425,7 +2594,8 @@ var esJson = {
|
|
|
2425
2594
|
QSM: QSM$c,
|
|
2426
2595
|
SRP: SRP$b,
|
|
2427
2596
|
ITINERARY: ITINERARY$b,
|
|
2428
|
-
FORM: FORM$b
|
|
2597
|
+
FORM: FORM$b,
|
|
2598
|
+
AGENT_ENTRIES: AGENT_ENTRIES$b
|
|
2429
2599
|
};
|
|
2430
2600
|
|
|
2431
2601
|
var STEPS$a = {
|
|
@@ -2882,6 +3052,39 @@ var FORM$a = {
|
|
|
2882
3052
|
YES: "Oui",
|
|
2883
3053
|
NO: "Non"
|
|
2884
3054
|
};
|
|
3055
|
+
var AGENT_ENTRIES$a = {
|
|
3056
|
+
TITLE: "Réservations",
|
|
3057
|
+
MY_BOOKINGS: "Mes réservations",
|
|
3058
|
+
NUMBER: "Numéro",
|
|
3059
|
+
DEPARTURE_DATE: "Date de départ",
|
|
3060
|
+
STATUS: "Statut",
|
|
3061
|
+
CUSTOM_STATUS: "Statut personnalisé",
|
|
3062
|
+
RETURN_DATE: "Date de retour",
|
|
3063
|
+
PROFIT: "Bénéfice",
|
|
3064
|
+
NETTO_SELLING_PRICE: "Prix de vente net",
|
|
3065
|
+
YOUR_SURCHARGE: "Votre supplément",
|
|
3066
|
+
CREATED: "Créé le",
|
|
3067
|
+
CONTACT: "Contact",
|
|
3068
|
+
MAIN_BOOKER: "Réservant principal",
|
|
3069
|
+
PRODUCT: "Produit",
|
|
3070
|
+
TRAVELERS: "Voyageurs",
|
|
3071
|
+
ACTIONS: "Actions",
|
|
3072
|
+
DETAILS: "Détails",
|
|
3073
|
+
HIDE_DETAILS: "Masquer les détails",
|
|
3074
|
+
PRINTS: "Impressions",
|
|
3075
|
+
ALL: "Tous",
|
|
3076
|
+
X_ITEMS: "{0} éléments",
|
|
3077
|
+
PAGE_SIZE: "Éléments par page",
|
|
3078
|
+
PREVIOUS: "Précédent",
|
|
3079
|
+
NEXT: "Suivant",
|
|
3080
|
+
PAGE_X_OF_Y: "Page {0} sur {1}",
|
|
3081
|
+
LOADING: "Chargement...",
|
|
3082
|
+
NO_ITEMS: "Aucune réservation trouvée.",
|
|
3083
|
+
ERROR: "Une erreur est survenue lors du chargement de vos réservations.",
|
|
3084
|
+
PRINT_ERROR: "L'impression a échoué, veuillez réessayer.",
|
|
3085
|
+
NOT_LOGGED_IN: "Connectez-vous en tant qu'agent pour voir vos réservations.",
|
|
3086
|
+
SESSION_EXPIRED: "Votre session a expiré, veuillez vous reconnecter."
|
|
3087
|
+
};
|
|
2885
3088
|
var frBeJson = {
|
|
2886
3089
|
STEPS: STEPS$a,
|
|
2887
3090
|
INPUT: INPUT$a,
|
|
@@ -2902,7 +3105,8 @@ var frBeJson = {
|
|
|
2902
3105
|
QSM: QSM$b,
|
|
2903
3106
|
SRP: SRP$a,
|
|
2904
3107
|
ITINERARY: ITINERARY$a,
|
|
2905
|
-
FORM: FORM$a
|
|
3108
|
+
FORM: FORM$a,
|
|
3109
|
+
AGENT_ENTRIES: AGENT_ENTRIES$a
|
|
2906
3110
|
};
|
|
2907
3111
|
|
|
2908
3112
|
var STEPS$9 = {
|
|
@@ -3355,6 +3559,39 @@ var FORM$9 = {
|
|
|
3355
3559
|
YES: "Oui",
|
|
3356
3560
|
NO: "Non"
|
|
3357
3561
|
};
|
|
3562
|
+
var AGENT_ENTRIES$9 = {
|
|
3563
|
+
TITLE: "Réservations",
|
|
3564
|
+
MY_BOOKINGS: "Mes réservations",
|
|
3565
|
+
NUMBER: "Numéro",
|
|
3566
|
+
DEPARTURE_DATE: "Date de départ",
|
|
3567
|
+
STATUS: "Statut",
|
|
3568
|
+
CUSTOM_STATUS: "Statut personnalisé",
|
|
3569
|
+
RETURN_DATE: "Date de retour",
|
|
3570
|
+
PROFIT: "Bénéfice",
|
|
3571
|
+
NETTO_SELLING_PRICE: "Prix de vente net",
|
|
3572
|
+
YOUR_SURCHARGE: "Votre supplément",
|
|
3573
|
+
CREATED: "Créé le",
|
|
3574
|
+
CONTACT: "Contact",
|
|
3575
|
+
MAIN_BOOKER: "Réservant principal",
|
|
3576
|
+
PRODUCT: "Produit",
|
|
3577
|
+
TRAVELERS: "Voyageurs",
|
|
3578
|
+
ACTIONS: "Actions",
|
|
3579
|
+
DETAILS: "Détails",
|
|
3580
|
+
HIDE_DETAILS: "Masquer les détails",
|
|
3581
|
+
PRINTS: "Impressions",
|
|
3582
|
+
ALL: "Tous",
|
|
3583
|
+
X_ITEMS: "{0} éléments",
|
|
3584
|
+
PAGE_SIZE: "Éléments par page",
|
|
3585
|
+
PREVIOUS: "Précédent",
|
|
3586
|
+
NEXT: "Suivant",
|
|
3587
|
+
PAGE_X_OF_Y: "Page {0} sur {1}",
|
|
3588
|
+
LOADING: "Chargement...",
|
|
3589
|
+
NO_ITEMS: "Aucune réservation trouvée.",
|
|
3590
|
+
ERROR: "Une erreur est survenue lors du chargement de vos réservations.",
|
|
3591
|
+
PRINT_ERROR: "L'impression a échoué, veuillez réessayer.",
|
|
3592
|
+
NOT_LOGGED_IN: "Connectez-vous en tant qu'agent pour voir vos réservations.",
|
|
3593
|
+
SESSION_EXPIRED: "Votre session a expiré, veuillez vous reconnecter."
|
|
3594
|
+
};
|
|
3358
3595
|
var frFrJson = {
|
|
3359
3596
|
STEPS: STEPS$9,
|
|
3360
3597
|
INPUT: INPUT$9,
|
|
@@ -3375,7 +3612,8 @@ var frFrJson = {
|
|
|
3375
3612
|
QSM: QSM$a,
|
|
3376
3613
|
SRP: SRP$9,
|
|
3377
3614
|
ITINERARY: ITINERARY$9,
|
|
3378
|
-
FORM: FORM$9
|
|
3615
|
+
FORM: FORM$9,
|
|
3616
|
+
AGENT_ENTRIES: AGENT_ENTRIES$9
|
|
3379
3617
|
};
|
|
3380
3618
|
|
|
3381
3619
|
var STEPS$8 = {
|
|
@@ -3828,6 +4066,39 @@ var FORM$8 = {
|
|
|
3828
4066
|
YES: "Já",
|
|
3829
4067
|
NO: "Nei"
|
|
3830
4068
|
};
|
|
4069
|
+
var AGENT_ENTRIES$8 = {
|
|
4070
|
+
TITLE: "Bókanir",
|
|
4071
|
+
MY_BOOKINGS: "Mínar bókanir",
|
|
4072
|
+
NUMBER: "Númer",
|
|
4073
|
+
DEPARTURE_DATE: "Brottfarardagur",
|
|
4074
|
+
STATUS: "Staða",
|
|
4075
|
+
CUSTOM_STATUS: "Sérsniðin staða",
|
|
4076
|
+
RETURN_DATE: "Heimkomudagur",
|
|
4077
|
+
PROFIT: "Hagnaður",
|
|
4078
|
+
NETTO_SELLING_PRICE: "Nettó söluverð",
|
|
4079
|
+
YOUR_SURCHARGE: "Þitt álag",
|
|
4080
|
+
CREATED: "Stofnað",
|
|
4081
|
+
CONTACT: "Tengiliður",
|
|
4082
|
+
MAIN_BOOKER: "Aðalbókandi",
|
|
4083
|
+
PRODUCT: "Vara",
|
|
4084
|
+
TRAVELERS: "Ferðalangar",
|
|
4085
|
+
ACTIONS: "Aðgerðir",
|
|
4086
|
+
DETAILS: "Nánar",
|
|
4087
|
+
HIDE_DETAILS: "Fela nánar",
|
|
4088
|
+
PRINTS: "Útprentanir",
|
|
4089
|
+
ALL: "Allt",
|
|
4090
|
+
X_ITEMS: "{0} atriði",
|
|
4091
|
+
PAGE_SIZE: "Atriði á síðu",
|
|
4092
|
+
PREVIOUS: "Fyrri",
|
|
4093
|
+
NEXT: "Næsta",
|
|
4094
|
+
PAGE_X_OF_Y: "Síða {0} af {1}",
|
|
4095
|
+
LOADING: "Hleður...",
|
|
4096
|
+
NO_ITEMS: "Engar bókanir fundust.",
|
|
4097
|
+
ERROR: "Eitthvað fór úrskeiðis við að hlaða bókunum þínum.",
|
|
4098
|
+
PRINT_ERROR: "Prentun mistókst, reyndu aftur.",
|
|
4099
|
+
NOT_LOGGED_IN: "Skráðu þig inn sem umboðsaðili til að sjá bókanir þínar.",
|
|
4100
|
+
SESSION_EXPIRED: "Lotan þín er útrunnin, skráðu þig inn aftur."
|
|
4101
|
+
};
|
|
3831
4102
|
var isJson = {
|
|
3832
4103
|
STEPS: STEPS$8,
|
|
3833
4104
|
INPUT: INPUT$8,
|
|
@@ -3848,7 +4119,8 @@ var isJson = {
|
|
|
3848
4119
|
QSM: QSM$9,
|
|
3849
4120
|
SRP: SRP$8,
|
|
3850
4121
|
ITINERARY: ITINERARY$8,
|
|
3851
|
-
FORM: FORM$8
|
|
4122
|
+
FORM: FORM$8,
|
|
4123
|
+
AGENT_ENTRIES: AGENT_ENTRIES$8
|
|
3852
4124
|
};
|
|
3853
4125
|
|
|
3854
4126
|
var STEPS$7 = {
|
|
@@ -4301,6 +4573,39 @@ var FORM$7 = {
|
|
|
4301
4573
|
YES: "Sì",
|
|
4302
4574
|
NO: "No"
|
|
4303
4575
|
};
|
|
4576
|
+
var AGENT_ENTRIES$7 = {
|
|
4577
|
+
TITLE: "Prenotazioni",
|
|
4578
|
+
MY_BOOKINGS: "Le mie prenotazioni",
|
|
4579
|
+
NUMBER: "Numero",
|
|
4580
|
+
DEPARTURE_DATE: "Data di partenza",
|
|
4581
|
+
STATUS: "Stato",
|
|
4582
|
+
CUSTOM_STATUS: "Stato personalizzato",
|
|
4583
|
+
RETURN_DATE: "Data di ritorno",
|
|
4584
|
+
PROFIT: "Profitto",
|
|
4585
|
+
NETTO_SELLING_PRICE: "Prezzo di vendita netto",
|
|
4586
|
+
YOUR_SURCHARGE: "Il tuo supplemento",
|
|
4587
|
+
CREATED: "Creato",
|
|
4588
|
+
CONTACT: "Contatto",
|
|
4589
|
+
MAIN_BOOKER: "Prenotante principale",
|
|
4590
|
+
PRODUCT: "Prodotto",
|
|
4591
|
+
TRAVELERS: "Viaggiatori",
|
|
4592
|
+
ACTIONS: "Azioni",
|
|
4593
|
+
DETAILS: "Dettagli",
|
|
4594
|
+
HIDE_DETAILS: "Nascondi dettagli",
|
|
4595
|
+
PRINTS: "Stampe",
|
|
4596
|
+
ALL: "Tutti",
|
|
4597
|
+
X_ITEMS: "{0} elementi",
|
|
4598
|
+
PAGE_SIZE: "Elementi per pagina",
|
|
4599
|
+
PREVIOUS: "Precedente",
|
|
4600
|
+
NEXT: "Successivo",
|
|
4601
|
+
PAGE_X_OF_Y: "Pagina {0} di {1}",
|
|
4602
|
+
LOADING: "Caricamento...",
|
|
4603
|
+
NO_ITEMS: "Nessuna prenotazione trovata.",
|
|
4604
|
+
ERROR: "Si è verificato un errore durante il caricamento delle prenotazioni.",
|
|
4605
|
+
PRINT_ERROR: "Stampa non riuscita, riprova.",
|
|
4606
|
+
NOT_LOGGED_IN: "Accedi come agente per vedere le tue prenotazioni.",
|
|
4607
|
+
SESSION_EXPIRED: "La sessione è scaduta, accedi di nuovo."
|
|
4608
|
+
};
|
|
4304
4609
|
var itJson = {
|
|
4305
4610
|
STEPS: STEPS$7,
|
|
4306
4611
|
INPUT: INPUT$7,
|
|
@@ -4321,7 +4626,8 @@ var itJson = {
|
|
|
4321
4626
|
QSM: QSM$8,
|
|
4322
4627
|
SRP: SRP$7,
|
|
4323
4628
|
ITINERARY: ITINERARY$7,
|
|
4324
|
-
FORM: FORM$7
|
|
4629
|
+
FORM: FORM$7,
|
|
4630
|
+
AGENT_ENTRIES: AGENT_ENTRIES$7
|
|
4325
4631
|
};
|
|
4326
4632
|
|
|
4327
4633
|
var STEPS$6 = {
|
|
@@ -4778,6 +5084,39 @@ var FORM$6 = {
|
|
|
4778
5084
|
YES: "Ja",
|
|
4779
5085
|
NO: "Nee"
|
|
4780
5086
|
};
|
|
5087
|
+
var AGENT_ENTRIES$6 = {
|
|
5088
|
+
TITLE: "Boekingen",
|
|
5089
|
+
MY_BOOKINGS: "Mijn boekingen",
|
|
5090
|
+
NUMBER: "Nummer",
|
|
5091
|
+
DEPARTURE_DATE: "Vertrekdatum",
|
|
5092
|
+
STATUS: "Status",
|
|
5093
|
+
CUSTOM_STATUS: "Aangepaste status",
|
|
5094
|
+
RETURN_DATE: "Terugkeerdatum",
|
|
5095
|
+
PROFIT: "Winst",
|
|
5096
|
+
NETTO_SELLING_PRICE: "Netto verkoopprijs",
|
|
5097
|
+
YOUR_SURCHARGE: "Jouw toeslag",
|
|
5098
|
+
CREATED: "Aangemaakt",
|
|
5099
|
+
CONTACT: "Contact",
|
|
5100
|
+
MAIN_BOOKER: "Hoofdboeker",
|
|
5101
|
+
PRODUCT: "Product",
|
|
5102
|
+
TRAVELERS: "Reizigers",
|
|
5103
|
+
ACTIONS: "Acties",
|
|
5104
|
+
DETAILS: "Details",
|
|
5105
|
+
HIDE_DETAILS: "Details verbergen",
|
|
5106
|
+
PRINTS: "Afdrukken",
|
|
5107
|
+
ALL: "Alle",
|
|
5108
|
+
X_ITEMS: "{0} items",
|
|
5109
|
+
PAGE_SIZE: "Items per pagina",
|
|
5110
|
+
PREVIOUS: "Vorige",
|
|
5111
|
+
NEXT: "Volgende",
|
|
5112
|
+
PAGE_X_OF_Y: "Pagina {0} van {1}",
|
|
5113
|
+
LOADING: "Laden...",
|
|
5114
|
+
NO_ITEMS: "Geen boekingen gevonden.",
|
|
5115
|
+
ERROR: "Er ging iets mis bij het laden van je boekingen.",
|
|
5116
|
+
PRINT_ERROR: "Afdrukken mislukt, probeer het opnieuw.",
|
|
5117
|
+
NOT_LOGGED_IN: "Log in als agent om je boekingen te zien.",
|
|
5118
|
+
SESSION_EXPIRED: "Je sessie is verlopen, log opnieuw in."
|
|
5119
|
+
};
|
|
4781
5120
|
var nlBeJson = {
|
|
4782
5121
|
STEPS: STEPS$6,
|
|
4783
5122
|
INPUT: INPUT$6,
|
|
@@ -4798,7 +5137,8 @@ var nlBeJson = {
|
|
|
4798
5137
|
QSM: QSM$7,
|
|
4799
5138
|
SRP: SRP$6,
|
|
4800
5139
|
ITINERARY: ITINERARY$6,
|
|
4801
|
-
FORM: FORM$6
|
|
5140
|
+
FORM: FORM$6,
|
|
5141
|
+
AGENT_ENTRIES: AGENT_ENTRIES$6
|
|
4802
5142
|
};
|
|
4803
5143
|
|
|
4804
5144
|
var STEPS$5 = {
|
|
@@ -5251,6 +5591,39 @@ var FORM$5 = {
|
|
|
5251
5591
|
YES: "Ja",
|
|
5252
5592
|
NO: "Nee"
|
|
5253
5593
|
};
|
|
5594
|
+
var AGENT_ENTRIES$5 = {
|
|
5595
|
+
TITLE: "Boekingen",
|
|
5596
|
+
MY_BOOKINGS: "Mijn boekingen",
|
|
5597
|
+
NUMBER: "Nummer",
|
|
5598
|
+
DEPARTURE_DATE: "Vertrekdatum",
|
|
5599
|
+
STATUS: "Status",
|
|
5600
|
+
CUSTOM_STATUS: "Aangepaste status",
|
|
5601
|
+
RETURN_DATE: "Terugkeerdatum",
|
|
5602
|
+
PROFIT: "Winst",
|
|
5603
|
+
NETTO_SELLING_PRICE: "Netto verkoopprijs",
|
|
5604
|
+
YOUR_SURCHARGE: "Jouw toeslag",
|
|
5605
|
+
CREATED: "Aangemaakt",
|
|
5606
|
+
CONTACT: "Contact",
|
|
5607
|
+
MAIN_BOOKER: "Hoofdboeker",
|
|
5608
|
+
PRODUCT: "Product",
|
|
5609
|
+
TRAVELERS: "Reizigers",
|
|
5610
|
+
ACTIONS: "Acties",
|
|
5611
|
+
DETAILS: "Details",
|
|
5612
|
+
HIDE_DETAILS: "Details verbergen",
|
|
5613
|
+
PRINTS: "Afdrukken",
|
|
5614
|
+
ALL: "Alle",
|
|
5615
|
+
X_ITEMS: "{0} items",
|
|
5616
|
+
PAGE_SIZE: "Items per pagina",
|
|
5617
|
+
PREVIOUS: "Vorige",
|
|
5618
|
+
NEXT: "Volgende",
|
|
5619
|
+
PAGE_X_OF_Y: "Pagina {0} van {1}",
|
|
5620
|
+
LOADING: "Laden...",
|
|
5621
|
+
NO_ITEMS: "Geen boekingen gevonden.",
|
|
5622
|
+
ERROR: "Er ging iets mis bij het laden van je boekingen.",
|
|
5623
|
+
PRINT_ERROR: "Afdrukken mislukt, probeer het opnieuw.",
|
|
5624
|
+
NOT_LOGGED_IN: "Log in als agent om je boekingen te zien.",
|
|
5625
|
+
SESSION_EXPIRED: "Je sessie is verlopen, log opnieuw in."
|
|
5626
|
+
};
|
|
5254
5627
|
var nlNlJson = {
|
|
5255
5628
|
STEPS: STEPS$5,
|
|
5256
5629
|
INPUT: INPUT$5,
|
|
@@ -5271,7 +5644,8 @@ var nlNlJson = {
|
|
|
5271
5644
|
QSM: QSM$6,
|
|
5272
5645
|
SRP: SRP$5,
|
|
5273
5646
|
ITINERARY: ITINERARY$5,
|
|
5274
|
-
FORM: FORM$5
|
|
5647
|
+
FORM: FORM$5,
|
|
5648
|
+
AGENT_ENTRIES: AGENT_ENTRIES$5
|
|
5275
5649
|
};
|
|
5276
5650
|
|
|
5277
5651
|
var STEPS$4 = {
|
|
@@ -5724,6 +6098,39 @@ var FORM$4 = {
|
|
|
5724
6098
|
YES: "Ja",
|
|
5725
6099
|
NO: "Nei"
|
|
5726
6100
|
};
|
|
6101
|
+
var AGENT_ENTRIES$4 = {
|
|
6102
|
+
TITLE: "Bestillinger",
|
|
6103
|
+
MY_BOOKINGS: "Mine bestillinger",
|
|
6104
|
+
NUMBER: "Nummer",
|
|
6105
|
+
DEPARTURE_DATE: "Avreisedato",
|
|
6106
|
+
STATUS: "Status",
|
|
6107
|
+
CUSTOM_STATUS: "Egendefinert status",
|
|
6108
|
+
RETURN_DATE: "Returdato",
|
|
6109
|
+
PROFIT: "Fortjeneste",
|
|
6110
|
+
NETTO_SELLING_PRICE: "Netto salgspris",
|
|
6111
|
+
YOUR_SURCHARGE: "Ditt tillegg",
|
|
6112
|
+
CREATED: "Opprettet",
|
|
6113
|
+
CONTACT: "Kontakt",
|
|
6114
|
+
MAIN_BOOKER: "Hovedbestiller",
|
|
6115
|
+
PRODUCT: "Produkt",
|
|
6116
|
+
TRAVELERS: "Reisende",
|
|
6117
|
+
ACTIONS: "Handlinger",
|
|
6118
|
+
DETAILS: "Detaljer",
|
|
6119
|
+
HIDE_DETAILS: "Skjul detaljer",
|
|
6120
|
+
PRINTS: "Utskrifter",
|
|
6121
|
+
ALL: "Alle",
|
|
6122
|
+
X_ITEMS: "{0} elementer",
|
|
6123
|
+
PAGE_SIZE: "Elementer per side",
|
|
6124
|
+
PREVIOUS: "Forrige",
|
|
6125
|
+
NEXT: "Neste",
|
|
6126
|
+
PAGE_X_OF_Y: "Side {0} av {1}",
|
|
6127
|
+
LOADING: "Laster...",
|
|
6128
|
+
NO_ITEMS: "Ingen bestillinger funnet.",
|
|
6129
|
+
ERROR: "Noe gikk galt under lasting av bestillingene dine.",
|
|
6130
|
+
PRINT_ERROR: "Utskrift mislyktes, prøv igjen.",
|
|
6131
|
+
NOT_LOGGED_IN: "Logg inn som agent for å se bestillingene dine.",
|
|
6132
|
+
SESSION_EXPIRED: "Økten din er utløpt, logg inn på nytt."
|
|
6133
|
+
};
|
|
5727
6134
|
var noJson = {
|
|
5728
6135
|
STEPS: STEPS$4,
|
|
5729
6136
|
INPUT: INPUT$4,
|
|
@@ -5744,7 +6151,8 @@ var noJson = {
|
|
|
5744
6151
|
QSM: QSM$5,
|
|
5745
6152
|
SRP: SRP$4,
|
|
5746
6153
|
ITINERARY: ITINERARY$4,
|
|
5747
|
-
FORM: FORM$4
|
|
6154
|
+
FORM: FORM$4,
|
|
6155
|
+
AGENT_ENTRIES: AGENT_ENTRIES$4
|
|
5748
6156
|
};
|
|
5749
6157
|
|
|
5750
6158
|
var STEPS$3 = {
|
|
@@ -6197,6 +6605,39 @@ var FORM$3 = {
|
|
|
6197
6605
|
YES: "Tak",
|
|
6198
6606
|
NO: "Nie"
|
|
6199
6607
|
};
|
|
6608
|
+
var AGENT_ENTRIES$3 = {
|
|
6609
|
+
TITLE: "Rezerwacje",
|
|
6610
|
+
MY_BOOKINGS: "Moje rezerwacje",
|
|
6611
|
+
NUMBER: "Numer",
|
|
6612
|
+
DEPARTURE_DATE: "Data wyjazdu",
|
|
6613
|
+
STATUS: "Status",
|
|
6614
|
+
CUSTOM_STATUS: "Status niestandardowy",
|
|
6615
|
+
RETURN_DATE: "Data powrotu",
|
|
6616
|
+
PROFIT: "Zysk",
|
|
6617
|
+
NETTO_SELLING_PRICE: "Cena sprzedaży netto",
|
|
6618
|
+
YOUR_SURCHARGE: "Twoja dopłata",
|
|
6619
|
+
CREATED: "Utworzono",
|
|
6620
|
+
CONTACT: "Kontakt",
|
|
6621
|
+
MAIN_BOOKER: "Główny rezerwujący",
|
|
6622
|
+
PRODUCT: "Produkt",
|
|
6623
|
+
TRAVELERS: "Podróżni",
|
|
6624
|
+
ACTIONS: "Akcje",
|
|
6625
|
+
DETAILS: "Szczegóły",
|
|
6626
|
+
HIDE_DETAILS: "Ukryj szczegóły",
|
|
6627
|
+
PRINTS: "Wydruki",
|
|
6628
|
+
ALL: "Wszystkie",
|
|
6629
|
+
X_ITEMS: "{0} pozycji",
|
|
6630
|
+
PAGE_SIZE: "Pozycji na stronę",
|
|
6631
|
+
PREVIOUS: "Poprzednia",
|
|
6632
|
+
NEXT: "Następna",
|
|
6633
|
+
PAGE_X_OF_Y: "Strona {0} z {1}",
|
|
6634
|
+
LOADING: "Ładowanie...",
|
|
6635
|
+
NO_ITEMS: "Nie znaleziono rezerwacji.",
|
|
6636
|
+
ERROR: "Wystąpił błąd podczas ładowania rezerwacji.",
|
|
6637
|
+
PRINT_ERROR: "Drukowanie nie powiodło się, spróbuj ponownie.",
|
|
6638
|
+
NOT_LOGGED_IN: "Zaloguj się jako agent, aby zobaczyć swoje rezerwacje.",
|
|
6639
|
+
SESSION_EXPIRED: "Twoja sesja wygasła, zaloguj się ponownie."
|
|
6640
|
+
};
|
|
6200
6641
|
var plJson = {
|
|
6201
6642
|
STEPS: STEPS$3,
|
|
6202
6643
|
INPUT: INPUT$3,
|
|
@@ -6217,7 +6658,8 @@ var plJson = {
|
|
|
6217
6658
|
QSM: QSM$4,
|
|
6218
6659
|
SRP: SRP$3,
|
|
6219
6660
|
ITINERARY: ITINERARY$3,
|
|
6220
|
-
FORM: FORM$3
|
|
6661
|
+
FORM: FORM$3,
|
|
6662
|
+
AGENT_ENTRIES: AGENT_ENTRIES$3
|
|
6221
6663
|
};
|
|
6222
6664
|
|
|
6223
6665
|
var STEPS$2 = {
|
|
@@ -6670,6 +7112,39 @@ var FORM$2 = {
|
|
|
6670
7112
|
YES: "Sim",
|
|
6671
7113
|
NO: "Não"
|
|
6672
7114
|
};
|
|
7115
|
+
var AGENT_ENTRIES$2 = {
|
|
7116
|
+
TITLE: "Reservas",
|
|
7117
|
+
MY_BOOKINGS: "As minhas reservas",
|
|
7118
|
+
NUMBER: "Número",
|
|
7119
|
+
DEPARTURE_DATE: "Data de partida",
|
|
7120
|
+
STATUS: "Estado",
|
|
7121
|
+
CUSTOM_STATUS: "Estado personalizado",
|
|
7122
|
+
RETURN_DATE: "Data de regresso",
|
|
7123
|
+
PROFIT: "Lucro",
|
|
7124
|
+
NETTO_SELLING_PRICE: "Preço de venda líquido",
|
|
7125
|
+
YOUR_SURCHARGE: "A sua sobretaxa",
|
|
7126
|
+
CREATED: "Criado",
|
|
7127
|
+
CONTACT: "Contacto",
|
|
7128
|
+
MAIN_BOOKER: "Titular da reserva",
|
|
7129
|
+
PRODUCT: "Produto",
|
|
7130
|
+
TRAVELERS: "Viajantes",
|
|
7131
|
+
ACTIONS: "Ações",
|
|
7132
|
+
DETAILS: "Detalhes",
|
|
7133
|
+
HIDE_DETAILS: "Ocultar detalhes",
|
|
7134
|
+
PRINTS: "Impressões",
|
|
7135
|
+
ALL: "Todos",
|
|
7136
|
+
X_ITEMS: "{0} itens",
|
|
7137
|
+
PAGE_SIZE: "Itens por página",
|
|
7138
|
+
PREVIOUS: "Anterior",
|
|
7139
|
+
NEXT: "Seguinte",
|
|
7140
|
+
PAGE_X_OF_Y: "Página {0} de {1}",
|
|
7141
|
+
LOADING: "A carregar...",
|
|
7142
|
+
NO_ITEMS: "Nenhuma reserva encontrada.",
|
|
7143
|
+
ERROR: "Ocorreu um erro ao carregar as suas reservas.",
|
|
7144
|
+
PRINT_ERROR: "A impressão falhou, tente novamente.",
|
|
7145
|
+
NOT_LOGGED_IN: "Inicie sessão como agente para ver as suas reservas.",
|
|
7146
|
+
SESSION_EXPIRED: "A sua sessão expirou, inicie sessão novamente."
|
|
7147
|
+
};
|
|
6673
7148
|
var ptJson = {
|
|
6674
7149
|
STEPS: STEPS$2,
|
|
6675
7150
|
INPUT: INPUT$2,
|
|
@@ -6690,7 +7165,8 @@ var ptJson = {
|
|
|
6690
7165
|
QSM: QSM$3,
|
|
6691
7166
|
SRP: SRP$2,
|
|
6692
7167
|
ITINERARY: ITINERARY$2,
|
|
6693
|
-
FORM: FORM$2
|
|
7168
|
+
FORM: FORM$2,
|
|
7169
|
+
AGENT_ENTRIES: AGENT_ENTRIES$2
|
|
6694
7170
|
};
|
|
6695
7171
|
|
|
6696
7172
|
var STEPS$1 = {
|
|
@@ -7143,6 +7619,39 @@ var FORM$1 = {
|
|
|
7143
7619
|
YES: "Ja",
|
|
7144
7620
|
NO: "Nej"
|
|
7145
7621
|
};
|
|
7622
|
+
var AGENT_ENTRIES$1 = {
|
|
7623
|
+
TITLE: "Bokningar",
|
|
7624
|
+
MY_BOOKINGS: "Mina bokningar",
|
|
7625
|
+
NUMBER: "Nummer",
|
|
7626
|
+
DEPARTURE_DATE: "Avresedatum",
|
|
7627
|
+
STATUS: "Status",
|
|
7628
|
+
CUSTOM_STATUS: "Anpassad status",
|
|
7629
|
+
RETURN_DATE: "Returdatum",
|
|
7630
|
+
PROFIT: "Vinst",
|
|
7631
|
+
NETTO_SELLING_PRICE: "Nettoförsäljningspris",
|
|
7632
|
+
YOUR_SURCHARGE: "Ditt tillägg",
|
|
7633
|
+
CREATED: "Skapad",
|
|
7634
|
+
CONTACT: "Kontakt",
|
|
7635
|
+
MAIN_BOOKER: "Huvudbokare",
|
|
7636
|
+
PRODUCT: "Produkt",
|
|
7637
|
+
TRAVELERS: "Resenärer",
|
|
7638
|
+
ACTIONS: "Åtgärder",
|
|
7639
|
+
DETAILS: "Detaljer",
|
|
7640
|
+
HIDE_DETAILS: "Dölj detaljer",
|
|
7641
|
+
PRINTS: "Utskrifter",
|
|
7642
|
+
ALL: "Alla",
|
|
7643
|
+
X_ITEMS: "{0} objekt",
|
|
7644
|
+
PAGE_SIZE: "Objekt per sida",
|
|
7645
|
+
PREVIOUS: "Föregående",
|
|
7646
|
+
NEXT: "Nästa",
|
|
7647
|
+
PAGE_X_OF_Y: "Sida {0} av {1}",
|
|
7648
|
+
LOADING: "Laddar...",
|
|
7649
|
+
NO_ITEMS: "Inga bokningar hittades.",
|
|
7650
|
+
ERROR: "Något gick fel när dina bokningar laddades.",
|
|
7651
|
+
PRINT_ERROR: "Utskriften misslyckades, försök igen.",
|
|
7652
|
+
NOT_LOGGED_IN: "Logga in som agent för att se dina bokningar.",
|
|
7653
|
+
SESSION_EXPIRED: "Din session har gått ut, logga in igen."
|
|
7654
|
+
};
|
|
7146
7655
|
var svJson = {
|
|
7147
7656
|
STEPS: STEPS$1,
|
|
7148
7657
|
INPUT: INPUT$1,
|
|
@@ -7163,7 +7672,8 @@ var svJson = {
|
|
|
7163
7672
|
QSM: QSM$2,
|
|
7164
7673
|
SRP: SRP$1,
|
|
7165
7674
|
ITINERARY: ITINERARY$1,
|
|
7166
|
-
FORM: FORM$1
|
|
7675
|
+
FORM: FORM$1,
|
|
7676
|
+
AGENT_ENTRIES: AGENT_ENTRIES$1
|
|
7167
7677
|
};
|
|
7168
7678
|
|
|
7169
7679
|
var STEPS = {
|
|
@@ -7616,6 +8126,39 @@ var FORM = {
|
|
|
7616
8126
|
YES: "はい",
|
|
7617
8127
|
NO: "いいえ"
|
|
7618
8128
|
};
|
|
8129
|
+
var AGENT_ENTRIES = {
|
|
8130
|
+
TITLE: "予約",
|
|
8131
|
+
MY_BOOKINGS: "マイ予約",
|
|
8132
|
+
NUMBER: "番号",
|
|
8133
|
+
DEPARTURE_DATE: "出発日",
|
|
8134
|
+
STATUS: "ステータス",
|
|
8135
|
+
CUSTOM_STATUS: "カスタムステータス",
|
|
8136
|
+
RETURN_DATE: "帰着日",
|
|
8137
|
+
PROFIT: "利益",
|
|
8138
|
+
NETTO_SELLING_PRICE: "正味販売価格",
|
|
8139
|
+
YOUR_SURCHARGE: "手数料",
|
|
8140
|
+
CREATED: "作成日",
|
|
8141
|
+
CONTACT: "連絡先",
|
|
8142
|
+
MAIN_BOOKER: "代表予約者",
|
|
8143
|
+
PRODUCT: "商品",
|
|
8144
|
+
TRAVELERS: "旅行者",
|
|
8145
|
+
ACTIONS: "操作",
|
|
8146
|
+
DETAILS: "詳細",
|
|
8147
|
+
HIDE_DETAILS: "詳細を隠す",
|
|
8148
|
+
PRINTS: "印刷",
|
|
8149
|
+
ALL: "すべて",
|
|
8150
|
+
X_ITEMS: "{0} 件",
|
|
8151
|
+
PAGE_SIZE: "1ページあたりの件数",
|
|
8152
|
+
PREVIOUS: "前へ",
|
|
8153
|
+
NEXT: "次へ",
|
|
8154
|
+
PAGE_X_OF_Y: "{0} / {1} ページ",
|
|
8155
|
+
LOADING: "読み込み中...",
|
|
8156
|
+
NO_ITEMS: "予約が見つかりません。",
|
|
8157
|
+
ERROR: "予約の読み込み中にエラーが発生しました。",
|
|
8158
|
+
PRINT_ERROR: "印刷に失敗しました。もう一度お試しください。",
|
|
8159
|
+
NOT_LOGGED_IN: "予約を表示するにはエージェントとしてログインしてください。",
|
|
8160
|
+
SESSION_EXPIRED: "セッションの有効期限が切れました。再度ログインしてください。"
|
|
8161
|
+
};
|
|
7619
8162
|
var jaJson = {
|
|
7620
8163
|
STEPS: STEPS,
|
|
7621
8164
|
INPUT: INPUT,
|
|
@@ -7636,7 +8179,8 @@ var jaJson = {
|
|
|
7636
8179
|
QSM: QSM$1,
|
|
7637
8180
|
SRP: SRP,
|
|
7638
8181
|
ITINERARY: ITINERARY,
|
|
7639
|
-
FORM: FORM
|
|
8182
|
+
FORM: FORM,
|
|
8183
|
+
AGENT_ENTRIES: AGENT_ENTRIES
|
|
7640
8184
|
};
|
|
7641
8185
|
|
|
7642
8186
|
exports.DepartureRange = void 0;
|
|
@@ -15589,6 +16133,7 @@ var ENDPOINT$1 = "/api/web/packaging";
|
|
|
15589
16133
|
var ENDPOINT_START_TRANSACTION = ENDPOINT$1 + "/start";
|
|
15590
16134
|
var ENDPOINT_ACCOMMODATIONS = ENDPOINT$1 + "/accommodations";
|
|
15591
16135
|
var ENDPOINT_EXCURSIONS = ENDPOINT$1 + "/excursions";
|
|
16136
|
+
var ENDPOINT_TRANSFERS = ENDPOINT$1 + "/transfers";
|
|
15592
16137
|
var ENDPOINT_FLIGHTS = ENDPOINT$1 + "/flights";
|
|
15593
16138
|
var ENDPOINT_PRICE_DETAILS = ENDPOINT$1 + "/price-details";
|
|
15594
16139
|
var ENDPOINT_BOOK = ENDPOINT$1 + "/book";
|
|
@@ -15621,6 +16166,12 @@ var searchPackagingExcursions = function (config, request, signal) {
|
|
|
15621
16166
|
var body = JSON.stringify(request);
|
|
15622
16167
|
return post(url, apiKey, body, config.token, signal, true);
|
|
15623
16168
|
};
|
|
16169
|
+
var searchPackagingTransfers = function (config, request, signal) {
|
|
16170
|
+
var url = "" + config.host + ENDPOINT_TRANSFERS;
|
|
16171
|
+
var apiKey = config.apiKey;
|
|
16172
|
+
var body = JSON.stringify(request);
|
|
16173
|
+
return post(url, apiKey, body, config.token, signal, true);
|
|
16174
|
+
};
|
|
15624
16175
|
var getEntry = function (config, magicLinkCode, signal) {
|
|
15625
16176
|
var apiKey = config.apiKey;
|
|
15626
16177
|
var url = "" + config.host + ENDPOINT_ENTRY(magicLinkCode);
|
|
@@ -15798,6 +16349,7 @@ exports.searchOords = searchOords;
|
|
|
15798
16349
|
exports.searchPackagingAccommodations = searchPackagingAccommodations;
|
|
15799
16350
|
exports.searchPackagingExcursions = searchPackagingExcursions;
|
|
15800
16351
|
exports.searchPackagingFlights = searchPackagingFlights;
|
|
16352
|
+
exports.searchPackagingTransfers = searchPackagingTransfers;
|
|
15801
16353
|
exports.searchRegions = searchRegions;
|
|
15802
16354
|
exports.searchWithErrorMapping = searchWithErrorMapping;
|
|
15803
16355
|
exports.sendContactForm = sendContactForm;
|
|
@@ -19290,10 +19842,30 @@ function formatBirthDate$1(birthDate) {
|
|
|
19290
19842
|
// A field can have separate "main-booker"/other-pax variants sharing the same identity
|
|
19291
19843
|
// (customFieldConfigurationId for custom fields, fieldName for built-in fields).
|
|
19292
19844
|
const MAIN_BOOKER_GROUP = 'main-booker';
|
|
19845
|
+
const MAIN_BOOKER_FIELD_PREFIX = 'mainBooker';
|
|
19293
19846
|
const isCustomPaxField = (field) => field.customFieldConfigurationId != null;
|
|
19847
|
+
// Tide names the built-in main-booker fields with a prefix ('mainBookerGender', 'mainBookerCountryId', ...),
|
|
19848
|
+
// the other-pax ones without ('gender', 'countryId'). Strip it so both are variants of the same field.
|
|
19849
|
+
function normalizeBuiltInFieldName(field) {
|
|
19850
|
+
if (isCustomPaxField(field) || !field.fieldName?.startsWith(MAIN_BOOKER_FIELD_PREFIX))
|
|
19851
|
+
return field;
|
|
19852
|
+
const stripped = field.fieldName.slice(MAIN_BOOKER_FIELD_PREFIX.length);
|
|
19853
|
+
if (!stripped)
|
|
19854
|
+
return field;
|
|
19855
|
+
return { ...field, fieldName: stripped.charAt(0).toLowerCase() + stripped.slice(1) };
|
|
19856
|
+
}
|
|
19857
|
+
// Once Tide sends built-in fields, that configuration decides which built-in fields are shown/required;
|
|
19858
|
+
// the hardcoded formFields / core defaults are only the fallback for when it doesn't.
|
|
19859
|
+
function hasConfiguredBuiltInPaxFields(paxFields = []) {
|
|
19860
|
+
return paxFields.some((f) => !isCustomPaxField(f));
|
|
19861
|
+
}
|
|
19862
|
+
// The main booker's address/contact details are then asked on the main booker's own traveler block.
|
|
19863
|
+
function hasConfiguredMainBookerFields(paxFields = []) {
|
|
19864
|
+
return paxFields.some((f) => !isCustomPaxField(f) && f.group === MAIN_BOOKER_GROUP);
|
|
19865
|
+
}
|
|
19294
19866
|
function resolveApplicablePaxFields(fields, isMainBooker) {
|
|
19295
19867
|
const variantsByKey = new Map();
|
|
19296
|
-
fields.forEach((field) => {
|
|
19868
|
+
fields.map(normalizeBuiltInFieldName).forEach((field) => {
|
|
19297
19869
|
const key = field.customFieldConfigurationId ?? field.fieldName;
|
|
19298
19870
|
const variants = variantsByKey.get(key) ?? [];
|
|
19299
19871
|
variants.push(field);
|
|
@@ -19355,11 +19927,50 @@ const BUILT_IN_FIELD_PATHS = {
|
|
|
19355
19927
|
// The 4 fields that always render/validate regardless of paxFields config (fallback behavior).
|
|
19356
19928
|
const CORE_FIELD_NAMES = new Set(['gender', 'firstName', 'lastName', 'dateOfBirth']);
|
|
19357
19929
|
const ADDRESS_FIELD_NAMES = ['street', 'location', 'countryId', 'postalCode', 'number'];
|
|
19930
|
+
// Built-in fields have no dataType from Tide; their control type and label follow from the fieldName.
|
|
19931
|
+
// gender, hasInsurance, countryId, weight and height have a dedicated control and only need a label here.
|
|
19932
|
+
function getBuiltInFieldControlMeta(translations) {
|
|
19933
|
+
return {
|
|
19934
|
+
gender: { label: translations.TRAVELERS_FORM.GENDER_ID },
|
|
19935
|
+
firstName: { label: translations.TRAVELERS_FORM.FIRST_NAME },
|
|
19936
|
+
lastName: { label: translations.TRAVELERS_FORM.LAST_NAME },
|
|
19937
|
+
dateOfBirth: { type: 'date', label: translations.TRAVELERS_FORM.BIRTHDATE },
|
|
19938
|
+
nickname: { label: translations.TRAVELERS_FORM.NICKNAME },
|
|
19939
|
+
birthplace: { label: translations.TRAVELERS_FORM.BIRTHPLACE },
|
|
19940
|
+
nationality: { label: translations.TRAVELERS_FORM.NATIONALITY },
|
|
19941
|
+
preferredLanguageId: { type: 'number', label: translations.TRAVELERS_FORM.PREFERRED_LANGUAGE },
|
|
19942
|
+
email: { type: 'email', label: translations.TRAVELERS_FORM.TRAVELER_EMAIL },
|
|
19943
|
+
phone: { type: 'tel', label: translations.TRAVELERS_FORM.TRAVELER_PHONE },
|
|
19944
|
+
mobile: { type: 'tel', label: translations.TRAVELERS_FORM.TRAVELER_MOBILE },
|
|
19945
|
+
passportNumber: { label: translations.TRAVELERS_FORM.PASSPORT_NUMBER },
|
|
19946
|
+
passportIssueDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_ISSUE_DATE },
|
|
19947
|
+
passportIssuedLocation: { label: translations.TRAVELERS_FORM.PASSPORT_ISSUED_LOCATION },
|
|
19948
|
+
passportExpiryDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_EXPIRY_DATE },
|
|
19949
|
+
emergencyNumber: { type: 'tel', label: translations.TRAVELERS_FORM.EMERGENCY_NUMBER },
|
|
19950
|
+
hasInsurance: { label: translations.TRAVELERS_FORM.HAS_INSURANCE },
|
|
19951
|
+
insuranceName: { label: translations.TRAVELERS_FORM.INSURANCE_NAME },
|
|
19952
|
+
info: { label: translations.TRAVELERS_FORM.INFO },
|
|
19953
|
+
weight: { label: translations.TRAVELERS_FORM.WEIGHT },
|
|
19954
|
+
height: { label: translations.TRAVELERS_FORM.HEIGHT },
|
|
19955
|
+
street: { label: translations.TRAVELERS_FORM.STREET },
|
|
19956
|
+
location: { label: translations.TRAVELERS_FORM.CITY },
|
|
19957
|
+
countryId: { label: translations.TRAVELERS_FORM.COUNTRY },
|
|
19958
|
+
postalCode: { label: translations.TRAVELERS_FORM.ZIPCODE },
|
|
19959
|
+
number: { label: translations.TRAVELERS_FORM.HOUSE_NUMBER }
|
|
19960
|
+
};
|
|
19961
|
+
}
|
|
19962
|
+
// The form's gender radio values ('m'/'f'/'x') <-> Tide's Gender enum.
|
|
19963
|
+
const GENDER_BY_FORM_VALUE = { m: build.Gender.male, f: build.Gender.female, x: build.Gender.other };
|
|
19964
|
+
function formValueFromGender(gender) {
|
|
19965
|
+
return Object.keys(GENDER_BY_FORM_VALUE).find((key) => GENDER_BY_FORM_VALUE[key] === gender) ?? '';
|
|
19966
|
+
}
|
|
19358
19967
|
// Shared by buildPax (new-booking) and applyTravelersFormValuesToEditablePackagingEntry
|
|
19359
19968
|
// (edit-booking), now that PackagingEntryPax and BookingPackagePax have the same shape.
|
|
19360
19969
|
function applyTravelerToPax(pax, traveler, mainBookerId) {
|
|
19361
19970
|
return {
|
|
19362
19971
|
...pax,
|
|
19972
|
+
// Unanswered (optional) gender keeps whatever the pax already had.
|
|
19973
|
+
gender: GENDER_BY_FORM_VALUE[traveler.gender] ?? pax.gender,
|
|
19363
19974
|
firstName: traveler.firstName ?? '',
|
|
19364
19975
|
lastName: traveler.lastName ?? '',
|
|
19365
19976
|
dateOfBirth: traveler.birthDate || null,
|
|
@@ -19519,7 +20130,13 @@ function mapPackagingEntryPaxToTraveler(roomTraveler) {
|
|
|
19519
20130
|
customFields: roomTraveler.customFields ?? []
|
|
19520
20131
|
};
|
|
19521
20132
|
}
|
|
19522
|
-
|
|
20133
|
+
// Keeps the values already on the entry's pax and adds an empty slot for every configured custom field it lacks,
|
|
20134
|
+
// so the form renders/validates the same set as createTraveler does for a new booking.
|
|
20135
|
+
function mergeCustomFields(existing = [], paxFields) {
|
|
20136
|
+
const missing = buildEmptyCustomFields(paxFields).filter((empty) => !existing.some((c) => c.customFieldConfigurationId === empty.customFieldConfigurationId));
|
|
20137
|
+
return [...existing, ...missing];
|
|
20138
|
+
}
|
|
20139
|
+
function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, agentAdressId, paxFields = editablePackagingEntry?.paxFields ?? []) {
|
|
19523
20140
|
const pax = editablePackagingEntry?.pax ?? [];
|
|
19524
20141
|
const rooms = editablePackagingEntry.rooms.map((room) => {
|
|
19525
20142
|
const roomPax = pax.filter((x) => room.paxIds.includes(x.id));
|
|
@@ -19532,8 +20149,9 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
|
|
|
19532
20149
|
firstName: roomTraveler.firstName ?? '',
|
|
19533
20150
|
lastName: roomTraveler.lastName ?? '',
|
|
19534
20151
|
birthDate: roomTraveler.dateOfBirth ? dateFns.format(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
19535
|
-
gender:
|
|
19536
|
-
...mapPackagingEntryPaxToTraveler(roomTraveler)
|
|
20152
|
+
gender: formValueFromGender(roomTraveler.gender),
|
|
20153
|
+
...mapPackagingEntryPaxToTraveler(roomTraveler),
|
|
20154
|
+
customFields: mergeCustomFields(roomTraveler.customFields, paxFields)
|
|
19537
20155
|
};
|
|
19538
20156
|
}),
|
|
19539
20157
|
children: children.map((roomTraveler) => {
|
|
@@ -19542,9 +20160,10 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
|
|
|
19542
20160
|
firstName: roomTraveler.firstName ?? '',
|
|
19543
20161
|
lastName: roomTraveler.lastName ?? '',
|
|
19544
20162
|
birthDate: roomTraveler.dateOfBirth ? dateFns.format(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
19545
|
-
gender:
|
|
20163
|
+
gender: formValueFromGender(roomTraveler.gender),
|
|
19546
20164
|
isBaby: isBabyAge(roomTraveler.age),
|
|
19547
|
-
...mapPackagingEntryPaxToTraveler(roomTraveler)
|
|
20165
|
+
...mapPackagingEntryPaxToTraveler(roomTraveler),
|
|
20166
|
+
customFields: mergeCustomFields(roomTraveler.customFields, paxFields)
|
|
19548
20167
|
};
|
|
19549
20168
|
})
|
|
19550
20169
|
};
|
|
@@ -19569,7 +20188,8 @@ function applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry
|
|
|
19569
20188
|
const travelers = values.rooms.flatMap((room) => [...room.adults, ...room.children]);
|
|
19570
20189
|
// The backend treats the main booker's per-pax address as authoritative, so keep the
|
|
19571
20190
|
// booking-level address in sync with it rather than sending two independent values.
|
|
19572
|
-
const
|
|
20191
|
+
const mainBookerTraveler = travelers.find((x) => x.id === values.mainBookerId);
|
|
20192
|
+
const mainBookerAddress = mainBookerTraveler?.address;
|
|
19573
20193
|
return {
|
|
19574
20194
|
...editablePackagingEntry,
|
|
19575
20195
|
pax: (editablePackagingEntry.pax ?? []).map((pax) => {
|
|
@@ -19585,8 +20205,9 @@ function applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry
|
|
|
19585
20205
|
place: mainBookerAddress?.location || values.place,
|
|
19586
20206
|
country: mainBookerAddress?.country || values.country,
|
|
19587
20207
|
travelAgentId: values.travelAgentId,
|
|
19588
|
-
|
|
19589
|
-
|
|
20208
|
+
// When Tide configures the main-booker fields, contact details live on the main booker's traveler block.
|
|
20209
|
+
phone: values.phone || mainBookerTraveler?.mobile || mainBookerTraveler?.phone,
|
|
20210
|
+
email: values.email || mainBookerTraveler?.email
|
|
19590
20211
|
}
|
|
19591
20212
|
};
|
|
19592
20213
|
}
|
|
@@ -19743,30 +20364,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19743
20364
|
return (React__default["default"].createElement("div", { key: field.customFieldConfigurationId, style: { gridColumn: `span ${field.col || 12}` } }, getCustomFieldControl(field, value, name)));
|
|
19744
20365
|
})));
|
|
19745
20366
|
};
|
|
19746
|
-
|
|
19747
|
-
const BUILT_IN_FIELD_CONTROL_META = {
|
|
19748
|
-
firstName: { label: translations.TRAVELERS_FORM.FIRST_NAME },
|
|
19749
|
-
lastName: { label: translations.TRAVELERS_FORM.LAST_NAME },
|
|
19750
|
-
dateOfBirth: { type: 'date', label: translations.TRAVELERS_FORM.BIRTHDATE },
|
|
19751
|
-
nickname: { label: translations.TRAVELERS_FORM.NICKNAME },
|
|
19752
|
-
birthplace: { label: translations.TRAVELERS_FORM.BIRTHPLACE },
|
|
19753
|
-
nationality: { label: translations.TRAVELERS_FORM.NATIONALITY },
|
|
19754
|
-
preferredLanguageId: { type: 'number', label: translations.TRAVELERS_FORM.PREFERRED_LANGUAGE },
|
|
19755
|
-
email: { type: 'email', label: translations.TRAVELERS_FORM.TRAVELER_EMAIL },
|
|
19756
|
-
phone: { label: translations.TRAVELERS_FORM.TRAVELER_PHONE },
|
|
19757
|
-
mobile: { label: translations.TRAVELERS_FORM.TRAVELER_MOBILE },
|
|
19758
|
-
passportNumber: { label: translations.TRAVELERS_FORM.PASSPORT_NUMBER },
|
|
19759
|
-
passportIssueDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_ISSUE_DATE },
|
|
19760
|
-
passportIssuedLocation: { label: translations.TRAVELERS_FORM.PASSPORT_ISSUED_LOCATION },
|
|
19761
|
-
passportExpiryDate: { type: 'date', label: translations.TRAVELERS_FORM.PASSPORT_EXPIRY_DATE },
|
|
19762
|
-
emergencyNumber: { label: translations.TRAVELERS_FORM.EMERGENCY_NUMBER },
|
|
19763
|
-
insuranceName: { label: translations.TRAVELERS_FORM.INSURANCE_NAME },
|
|
19764
|
-
info: { label: translations.TRAVELERS_FORM.INFO },
|
|
19765
|
-
street: { label: translations.TRAVELERS_FORM.STREET },
|
|
19766
|
-
location: { label: translations.TRAVELERS_FORM.CITY },
|
|
19767
|
-
postalCode: { label: translations.TRAVELERS_FORM.ZIPCODE },
|
|
19768
|
-
number: { label: translations.TRAVELERS_FORM.HOUSE_NUMBER }
|
|
19769
|
-
};
|
|
20367
|
+
const BUILT_IN_FIELD_CONTROL_META = getBuiltInFieldControlMeta(translations);
|
|
19770
20368
|
const renderBuiltInFieldControl = (fieldName, isRequired, travelerValues, namePrefix) => {
|
|
19771
20369
|
const path = BUILT_IN_FIELD_PATHS[fieldName] ?? fieldName;
|
|
19772
20370
|
const name = `${namePrefix}.${path}`;
|
|
@@ -19801,7 +20399,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19801
20399
|
const resolveBuiltInField = (fieldName, travelerValues) => {
|
|
19802
20400
|
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
19803
20401
|
const configured = getBuiltInPaxField(paxFields, fieldName, isMainBooker);
|
|
19804
|
-
const fallback = CORE_FIELD_DEFAULTS[fieldName];
|
|
20402
|
+
const fallback = hasConfiguredBuiltInPaxFields(paxFields) ? undefined : CORE_FIELD_DEFAULTS[fieldName];
|
|
19805
20403
|
if (!configured && !fallback)
|
|
19806
20404
|
return undefined;
|
|
19807
20405
|
return { isRequired: configured?.isRequired ?? fallback.isRequired, col: configured?.col ?? fallback.col };
|
|
@@ -19813,7 +20411,14 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19813
20411
|
return (React__default["default"].createElement("div", { key: fieldName, style: { gridColumn: `span ${resolved.col || 12}` } }, renderBuiltInFieldControl(fieldName, resolved.isRequired, travelerValues, namePrefix)));
|
|
19814
20412
|
};
|
|
19815
20413
|
const renderTravelerAddressFields = (travelerValues, namePrefix) => {
|
|
19816
|
-
const
|
|
20414
|
+
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
20415
|
+
// Configured order when Tide sends one, so the configured col widths line up as intended.
|
|
20416
|
+
const fieldNames = hasConfiguredBuiltInPaxFields(paxFields)
|
|
20417
|
+
? getApplicableBuiltInPaxFields(paxFields, isMainBooker)
|
|
20418
|
+
.map((field) => field.fieldName)
|
|
20419
|
+
.filter((fieldName) => ADDRESS_FIELD_NAMES.includes(fieldName))
|
|
20420
|
+
: ADDRESS_FIELD_NAMES;
|
|
20421
|
+
const fields = fieldNames.map((fieldName) => renderBuiltInField(fieldName, travelerValues, namePrefix)).filter(Boolean);
|
|
19817
20422
|
if (!fields.length)
|
|
19818
20423
|
return null;
|
|
19819
20424
|
return React__default["default"].createElement("div", { className: "travelers-form__custom-fields-grid" }, fields);
|
|
@@ -19856,15 +20461,18 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19856
20461
|
return (React__default["default"].createElement("div", { className: "form__row" },
|
|
19857
20462
|
React__default["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 })));
|
|
19858
20463
|
}
|
|
19859
|
-
// 'birthDate' (the legacy formFields type string) is normalized to the paxFields catalog's
|
|
19860
|
-
// 'dateOfBirth' fieldName for config lookups.
|
|
19861
|
-
const baseFieldNames = (travellersSettings?.formFields?.length ? travellersSettings.formFields.map((field) => field.type) : ['gender', 'firstName', 'lastName', 'dateOfBirth']).map((fieldName) => (fieldName === 'birthDate' ? 'dateOfBirth' : fieldName));
|
|
19862
20464
|
const isMainBooker = travelerValues.id === formik.values.mainBookerId;
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
|
|
20465
|
+
// With a Tide field configuration, exactly the configured fields render, in their configured order.
|
|
20466
|
+
// Without one, fall back to formFields ('birthDate', the legacy type string, maps to 'dateOfBirth').
|
|
20467
|
+
const fieldNames = hasConfiguredBuiltInPaxFields(paxFields)
|
|
20468
|
+
? getApplicableBuiltInPaxFields(paxFields, isMainBooker)
|
|
20469
|
+
.map((field) => field.fieldName)
|
|
20470
|
+
.filter((fieldName) => !ADDRESS_FIELD_NAMES.includes(fieldName))
|
|
20471
|
+
: (travellersSettings?.formFields?.length
|
|
20472
|
+
? travellersSettings.formFields.map((field) => field.type)
|
|
20473
|
+
: ['gender', 'firstName', 'lastName', 'dateOfBirth']).map((fieldName) => (fieldName === 'birthDate' ? 'dateOfBirth' : fieldName));
|
|
19866
20474
|
return (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
19867
|
-
React__default["default"].createElement("div", { className: "travelers-form__custom-fields-grid" },
|
|
20475
|
+
React__default["default"].createElement("div", { className: "travelers-form__custom-fields-grid" }, fieldNames.map((fieldName) => renderBuiltInField(fieldName, travelerValues, namePrefix))),
|
|
19868
20476
|
renderTravelerAddressFields(travelerValues, namePrefix),
|
|
19869
20477
|
renderCustomFields(travelerValues, namePrefix),
|
|
19870
20478
|
travelersFirstStep && isAdult && formik.values.rooms[roomIndex].adults.length > 1 && (React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleRemoveTraveler(roomIndex, travelerIndex) }, translations.TRAVELERS_FORM.REMOVE_TRAVELER))));
|
|
@@ -19902,7 +20510,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19902
20510
|
renderTravelerFields(travelerValues, `rooms[${roomIndex}].children[${index}]`, false, roomIndex, index)))),
|
|
19903
20511
|
!useCompactForm && travelersFirstStep && (React__default["default"].createElement("div", { className: "form__region" },
|
|
19904
20512
|
React__default["default"].createElement("button", { type: "button", className: "cta cta--select", onClick: () => handleAddTraveler(roomIndex) }, translations.TRAVELERS_FORM.ADD_TRAVELER)))))),
|
|
19905
|
-
|
|
20513
|
+
useCompactForm || hasConfiguredMainBookerFields(paxFields) ? null : bookingType !== 'b2b' || travellersSettings?.mainBookerFormFields?.length ? (React__default["default"].createElement("div", { className: "form__region" },
|
|
19906
20514
|
React__default["default"].createElement("div", { className: "form__region-header" },
|
|
19907
20515
|
React__default["default"].createElement("h5", { className: "form__region-heading" }, translations.TRAVELERS_FORM.MAIN_BOOKER),
|
|
19908
20516
|
React__default["default"].createElement("p", { className: "form__region-label" }, lodash.compact([lodash.compact([mainBooker?.firstName, mainBooker?.lastName]).join(' '), formatBirthDate$1(mainBooker?.birthDate)]).join(', '))),
|
|
@@ -19921,9 +20529,9 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
|
|
|
19921
20529
|
React__default["default"].createElement("div", { className: "form__row" },
|
|
19922
20530
|
React__default["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 }),
|
|
19923
20531
|
React__default["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 }),
|
|
19924
|
-
React__default["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 })))))) :
|
|
20532
|
+
React__default["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["default"].createElement("div", { className: "form__region" },
|
|
19925
20533
|
React__default["default"].createElement("div", { className: "form__row" },
|
|
19926
|
-
React__default["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 }))))
|
|
20534
|
+
React__default["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 })))),
|
|
19927
20535
|
!useCompactForm && showAgentSelection && (React__default["default"].createElement("div", { className: "form__region" },
|
|
19928
20536
|
React__default["default"].createElement("div", { className: "form__region-header" },
|
|
19929
20537
|
React__default["default"].createElement("h5", { className: "form__region-heading" }, translations.TRAVELERS_FORM.BOOK_WITH_AGENT),
|
|
@@ -20534,8 +21142,9 @@ const selectBookingPackagePax = toolkit.createSelector(selectTravelersFormValues
|
|
|
20534
21142
|
formValues?.rooms.forEach((r) => r.adults.forEach((x) => {
|
|
20535
21143
|
const adultPax = buildPax(x, formValues?.mainBookerId);
|
|
20536
21144
|
if (adultPax.isMainBooker) {
|
|
20537
|
-
|
|
20538
|
-
adultPax.
|
|
21145
|
+
// Without the main booker block (Tide configures main-booker fields), keep the traveler's own details.
|
|
21146
|
+
adultPax.mobilePhone = formValues?.phone || adultPax.mobilePhone;
|
|
21147
|
+
adultPax.email = formValues?.email || adultPax.email;
|
|
20539
21148
|
}
|
|
20540
21149
|
pax.push(adultPax);
|
|
20541
21150
|
}));
|
|
@@ -20559,8 +21168,8 @@ const selectBookingAddress = toolkit.createSelector(selectTravelersFormValues, s
|
|
|
20559
21168
|
postalCode: mainBookerAddress?.postalCode || formValues?.zipCode,
|
|
20560
21169
|
location: mainBookerAddress?.location || formValues?.place,
|
|
20561
21170
|
country: mainBookerAddress?.country || formValues?.country,
|
|
20562
|
-
mobilePhone:
|
|
20563
|
-
email:
|
|
21171
|
+
mobilePhone: mainBooker.mobilePhone,
|
|
21172
|
+
email: mainBooker.email
|
|
20564
21173
|
};
|
|
20565
21174
|
});
|
|
20566
21175
|
const selectSubFormAnswers = (state) => state.booking.subFormAnswers;
|
|
@@ -25697,6 +26306,10 @@ const Summary = () => {
|
|
|
25697
26306
|
React__default["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))))));
|
|
25698
26307
|
};
|
|
25699
26308
|
|
|
26309
|
+
// lodash isEmpty is true for every number, which would flag a filled-in preferredLanguageId as missing.
|
|
26310
|
+
function isBlank(value) {
|
|
26311
|
+
return value === null || value === undefined || (typeof value === 'string' && value.trim() === '');
|
|
26312
|
+
}
|
|
25700
26313
|
function isValidEmail(email) {
|
|
25701
26314
|
return !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,24}$/i.test(email);
|
|
25702
26315
|
}
|
|
@@ -25720,9 +26333,14 @@ function getAge(birthDateText, startDateText) {
|
|
|
25720
26333
|
}
|
|
25721
26334
|
const validateForm = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE, maxBabyAge = BABY_MAX_AGE, paxFields = []) => {
|
|
25722
26335
|
const errors = {};
|
|
26336
|
+
const usesFieldConfiguration = hasConfiguredBuiltInPaxFields(paxFields);
|
|
26337
|
+
const builtInFieldMeta = getBuiltInFieldControlMeta(translations);
|
|
25723
26338
|
const isFormFieldPresent = (type) => {
|
|
25724
26339
|
return formFields?.some((f) => f.type === type) ?? true;
|
|
25725
26340
|
};
|
|
26341
|
+
// The 4 core fields: with a Tide field configuration they're required only when configured so for the
|
|
26342
|
+
// traveler's role (main booker / other pax); without one, whenever formFields lists them (legacy behavior).
|
|
26343
|
+
const isCoreFieldRequired = (traveler, legacyType, fieldName = legacyType) => usesFieldConfiguration ? !!getBuiltInPaxField(paxFields, fieldName, traveler.id === values.mainBookerId)?.isRequired : isFormFieldPresent(legacyType);
|
|
25726
26344
|
const isMainBookerFormFieldPresent = (type) => {
|
|
25727
26345
|
return mainBookerFormFields?.some((f) => f.type === type) ?? true;
|
|
25728
26346
|
};
|
|
@@ -25774,16 +26392,16 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25774
26392
|
const fieldPath = BUILT_IN_FIELD_PATHS[field.fieldName];
|
|
25775
26393
|
if (!fieldPath)
|
|
25776
26394
|
return;
|
|
25777
|
-
if (
|
|
25778
|
-
lodash.set(errors, `${path}.${fieldPath}`, formatTravelerField(room, pax, field.fieldName));
|
|
26395
|
+
if (isBlank(lodash.get(traveler, fieldPath))) {
|
|
26396
|
+
lodash.set(errors, `${path}.${fieldPath}`, formatTravelerField(room, pax, builtInFieldMeta[field.fieldName]?.label ?? field.fieldName));
|
|
25779
26397
|
}
|
|
25780
26398
|
});
|
|
25781
26399
|
};
|
|
25782
26400
|
values.rooms.forEach((r, rIndex) => r.adults.forEach((adult, index) => {
|
|
25783
|
-
if (lodash.isEmpty(adult.gender) &&
|
|
26401
|
+
if (lodash.isEmpty(adult.gender) && isCoreFieldRequired(adult, 'gender')) {
|
|
25784
26402
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].gender`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.GENDER));
|
|
25785
26403
|
}
|
|
25786
|
-
if (
|
|
26404
|
+
if (isCoreFieldRequired(adult, 'firstName') || !lodash.isEmpty(adult.firstName)) {
|
|
25787
26405
|
if (lodash.isEmpty(adult.firstName)) {
|
|
25788
26406
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].firstName`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25789
26407
|
}
|
|
@@ -25791,7 +26409,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25791
26409
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25792
26410
|
}
|
|
25793
26411
|
}
|
|
25794
|
-
if (
|
|
26412
|
+
if (isCoreFieldRequired(adult, 'lastName') || !lodash.isEmpty(adult.lastName)) {
|
|
25795
26413
|
if (lodash.isEmpty(adult.lastName)) {
|
|
25796
26414
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].lastName`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25797
26415
|
}
|
|
@@ -25799,7 +26417,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25799
26417
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].lastName`, formatTravelerFieldInvalidCharacters(rIndex + 1, index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25800
26418
|
}
|
|
25801
26419
|
}
|
|
25802
|
-
if (
|
|
26420
|
+
if (isCoreFieldRequired(adult, 'birthDate', 'dateOfBirth') || !lodash.isEmpty(adult.birthDate)) {
|
|
25803
26421
|
if (lodash.isEmpty(adult.birthDate) || !isValidBirthDate(adult.birthDate)) {
|
|
25804
26422
|
lodash.set(errors, `rooms[${rIndex}].adults[${index}].birthDate`, formatTravelerField(rIndex + 1, index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
|
|
25805
26423
|
}
|
|
@@ -25815,10 +26433,10 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25815
26433
|
validateRequiredBuiltInFields(adult, `rooms[${rIndex}].adults[${index}]`, rIndex + 1, index + 1);
|
|
25816
26434
|
}));
|
|
25817
26435
|
values.rooms.forEach((r, rIndex) => r.children.forEach((child, index) => {
|
|
25818
|
-
if (lodash.isEmpty(child.gender) &&
|
|
26436
|
+
if (lodash.isEmpty(child.gender) && isCoreFieldRequired(child, 'gender')) {
|
|
25819
26437
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].gender`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.GENDER));
|
|
25820
26438
|
}
|
|
25821
|
-
if (
|
|
26439
|
+
if (isCoreFieldRequired(child, 'firstName') || !lodash.isEmpty(child.firstName)) {
|
|
25822
26440
|
if (lodash.isEmpty(child.firstName)) {
|
|
25823
26441
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25824
26442
|
}
|
|
@@ -25826,7 +26444,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25826
26444
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
|
|
25827
26445
|
}
|
|
25828
26446
|
}
|
|
25829
|
-
if (
|
|
26447
|
+
if (isCoreFieldRequired(child, 'lastName') || !lodash.isEmpty(child.lastName)) {
|
|
25830
26448
|
if (lodash.isEmpty(child.lastName)) {
|
|
25831
26449
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].lastName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25832
26450
|
}
|
|
@@ -25834,7 +26452,7 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25834
26452
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].lastName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.LAST_NAME));
|
|
25835
26453
|
}
|
|
25836
26454
|
}
|
|
25837
|
-
if (
|
|
26455
|
+
if (isCoreFieldRequired(child, 'birthDate', 'dateOfBirth') || !lodash.isEmpty(child.birthDate)) {
|
|
25838
26456
|
if (lodash.isEmpty(child.birthDate) || !isValidBirthDate(child.birthDate)) {
|
|
25839
26457
|
lodash.set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
|
|
25840
26458
|
}
|
|
@@ -25860,7 +26478,8 @@ const validateForm = (values, agentRequired, bookingType, translations, formFiel
|
|
|
25860
26478
|
if (values.mainBookerId < 0) {
|
|
25861
26479
|
errors.mainBookerId = translations.TRAVELERS_FORM.VALIDATION.NO_MAIN_BOOKER_SELECTED;
|
|
25862
26480
|
}
|
|
25863
|
-
if (
|
|
26481
|
+
if (hasConfiguredMainBookerFields(paxFields)) ;
|
|
26482
|
+
else if (bookingType != 'b2b' || mainBookerFormFields?.length) {
|
|
25864
26483
|
if (lodash.isEmpty(values.street) && isMainBookerFormFieldPresent('street')) {
|
|
25865
26484
|
errors.street = format$1(translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD, [translations.TRAVELERS_FORM.STREET]);
|
|
25866
26485
|
}
|
|
@@ -26555,7 +27174,7 @@ const LanguageSwitcher = ({ value = 'EN', languages = DEFAULT_LANGUAGES, onChang
|
|
|
26555
27174
|
React__default["default"].createElement("span", { className: "nav__subnav__languages__option__label" }, l.label)))))));
|
|
26556
27175
|
};
|
|
26557
27176
|
|
|
26558
|
-
const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, languages, onLanguageChange, onSearch, member, onLogin, onLogout }) => {
|
|
27177
|
+
const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, languages, onLanguageChange, onSearch, member, onLogin, onLogout, onMyBookings }) => {
|
|
26559
27178
|
const [menuOpen, setMenuOpen] = React.useState(false);
|
|
26560
27179
|
const [query, setQuery] = React.useState('');
|
|
26561
27180
|
const [activeMobileGroup, setActiveMobileGroup] = React.useState();
|
|
@@ -26649,6 +27268,12 @@ const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, lan
|
|
|
26649
27268
|
onLogout();
|
|
26650
27269
|
}
|
|
26651
27270
|
};
|
|
27271
|
+
const handleMyBookings = (event) => {
|
|
27272
|
+
event.preventDefault();
|
|
27273
|
+
if (onMyBookings) {
|
|
27274
|
+
onMyBookings();
|
|
27275
|
+
}
|
|
27276
|
+
};
|
|
26652
27277
|
const handleLogin = (event) => {
|
|
26653
27278
|
event.preventDefault();
|
|
26654
27279
|
if (onLogin) {
|
|
@@ -26662,7 +27287,9 @@ const Navbar = ({ currentPath, logo, onLogoClick, topLinks, items, language, lan
|
|
|
26662
27287
|
member && (React__default["default"].createElement("span", { className: "nav__subnav__member" },
|
|
26663
27288
|
translations.LOGIN.WELCOME_X,
|
|
26664
27289
|
member.name)),
|
|
26665
|
-
member ? (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
27290
|
+
member ? (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
27291
|
+
onMyBookings && (React__default["default"].createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleMyBookings }, translations.AGENT_ENTRIES.MY_BOOKINGS)),
|
|
27292
|
+
onLogout && (React__default["default"].createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleLogout }, translations.LOGIN.LOGOUT)))) : (React__default["default"].createElement(React__default["default"].Fragment, null, onLogin && (React__default["default"].createElement("a", { href: "#", className: "nav__subnav__link", onClick: handleLogin }, translations.LOGIN.LOGIN)))),
|
|
26666
27293
|
React__default["default"].createElement(LanguageSwitcher, { value: language.code, languages: languages, onChange: (lang) => {
|
|
26667
27294
|
console.log('Selected language:', lang);
|
|
26668
27295
|
onLanguageChange(lang);
|
|
@@ -28631,6 +29258,7 @@ const initialState$1 = {
|
|
|
28631
29258
|
bookingNumber: undefined,
|
|
28632
29259
|
trajectNodeAvailability: {},
|
|
28633
29260
|
trajectFlightAvailability: {},
|
|
29261
|
+
trajectTransferAvailability: {},
|
|
28634
29262
|
trajectDaySuggestions: {},
|
|
28635
29263
|
trajectEditLineGuid: null,
|
|
28636
29264
|
trajectActivitiesDayOrder: null,
|
|
@@ -28843,6 +29471,12 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
28843
29471
|
node.selectedCode = code;
|
|
28844
29472
|
node.status = 'resolved';
|
|
28845
29473
|
},
|
|
29474
|
+
clearTrajectNodeSelection(state, action) {
|
|
29475
|
+
const node = state.trajectNodeAvailability[action.payload];
|
|
29476
|
+
if (!node)
|
|
29477
|
+
return;
|
|
29478
|
+
node.selectedCode = null;
|
|
29479
|
+
},
|
|
28846
29480
|
updateEditableEntryLine(state, action) {
|
|
28847
29481
|
if (!state.editablePackagingEntry)
|
|
28848
29482
|
return;
|
|
@@ -28856,6 +29490,32 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
28856
29490
|
return;
|
|
28857
29491
|
state.editablePackagingEntry.lines = [...(state.editablePackagingEntry.lines ?? []), ...action.payload];
|
|
28858
29492
|
},
|
|
29493
|
+
upsertEditableEntryLines(state, action) {
|
|
29494
|
+
if (!state.editablePackagingEntry)
|
|
29495
|
+
return;
|
|
29496
|
+
const lines = [...(state.editablePackagingEntry.lines ?? [])];
|
|
29497
|
+
action.payload.forEach((line) => {
|
|
29498
|
+
const index = lines.findIndex((x) => x.guid === line.guid);
|
|
29499
|
+
if (index === -1)
|
|
29500
|
+
lines.push(line);
|
|
29501
|
+
else
|
|
29502
|
+
lines[index] = line;
|
|
29503
|
+
});
|
|
29504
|
+
state.editablePackagingEntry.lines = lines;
|
|
29505
|
+
const restored = new Set(action.payload.map((line) => line.trajectNodeId).filter((x) => x != null));
|
|
29506
|
+
if (restored.size && state.editablePackagingEntry.removedTrajectNodeIds?.length) {
|
|
29507
|
+
state.editablePackagingEntry.removedTrajectNodeIds = state.editablePackagingEntry.removedTrajectNodeIds.filter((x) => !restored.has(x));
|
|
29508
|
+
}
|
|
29509
|
+
},
|
|
29510
|
+
removeTrajectNode(state, action) {
|
|
29511
|
+
if (!state.editablePackagingEntry)
|
|
29512
|
+
return;
|
|
29513
|
+
const guids = new Set(action.payload.lineGuids);
|
|
29514
|
+
state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
|
|
29515
|
+
const removed = state.editablePackagingEntry.removedTrajectNodeIds ?? [];
|
|
29516
|
+
if (!removed.includes(action.payload.nodeId))
|
|
29517
|
+
state.editablePackagingEntry.removedTrajectNodeIds = [...removed, action.payload.nodeId];
|
|
29518
|
+
},
|
|
28859
29519
|
removeEditableEntryLines(state, action) {
|
|
28860
29520
|
if (!state.editablePackagingEntry)
|
|
28861
29521
|
return;
|
|
@@ -28887,6 +29547,19 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
28887
29547
|
flight.selectedGuid = action.payload.guid;
|
|
28888
29548
|
flight.status = 'resolved';
|
|
28889
29549
|
},
|
|
29550
|
+
clearTrajectFlightSelection(state, action) {
|
|
29551
|
+
const flight = state.trajectFlightAvailability[action.payload];
|
|
29552
|
+
if (!flight)
|
|
29553
|
+
return;
|
|
29554
|
+
flight.selectedGuid = null;
|
|
29555
|
+
},
|
|
29556
|
+
setTrajectTransferLoading(state, action) {
|
|
29557
|
+
state.trajectTransferAvailability[action.payload] = { nodeId: action.payload, status: 'loading', result: null };
|
|
29558
|
+
},
|
|
29559
|
+
setTrajectTransferAvailability(state, action) {
|
|
29560
|
+
const { nodeId, result } = action.payload;
|
|
29561
|
+
state.trajectTransferAvailability[nodeId] = { nodeId, status: result ? 'resolved' : 'unavailable', result };
|
|
29562
|
+
},
|
|
28890
29563
|
setTrajectDaySuggestionsLoading(state, action) {
|
|
28891
29564
|
const dayOrder = action.payload;
|
|
28892
29565
|
state.trajectDaySuggestions[dayOrder] = {
|
|
@@ -28923,6 +29596,7 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
28923
29596
|
resetTrajectAvailability(state) {
|
|
28924
29597
|
state.trajectNodeAvailability = {};
|
|
28925
29598
|
state.trajectFlightAvailability = {};
|
|
29599
|
+
state.trajectTransferAvailability = {};
|
|
28926
29600
|
state.trajectDaySuggestions = {};
|
|
28927
29601
|
state.trajectEditLineGuid = null;
|
|
28928
29602
|
state.trajectActivitiesDayOrder = null;
|
|
@@ -28931,7 +29605,7 @@ const searchResultsSlice = toolkit.createSlice({
|
|
|
28931
29605
|
}
|
|
28932
29606
|
}
|
|
28933
29607
|
});
|
|
28934
|
-
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;
|
|
29608
|
+
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;
|
|
28935
29609
|
var searchResultsReducer = searchResultsSlice.reducer;
|
|
28936
29610
|
|
|
28937
29611
|
const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
|
|
@@ -29146,7 +29820,7 @@ const numberOfNights = (segment) => {
|
|
|
29146
29820
|
const CHARTER_SERVICE_TYPE = 10;
|
|
29147
29821
|
const CRUISE_SERVICE_TYPE = 11;
|
|
29148
29822
|
const FERRY_SERVICE_TYPE = 12;
|
|
29149
|
-
const TRANSFER_SERVICE_TYPE = 13;
|
|
29823
|
+
const TRANSFER_SERVICE_TYPE$1 = 13;
|
|
29150
29824
|
const BUS_SERVICE_TYPE = 14;
|
|
29151
29825
|
const CAR_SERVICE_TYPE = 17;
|
|
29152
29826
|
const CAMPER_SERVICE_TYPE = 18;
|
|
@@ -29178,7 +29852,7 @@ const getServiceTypeIcon = (serviceType) => {
|
|
|
29178
29852
|
return 'ui-bus';
|
|
29179
29853
|
case TRAIN_SERVICE_TYPE:
|
|
29180
29854
|
return 'ui-train';
|
|
29181
|
-
case TRANSFER_SERVICE_TYPE:
|
|
29855
|
+
case TRANSFER_SERVICE_TYPE$1:
|
|
29182
29856
|
return 'ui-transfer';
|
|
29183
29857
|
case EVENT_SERVICE_TYPE:
|
|
29184
29858
|
return 'ui-ticket';
|
|
@@ -29314,6 +29988,81 @@ const getTrajectNodesWithLines = (trajectEntry) => {
|
|
|
29314
29988
|
})
|
|
29315
29989
|
.filter((x) => !!x.line);
|
|
29316
29990
|
};
|
|
29991
|
+
// Qite.Offer.Enums.ServiceType.Transfer: a traject's connecting node is booked as one.
|
|
29992
|
+
const TRANSFER_SERVICE_TYPE = 13;
|
|
29993
|
+
// Qite.Offer.Enums.RequirementType. A Mandatory (0) stop, and one RequiredInGroup (3) — one of the node's
|
|
29994
|
+
// alternatives has to be booked — always keep a selection; only these two may be taken off the trip.
|
|
29995
|
+
const OPTIONAL_REQUIREMENT_TYPE = 1;
|
|
29996
|
+
const OPTIONAL_IN_GROUP_REQUIREMENT_TYPE = 2;
|
|
29997
|
+
const canRemoveTrajectNode = (node) => node.requirementType === OPTIONAL_REQUIREMENT_TYPE || node.requirementType === OPTIONAL_IN_GROUP_REQUIREMENT_TYPE;
|
|
29998
|
+
const getDroppedTrajectNodeIds = (trajectEntry, entry) => {
|
|
29999
|
+
const dropped = new Set();
|
|
30000
|
+
if (!entry || !!trajectEntry.entry.magicLink)
|
|
30001
|
+
return dropped;
|
|
30002
|
+
const removed = new Set(entry.removedTrajectNodeIds ?? []);
|
|
30003
|
+
if (!removed.size)
|
|
30004
|
+
return dropped;
|
|
30005
|
+
const byDay = new Map();
|
|
30006
|
+
[...(trajectEntry.nodes ?? [])]
|
|
30007
|
+
.sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
|
|
30008
|
+
.forEach((node) => byDay.set(node.dayOrder, [...(byDay.get(node.dayOrder) ?? []), node]));
|
|
30009
|
+
byDay.forEach((nodes) => nodes.forEach((node, index) => {
|
|
30010
|
+
if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE || !canRemoveTrajectNode(node) || !removed.has(node.nodeId))
|
|
30011
|
+
return;
|
|
30012
|
+
dropped.add(node.nodeId);
|
|
30013
|
+
[nodes[index - 1], nodes[index + 1]]
|
|
30014
|
+
.filter((x) => !!x && x.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE)
|
|
30015
|
+
.forEach((x) => dropped.add(x.nodeId));
|
|
30016
|
+
}));
|
|
30017
|
+
return dropped;
|
|
30018
|
+
};
|
|
30019
|
+
const isTrajectTransferNode = (node) => node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE && !!node.pickUp && !!node.dropOff;
|
|
30020
|
+
const buildTrajectTransferRequest = (node, context) => ({
|
|
30021
|
+
transactionId: context.transactionId,
|
|
30022
|
+
officeId: context.officeId,
|
|
30023
|
+
agentId: context.agentId ?? null,
|
|
30024
|
+
catalogueId: context.catalogueId,
|
|
30025
|
+
searchConfigurationId: context.searchConfigurationId,
|
|
30026
|
+
language: context.language,
|
|
30027
|
+
date: node.from,
|
|
30028
|
+
pickUp: node.pickUp,
|
|
30029
|
+
dropOff: node.dropOff,
|
|
30030
|
+
travellers: context.rooms.flatMap((room) => room.travellers)
|
|
30031
|
+
});
|
|
30032
|
+
const buildTrajectTransferLine = (node, result) => {
|
|
30033
|
+
const option = result.rooms?.[0]?.options?.find((x) => x.isSelected) ?? result.rooms?.[0]?.options?.[0];
|
|
30034
|
+
if (!option?.guid)
|
|
30035
|
+
return null;
|
|
30036
|
+
return {
|
|
30037
|
+
guid: option.guid,
|
|
30038
|
+
parentGuid: null,
|
|
30039
|
+
order: 0,
|
|
30040
|
+
trajectNodeId: node.nodeId,
|
|
30041
|
+
isChanged: true,
|
|
30042
|
+
from: result.fromDate ?? node.from,
|
|
30043
|
+
to: result.toDate ?? node.to,
|
|
30044
|
+
moment: node.moment ?? '',
|
|
30045
|
+
serviceType: TRANSFER_SERVICE_TYPE,
|
|
30046
|
+
productName: result.name,
|
|
30047
|
+
productCode: result.code,
|
|
30048
|
+
accommodationName: option.accommodationName,
|
|
30049
|
+
accommodationCode: option.accommodationCode,
|
|
30050
|
+
regimeName: option.regimeName,
|
|
30051
|
+
regimeCode: option.regimeCode,
|
|
30052
|
+
vendor: result.vendorType ?? null,
|
|
30053
|
+
externalVendorId: result.vendorId ?? null,
|
|
30054
|
+
groupKey: '',
|
|
30055
|
+
isActive: true,
|
|
30056
|
+
country: result.countryId ? { id: result.countryId, name: result.countryName, localizations: [] } : null,
|
|
30057
|
+
region: result.regionId ? { id: result.regionId, name: result.regionName, localizations: [] } : null,
|
|
30058
|
+
oord: result.oordId ? { id: result.oordId, name: result.oordName, localizations: [] } : null,
|
|
30059
|
+
location: result.locationId ? { id: result.locationId, name: result.locationName, localizations: [] } : null,
|
|
30060
|
+
longitude: result.longitude ?? null,
|
|
30061
|
+
latitude: result.latitude ?? null,
|
|
30062
|
+
pax: (option.paxIds ?? []).map((paxId, paxIndex) => ({ paxId, room: 0, order: paxIndex })),
|
|
30063
|
+
flightInformation: null
|
|
30064
|
+
};
|
|
30065
|
+
};
|
|
29317
30066
|
const getCoordinates = (line, node, result) => {
|
|
29318
30067
|
const sources = [
|
|
29319
30068
|
...(result ? [result] : []),
|
|
@@ -29741,9 +30490,15 @@ const nightsOf = (node, line) => dateFns.differenceInCalendarDays(new Date(line?
|
|
|
29741
30490
|
const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
29742
30491
|
const timeline = React.useMemo(() => {
|
|
29743
30492
|
const linesByGuid = new Map((packagingEntry.lines ?? []).map((line) => [line.guid, line]));
|
|
30493
|
+
const dropped = getDroppedTrajectNodeIds(trajectEntry, packagingEntry);
|
|
29744
30494
|
const nodes = [...(trajectEntry.nodes ?? [])]
|
|
30495
|
+
.filter((node) => !dropped.has(node.nodeId))
|
|
29745
30496
|
.sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
|
|
29746
30497
|
.map((node) => {
|
|
30498
|
+
// A connecting node has no line of its own; the transfer found for it carries its node id.
|
|
30499
|
+
if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) {
|
|
30500
|
+
return { node, lines: (packagingEntry.lines ?? []).filter((line) => line.trajectNodeId === node.nodeId) };
|
|
30501
|
+
}
|
|
29747
30502
|
const guids = node.lineGuids?.length ? node.lineGuids : [node.lineGuid];
|
|
29748
30503
|
const lines = guids.map((guid) => linesByGuid.get(guid)).filter((x) => !!x);
|
|
29749
30504
|
const groupKey = lines.length ? getLineGroupKey(lines[0]) : '';
|
|
@@ -29813,10 +30568,11 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
|
29813
30568
|
React__default["default"].createElement("p", { className: "search__filter__itinerary__transport-date-date" },
|
|
29814
30569
|
React__default["default"].createElement("strong", null, dateFns.format(new Date(value), 'd'))),
|
|
29815
30570
|
React__default["default"].createElement("p", null, dateFns.format(new Date(value), 'MMM'))));
|
|
29816
|
-
const renderConnectingNode = ({ node }) => {
|
|
30571
|
+
const renderConnectingNode = ({ node, lines }) => {
|
|
29817
30572
|
const distance = node.distanceInKm ? `${Math.round(node.distanceInKm)} km` : '';
|
|
29818
30573
|
// How long the hop takes and how far it is, the way the traject editor puts them.
|
|
29819
30574
|
const journey = [getTrajectNodeDuration(node), distance].filter(Boolean).join(' · ');
|
|
30575
|
+
const title = lines[0]?.productName || node.name;
|
|
29820
30576
|
return (React__default["default"].createElement("div", { className: "search__filter__itinerary__transport", key: `connect-${node.nodeId}` },
|
|
29821
30577
|
React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-timeline" },
|
|
29822
30578
|
React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-timeline-line" })),
|
|
@@ -29825,8 +30581,8 @@ const TrajectItinerary = ({ trajectEntry, packagingEntry, translations }) => {
|
|
|
29825
30581
|
React__default["default"].createElement("div", { className: badgeClass('transport', getTrajectNodeBadgeModifier(node)) },
|
|
29826
30582
|
React__default["default"].createElement(Icon, { name: getTrajectNodeIcon(node), height: 15 })),
|
|
29827
30583
|
React__default["default"].createElement("div", { className: "search__filter__itinerary__transport-details" },
|
|
29828
|
-
React__default["default"].createElement("h6", null,
|
|
29829
|
-
!!
|
|
30584
|
+
React__default["default"].createElement("h6", null, title || journey),
|
|
30585
|
+
!!title && !!journey && React__default["default"].createElement("p", { className: "search__filter__itinerary__transport-details-time" }, journey)))));
|
|
29830
30586
|
};
|
|
29831
30587
|
const renderOvernight = (item, index) => {
|
|
29832
30588
|
const { dayOrder } = item.node;
|
|
@@ -33077,7 +33833,7 @@ const TrajectResultsFlyIn = ({ isLoading }) => {
|
|
|
33077
33833
|
if (!result)
|
|
33078
33834
|
return;
|
|
33079
33835
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
|
|
33080
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
33836
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
33081
33837
|
dispatch(setTrajectEditLineGuid(null));
|
|
33082
33838
|
dispatch(setFlyInIsOpen(false));
|
|
33083
33839
|
};
|
|
@@ -33122,7 +33878,7 @@ const TrajectFlightsFlyIn = ({ isLoading }) => {
|
|
|
33122
33878
|
if (!flight)
|
|
33123
33879
|
return;
|
|
33124
33880
|
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
33125
|
-
dispatch(
|
|
33881
|
+
dispatch(upsertEditableEntryLines([applyFlightToLine(item.line, flight)]));
|
|
33126
33882
|
dispatch(setTrajectEditLineGuid(null));
|
|
33127
33883
|
dispatch(setFlyInIsOpen(false));
|
|
33128
33884
|
};
|
|
@@ -33185,10 +33941,16 @@ const TrajectDayActivitiesFlyIn = ({ isLoading }) => {
|
|
|
33185
33941
|
if (!item)
|
|
33186
33942
|
return;
|
|
33187
33943
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code: result.code }));
|
|
33188
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
33944
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
33189
33945
|
dispatch(setTrajectActivitiesDayOrder(null));
|
|
33190
33946
|
dispatch(setFlyInIsOpen(false));
|
|
33191
33947
|
};
|
|
33948
|
+
const handleRemove = ({ item }) => {
|
|
33949
|
+
if (!item)
|
|
33950
|
+
return;
|
|
33951
|
+
dispatch(clearTrajectNodeSelection(item.line.guid));
|
|
33952
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
33953
|
+
};
|
|
33192
33954
|
if (isLoading || suggestions?.status === 'loading') {
|
|
33193
33955
|
return React__default["default"].createElement(React__default["default"].Fragment, null, context.customSpinner ?? React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ACTIVITIES }));
|
|
33194
33956
|
}
|
|
@@ -33202,7 +33964,8 @@ const TrajectDayActivitiesFlyIn = ({ isLoading }) => {
|
|
|
33202
33964
|
const { result, item } = card;
|
|
33203
33965
|
const isSelected = item ? trajectNodeAvailability[item.line.guid]?.selectedCode === result.code : getAddedLines(result).length > 0;
|
|
33204
33966
|
const isBookedCard = !!item && bookedMode && matchesCode(result, item.node.code ?? '');
|
|
33205
|
-
|
|
33967
|
+
const canRemove = !!item && isSelected && !bookedMode && canRemoveTrajectNode(item.node);
|
|
33968
|
+
return (React__default["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 }));
|
|
33206
33969
|
})))));
|
|
33207
33970
|
};
|
|
33208
33971
|
|
|
@@ -35596,16 +36359,18 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
|
|
|
35596
36359
|
apiKey: context.tideConnection.apiKey
|
|
35597
36360
|
};
|
|
35598
36361
|
}, [context]);
|
|
36362
|
+
// The field configuration on the entry is leading for which traveler fields are shown and required.
|
|
36363
|
+
const paxFields = editablePackagingEntry?.paxFields ?? [];
|
|
35599
36364
|
const initialValues = React.useMemo(() => {
|
|
35600
36365
|
if (!editablePackagingEntry) {
|
|
35601
36366
|
return {};
|
|
35602
36367
|
}
|
|
35603
|
-
return createInitialValuesFromEditablePackagingEntry(editablePackagingEntry);
|
|
36368
|
+
return createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, undefined, paxFields);
|
|
35604
36369
|
}, [editablePackagingEntry?.transactionId]);
|
|
35605
36370
|
const formik$1 = formik.useFormik({
|
|
35606
36371
|
initialValues,
|
|
35607
36372
|
enableReinitialize: true,
|
|
35608
|
-
validate: (values) => validateForm(values, false, 'b2c', translations, travellersSettings.formFields, travellersSettings.mainBookerFormFields, undefined, undefined,
|
|
36373
|
+
validate: (values) => validateForm(values, false, 'b2c', translations, travellersSettings.formFields, travellersSettings.mainBookerFormFields, undefined, undefined, paxFields),
|
|
35609
36374
|
onSubmit: (values) => {
|
|
35610
36375
|
if (!editablePackagingEntry)
|
|
35611
36376
|
return;
|
|
@@ -35690,7 +36455,7 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
|
|
|
35690
36455
|
".\u00A0",
|
|
35691
36456
|
stepLabels[step])) },
|
|
35692
36457
|
isConfirmationPage && isLoading && React__default["default"].createElement(Spinner, { label: translations.SUMMARY.PROCESS_BOOKING }),
|
|
35693
|
-
currentStep === 0 && (React__default["default"].createElement(SharedTravelersForm, { formik: formik$1, translations: translations, travellersSettings: travellersSettings, countries: countries, travelersFirstStep: false, isUnavailable: false, useCompactForm: false, showAgentSelection: false, paxFields:
|
|
36458
|
+
currentStep === 0 && (React__default["default"].createElement(SharedTravelersForm, { formik: formik$1, translations: translations, travellersSettings: travellersSettings, countries: countries, travelersFirstStep: false, isUnavailable: false, useCompactForm: false, showAgentSelection: false, paxFields: paxFields })),
|
|
35694
36459
|
currentStep === 1 && (React__default["default"].createElement(SharedSummary, { translations: translations, travelerFormValues: formik$1.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["default"].createElement("button", { type: "button", title: translations.STEPS.PREVIOUS, onClick: () => dispatch(setCurrentStep(0)), className: "cta cta--secondary" }, translations.STEPS.PREVIOUS)) })),
|
|
35695
36460
|
currentStep === 2 && (React__default["default"].createElement(SharedConfirmation, { bookingNumber: bookingNumber ?? editablePackagingEntry?.dossierNumber ?? '', isOption: false, isOffer: false, translations: translations.CONFIRMATION })),
|
|
35696
36461
|
currentStep === 3 && React__default["default"].createElement("div", null))),
|
|
@@ -35790,11 +36555,13 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35790
36555
|
});
|
|
35791
36556
|
return map;
|
|
35792
36557
|
}, [trajectEntry]);
|
|
36558
|
+
const droppedNodeIds = trajectEntry ? getDroppedTrajectNodeIds(trajectEntry, editablePackagingEntry) : new Set();
|
|
36559
|
+
const droppedKey = [...droppedNodeIds].sort((a, b) => a - b).join(',');
|
|
35793
36560
|
const { stayByDay, stayStartByNodeId } = React.useMemo(() => {
|
|
35794
36561
|
const byDay = new Map();
|
|
35795
36562
|
const byNodeId = new Map();
|
|
35796
36563
|
nodesWithLines
|
|
35797
|
-
.filter((x) => x.node.serviceType === ACCOMMODATION_SERVICE_TYPE)
|
|
36564
|
+
.filter((x) => x.node.serviceType === ACCOMMODATION_SERVICE_TYPE && !droppedNodeIds.has(x.node.nodeId))
|
|
35798
36565
|
.forEach((item) => {
|
|
35799
36566
|
const nights = Math.max(dateFns.differenceInCalendarDays(new Date(item.line.to), new Date(item.line.from)), 1);
|
|
35800
36567
|
byNodeId.set(item.node.nodeId, { item, night: 0, nights });
|
|
@@ -35803,7 +36570,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35803
36570
|
}
|
|
35804
36571
|
});
|
|
35805
36572
|
return { stayByDay: byDay, stayStartByNodeId: byNodeId };
|
|
35806
|
-
}, [nodesWithLines]);
|
|
36573
|
+
}, [nodesWithLines, droppedKey]);
|
|
35807
36574
|
/** Whether every node of the trip has an answer, one way or the other. */
|
|
35808
36575
|
const tripResolved = React.useMemo(() => nodesWithLines
|
|
35809
36576
|
.filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node))
|
|
@@ -35830,7 +36597,20 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35830
36597
|
if (!result)
|
|
35831
36598
|
return;
|
|
35832
36599
|
dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
|
|
35833
|
-
buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])
|
|
36600
|
+
dispatch(upsertEditableEntryLines(buildNodeSelectionLines(item, result, bookedMode, editablePackagingEntry?.lines ?? [])));
|
|
36601
|
+
};
|
|
36602
|
+
/**
|
|
36603
|
+
* An optional stop can be taken off the trip; a mandatory one, or one of which the group needs a pick,
|
|
36604
|
+
* only swapped. A booked entry's services are never taken off here.
|
|
36605
|
+
*/
|
|
36606
|
+
const canRemove = (item) => !bookedMode && canRemoveTrajectNode(item.node);
|
|
36607
|
+
const handleRemoveNode = (item) => {
|
|
36608
|
+
dispatch(clearTrajectNodeSelection(item.line.guid));
|
|
36609
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
36610
|
+
};
|
|
36611
|
+
const handleRemoveFlight = (item) => {
|
|
36612
|
+
dispatch(clearTrajectFlightSelection(item.line.guid));
|
|
36613
|
+
dispatch(removeTrajectNode({ nodeId: item.node.nodeId, lineGuids: item.lines.map((line) => line.guid) }));
|
|
35834
36614
|
};
|
|
35835
36615
|
/** The remaining legs for a flight node open in the fly-in, as the regular flight results do. */
|
|
35836
36616
|
const handleShowMoreFlights = (item) => {
|
|
@@ -35898,9 +36678,17 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35898
36678
|
// A hotel row holds the hotels configured on the node; a portal can also let it fill up with
|
|
35899
36679
|
// non-preferred hotels found in the area, the rest staying behind "show more".
|
|
35900
36680
|
const fill = showNonPreferredHotels && node.serviceType === ACCOMMODATION_SERVICE_TYPE ? others.slice(0, Math.max(MAX_HOTEL_RESULTS - 1 - configured.length, 0)) : [];
|
|
35901
|
-
const remaining = others.length - fill.length;
|
|
35902
36681
|
// No entry yet means the node's search has been queued but not dispatched — still loading.
|
|
35903
36682
|
const status = availability?.status ?? 'loading';
|
|
36683
|
+
// A stop taken off the trip keeps its results in view, to pick one back.
|
|
36684
|
+
const isRemoved = status === 'resolved' && !selected && results.length > 0;
|
|
36685
|
+
const removable = canRemove(item);
|
|
36686
|
+
const shown = selected
|
|
36687
|
+
? [selected, ...configured, ...fill]
|
|
36688
|
+
: configured.length || fill.length
|
|
36689
|
+
? [...configured, ...fill]
|
|
36690
|
+
: others.slice(0, MAX_HOTEL_RESULTS);
|
|
36691
|
+
const remaining = results.length - shown.length;
|
|
35904
36692
|
return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
|
|
35905
36693
|
showHeader && (React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
35906
36694
|
React__default["default"].createElement("div", { className: "search__results__label__date" },
|
|
@@ -35912,13 +36700,18 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35912
36700
|
React__default["default"].createElement("strong", null, headerTitle || node.name))))),
|
|
35913
36701
|
status === 'loading' && React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ACCOMMODATIONS }),
|
|
35914
36702
|
status === 'unavailable' && React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
35915
|
-
status === 'resolved' && selected && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
35916
|
-
availability.preferredUnavailable && node.preferredAccommodationName && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
36703
|
+
status === 'resolved' && (selected || isRemoved) && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
36704
|
+
selected && availability.preferredUnavailable && node.preferredAccommodationName && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
35917
36705
|
React__default["default"].createElement("span", null,
|
|
35918
36706
|
node.preferredAccommodationName,
|
|
35919
36707
|
" \u2014 ",
|
|
35920
36708
|
translations.SRP.NO_RESULTS))),
|
|
35921
|
-
React__default["default"].createElement(TrajectCardRow, { selectionKey: selected
|
|
36709
|
+
React__default["default"].createElement(TrajectCardRow, { selectionKey: selected?.code ?? '' }, shown.map((result) => {
|
|
36710
|
+
const isSelected = result.code === selected?.code;
|
|
36711
|
+
return (React__default["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,
|
|
36712
|
+
// selectedLabel={bookedMode && matchesCode(result, node.code ?? '') ? translations.SHARED.BOOKED : undefined}
|
|
36713
|
+
selectedLabel: removable ? translations.SRP.REMOVE : undefined }));
|
|
36714
|
+
})),
|
|
35922
36715
|
remaining > 0 && !hideShowMoreResults && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
35923
36716
|
React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMore(item) },
|
|
35924
36717
|
translations.SRP.SHOW_MORE,
|
|
@@ -35928,7 +36721,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35928
36721
|
};
|
|
35929
36722
|
const handleSelectFlight = (item, flight) => {
|
|
35930
36723
|
dispatch(setTrajectFlightSelection({ lineGuid: item.line.guid, guid: flight.outwardGuid }));
|
|
35931
|
-
dispatch(
|
|
36724
|
+
dispatch(upsertEditableEntryLines([buildFlightSelectionLine(item, flight, bookedMode)]));
|
|
35932
36725
|
};
|
|
35933
36726
|
const renderFlightNode = (item) => {
|
|
35934
36727
|
const { node, line } = item;
|
|
@@ -35937,7 +36730,9 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35937
36730
|
const flights = availability?.results ?? [];
|
|
35938
36731
|
const selected = flights.find((x) => x.outwardGuid === availability?.selectedGuid) ?? null;
|
|
35939
36732
|
const others = flights.filter((x) => x.outwardGuid !== availability?.selectedGuid);
|
|
35940
|
-
const
|
|
36733
|
+
const isRemoved = status === 'resolved' && !selected && flights.length > 0;
|
|
36734
|
+
const removable = canRemove(item);
|
|
36735
|
+
const visible = others.slice(0, selected ? 2 : 3);
|
|
35941
36736
|
return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
|
|
35942
36737
|
React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
|
|
35943
36738
|
React__default["default"].createElement("div", { className: "search__results__label__date" },
|
|
@@ -35952,15 +36747,15 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
35952
36747
|
node.arrivalAirportCode)))),
|
|
35953
36748
|
status === 'loading' && React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS }),
|
|
35954
36749
|
status === 'unavailable' && React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
|
|
35955
|
-
status === 'resolved' && selected && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
36750
|
+
status === 'resolved' && (selected || isRemoved) && (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
35956
36751
|
React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
|
|
35957
|
-
React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price, selectedLabel: bookedMode && selected.outwardGuid === line.guid ? translations.SHARED.BOOKED : undefined }),
|
|
35958
|
-
visible.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, isOutward: true, price: result.price, currentSelectedPrice: selected
|
|
35959
|
-
others.length >
|
|
36752
|
+
selected && (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selected.outwardGuid}`, item: selected.outward, guid: selected.outwardGuid, selectedGuid: selected.outwardGuid, isOutward: true, showSelectedState: true, price: selected.price, onSelect: removable ? () => handleRemoveFlight(item) : undefined, selectedLabel: bookedMode && selected.outwardGuid === line.guid ? translations.SHARED.BOOKED : removable ? translations.SRP.REMOVE : undefined })),
|
|
36753
|
+
visible.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.outward, guid: result.outwardGuid, isOutward: true, price: result.price, currentSelectedPrice: selected?.price, onSelect: () => handleSelectFlight(item, result) })))),
|
|
36754
|
+
others.length > visible.length && !hideShowMoreResults && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
|
|
35960
36755
|
React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => handleShowMoreFlights(item) },
|
|
35961
36756
|
translations.SRP.SHOW_MORE,
|
|
35962
36757
|
" (",
|
|
35963
|
-
others.length -
|
|
36758
|
+
others.length - visible.length,
|
|
35964
36759
|
")")))))));
|
|
35965
36760
|
};
|
|
35966
36761
|
/** The lines a suggested activity put on the entry, which is also how we know it was added. */
|
|
@@ -36036,13 +36831,21 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
36036
36831
|
")")))));
|
|
36037
36832
|
};
|
|
36038
36833
|
/**
|
|
36039
|
-
* An activity the traject books is swapped for another, the way a hotel is
|
|
36040
|
-
* found for themselves is added to the trip or taken back off it.
|
|
36834
|
+
* An activity the traject books is swapped for another, the way a hotel is, or - when it is optional -
|
|
36835
|
+
* taken off the trip; one the traveller found for themselves is added to the trip or taken back off it.
|
|
36041
36836
|
*/
|
|
36042
36837
|
const renderActivityCard = ({ result, item }) => {
|
|
36043
36838
|
const isSelected = isActivitySelected({ result, item });
|
|
36044
36839
|
const isBookedCard = !!item && bookedMode && matchesCode(result, item.node.code ?? '');
|
|
36045
|
-
|
|
36840
|
+
const removable = !!item && canRemove(item);
|
|
36841
|
+
const handleClick = () => {
|
|
36842
|
+
if (!item)
|
|
36843
|
+
return handleToggleActivity(result);
|
|
36844
|
+
if (isSelected && removable)
|
|
36845
|
+
return handleRemoveNode(item);
|
|
36846
|
+
handleSelect(item, result.code);
|
|
36847
|
+
};
|
|
36848
|
+
return (React__default["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 }));
|
|
36046
36849
|
};
|
|
36047
36850
|
if (isLoading)
|
|
36048
36851
|
return React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
|
|
@@ -36077,6 +36880,7 @@ const TrajectResults = ({ isLoading }) => {
|
|
|
36077
36880
|
const useTrajectAvailability = () => {
|
|
36078
36881
|
const context = React.useContext(SearchResultsConfigurationContext);
|
|
36079
36882
|
const dispatch = reactRedux.useDispatch();
|
|
36883
|
+
const { editablePackagingEntry, trajectTransferAvailability } = reactRedux.useSelector((state) => state.searchResults);
|
|
36080
36884
|
const trajectEntry = context?.trajectEntry;
|
|
36081
36885
|
const showApiItems = !!context?.showApiItems;
|
|
36082
36886
|
const hideShowMoreResults = !!context?.hideShowMoreResults;
|
|
@@ -36102,12 +36906,14 @@ const useTrajectAvailability = () => {
|
|
|
36102
36906
|
rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
|
|
36103
36907
|
};
|
|
36104
36908
|
// Flight searches take passengers rather than rooms; the API buckets by age.
|
|
36909
|
+
// The ids must be the entry's own pax ids: the flight lines this search caches carry them as
|
|
36910
|
+
// EntryLinePax.PaxId, and booking maps those onto the entry's travelers (PackagingService.SyncPaxIds).
|
|
36105
36911
|
const pax = trajectEntry.entry.pax ?? [];
|
|
36106
36912
|
const ageOf = (p) => p.age ?? 30;
|
|
36107
|
-
const adults = pax.filter((p) => ageOf(p) >= 12)
|
|
36108
|
-
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12)
|
|
36109
|
-
const babies = pax.filter((p) => ageOf(p) < 2)
|
|
36110
|
-
const flightPax = lodash.concat(
|
|
36913
|
+
const adults = pax.filter((p) => ageOf(p) >= 12);
|
|
36914
|
+
const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12);
|
|
36915
|
+
const babies = pax.filter((p) => ageOf(p) < 2);
|
|
36916
|
+
const flightPax = lodash.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 })));
|
|
36111
36917
|
const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
|
|
36112
36918
|
// The other members of a line group are alternatives whether or not a search still finds
|
|
36113
36919
|
// them; the ones it does not are drawn from their lines, as the booked service itself is.
|
|
@@ -36238,9 +37044,30 @@ const useTrajectAvailability = () => {
|
|
|
36238
37044
|
return item.lines.map((x) => x.guid);
|
|
36239
37045
|
}
|
|
36240
37046
|
};
|
|
37047
|
+
const resolveTransferNode = async (node) => {
|
|
37048
|
+
dispatch(setTrajectTransferLoading(node.nodeId));
|
|
37049
|
+
try {
|
|
37050
|
+
const results = (await build.searchPackagingTransfers(config, buildTrajectTransferRequest(node, searchContext), controller.signal)) ?? [];
|
|
37051
|
+
if (controller.signal.aborted)
|
|
37052
|
+
return [];
|
|
37053
|
+
const result = results[0] ?? null;
|
|
37054
|
+
dispatch(setTrajectTransferAvailability({ nodeId: node.nodeId, result: result && buildTrajectTransferLine(node, result) ? result : null }));
|
|
37055
|
+
}
|
|
37056
|
+
catch (error) {
|
|
37057
|
+
if (controller.signal.aborted)
|
|
37058
|
+
return [];
|
|
37059
|
+
console.error('Failed to resolve traject transfer', node.name, error);
|
|
37060
|
+
dispatch(setTrajectTransferAvailability({ nodeId: node.nodeId, result: null }));
|
|
37061
|
+
}
|
|
37062
|
+
return [];
|
|
37063
|
+
};
|
|
36241
37064
|
(async () => {
|
|
36242
37065
|
const resolvable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node) || isTrajectFlightNode(x.node));
|
|
36243
|
-
const
|
|
37066
|
+
const transfers = bookedMode ? [] : (trajectEntry.nodes ?? []).filter(isTrajectTransferNode);
|
|
37067
|
+
const unresolved = (await Promise.all([
|
|
37068
|
+
...resolvable.map((item) => (isTrajectFlightNode(item.node) ? resolveFlightNode(item) : resolveNode(item))),
|
|
37069
|
+
...transfers.map(resolveTransferNode)
|
|
37070
|
+
])).flat();
|
|
36244
37071
|
if (controller.signal.aborted)
|
|
36245
37072
|
return;
|
|
36246
37073
|
dispatch(setTrajectResolving(false));
|
|
@@ -36252,6 +37079,28 @@ const useTrajectAvailability = () => {
|
|
|
36252
37079
|
})();
|
|
36253
37080
|
return () => controller.abort();
|
|
36254
37081
|
}, [trajectEntry, showApiItems, hideShowMoreResults]);
|
|
37082
|
+
React.useEffect(() => {
|
|
37083
|
+
if (!trajectEntry || !editablePackagingEntry || isBookedEntryTraject(trajectEntry))
|
|
37084
|
+
return;
|
|
37085
|
+
const dropped = getDroppedTrajectNodeIds(trajectEntry, editablePackagingEntry);
|
|
37086
|
+
const guids = new Set((editablePackagingEntry.lines ?? []).map((line) => line.guid));
|
|
37087
|
+
const toAdd = [];
|
|
37088
|
+
const toRemove = [];
|
|
37089
|
+
(trajectEntry.nodes ?? []).filter(isTrajectTransferNode).forEach((node) => {
|
|
37090
|
+
const result = trajectTransferAvailability[node.nodeId]?.result;
|
|
37091
|
+
const line = result ? buildTrajectTransferLine(node, result) : null;
|
|
37092
|
+
if (!line)
|
|
37093
|
+
return;
|
|
37094
|
+
if (dropped.has(node.nodeId) && guids.has(line.guid))
|
|
37095
|
+
toRemove.push(line.guid);
|
|
37096
|
+
if (!dropped.has(node.nodeId) && !guids.has(line.guid))
|
|
37097
|
+
toAdd.push(line);
|
|
37098
|
+
});
|
|
37099
|
+
if (toRemove.length)
|
|
37100
|
+
dispatch(removeEditableEntryLines(toRemove));
|
|
37101
|
+
if (toAdd.length)
|
|
37102
|
+
dispatch(addEditableEntryLines(toAdd));
|
|
37103
|
+
}, [trajectEntry, editablePackagingEntry, trajectTransferAvailability]);
|
|
36255
37104
|
};
|
|
36256
37105
|
|
|
36257
37106
|
const SearchResultsContainer = ({ onBookingStarted }) => {
|
|
@@ -36556,10 +37405,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
|
|
|
36556
37405
|
const item = getTrajectNodesWithLines(context.trajectEntry).find((x) => x.line.guid === trajectEditLineGuid);
|
|
36557
37406
|
const result = packagingAccoSearchDetails.find((x) => x.code === selectedPackagingAccoResultCode);
|
|
36558
37407
|
if (item && result) {
|
|
36559
|
-
|
|
36560
|
-
|
|
36561
|
-
|
|
36562
|
-
applyResultToLines(currentLines, result).forEach((line) => dispatch(updateEditableEntryLine(line)));
|
|
37408
|
+
// A stop the traveller took off has no lines left on the entry: the traject's own put it back.
|
|
37409
|
+
const currentLines = item.lines.map((line) => editablePackagingEntry?.lines?.find((x) => x.guid === line.guid) ?? line);
|
|
37410
|
+
dispatch(upsertEditableEntryLines(applyResultToLines(currentLines, result)));
|
|
36563
37411
|
dispatch(updateTrajectNodeResult({ lineGuid: trajectEditLineGuid, result }));
|
|
36564
37412
|
}
|
|
36565
37413
|
dispatch(setTrajectEditLineGuid(null));
|
|
@@ -40184,6 +41032,363 @@ const Login = ({ tideClientConfig, portalId, languageCode, imageSrc, logo, isMem
|
|
|
40184
41032
|
isMemberConfirmation && (React__default["default"].createElement(ConfirmComponent, { tideClientConfig: tideClientConfig, portalId: portalId, languageCode: languageCode, member: member, setMember: setMember, handleBackToHome: handleBackToHome, handleBackToLogin: handleBackToLogin }))))));
|
|
40185
41033
|
};
|
|
40186
41034
|
|
|
41035
|
+
/** Agent endpoints need the member token, fall back to the one the Login component stored. */
|
|
41036
|
+
const withAgentToken = (config) => ({
|
|
41037
|
+
...config,
|
|
41038
|
+
token: config.token ?? selectAgentToken()
|
|
41039
|
+
});
|
|
41040
|
+
/** False when the token is not a JWT or has expired. */
|
|
41041
|
+
const isAgentTokenValid = (token) => {
|
|
41042
|
+
if (!token)
|
|
41043
|
+
return false;
|
|
41044
|
+
try {
|
|
41045
|
+
const { exp } = jwtDecode(token);
|
|
41046
|
+
return !exp || exp * 1000 > Date.now();
|
|
41047
|
+
}
|
|
41048
|
+
catch {
|
|
41049
|
+
return false;
|
|
41050
|
+
}
|
|
41051
|
+
};
|
|
41052
|
+
// tide-client throws Error(statusText) without the status, and statusText is empty over HTTP/2,
|
|
41053
|
+
// so also treat any failure with an invalid/expired token as unauthorized.
|
|
41054
|
+
const isUnauthorizedError = (error, token) => (error instanceof Error && /unauthori[sz]ed|forbidden/i.test(error.message)) || !isAgentTokenValid(token);
|
|
41055
|
+
const fetchLookups = async (config, languageCode, signal) => {
|
|
41056
|
+
// A failing lookup should not block the list itself.
|
|
41057
|
+
const [entryStatuses, customEntryStatuses, printActions] = await Promise.allSettled([
|
|
41058
|
+
build.getEntryStatus(config, signal, languageCode),
|
|
41059
|
+
build.getCustomEntryStatus(config, signal, languageCode),
|
|
41060
|
+
build.getPrintActions(config, build.PrintActionGroup.Dossier, signal)
|
|
41061
|
+
]);
|
|
41062
|
+
return {
|
|
41063
|
+
entryStatuses: entryStatuses.status === 'fulfilled' ? entryStatuses.value ?? [] : [],
|
|
41064
|
+
customEntryStatuses: customEntryStatuses.status === 'fulfilled' ? customEntryStatuses.value ?? [] : [],
|
|
41065
|
+
printActions: printActions.status === 'fulfilled' ? printActions.value ?? [] : []
|
|
41066
|
+
};
|
|
41067
|
+
};
|
|
41068
|
+
/** Converts the raw filter inputs to the OData column filters understood by tide-client's createParams. */
|
|
41069
|
+
const buildFilterItem = (columns, filterValues, sort, page, take) => {
|
|
41070
|
+
const filterColumns = {};
|
|
41071
|
+
columns.forEach((column) => {
|
|
41072
|
+
const raw = filterValues[column.id]?.trim();
|
|
41073
|
+
if (!raw)
|
|
41074
|
+
return;
|
|
41075
|
+
switch (column.kind) {
|
|
41076
|
+
case 'text':
|
|
41077
|
+
filterColumns[column.id] = { type: 'text', value: raw };
|
|
41078
|
+
break;
|
|
41079
|
+
case 'number': {
|
|
41080
|
+
const value = parseFloat(raw.replace(',', '.'));
|
|
41081
|
+
if (!isNaN(value))
|
|
41082
|
+
filterColumns[column.id] = { type: 'number', value };
|
|
41083
|
+
break;
|
|
41084
|
+
}
|
|
41085
|
+
case 'date': {
|
|
41086
|
+
// <input type="date"> value: yyyy-MM-dd, createParams expects a 1-based month.
|
|
41087
|
+
const [year, month, day] = raw.split('-').map((x) => parseInt(x, 10));
|
|
41088
|
+
if (year && month && day)
|
|
41089
|
+
filterColumns[column.id] = { type: 'date', value: { year, month, day } };
|
|
41090
|
+
break;
|
|
41091
|
+
}
|
|
41092
|
+
case 'status':
|
|
41093
|
+
case 'customStatus':
|
|
41094
|
+
filterColumns[column.id] = { type: 'enum', value: parseInt(raw, 10) };
|
|
41095
|
+
break;
|
|
41096
|
+
}
|
|
41097
|
+
});
|
|
41098
|
+
return { take, page, sort, columns: filterColumns };
|
|
41099
|
+
};
|
|
41100
|
+
const fetchEntries = (config, filter, signal) => build.getEntryList(config, filter, undefined, signal);
|
|
41101
|
+
/** Prints the entry and returns an object url to the resulting pdf. */
|
|
41102
|
+
const printEntry = async (config, printActionId, entryId) => {
|
|
41103
|
+
// Same request as the agent portal: the print action and the entry (version) id.
|
|
41104
|
+
const request = { id: printActionId, entryId };
|
|
41105
|
+
const response = await build.print(config, request);
|
|
41106
|
+
if (!response.ok)
|
|
41107
|
+
throw new Error(response.statusText);
|
|
41108
|
+
const buffer = await response.arrayBuffer();
|
|
41109
|
+
return URL.createObjectURL(new Blob([buffer], { type: 'application/pdf' }));
|
|
41110
|
+
};
|
|
41111
|
+
|
|
41112
|
+
const PAGE_SIZES = [10, 20, 50, 100];
|
|
41113
|
+
const FILTER_DEBOUNCE_MS = 400;
|
|
41114
|
+
const EyeIcon = () => (React__default["default"].createElement("svg", { className: "agent-entries__icon", viewBox: "0 0 576 512", fill: "currentColor", "aria-hidden": "true" },
|
|
41115
|
+
React__default["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" })));
|
|
41116
|
+
const PrintIcon = () => (React__default["default"].createElement("svg", { className: "agent-entries__icon", viewBox: "0 0 512 512", fill: "currentColor", "aria-hidden": "true" },
|
|
41117
|
+
React__default["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" })));
|
|
41118
|
+
const SortIcon = ({ asc }) => (React__default["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" },
|
|
41119
|
+
React__default["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" })));
|
|
41120
|
+
const AgentEntries = ({ tideClientConfig, languageCode, title, pageSize, customTranslations, onLogin, onUnauthorized }) => {
|
|
41121
|
+
const translations = React.useMemo(() => getTranslations(languageCode ?? 'en-GB', customTranslations), [languageCode, customTranslations]);
|
|
41122
|
+
const t = translations.AGENT_ENTRIES;
|
|
41123
|
+
const config = React.useMemo(() => withAgentToken(tideClientConfig), [tideClientConfig.host, tideClientConfig.apiKey, tideClientConfig.token]);
|
|
41124
|
+
const isLoggedIn = !!config.token;
|
|
41125
|
+
const hasValidToken = isLoggedIn && isAgentTokenValid(config.token);
|
|
41126
|
+
const columns = React.useMemo(() => [
|
|
41127
|
+
{ id: 'number', kind: 'text', label: t.NUMBER },
|
|
41128
|
+
{ id: 'departureDate', kind: 'date', label: t.DEPARTURE_DATE },
|
|
41129
|
+
{ id: 'status', kind: 'status', label: t.STATUS },
|
|
41130
|
+
{ id: 'customEntryStatusId', kind: 'customStatus', label: t.CUSTOM_STATUS },
|
|
41131
|
+
{ id: 'returnDate', kind: 'date', label: t.RETURN_DATE },
|
|
41132
|
+
{ id: 'profit', kind: 'number', label: t.PROFIT },
|
|
41133
|
+
{ id: 'totalPrice', kind: 'number', label: t.NETTO_SELLING_PRICE },
|
|
41134
|
+
{ id: 'calculatedAgentSurchargeAmount', kind: 'number', label: t.YOUR_SURCHARGE },
|
|
41135
|
+
{ id: 'createdDate', kind: 'date', label: t.CREATED },
|
|
41136
|
+
{ id: 'contact', kind: 'text', label: t.CONTACT },
|
|
41137
|
+
{ id: 'travelerAddress', kind: 'text', label: t.MAIN_BOOKER }
|
|
41138
|
+
], [t]);
|
|
41139
|
+
const [lookups, setLookups] = React.useState({ entryStatuses: [], customEntryStatuses: [], printActions: [] });
|
|
41140
|
+
const [entries, setEntries] = React.useState([]);
|
|
41141
|
+
const [count, setCount] = React.useState();
|
|
41142
|
+
const [loadState, setLoadState] = React.useState('idle');
|
|
41143
|
+
const [filterInputs, setFilterInputs] = React.useState({});
|
|
41144
|
+
const [filterValues, setFilterValues] = React.useState({});
|
|
41145
|
+
const [sort, setSort] = React.useState({ name: 'number', asc: true });
|
|
41146
|
+
const [page, setPage] = React.useState(1);
|
|
41147
|
+
const [take, setTake] = React.useState(pageSize ?? 20);
|
|
41148
|
+
const [expandedId, setExpandedId] = React.useState();
|
|
41149
|
+
const [printingKey, setPrintingKey] = React.useState();
|
|
41150
|
+
const [printError, setPrintError] = React.useState(false);
|
|
41151
|
+
const handleError = (error) => {
|
|
41152
|
+
if (error instanceof DOMException && error.name === 'AbortError')
|
|
41153
|
+
return;
|
|
41154
|
+
if (isUnauthorizedError(error, config.token)) {
|
|
41155
|
+
setLoadState('unauthorized');
|
|
41156
|
+
onUnauthorized?.();
|
|
41157
|
+
}
|
|
41158
|
+
else {
|
|
41159
|
+
console.error(error);
|
|
41160
|
+
setLoadState('error');
|
|
41161
|
+
}
|
|
41162
|
+
};
|
|
41163
|
+
React.useEffect(() => {
|
|
41164
|
+
if (isLoggedIn && !hasValidToken)
|
|
41165
|
+
onUnauthorized?.();
|
|
41166
|
+
}, [isLoggedIn, hasValidToken]);
|
|
41167
|
+
// Lookups (statuses & print actions) only need to be fetched once.
|
|
41168
|
+
React.useEffect(() => {
|
|
41169
|
+
if (!hasValidToken)
|
|
41170
|
+
return;
|
|
41171
|
+
const controller = new AbortController();
|
|
41172
|
+
fetchLookups(config, languageCode, controller.signal)
|
|
41173
|
+
.then(setLookups)
|
|
41174
|
+
.catch(() => { });
|
|
41175
|
+
return () => controller.abort();
|
|
41176
|
+
}, [config, languageCode, hasValidToken]);
|
|
41177
|
+
// Debounce the typed filters, a selected dropdown/date is applied immediately.
|
|
41178
|
+
React.useEffect(() => {
|
|
41179
|
+
const handle = setTimeout(() => {
|
|
41180
|
+
if (lodash.isEqual(filterInputs, filterValues))
|
|
41181
|
+
return;
|
|
41182
|
+
setFilterValues(filterInputs);
|
|
41183
|
+
setPage(1);
|
|
41184
|
+
}, FILTER_DEBOUNCE_MS);
|
|
41185
|
+
return () => clearTimeout(handle);
|
|
41186
|
+
}, [filterInputs]);
|
|
41187
|
+
React.useEffect(() => {
|
|
41188
|
+
if (!hasValidToken)
|
|
41189
|
+
return;
|
|
41190
|
+
const controller = new AbortController();
|
|
41191
|
+
setLoadState('loading');
|
|
41192
|
+
fetchEntries(config, buildFilterItem(columns, filterValues, sort, page, take), controller.signal)
|
|
41193
|
+
.then((result) => {
|
|
41194
|
+
setEntries(result?.items ?? []);
|
|
41195
|
+
setCount(result?.count ?? undefined);
|
|
41196
|
+
setLoadState('loaded');
|
|
41197
|
+
})
|
|
41198
|
+
.catch(handleError);
|
|
41199
|
+
return () => controller.abort();
|
|
41200
|
+
}, [config, hasValidToken, columns, filterValues, sort, page, take]);
|
|
41201
|
+
const totalPages = count !== undefined ? Math.max(1, Math.ceil(count / take)) : undefined;
|
|
41202
|
+
const hasNextPage = totalPages !== undefined ? page < totalPages : entries.length === take;
|
|
41203
|
+
const handleSort = (columnId) => {
|
|
41204
|
+
setSort((current) => (current.name === columnId ? { name: columnId, asc: !current.asc } : { name: columnId, asc: true }));
|
|
41205
|
+
setPage(1);
|
|
41206
|
+
};
|
|
41207
|
+
const handleFilterChange = (columnId, value, immediate) => {
|
|
41208
|
+
const next = { ...filterInputs, [columnId]: value };
|
|
41209
|
+
setFilterInputs(next);
|
|
41210
|
+
if (immediate) {
|
|
41211
|
+
setFilterValues(next);
|
|
41212
|
+
setPage(1);
|
|
41213
|
+
}
|
|
41214
|
+
};
|
|
41215
|
+
const handlePrint = async (entry, printAction) => {
|
|
41216
|
+
// Open the tab synchronously, otherwise the popup blocker kicks in once the pdf arrives.
|
|
41217
|
+
const printWindow = window.open('', '_blank');
|
|
41218
|
+
setPrintingKey(`${entry.id}-${printAction.id}`);
|
|
41219
|
+
setPrintError(false);
|
|
41220
|
+
try {
|
|
41221
|
+
const url = await printEntry(config, printAction.id, entry.id);
|
|
41222
|
+
if (printWindow) {
|
|
41223
|
+
printWindow.location.href = url;
|
|
41224
|
+
}
|
|
41225
|
+
else {
|
|
41226
|
+
window.open(url, '_blank');
|
|
41227
|
+
}
|
|
41228
|
+
setTimeout(() => URL.revokeObjectURL(url), 60000);
|
|
41229
|
+
}
|
|
41230
|
+
catch (error) {
|
|
41231
|
+
printWindow?.close();
|
|
41232
|
+
if (isUnauthorizedError(error, config.token)) {
|
|
41233
|
+
handleError(error);
|
|
41234
|
+
}
|
|
41235
|
+
else {
|
|
41236
|
+
console.error(error);
|
|
41237
|
+
setPrintError(true);
|
|
41238
|
+
}
|
|
41239
|
+
}
|
|
41240
|
+
finally {
|
|
41241
|
+
setPrintingKey(undefined);
|
|
41242
|
+
}
|
|
41243
|
+
};
|
|
41244
|
+
const formatDate = (value) => {
|
|
41245
|
+
if (!value)
|
|
41246
|
+
return '';
|
|
41247
|
+
const date = new Date(value);
|
|
41248
|
+
if (isNaN(date.getTime()))
|
|
41249
|
+
return '';
|
|
41250
|
+
return new Intl.DateTimeFormat(languageCode, { day: '2-digit', month: '2-digit', year: 'numeric' }).format(date);
|
|
41251
|
+
};
|
|
41252
|
+
const formatNumber = (value) => {
|
|
41253
|
+
if (value === undefined || value === null)
|
|
41254
|
+
return '';
|
|
41255
|
+
return new Intl.NumberFormat(languageCode, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value);
|
|
41256
|
+
};
|
|
41257
|
+
const getEntryStatusLabel = (status) => lookups.entryStatuses.find((x) => x.key === status)?.value ?? '';
|
|
41258
|
+
const getCustomEntryStatusLabel = (id) => lookups.customEntryStatuses.find((x) => x.id === id)?.name ?? '';
|
|
41259
|
+
const getPrintActionsForEntry = (entry) => lookups.printActions.filter((x) => x.validEntryStatuses?.includes(entry.status));
|
|
41260
|
+
const renderCell = (entry, column) => {
|
|
41261
|
+
const value = entry[column.id];
|
|
41262
|
+
switch (column.kind) {
|
|
41263
|
+
case 'date':
|
|
41264
|
+
return formatDate(value);
|
|
41265
|
+
case 'number':
|
|
41266
|
+
return formatNumber(value);
|
|
41267
|
+
case 'status':
|
|
41268
|
+
return getEntryStatusLabel(value);
|
|
41269
|
+
case 'customStatus':
|
|
41270
|
+
return getCustomEntryStatusLabel(value);
|
|
41271
|
+
default:
|
|
41272
|
+
return value ?? '';
|
|
41273
|
+
}
|
|
41274
|
+
};
|
|
41275
|
+
const renderFilter = (column) => {
|
|
41276
|
+
const value = filterInputs[column.id] ?? '';
|
|
41277
|
+
const className = 'agent-entries__filter';
|
|
41278
|
+
switch (column.kind) {
|
|
41279
|
+
case 'date':
|
|
41280
|
+
return (React__default["default"].createElement("input", { type: "date", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value, true) }));
|
|
41281
|
+
case 'status':
|
|
41282
|
+
case 'customStatus': {
|
|
41283
|
+
const options = column.kind === 'status'
|
|
41284
|
+
? lookups.entryStatuses.filter((x) => x.key !== undefined && x.key !== null).map((x) => ({ key: x.key, value: x.value }))
|
|
41285
|
+
: lookups.customEntryStatuses.map((x) => ({ key: x.id, value: x.name }));
|
|
41286
|
+
return (React__default["default"].createElement("select", { className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value, true) },
|
|
41287
|
+
React__default["default"].createElement("option", { value: "" }, t.ALL),
|
|
41288
|
+
options.map((option) => (React__default["default"].createElement("option", { key: option.key, value: option.key }, option.value)))));
|
|
41289
|
+
}
|
|
41290
|
+
case 'number':
|
|
41291
|
+
return (React__default["default"].createElement("input", { type: "number", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value) }));
|
|
41292
|
+
default:
|
|
41293
|
+
return (React__default["default"].createElement("input", { type: "text", className: className, value: value, "aria-label": column.label, onChange: (e) => handleFilterChange(column.id, e.target.value) }));
|
|
41294
|
+
}
|
|
41295
|
+
};
|
|
41296
|
+
const renderDetails = (entry) => {
|
|
41297
|
+
const printActions = getPrintActionsForEntry(entry);
|
|
41298
|
+
const travelers = entry.pax?.length ? entry.pax.map((p) => (p.isMainBooker ? `${p.name} (${t.MAIN_BOOKER.toLowerCase()})` : p.name)).join(', ') : '';
|
|
41299
|
+
const details = [
|
|
41300
|
+
{ label: t.NUMBER, value: entry.number },
|
|
41301
|
+
{ label: t.PRODUCT, value: entry.firstProductName },
|
|
41302
|
+
{ label: t.STATUS, value: getEntryStatusLabel(entry.status) },
|
|
41303
|
+
{ label: t.CUSTOM_STATUS, value: getCustomEntryStatusLabel(entry.customEntryStatusId) },
|
|
41304
|
+
{ label: t.DEPARTURE_DATE, value: formatDate(entry.departureDate) },
|
|
41305
|
+
{ label: t.RETURN_DATE, value: formatDate(entry.returnDate) },
|
|
41306
|
+
{ label: t.CREATED, value: formatDate(entry.createdDate) },
|
|
41307
|
+
{ label: t.CONTACT, value: entry.contact },
|
|
41308
|
+
{ label: t.MAIN_BOOKER, value: entry.travelerAddress },
|
|
41309
|
+
{ label: t.TRAVELERS, value: travelers || (entry.paxCount ? entry.paxCount : '') },
|
|
41310
|
+
{ label: t.NETTO_SELLING_PRICE, value: formatNumber(entry.totalPrice) },
|
|
41311
|
+
{ label: t.YOUR_SURCHARGE, value: formatNumber(entry.calculatedAgentSurchargeAmount) },
|
|
41312
|
+
{ label: t.PROFIT, value: formatNumber(entry.profit) }
|
|
41313
|
+
];
|
|
41314
|
+
return (React__default["default"].createElement("div", { className: "agent-entries__details" },
|
|
41315
|
+
React__default["default"].createElement("dl", { className: "agent-entries__details__list" }, details
|
|
41316
|
+
.filter((detail) => detail.value !== undefined && detail.value !== null && detail.value !== '')
|
|
41317
|
+
.map((detail) => (React__default["default"].createElement("div", { className: "agent-entries__details__item", key: detail.label },
|
|
41318
|
+
React__default["default"].createElement("dt", null, detail.label),
|
|
41319
|
+
React__default["default"].createElement("dd", null, detail.value))))),
|
|
41320
|
+
printActions.length > 0 && (React__default["default"].createElement("div", { className: "agent-entries__details__prints" },
|
|
41321
|
+
React__default["default"].createElement("span", { className: "agent-entries__details__prints__title" }, t.PRINTS),
|
|
41322
|
+
React__default["default"].createElement("div", { className: "agent-entries__details__prints__buttons" }, printActions.map((printAction) => (React__default["default"].createElement("button", { type: "button", key: printAction.id, className: "agent-entries__print-button", disabled: printingKey === `${entry.id}-${printAction.id}`, onClick: () => handlePrint(entry, printAction) },
|
|
41323
|
+
React__default["default"].createElement(PrintIcon, null),
|
|
41324
|
+
printAction.label))))))));
|
|
41325
|
+
};
|
|
41326
|
+
const renderLoginMessage = (message) => (React__default["default"].createElement("div", { className: "agent-entries__message" },
|
|
41327
|
+
React__default["default"].createElement("p", null, message),
|
|
41328
|
+
onLogin && (React__default["default"].createElement("button", { type: "button", className: "cta cta--primary", onClick: onLogin }, translations.LOGIN.LOGIN))));
|
|
41329
|
+
if (!isLoggedIn) {
|
|
41330
|
+
return (React__default["default"].createElement("div", { className: "agent-entries" },
|
|
41331
|
+
React__default["default"].createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41332
|
+
renderLoginMessage(t.NOT_LOGGED_IN)));
|
|
41333
|
+
}
|
|
41334
|
+
if (!hasValidToken || loadState === 'unauthorized') {
|
|
41335
|
+
return (React__default["default"].createElement("div", { className: "agent-entries" },
|
|
41336
|
+
React__default["default"].createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41337
|
+
renderLoginMessage(t.SESSION_EXPIRED)));
|
|
41338
|
+
}
|
|
41339
|
+
const columnCount = columns.length + 1;
|
|
41340
|
+
return (React__default["default"].createElement("div", { className: "agent-entries" },
|
|
41341
|
+
React__default["default"].createElement("h2", { className: "agent-entries__title" }, title ?? t.TITLE),
|
|
41342
|
+
printError && (React__default["default"].createElement("div", { className: "agent-entries__error", role: "alert" },
|
|
41343
|
+
t.PRINT_ERROR,
|
|
41344
|
+
React__default["default"].createElement("button", { type: "button", className: "agent-entries__error__close", "aria-label": "close", onClick: () => setPrintError(false) }, "\u00D7"))),
|
|
41345
|
+
React__default["default"].createElement("div", { className: buildClassName(['agent-entries__card', loadState === 'loading' && 'agent-entries__card--loading']) },
|
|
41346
|
+
React__default["default"].createElement("div", { className: "agent-entries__table-wrapper" },
|
|
41347
|
+
React__default["default"].createElement("table", { className: "agent-entries__table" },
|
|
41348
|
+
React__default["default"].createElement("thead", null,
|
|
41349
|
+
React__default["default"].createElement("tr", null,
|
|
41350
|
+
React__default["default"].createElement("th", { className: "agent-entries__actions-header" },
|
|
41351
|
+
React__default["default"].createElement("span", { className: "agent-entries__sr-only" }, t.ACTIONS)),
|
|
41352
|
+
columns.map((column) => (React__default["default"].createElement("th", { key: column.id, "aria-sort": sort.name === column.id ? (sort.asc ? 'ascending' : 'descending') : undefined },
|
|
41353
|
+
React__default["default"].createElement("button", { type: "button", className: "agent-entries__sort", onClick: () => handleSort(column.id) },
|
|
41354
|
+
column.label,
|
|
41355
|
+
sort.name === column.id && React__default["default"].createElement(SortIcon, { asc: sort.asc })))))),
|
|
41356
|
+
React__default["default"].createElement("tr", { className: "agent-entries__filter-row" },
|
|
41357
|
+
React__default["default"].createElement("th", null),
|
|
41358
|
+
columns.map((column) => (React__default["default"].createElement("th", { key: column.id }, renderFilter(column)))))),
|
|
41359
|
+
React__default["default"].createElement("tbody", null,
|
|
41360
|
+
loadState === 'error' && (React__default["default"].createElement("tr", null,
|
|
41361
|
+
React__default["default"].createElement("td", { colSpan: columnCount, className: "agent-entries__empty" }, t.ERROR))),
|
|
41362
|
+
loadState !== 'error' && entries.length === 0 && (React__default["default"].createElement("tr", null,
|
|
41363
|
+
React__default["default"].createElement("td", { colSpan: columnCount, className: "agent-entries__empty" }, loadState === 'loading' ? t.LOADING : t.NO_ITEMS))),
|
|
41364
|
+
loadState !== 'error' &&
|
|
41365
|
+
entries.map((entry) => {
|
|
41366
|
+
const isExpanded = expandedId === entry.id;
|
|
41367
|
+
return (React__default["default"].createElement(React__default["default"].Fragment, { key: entry.id },
|
|
41368
|
+
React__default["default"].createElement("tr", { className: buildClassName(['agent-entries__row', isExpanded && 'agent-entries__row--expanded']) },
|
|
41369
|
+
React__default["default"].createElement("td", { className: "agent-entries__actions" },
|
|
41370
|
+
React__default["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) },
|
|
41371
|
+
React__default["default"].createElement(EyeIcon, null)),
|
|
41372
|
+
getPrintActionsForEntry(entry).map((printAction) => (React__default["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) },
|
|
41373
|
+
React__default["default"].createElement(PrintIcon, null))))),
|
|
41374
|
+
columns.map((column) => (React__default["default"].createElement("td", { key: column.id, className: `agent-entries__cell agent-entries__cell--${column.kind}` }, renderCell(entry, column))))),
|
|
41375
|
+
isExpanded && (React__default["default"].createElement("tr", { className: "agent-entries__details-row" },
|
|
41376
|
+
React__default["default"].createElement("td", { colSpan: columnCount }, renderDetails(entry))))));
|
|
41377
|
+
})))),
|
|
41378
|
+
React__default["default"].createElement("div", { className: "agent-entries__footer" },
|
|
41379
|
+
React__default["default"].createElement("select", { className: "agent-entries__page-size", value: take, "aria-label": t.PAGE_SIZE, onChange: (e) => {
|
|
41380
|
+
setTake(parseInt(e.target.value, 10));
|
|
41381
|
+
setPage(1);
|
|
41382
|
+
} }, Array.from(new Set([...PAGE_SIZES, take]))
|
|
41383
|
+
.sort((a, b) => a - b)
|
|
41384
|
+
.map((size) => (React__default["default"].createElement("option", { key: size, value: size }, size)))),
|
|
41385
|
+
count !== undefined && React__default["default"].createElement("span", { className: "agent-entries__count" }, format$1(t.X_ITEMS, [count])),
|
|
41386
|
+
React__default["default"].createElement("div", { className: "agent-entries__pager" },
|
|
41387
|
+
React__default["default"].createElement("button", { type: "button", className: "agent-entries__pager__button", disabled: page <= 1, onClick: () => setPage(page - 1) }, t.PREVIOUS),
|
|
41388
|
+
React__default["default"].createElement("span", { className: "agent-entries__pager__info" }, totalPages !== undefined ? format$1(t.PAGE_X_OF_Y, [page, totalPages]) : page),
|
|
41389
|
+
React__default["default"].createElement("button", { type: "button", className: "agent-entries__pager__button", disabled: !hasNextPage, onClick: () => setPage(page + 1) }, t.NEXT))))));
|
|
41390
|
+
};
|
|
41391
|
+
|
|
40187
41392
|
const ImageWithTextCard = ({ noCard, fullImage, reverse, imageSrc, imageAlt, title, section1Title, section1Text, section2Title, section2Text, buttonText, onButtonClick }) => {
|
|
40188
41393
|
let cardClassName = 'image-with-text__card';
|
|
40189
41394
|
if (noCard) {
|
|
@@ -44642,6 +45847,7 @@ var signalR = /*#__PURE__*/_mergeNamespaces({
|
|
|
44642
45847
|
'default': signalR$1
|
|
44643
45848
|
}, [signalR$1]);
|
|
44644
45849
|
|
|
45850
|
+
exports.AgentEntries = AgentEntries;
|
|
44645
45851
|
exports.BookingProduct = BookingProduct;
|
|
44646
45852
|
exports.BookingWizard = BookingWizard;
|
|
44647
45853
|
exports.Breadcrumbs = Breadcrumbs;
|