ublo-lib 1.36.31 → 1.37.0

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.
Files changed (64) hide show
  1. package/es/common/components/cross-selling-editor/cross-selling-editor.d.ts +3 -1
  2. package/es/common/components/cross-selling-editor/cross-selling-editor.d.ts.map +1 -1
  3. package/es/common/components/cross-selling-editor/cross-selling-editor.js +4 -2
  4. package/es/common/components/cross-selling-editor/editor.d.ts +3 -1
  5. package/es/common/components/cross-selling-editor/editor.d.ts.map +1 -1
  6. package/es/common/components/cross-selling-editor/editor.js +2 -2
  7. package/es/common/components/cross-selling-editor/esf/index.d.ts +3 -0
  8. package/es/common/components/cross-selling-editor/esf/index.d.ts.map +1 -0
  9. package/es/common/components/cross-selling-editor/esf/index.js +2 -0
  10. package/es/common/components/cross-selling-editor/esf/special-rule-form.d.ts +12 -0
  11. package/es/common/components/cross-selling-editor/esf/special-rule-form.d.ts.map +1 -0
  12. package/es/common/components/cross-selling-editor/esf/special-rule-form.js +27 -0
  13. package/es/common/components/cross-selling-editor/esf/special-rule-form.module.css +4 -0
  14. package/es/common/components/cross-selling-editor/esf/step-1.d.ts +12 -0
  15. package/es/common/components/cross-selling-editor/esf/step-1.d.ts.map +1 -0
  16. package/es/common/components/cross-selling-editor/esf/step-1.js +78 -0
  17. package/es/common/components/cross-selling-editor/esf/step-1.module.css +35 -0
  18. package/es/common/components/cross-selling-editor/esf/step-2.d.ts +12 -0
  19. package/es/common/components/cross-selling-editor/esf/step-2.d.ts.map +1 -0
  20. package/es/common/components/cross-selling-editor/esf/step-2.js +157 -0
  21. package/es/common/components/cross-selling-editor/esf/step-2.module.css +72 -0
  22. package/es/common/components/cross-selling-editor/hooks/use-custom-offers.d.ts.map +1 -1
  23. package/es/common/components/cross-selling-editor/hooks/use-custom-offers.js +3 -0
  24. package/es/common/components/cross-selling-editor/hooks/use-fetch.d.ts +12 -0
  25. package/es/common/components/cross-selling-editor/hooks/use-fetch.d.ts.map +1 -0
  26. package/es/common/components/cross-selling-editor/hooks/use-fetch.js +35 -0
  27. package/es/common/components/cross-selling-editor/hooks/use-tunnel-offers.d.ts.map +1 -1
  28. package/es/common/components/cross-selling-editor/hooks/use-tunnel-offers.js +2 -0
  29. package/es/common/components/cross-selling-editor/override.d.ts +2 -1
  30. package/es/common/components/cross-selling-editor/override.d.ts.map +1 -1
  31. package/es/common/components/cross-selling-editor/override.js +12 -6
  32. package/es/common/components/cross-selling-editor/overrides-list.d.ts.map +1 -1
  33. package/es/common/components/cross-selling-editor/overrides-list.js +9 -6
  34. package/es/common/components/cross-selling-editor/overrides-list.module.css +24 -8
  35. package/es/common/components/cross-selling-editor/rules.d.ts +3 -2
  36. package/es/common/components/cross-selling-editor/rules.d.ts.map +1 -1
  37. package/es/common/components/cross-selling-editor/rules.js +18 -7
  38. package/es/common/components/cross-selling-editor/services/api.d.ts +7 -0
  39. package/es/common/components/cross-selling-editor/services/api.d.ts.map +1 -1
  40. package/es/common/components/cross-selling-editor/services/api.js +101 -3
  41. package/es/common/components/cross-selling-editor/services/utils.d.ts +7 -4
  42. package/es/common/components/cross-selling-editor/services/utils.d.ts.map +1 -1
  43. package/es/common/components/cross-selling-editor/services/utils.js +51 -11
  44. package/es/common/components/cross-selling-editor/tester/index.d.ts +3 -0
  45. package/es/common/components/cross-selling-editor/tester/index.d.ts.map +1 -0
  46. package/es/common/components/cross-selling-editor/tester/index.js +2 -0
  47. package/es/common/components/cross-selling-editor/tester/tester.d.ts +11 -0
  48. package/es/common/components/cross-selling-editor/tester/tester.d.ts.map +1 -0
  49. package/es/common/components/cross-selling-editor/{tester.js → tester/tester.js} +72 -27
  50. package/es/common/components/cross-selling-editor/{tester.module.css → tester/tester.module.css} +1 -0
  51. package/es/common/components/cross-selling-editor/{tester-tunnel-offer.d.ts → tester/tunnel-offer.d.ts} +4 -3
  52. package/es/common/components/cross-selling-editor/tester/tunnel-offer.d.ts.map +1 -0
  53. package/es/common/components/cross-selling-editor/tester/tunnel-offer.js +54 -0
  54. package/es/common/components/cross-selling-editor/{tester-tunnel-offer.module.css → tester/tunnel-offer.module.css} +16 -3
  55. package/es/common/components/cross-selling-editor/types.d.ts +65 -0
  56. package/es/common/components/cross-selling-editor/types.d.ts.map +1 -1
  57. package/es/lbm/components/instant-search/services/api.d.ts +0 -1
  58. package/es/lbm/components/instant-search/services/api.d.ts.map +1 -1
  59. package/es/lbm/components/instant-search/services/api.js +1 -12
  60. package/package.json +1 -1
  61. package/es/common/components/cross-selling-editor/tester-tunnel-offer.d.ts.map +0 -1
  62. package/es/common/components/cross-selling-editor/tester-tunnel-offer.js +0 -21
  63. package/es/common/components/cross-selling-editor/tester.d.ts +0 -10
  64. package/es/common/components/cross-selling-editor/tester.d.ts.map +0 -1
@@ -12,8 +12,10 @@ type Props = {
12
12
  contentZoneProps?: ZoneProps;
13
13
  durations?: Durations;
14
14
  className?: string;
15
+ tunnelOffersOrder?: string[];
16
+ displayedTunnelOffers?: string[];
15
17
  children?: React.ReactNode;
16
18
  };
17
- export default function CrossSellingEditor({ titleZoneProps, contentZoneProps, durations, className, children, }: Props): import("react/jsx-runtime").JSX.Element;
19
+ export default function CrossSellingEditor({ titleZoneProps, contentZoneProps, durations, className, tunnelOffersOrder, displayedTunnelOffers, children, }: Props): import("react/jsx-runtime").JSX.Element;
18
20
  export {};
19
21
  //# sourceMappingURL=cross-selling-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cross-selling-editor.d.ts","sourceRoot":"","sources":["../../../../src/common/components/cross-selling-editor/cross-selling-editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,KAAK,SAAS,GAAG;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,cAAmB,EACnB,gBAAqB,EACrB,SAAS,EACT,SAAS,EACT,QAAQ,GACT,EAAE,KAAK,2CAqDP"}
1
+ {"version":3,"file":"cross-selling-editor.d.ts","sourceRoot":"","sources":["../../../../src/common/components/cross-selling-editor/cross-selling-editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,KAAK,SAAS,GAAG;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,cAAmB,EACnB,gBAAqB,EACrB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,qBAAqB,EACrB,QAAQ,GACT,EAAE,KAAK,2CA6DP"}
@@ -6,12 +6,14 @@ import { useUbloContext } from "ublo/with-ublo";
6
6
  import * as Plausible from "../plausible";
7
7
  import Editor from "./editor";
8
8
  import styles from "./cross-selling-editor.module.css";
9
- export default function CrossSellingEditor({ titleZoneProps = {}, contentZoneProps = {}, durations, className, children, }) {
9
+ export default function CrossSellingEditor({ titleZoneProps = {}, contentZoneProps = {}, durations, className, tunnelOffersOrder, displayedTunnelOffers, children, }) {
10
10
  const ref = React.useRef();
11
11
  const titleRef = React.useRef();
12
12
  const { cmsMode } = useUbloContext();
13
13
  const sendPlausibleEvent = (e) => {
14
14
  const container = e.target.closest("data-custom-offers");
15
+ if (cmsMode || !container)
16
+ return;
15
17
  const sections = Array.from(container.querySelectorAll("section"));
16
18
  const section = e.target.closest("section");
17
19
  const link = section.querySelector("a");
@@ -25,5 +27,5 @@ export default function CrossSellingEditor({ titleZoneProps = {}, contentZonePro
25
27
  });
26
28
  }
27
29
  };
28
- return (_jsxs("div", { className: classNames(styles.editor, className), onClick: sendPlausibleEvent, children: [children, cmsMode === "editing" && _jsx(Editor, { zoneRef: ref, durations: durations }), titleZoneProps.enabled && (_jsx(Zone, { ref: titleRef, id: titleZoneProps.id || "tunnel-offers-title", className: classNames(styles.titleZone, titleZoneProps.className), section: titleZoneProps.section, maxSections: 1, tooltip: "Zone d'edition : Titre des offres", "data-title-zone": titleZoneProps.dataAttributeValue || "" })), contentZoneProps.enabled && (_jsx(Zone, { ref: ref, id: contentZoneProps.id || "tunnel-offers", className: classNames(styles.contentZone, contentZoneProps.className), section: contentZoneProps.section, tooltip: "Zone d'edition : Offres", "data-content-zone": contentZoneProps.dataAttributeValue || "" }))] }));
30
+ return (_jsxs("div", { className: classNames(styles.editor, className), onClick: sendPlausibleEvent, children: [children, cmsMode === "editing" && (_jsx(Editor, { zoneRef: ref, durations: durations, tunnelOffersOrder: tunnelOffersOrder, displayedTunnelOffers: displayedTunnelOffers })), titleZoneProps.enabled && (_jsx(Zone, { ref: titleRef, id: titleZoneProps.id || "tunnel-offers-title", className: classNames(styles.titleZone, titleZoneProps.className), section: titleZoneProps.section, maxSections: 1, tooltip: "Zone d'\u00E9dition : Titre des offres", "data-title-zone": titleZoneProps.dataAttributeValue || "" })), contentZoneProps.enabled && (_jsx(Zone, { ref: ref, id: contentZoneProps.id || "tunnel-offers", className: classNames(styles.contentZone, contentZoneProps.className), section: contentZoneProps.section, tooltip: "Zone d'\u00E9dition : Offres", "data-content-zone": contentZoneProps.dataAttributeValue || "" }))] }));
29
31
  }
@@ -3,7 +3,9 @@ import type { Durations } from "./types";
3
3
  type Props = {
4
4
  zoneRef: React.RefObject<HTMLElement>;
5
5
  durations: Durations;
6
+ tunnelOffersOrder?: string[];
7
+ displayedTunnelOffers?: string[];
6
8
  };
7
- export default function Editor({ zoneRef, durations }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export default function Editor({ zoneRef, durations, tunnelOffersOrder, displayedTunnelOffers, }: Props): import("react/jsx-runtime").JSX.Element;
8
10
  export {};
9
11
  //# sourceMappingURL=editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../../src/common/components/cross-selling-editor/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,SAAS,CAAC;AAGjD,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,2CAgE3D"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../../src/common/components/cross-selling-editor/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,SAAS,CAAC;AAGjD,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,qBAAqB,GACtB,EAAE,KAAK,2CAkEP"}
@@ -8,7 +8,7 @@ import Rules from "./rules";
8
8
  import Tester from "./tester";
9
9
  import * as Utils from "./services/utils";
10
10
  import styles from "./editor.module.css";
11
- export default function Editor({ zoneRef, durations }) {
11
+ export default function Editor({ zoneRef, durations, tunnelOffersOrder, displayedTunnelOffers, }) {
12
12
  const zoneContainer = zoneRef.current;
13
13
  const [dialogOpened, setDialogOpened] = React.useState(false);
14
14
  const [config, setConfig] = React.useState({});
@@ -36,7 +36,7 @@ export default function Editor({ zoneRef, durations }) {
36
36
  const closeDialog = () => {
37
37
  setDialogOpened(false);
38
38
  };
39
- return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { content: "Param\u00E9trer les offres crois\u00E9es", children: _jsx(Button, { className: styles.button, onClick: openDialog, children: _jsx(Icons.Settings, {}) }) }), _jsx(Dialog, { className: styles.dialog, isOpened: dialogOpened, close: closeDialog, showAsModal: false, children: _jsxs("div", { className: styles.dialogInner, children: [_jsx(Rules, { container: zoneContainer, config: config, setConfig: setConfig, tunnelOffers: Utils.tunnelOffers, durations: durations }), _jsx(Tester, { container: zoneContainer, config: config, tunnelOffers: Utils.tunnelOffers, durations: durations })] }) })] }));
39
+ return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { content: "Param\u00E9trer les offres crois\u00E9es", children: _jsx(Button, { className: styles.button, onClick: openDialog, children: _jsx(Icons.Settings, {}) }) }), _jsx(Dialog, { className: styles.dialog, isOpened: dialogOpened, close: closeDialog, showAsModal: false, children: _jsxs("div", { className: styles.dialogInner, children: [_jsx(Rules, { container: zoneContainer, config: config, setConfig: setConfig, durations: durations, tunnelOffersOrder: tunnelOffersOrder, displayedTunnelOffers: displayedTunnelOffers }), _jsx(Tester, { container: zoneContainer, config: config, durations: durations, tunnelOffersOrder: tunnelOffersOrder, displayedTunnelOffers: displayedTunnelOffers })] }) })] }));
40
40
  }
41
41
  function init(zoneContainer, setConfig) {
42
42
  let configContainer = zoneContainer?.querySelector(`#${Utils.CONFIG_ID}`);
@@ -0,0 +1,3 @@
1
+ import EsfSpecialRulForm from "./special-rule-form";
2
+ export default EsfSpecialRulForm;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/esf/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import EsfSpecialRulForm from "./special-rule-form";
2
+ export default EsfSpecialRulForm;
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import type { Config, Override } from "../types";
3
+ type Props = {
4
+ open: boolean;
5
+ close: () => void;
6
+ currentOffer: string;
7
+ override: Override;
8
+ setConfig: React.Dispatch<React.SetStateAction<Config>>;
9
+ };
10
+ export default function EsfSpecialRuleForm({ open, close, currentOffer, override, setConfig, }: Props): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=special-rule-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"special-rule-form.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/esf/special-rule-form.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,MAAM,EAAc,QAAQ,EAAE,MAAM,UAAU,CAAC;AAG7D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,SAAS,GACV,EAAE,KAAK,2CAgDP"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { useUbloContext } from "ublo/with-ublo";
4
+ import Dialog from "dt-design-system/es/dialog";
5
+ import Step1 from "./step-1";
6
+ import Step2 from "./step-2";
7
+ import useFetch from "../hooks/use-fetch";
8
+ import * as API from "../services/api";
9
+ import styles from "./special-rule-form.module.css";
10
+ export default function EsfSpecialRuleForm({ open, close, currentOffer, override, setConfig, }) {
11
+ const [currentStep, setCurrentStep] = React.useState(1);
12
+ const { lang } = useUbloContext();
13
+ const { data: welcome, loading } = useFetch({
14
+ callback: (abortController) => API.fetchEsfWelcome(lang, abortController),
15
+ ready: open,
16
+ });
17
+ const goToStep = (step) => {
18
+ setCurrentStep(step);
19
+ };
20
+ const closeModal = () => {
21
+ close();
22
+ setTimeout(() => {
23
+ setCurrentStep(1);
24
+ }, 240);
25
+ };
26
+ return (_jsxs(Dialog, { className: styles.dialog, isOpened: open, close: closeModal, showAsModal: false, loading: loading, children: [currentStep === 1 && (_jsx(Step1, { welcome: welcome, goToStep: goToStep, currentOffer: currentOffer, override: override, setConfig: setConfig })), currentStep === 2 && (_jsx(Step2, { goToStep: goToStep, currentOffer: currentOffer, override: override, setConfig: setConfig, closeModal: closeModal }))] }));
27
+ }
@@ -0,0 +1,4 @@
1
+ .dialog {
2
+ width: 420px;
3
+ min-height: 120px;
4
+ }
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import type { Config, Override, EsfWelcome } from "../types";
3
+ type Props = {
4
+ welcome: EsfWelcome;
5
+ goToStep: (step: number) => void;
6
+ currentOffer: string;
7
+ override: Override;
8
+ setConfig: React.Dispatch<React.SetStateAction<Config>>;
9
+ };
10
+ export default function Step1({ welcome, goToStep, currentOffer, override, setConfig, }: Props): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=step-1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-1.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/esf/step-1.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AAGxE,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,UAAU,CAAC;IAEpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,SAAS,GACV,EAAE,KAAK,2CAgHP"}
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Input from "dt-design-system/es/input";
3
+ import Select from "dt-design-system/es/select";
4
+ import Button from "dt-design-system/es/button";
5
+ import styles from "./step-1.module.css";
6
+ export default function Step1({ welcome, goToStep, currentOffer, override, setConfig, }) {
7
+ const { stayFrom, stayTo, esf = {} } = override?.triggers || {};
8
+ const { season } = esf;
9
+ if (!welcome)
10
+ return null;
11
+ const submitForm = (e) => {
12
+ e.preventDefault();
13
+ e.stopPropagation();
14
+ goToStep(2);
15
+ };
16
+ const updateStay = (kind) => (value) => {
17
+ setConfig((config = {}) => {
18
+ const itemConfig = (config[currentOffer] || {});
19
+ const itemOverrides = itemConfig.overrides || [];
20
+ const newConfig = {
21
+ ...config,
22
+ [currentOffer]: {
23
+ ...itemConfig,
24
+ overrides: [
25
+ ...itemOverrides.map((o) => {
26
+ if (o.id === override.id) {
27
+ const triggersConfig = o.triggers || {};
28
+ return {
29
+ ...o,
30
+ triggers: {
31
+ ...triggersConfig,
32
+ [kind]: value,
33
+ },
34
+ };
35
+ }
36
+ return o;
37
+ }),
38
+ ],
39
+ },
40
+ };
41
+ return newConfig;
42
+ });
43
+ };
44
+ const updateSeason = (value) => {
45
+ setConfig((config = {}) => {
46
+ const itemConfig = (config[currentOffer] || {});
47
+ const itemOverrides = itemConfig.overrides || [];
48
+ const newConfig = {
49
+ ...config,
50
+ [currentOffer]: {
51
+ ...itemConfig,
52
+ overrides: [
53
+ ...itemOverrides.map((o) => {
54
+ if (o.id === override.id) {
55
+ const triggersConfig = o.triggers || {};
56
+ return {
57
+ ...o,
58
+ triggers: {
59
+ ...triggersConfig,
60
+ esf: {
61
+ ...(triggersConfig.esf || {}),
62
+ season: value,
63
+ },
64
+ },
65
+ };
66
+ }
67
+ return o;
68
+ }),
69
+ ],
70
+ },
71
+ };
72
+ return newConfig;
73
+ });
74
+ };
75
+ const { availableSeasons = [] } = welcome;
76
+ const isDisabled = !season || !stayFrom || !stayTo;
77
+ return (_jsxs("form", { className: styles.form, onSubmit: submitForm, children: [_jsx("div", { className: styles.title, children: "Contexte" }), _jsx(Select, { className: styles.input, label: "Saison", placeholder: "Choisissez une saison", options: availableSeasons, value: season || "", onValueChange: updateSeason }), _jsx("div", { className: styles.subTitle, children: "S\u00E9jour" }), _jsx(Input, { className: styles.input, type: "date", label: "Inclus entre le", value: stayFrom || "", onValueChange: updateStay("stayFrom") }), _jsx(Input, { className: styles.input, type: "date", label: "et le", value: stayTo || "", onValueChange: updateStay("stayTo") }), _jsx("div", { className: styles.actions, children: _jsx(Button, { type: "submit", className: styles.action, disabled: isDisabled, children: "Suivant" }) })] }));
78
+ }
@@ -0,0 +1,35 @@
1
+ .form {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 12px;
5
+ padding: 20px;
6
+ }
7
+
8
+ .title {
9
+ text-align: center;
10
+ font-size: 20px;
11
+ font-weight: 700;
12
+ }
13
+
14
+ .subTitle {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 8px;
18
+ font-size: 14px;
19
+ }
20
+
21
+ .subTitle::after {
22
+ content: "";
23
+ flex: 1 1 100%;
24
+ height: 1px;
25
+ background-color: var(--ds-grey-200, #ededed);
26
+ }
27
+
28
+ .actions {
29
+ display: flex;
30
+ justify-content: flex-end;
31
+ gap: 8px;
32
+ }
33
+
34
+ .action {
35
+ }
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import type { Config, Override } from "../types";
3
+ type Props = {
4
+ goToStep: (step: number) => void;
5
+ currentOffer: string;
6
+ override: Override;
7
+ setConfig: React.Dispatch<React.SetStateAction<Config>>;
8
+ closeModal: () => void;
9
+ };
10
+ export default function Step2({ goToStep, currentOffer, override, setConfig, closeModal, }: Props): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=step-2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-2.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/esf/step-2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,KAAK,EAIV,MAAM,EASN,QAAQ,EAET,MAAM,UAAU,CAAC;AAGlB,KAAK,KAAK,GAAG;IAEX,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAUF,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,UAAU,GACX,EAAE,KAAK,2CA0RP"}
@@ -0,0 +1,157 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useUbloContext } from "ublo/with-ublo";
3
+ import Select, { formatOptions } from "dt-design-system/es/select";
4
+ import MultipleSelect from "dt-design-system/es/multiple-select";
5
+ import Button from "dt-design-system/es/button";
6
+ import Loader from "dt-design-system/es/loader";
7
+ import Popover from "dt-design-system/es/popover";
8
+ import * as Icons from "dt-design-system/es/icons";
9
+ import useFetch from "../hooks/use-fetch";
10
+ import * as API from "../services/api";
11
+ import * as Utils from "../services/utils";
12
+ import styles from "./step-2.module.css";
13
+ export default function Step2({ goToStep, currentOffer, override, setConfig, closeModal, }) {
14
+ const { lang } = useUbloContext();
15
+ const { stayFrom, stayTo, esf = {} } = override?.triggers || {};
16
+ const { season, rules = {} } = esf;
17
+ const { kinds: selectedKinds, activities: selectedActivities, levels: selectedLevels, meetings: selectedMeetings, } = rules;
18
+ const period = Utils.getIntervalLengthFromDates(stayFrom, stayTo);
19
+ const { data: kinds, loading: isKindsLoading } = useFetch({
20
+ callback: (abortController) => API.fetchEsfKinds(lang, season, stayFrom, stayTo, period, abortController),
21
+ });
22
+ const { data: ages } = useFetch({
23
+ callback: (abortController) => API.fetchEsfAges(lang, season, stayFrom, stayTo, period, abortController),
24
+ });
25
+ const { data: activities, loading: isActivitiesLoading } = useFetch({
26
+ key: selectedKinds,
27
+ callback: (abortController) => API.fetchEsfActivities(lang, season, stayFrom, stayTo, period, formatAges(ages?.choices), selectedKinds?.split(","), abortController),
28
+ ready: Boolean(selectedKinds),
29
+ });
30
+ const activitiesParam = split(selectedActivities)?.length > 0
31
+ ? split(selectedActivities)
32
+ : formatParams(activities?.choices);
33
+ const { data: levels, loading: isLevelsLoading } = useFetch({
34
+ key: selectedKinds + selectedActivities,
35
+ callback: (abortController) => API.fetchEsfLevels(lang, season, stayFrom, stayTo, period, activitiesParam, formatAges(ages?.choices), split(selectedKinds), abortController),
36
+ ready: Boolean(selectedKinds),
37
+ });
38
+ const levelsParams = split(selectedLevels)?.length > 0
39
+ ? split(selectedLevels)
40
+ : formatParams(levels?.choices);
41
+ const { data: meetings, loading: isMeetingsLoading } = useFetch({
42
+ key: selectedKinds + selectedActivities + selectedLevels,
43
+ callback: (abortController) => API.fetchEsfMeetings(lang, season, stayFrom, stayTo, period, activitiesParam, formatAges(ages?.choices), split(selectedKinds), levelsParams, abortController),
44
+ ready: Boolean(selectedKinds),
45
+ });
46
+ const meetingsParams = split(selectedMeetings)?.length > 0
47
+ ? split(selectedMeetings)
48
+ : formatParams(meetings?.choices);
49
+ const { data: products, loading: isProductsLoading } = useFetch({
50
+ key: selectedKinds + selectedActivities + selectedLevels + selectedMeetings,
51
+ callback: (abortController) => API.fetchEsfProducts(lang, season, stayFrom, stayTo, period, activitiesParam, formatAges(ages?.choices), split(selectedKinds), levelsParams, meetingsParams, abortController),
52
+ ready: Boolean(selectedKinds),
53
+ });
54
+ const formattedProducts = formatProducts(products);
55
+ const kindOptions = formatOptions("name", "code", dedupe(kinds?.choices));
56
+ const activityOptions = formatOptions("name", "code", dedupe(activities?.choices));
57
+ const levelOptions = formatOptions("name", "code", dedupe(levels?.choices));
58
+ const meetingOptions = formatOptions("name", "code", dedupe(meetings?.choices));
59
+ const activityValues = formatValues(selectedActivities, activityOptions);
60
+ const levelValues = formatValues(selectedLevels, levelOptions);
61
+ const meetingValues = formatValues(selectedMeetings, meetingOptions);
62
+ const updateEsfRules = (key) => (value) => {
63
+ const formattedValue = typeof value === "string"
64
+ ? value
65
+ : value.map((v) => (typeof v === "string" ? v : v.value)).join(",");
66
+ if (key === "kinds") {
67
+ updateEsfRules("activities")("");
68
+ }
69
+ if (key === "kinds" || key === "activities") {
70
+ updateEsfRules("levels")("");
71
+ }
72
+ if (key === "kinds" || key === "activities" || key === "levels") {
73
+ updateEsfRules("meetings")("");
74
+ }
75
+ setConfig((config = {}) => {
76
+ const itemConfig = (config[currentOffer] || {});
77
+ const itemOverrides = itemConfig.overrides || [];
78
+ const newConfig = {
79
+ ...config,
80
+ [currentOffer]: {
81
+ ...itemConfig,
82
+ overrides: [
83
+ ...itemOverrides.map((o) => {
84
+ if (o.id === override.id) {
85
+ const triggersConfig = o.triggers || {};
86
+ const esfConfig = triggersConfig.esf || {};
87
+ const esfRulesConfig = esfConfig.rules || {};
88
+ return {
89
+ ...o,
90
+ triggers: {
91
+ ...triggersConfig,
92
+ esf: {
93
+ ...esfConfig,
94
+ rules: { ...esfRulesConfig, [key]: formattedValue },
95
+ },
96
+ },
97
+ };
98
+ }
99
+ return o;
100
+ }),
101
+ ],
102
+ },
103
+ };
104
+ return newConfig;
105
+ });
106
+ };
107
+ const isDisabled = !selectedKinds;
108
+ const submitForm = (e) => {
109
+ e.preventDefault();
110
+ e.stopPropagation();
111
+ closeModal();
112
+ };
113
+ return (_jsxs("form", { className: styles.form, onSubmit: submitForm, children: [_jsx("div", { className: styles.title, children: "R\u00E8gles" }), _jsx(Select, { label: "Type de produit", placeholder: "Choisissez un type", options: kindOptions, loading: isKindsLoading, value: selectedKinds, onValueChange: updateEsfRules("kinds") }), _jsx(MultipleSelect, { label: "Activit\u00E9s", placeholder: "Choisissez une ou plusieurs activit\u00E9s", options: activityOptions, loading: isActivitiesLoading, values: activityValues, onChange: updateEsfRules("activities"), disabled: !selectedKinds || !Boolean(activityOptions?.length) }), _jsx(MultipleSelect, { label: "Niveaux", placeholder: "Choisissez un ou plusieurs niveaux", options: levelOptions, loading: isLevelsLoading, values: levelValues, onChange: updateEsfRules("levels"), disabled: !selectedKinds || !Boolean(levelOptions?.length) }), _jsx(MultipleSelect, { label: "Lieux de rendez-vous", placeholder: "Choisissez un ou plusieurs RDV", options: meetingOptions, loading: isMeetingsLoading, values: meetingValues, onChange: updateEsfRules("meetings"), disabled: !selectedKinds || !Boolean(meetingOptions?.length) }), _jsxs("div", { className: styles.actions, children: [_jsx(Popover, { className: styles.popover, trigger: _jsx(Button, { className: styles.products, variant: "transparent", disabled: !isProductsLoading && !formattedProducts.length, children: isProductsLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader, { className: styles.loader }), " R\u00E9cup\u00E9ration des produits..."] })) : (_jsxs(_Fragment, { children: [_jsx(Icons.ShoppingBag, {}), formattedProducts.length, " produit", formattedProducts.length > 1 && "s", " correspondant", formattedProducts.length > 1 && "s"] })) }), children: _jsx("div", { className: styles.popoverItems, children: formattedProducts.map((product) => {
114
+ const { code, name } = product;
115
+ return (_jsx("div", { className: styles.popoverItem, children: name }, code));
116
+ }) }) }), _jsx(Button, { className: styles.Action, variant: "transparent", onClick: () => goToStep(1), children: "Retour" }), _jsx(Button, { type: "submit", variant: "success", className: styles.action, disabled: isDisabled, children: "Valider" })] })] }));
117
+ }
118
+ function dedupe(items) {
119
+ if (!items)
120
+ return [];
121
+ return items.reduce((acc, item) => {
122
+ if (acc.some((i) => i.code === item.code))
123
+ return acc;
124
+ return [...acc, item];
125
+ }, []);
126
+ }
127
+ function formatAges(ages) {
128
+ if (!ages)
129
+ return [];
130
+ const allCodes = ages.reduce((acc, age) => {
131
+ return [...acc, ...age.ages];
132
+ }, []);
133
+ return [...new Set(allCodes)];
134
+ }
135
+ function formatParams(items) {
136
+ if (!items)
137
+ return [];
138
+ return items.map((item) => item.code);
139
+ }
140
+ function split(value) {
141
+ if (!value)
142
+ return [];
143
+ return value.split(",").filter(Boolean);
144
+ }
145
+ function formatValues(values, options) {
146
+ if (!values || !options)
147
+ return [];
148
+ return options.filter((o) => split(values).includes(typeof o === "string" ? o : o.value));
149
+ }
150
+ function formatProducts(products) {
151
+ if (!products)
152
+ return [];
153
+ return products.choices.reduce((acc, item) => {
154
+ const { products } = item;
155
+ return [...acc, ...products];
156
+ }, []);
157
+ }
@@ -0,0 +1,72 @@
1
+ .form {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 12px;
5
+ padding: 20px;
6
+ }
7
+
8
+ .title {
9
+ text-align: center;
10
+ font-size: 20px;
11
+ font-weight: 700;
12
+ }
13
+
14
+ .subTitle {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 8px;
18
+ font-size: 14px;
19
+ }
20
+
21
+ .subTitle::after {
22
+ content: "";
23
+ flex: 1 1 100%;
24
+ height: 1px;
25
+ background-color: var(--ds-grey-200, #ededed);
26
+ }
27
+
28
+ .actions {
29
+ display: flex;
30
+ justify-content: flex-end;
31
+ gap: 8px;
32
+ }
33
+
34
+ .action {
35
+ }
36
+
37
+ .products {
38
+ --ds-loader-spinner-size: 17px;
39
+ --ds-loader-thickness: 2px;
40
+ --ds-button-font-weight: 400;
41
+ --ds-button-font-size: 13px;
42
+ --ds-loader-foreground: var(
43
+ --ds-button-background,
44
+ var(--ds-secondary, var(--ds-blue-400, #0038ff))
45
+ );
46
+
47
+ margin-right: auto;
48
+ }
49
+
50
+ .popover {
51
+ padding: 0;
52
+ }
53
+
54
+ .popoverItems {
55
+ max-height: 45vh;
56
+ display: flex;
57
+ flex-direction: column;
58
+ align-items: stretch;
59
+ gap: 4px;
60
+ padding: 12px;
61
+ overflow: auto;
62
+ }
63
+
64
+ .popoverItem {
65
+ display: flex;
66
+ gap: 12px;
67
+ padding: 6px;
68
+ }
69
+
70
+ .popoverItem b {
71
+ margin-right: auto;
72
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"use-custom-offers.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/hooks/use-custom-offers.ts"],"names":[],"mappings":"AAKA,KAAK,KAAK,GAAG;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,aAAa,EACb,eAAe,GAChB,GAAE,KAAU,UAgEZ"}
1
+ {"version":3,"file":"use-custom-offers.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/hooks/use-custom-offers.ts"],"names":[],"mappings":"AAKA,KAAK,KAAK,GAAG;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,aAAa,EACb,eAAe,GAChB,GAAE,KAAU,UAmEZ"}
@@ -15,6 +15,7 @@ export default function useCustomOffers({ titleSelector, contentSelector, } = {}
15
15
  let stay = {};
16
16
  let skiPassDurations = [];
17
17
  let durationTags = [];
18
+ let esfOffersContent = [];
18
19
  if (cartId) {
19
20
  try {
20
21
  const { cart } = await API.fetchMseMCart(cartId, lang);
@@ -25,6 +26,7 @@ export default function useCustomOffers({ titleSelector, contentSelector, } = {}
25
26
  Utils.getSkiPassDurationFromCart(cart),
26
27
  Utils.getDurationTagsFromCart(cart),
27
28
  ]);
29
+ esfOffersContent = Utils.getEsfOffersFromCart(cart);
28
30
  }
29
31
  catch (e) { }
30
32
  }
@@ -34,6 +36,7 @@ export default function useCustomOffers({ titleSelector, contentSelector, } = {}
34
36
  stay,
35
37
  skiPassDurations,
36
38
  durationTags,
39
+ esfOffersContent,
37
40
  };
38
41
  const storedConfig = Utils.getConfig(contentZone);
39
42
  const sortedOffers = Utils.getSortedOffers(contentZone, content, storedConfig);
@@ -0,0 +1,12 @@
1
+ type Params = {
2
+ key?: string;
3
+ callback: <T>(abortController: AbortController) => Promise<T>;
4
+ ready?: boolean;
5
+ };
6
+ type ReturnType<T> = {
7
+ data: T;
8
+ loading: boolean;
9
+ };
10
+ export default function useFetch<T>({ key, callback, ready, }: Params): ReturnType<T>;
11
+ export {};
12
+ //# sourceMappingURL=use-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-fetch.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/hooks/use-fetch.ts"],"names":[],"mappings":"AAEA,KAAK,MAAM,GAAG;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,UAAU,CAAC,CAAC,IAAI;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,CAAC,EAAE,EAClC,GAAG,EACH,QAAQ,EACR,KAAY,GACb,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAoCxB"}
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ export default function useFetch({ key, callback, ready = true, }) {
3
+ const [data, setData] = React.useState();
4
+ const [loading, setLoading] = React.useState(false);
5
+ const controller = React.useRef();
6
+ React.useEffect(() => {
7
+ if (ready && data === undefined) {
8
+ const runEffect = async () => {
9
+ try {
10
+ if (controller.current) {
11
+ controller.current.abort();
12
+ controller.current = undefined;
13
+ }
14
+ setLoading(true);
15
+ const abortController = new AbortController();
16
+ controller.current = abortController;
17
+ const result = await callback(abortController);
18
+ setData(result);
19
+ setLoading(false);
20
+ }
21
+ catch (e) {
22
+ console.error(e);
23
+ setData(null);
24
+ }
25
+ };
26
+ runEffect();
27
+ }
28
+ }, [callback, data, ready]);
29
+ React.useEffect(() => {
30
+ if (key) {
31
+ setData(undefined);
32
+ }
33
+ }, [key, ready]);
34
+ return { data, loading };
35
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"use-tunnel-offers.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/hooks/use-tunnel-offers.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,KAAA,SAyCvE"}
1
+ {"version":3,"file":"use-tunnel-offers.d.ts","sourceRoot":"","sources":["../../../../../src/common/components/cross-selling-editor/hooks/use-tunnel-offers.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,KAAA,SA2CvE"}
@@ -18,12 +18,14 @@ export default function useTunnelOffers(zone, path, cart) {
18
18
  Utils.getSkiPassDurationFromCart(cart),
19
19
  Utils.getDurationTagsFromCart(cart),
20
20
  ]);
21
+ const esfOffersContent = Utils.getEsfOffersFromCart(cart);
21
22
  const content = {
22
23
  items,
23
24
  merchants,
24
25
  stay,
25
26
  skiPassDurations,
26
27
  durationTags,
28
+ esfOffersContent,
27
29
  };
28
30
  const storedConfig = Utils.getConfig(container);
29
31
  const sortedOffers = Utils.getSortedOffers(container, content, storedConfig);