@adyen/kyc-components 2.61.1 → 2.62.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.
@@ -24,7 +24,6 @@ class UserEvents {
24
24
  subCategory: "hosted onboarding",
25
25
  countryCode: void 0,
26
26
  capabilities: void 0,
27
- legalEntityId: void 0,
28
27
  task: void 0
29
28
  };
30
29
  this.sharedEventProperties = {};
@@ -47,11 +46,14 @@ class UserEvents {
47
46
  this.notifySubscribers();
48
47
  }
49
48
  /**
50
- * Starts a timer for an event to measure the time it takes for an event to occur. Time is ended when `addEvent` is executed with the same key
49
+ * Adds an event with context specific to page-related events
51
50
  */
52
- startEvent(eventName) {
53
- this.add({ type: "start_event", name: eventName });
54
- this.notifySubscribers();
51
+ addPageEvent(eventName, properties) {
52
+ this.addEvent(eventName, {
53
+ actionLevel: "page",
54
+ page: this.sharedEventProperties.page,
55
+ ...properties
56
+ });
55
57
  }
56
58
  /**
57
59
  * Adds an event with context specific to field-related events
@@ -63,6 +65,13 @@ class UserEvents {
63
65
  ...properties
64
66
  });
65
67
  }
68
+ /**
69
+ * Starts a timer for an event to measure the time it takes for an event to occur. Time is ended when `addEvent` is executed with the same key
70
+ */
71
+ startEvent(eventName) {
72
+ this.add({ type: "start_event", name: eventName });
73
+ this.notifySubscribers();
74
+ }
66
75
  /**
67
76
  * Subscribes a callback to analytics events. It gets called every time
68
77
  * one of the above public methods get called, and the event data is passed back as an array.
@@ -110,7 +119,7 @@ const getAssociatedLeAnalyticsPayload = ({
110
119
  associatedLegalEntityOrgType: associatedLegalEntityOrg == null ? void 0 : associatedLegalEntityOrg.type
111
120
  } : {}
112
121
  });
113
- const debouncedInputEvent$1 = debounce$1(
122
+ const debouncedInputEvent = debounce$1(
114
123
  (properties) => userEvents.addFieldEvent("Interacted with form field", properties),
115
124
  500
116
125
  );
@@ -3747,11 +3756,11 @@ const Field = ({
3747
3756
  const returnValue = typeof errorMessage === "string" && errorMessage || "invalid";
3748
3757
  userEvents.addFieldEvent("Encountered error", {
3749
3758
  actionType: "input",
3750
- field: label,
3759
+ field: name,
3751
3760
  returnType: "validation",
3752
3761
  returnValue
3753
3762
  });
3754
- }, [label, errorMessage]);
3763
+ }, [name, errorMessage]);
3755
3764
  return /* @__PURE__ */ jsx(
3756
3765
  "div",
3757
3766
  {
@@ -4035,12 +4044,11 @@ function Checkbox({
4035
4044
  enableTracking = false,
4036
4045
  ...props
4037
4046
  }) {
4038
- const field = typeof label === "string" ? label : props.name;
4039
4047
  const handleChange = (newValue) => {
4040
4048
  if (enableTracking) {
4041
4049
  userEvents.addFieldEvent("Interacted with form field", {
4042
4050
  actionType: "input",
4043
- field,
4051
+ field: props.name,
4044
4052
  returnValue: String(newValue)
4045
4053
  });
4046
4054
  }
@@ -4399,7 +4407,7 @@ const Select = ({
4399
4407
  (e) => {
4400
4408
  const { value } = e.target;
4401
4409
  if (enableTracking) {
4402
- debouncedInputEvent$1({ actionType: "input", field: name });
4410
+ debouncedInputEvent({ actionType: "input", field: name });
4403
4411
  }
4404
4412
  if (isSearch && value.length > 2) {
4405
4413
  debouncedOnSearch(value);
@@ -5015,7 +5023,7 @@ const InputBase = forwardRef((props, ref) => {
5015
5023
  const handleInput = (e) => {
5016
5024
  var _a;
5017
5025
  if (enableTracking) {
5018
- debouncedInputEvent$1({ actionType: "input", field: name });
5026
+ debouncedInputEvent({ actionType: "input", field: name });
5019
5027
  }
5020
5028
  e.target.value = convertFullToHalf(e.target.value);
5021
5029
  (_a = props.onInput) == null ? void 0 : _a.call(props, e);
@@ -11011,7 +11019,7 @@ const isExistingFile = (file) => "existing" in file && file.existing;
11011
11019
  const isNewlyUploadedFile = (file) => !isExistingFile(file);
11012
11020
  function DropzoneFile(props) {
11013
11021
  var _a;
11014
- const { label, file, errorMessage, onDelete } = props;
11022
+ const { file, errorMessage, onDelete } = props;
11015
11023
  const { i18n } = useI18nContext();
11016
11024
  let documentIcon;
11017
11025
  const formatSize = (bytes) => {
@@ -11032,11 +11040,11 @@ function DropzoneFile(props) {
11032
11040
  if (!errorMessage) return;
11033
11041
  userEvents.addFieldEvent("Encountered error", {
11034
11042
  actionType: "change",
11035
- field: label || "dropzone",
11043
+ field: "dropzone file",
11036
11044
  returnType: "validation",
11037
11045
  returnValue: errorMessage
11038
11046
  });
11039
- }, [label, errorMessage]);
11047
+ }, [errorMessage]);
11040
11048
  return /* @__PURE__ */ jsxs(
11041
11049
  "div",
11042
11050
  {
@@ -11228,7 +11236,7 @@ function Dropzone(props) {
11228
11236
  if (enableTracking) {
11229
11237
  userEvents.addFieldEvent("Interacted with form field", {
11230
11238
  actionType: "change",
11231
- field: label || "file picker"
11239
+ field: name || "file picker"
11232
11240
  });
11233
11241
  }
11234
11242
  const currentFiles = (data == null ? void 0 : data[name]) || [];
@@ -11266,7 +11274,6 @@ function Dropzone(props) {
11266
11274
  return /* @__PURE__ */ jsx(
11267
11275
  DropzoneFile,
11268
11276
  {
11269
- label,
11270
11277
  file,
11271
11278
  onDelete: () => handleFileDelete(file),
11272
11279
  errorMessage: (_a2 = errors == null ? void 0 : errors[name]) == null ? void 0 : _a2.errorMessage
@@ -11316,10 +11323,6 @@ function Dropzone(props) {
11316
11323
  ] });
11317
11324
  }
11318
11325
  const logger$z = createLogger("TextArea");
11319
- const debouncedInputEvent = debounce$2(
11320
- (properties) => userEvents.addFieldEvent("Interacted with form field", properties),
11321
- 500
11322
- );
11323
11326
  function TextArea(props) {
11324
11327
  const { classNameModifiers, uniqueId, ...passedProps } = props;
11325
11328
  const {
@@ -19138,6 +19141,7 @@ function FilePicker({
19138
19141
  errorMessage,
19139
19142
  multiple = false,
19140
19143
  label,
19144
+ name,
19141
19145
  iconPrefix = "generic-document",
19142
19146
  enableTracking = false,
19143
19147
  // file validation options
@@ -19184,7 +19188,7 @@ function FilePicker({
19184
19188
  if (enableTracking) {
19185
19189
  userEvents.addFieldEvent("Interacted with form field", {
19186
19190
  actionType: "change",
19187
- field: label || "dropzone"
19191
+ field: name || "dropzone"
19188
19192
  });
19189
19193
  }
19190
19194
  setFiles([...newFiles, ...files]);
@@ -19203,7 +19207,6 @@ function FilePicker({
19203
19207
  files.map((file) => /* @__PURE__ */ jsx(
19204
19208
  DropzoneFile,
19205
19209
  {
19206
- label,
19207
19210
  file,
19208
19211
  onDelete: () => handleFileDelete(file),
19209
19212
  errorMessage,
@@ -19573,6 +19576,7 @@ function BankDocument(props) {
19573
19576
  FilePicker,
19574
19577
  {
19575
19578
  ...childProps,
19579
+ name: "bankStatementDocument",
19576
19580
  files: data.bankStatementDocument ?? [],
19577
19581
  setFiles: handleChangeFor("bankStatementDocument"),
19578
19582
  isValid: valid.bankStatementDocument ?? isBankStatementOptional,
@@ -23970,9 +23974,9 @@ function Summary({
23970
23974
  icon: "edit",
23971
23975
  onClick: () => {
23972
23976
  trackNavigation2({
23973
- fromForm: "summary",
23977
+ actionType: "edit",
23974
23978
  toForm: formName,
23975
- component: "Pencil icon"
23979
+ label: "Pencil icon"
23976
23980
  });
23977
23981
  editForm(formId);
23978
23982
  },
@@ -24050,18 +24054,18 @@ function Summary({
24050
24054
  ] });
24051
24055
  }
24052
24056
  const trackNavigation = ({
24053
- fromForm,
24057
+ actionType,
24054
24058
  toForm,
24055
- component,
24059
+ label,
24060
+ returnValue,
24056
24061
  baseTrackingPayload
24057
24062
  }) => {
24058
- userEvents.addEvent("Clicked button", {
24059
- ...baseTrackingPayload,
24060
- actionLevel: "page",
24061
- actionType: "navigate",
24062
- page: fromForm,
24063
- label: component,
24064
- toPage: toForm
24063
+ userEvents.addPageEvent("Clicked button", {
24064
+ actionType,
24065
+ toPage: toForm,
24066
+ label,
24067
+ returnValue,
24068
+ ...baseTrackingPayload
24065
24069
  });
24066
24070
  };
24067
24071
  const useHideButton = (condition, setHideState) => {
@@ -24118,7 +24122,7 @@ const useFormComposer = ({
24118
24122
  );
24119
24123
  }, [forms]);
24120
24124
  useEffect(() => {
24121
- userEvents.updateSharedEventProperties({ page: activeForm.formHeading || activeForm.formId });
24125
+ userEvents.updateSharedEventProperties({ page: activeForm.formName });
24122
24126
  }, [activeForm]);
24123
24127
  useEffect(() => {
24124
24128
  if (hasAlreadyNavigatedForm) return;
@@ -24127,14 +24131,6 @@ const useFormComposer = ({
24127
24131
  setActiveForm(openingStep);
24128
24132
  }
24129
24133
  }, [activeForm, forms, problems == null ? void 0 : problems.remediationActions, hasAlreadyNavigatedForm]);
24130
- const trackSectionCompletion = (formName) => {
24131
- userEvents.addEvent("Success", {
24132
- ...baseTrackingPayload,
24133
- actionLevel: "page",
24134
- actionType: "next",
24135
- page: formName
24136
- });
24137
- };
24138
24134
  const gotoFormByFormIndex = (nextFormIndex) => {
24139
24135
  if (formRef == null ? void 0 : formRef.current.verifyForm) {
24140
24136
  formRef.current.verifyForm(activeForm.formId).then((isVerified) => {
@@ -24162,6 +24158,12 @@ const useFormComposer = ({
24162
24158
  }
24163
24159
  if (!activeForm.isValid) {
24164
24160
  validateCurrentForm();
24161
+ trackNavigation({
24162
+ actionType: "next",
24163
+ label: "next",
24164
+ returnValue: "validation error",
24165
+ baseTrackingPayload
24166
+ });
24165
24167
  return;
24166
24168
  }
24167
24169
  if (isFinalStep) {
@@ -24169,27 +24171,25 @@ const useFormComposer = ({
24169
24171
  return;
24170
24172
  }
24171
24173
  setShouldValidate(false);
24172
- const toFormIndex = forms.findIndex((form) => form.formId === activeForm.formId) + 1;
24174
+ const toFormIndex = currentStep + 1;
24173
24175
  gotoFormByFormIndex(toFormIndex);
24174
24176
  trackNavigation({
24175
- fromForm: activeForm.formName,
24177
+ actionType: "next",
24176
24178
  toForm: forms[toFormIndex].formName,
24177
- component: "ActionBar",
24179
+ label: "next",
24180
+ returnValue: "success",
24178
24181
  baseTrackingPayload
24179
24182
  });
24180
- trackSectionCompletion(activeForm.formName);
24181
24183
  };
24182
24184
  const handleBackClick = () => {
24183
- const currentFormIndex = forms.findIndex((form) => form.formId === activeForm.formId);
24184
- if (currentFormIndex) {
24185
- const fromForm = forms[currentFormIndex];
24186
- const toForm = forms[currentFormIndex - 1];
24185
+ if (currentStep > 0) {
24186
+ const toForm = forms[currentStep - 1];
24187
24187
  setActiveForm(toForm);
24188
24188
  setHasAlreadyNavigatedForm(true);
24189
24189
  trackNavigation({
24190
- fromForm: fromForm.formName,
24190
+ actionType: "back",
24191
24191
  toForm: toForm.formName,
24192
- component: "ActionBar",
24192
+ label: "back",
24193
24193
  baseTrackingPayload
24194
24194
  });
24195
24195
  }
@@ -27665,9 +27665,10 @@ function FormNavigation({
27665
27665
  if (form.formId === activeForm.formId) return;
27666
27666
  gotoForm(getFormIndex(form));
27667
27667
  trackNavigation2({
27668
- fromForm: form.formName,
27669
- toForm: activeForm.formName,
27670
- component: "FormNavigation"
27668
+ actionType: "navigate",
27669
+ toForm: form.formName,
27670
+ label: form.formName,
27671
+ returnValue: "success"
27671
27672
  });
27672
27673
  };
27673
27674
  const getNavigateHandler = (form, activeForm2) => {
@@ -27676,7 +27677,15 @@ function FormNavigation({
27676
27677
  if (allPriorFormsValid || !validateForm) {
27677
27678
  return goToForm(form);
27678
27679
  }
27679
- return activeForm2.isValid ? void 0 : validateForm;
27680
+ return activeForm2.isValid ? void 0 : () => {
27681
+ trackNavigation2({
27682
+ actionType: "navigate",
27683
+ toForm: form.formName,
27684
+ label: form.formName,
27685
+ returnValue: "validation error"
27686
+ });
27687
+ validateForm();
27688
+ };
27680
27689
  };
27681
27690
  return /* @__PURE__ */ jsxs("div", { className: cx("adyen-kyc-form-navigation", className), children: [
27682
27691
  /* @__PURE__ */ jsx("div", { className: "adyen-kyc-form-navigation__header", children: i18n.get(taskName) }),
@@ -27754,15 +27763,9 @@ const FormWrapper = ({
27754
27763
  );
27755
27764
  const showTaxExemptedLegalCaption = showExtraTaxExemptionReasons && ((_a = summaryData.companyRegistrationDetails) == null ? void 0 : _a.vatAbsenceReason) && ["companyDetails", "businessDetails"].includes(taskName);
27756
27765
  const handleTrackNavigation = useCallback(
27757
- ({
27758
- fromForm,
27759
- toForm,
27760
- component
27761
- }) => {
27766
+ (props) => {
27762
27767
  trackNavigation({
27763
- fromForm,
27764
- toForm,
27765
- component,
27768
+ ...props,
27766
27769
  baseTrackingPayload
27767
27770
  });
27768
27771
  },
@@ -28632,9 +28635,10 @@ function BusinessDetailsDropinComponent({
28632
28635
  case "basicInformation":
28633
28636
  if (((_b2 = currentState.validityByForm) == null ? void 0 : _b2.basicInformation) && !isBusinessSelection && !verifiedBusiness) {
28634
28637
  trackNavigation({
28635
- fromForm: activeForm.formName,
28638
+ actionType: "next",
28636
28639
  toForm: toFormName || "home",
28637
- component: "next"
28640
+ label: "next",
28641
+ returnValue: "success"
28638
28642
  });
28639
28643
  findBusiness(currentState.data.basicInformation);
28640
28644
  setShowBusinessSelection(true);
@@ -28649,7 +28653,6 @@ function BusinessDetailsDropinComponent({
28649
28653
  handleNextClick,
28650
28654
  forms,
28651
28655
  activeForm.formId,
28652
- activeForm.formName,
28653
28656
  (_e = currentState.validityByForm) == null ? void 0 : _e.basicInformation,
28654
28657
  currentState.data.basicInformation,
28655
28658
  isBusinessSelection,
@@ -28661,9 +28664,9 @@ function BusinessDetailsDropinComponent({
28661
28664
  switch (activeForm.formId) {
28662
28665
  case "basicInformation": {
28663
28666
  trackNavigation({
28664
- fromForm: activeForm.formName,
28667
+ actionType: "back",
28665
28668
  toForm: "basicDetails",
28666
- component: "back"
28669
+ label: "back"
28667
28670
  });
28668
28671
  return showBusinessSelection ? setShowBusinessSelection(false) : void 0;
28669
28672
  }
@@ -28689,8 +28692,6 @@ function BusinessDetailsDropinComponent({
28689
28692
  }
28690
28693
  }, [
28691
28694
  activeForm.formId,
28692
- activeForm.formName,
28693
- i18n,
28694
28695
  country,
28695
28696
  handleBackClick,
28696
28697
  searching,
@@ -28700,9 +28701,9 @@ function BusinessDetailsDropinComponent({
28700
28701
  ]);
28701
28702
  const homeClick = () => {
28702
28703
  trackNavigation({
28703
- fromForm: activeForm.formName,
28704
+ actionType: "save",
28704
28705
  toForm: "home",
28705
- component: "home"
28706
+ label: "home"
28706
28707
  });
28707
28708
  handleHomeClick == null ? void 0 : handleHomeClick();
28708
28709
  };
@@ -30122,6 +30123,10 @@ const BusinessTypeSelection = ({
30122
30123
  if (loadingStatus === "loading") return;
30123
30124
  triggerValidation();
30124
30125
  if (isValid) {
30126
+ userEvents.addEvent("Clicked button", {
30127
+ actionLevel: "task",
30128
+ actionType: "next"
30129
+ });
30125
30130
  if (((_a2 = data.businessType) == null ? void 0 : _a2.id) === "legalArrangement") {
30126
30131
  if (currentStep !== 1) {
30127
30132
  setCurrentStep(
@@ -30812,6 +30817,12 @@ const DecisionMakersComponent = ({
30812
30817
  }, {});
30813
30818
  const uniqueDecisionMakers = mappedDecisionMakers ? Object.values(mappedDecisionMakers) : [];
30814
30819
  const showWarning = Boolean(remediationMessages.DECISION_MAKER && uniqueDecisionMakers.length);
30820
+ useEffect(() => {
30821
+ userEvents.addEvent("Landed on page", {
30822
+ actionLevel: "task",
30823
+ actionType: "start"
30824
+ });
30825
+ }, []);
30815
30826
  useEffect(() => {
30816
30827
  if (showWarning) {
30817
30828
  userEvents.addEvent("Encountered error", {
@@ -31139,15 +31150,16 @@ const Introduction = ({
31139
31150
  page: (introductionScreens == null ? void 0 : introductionScreens.length) ? introductionScreens[activeIndex] : void 0
31140
31151
  };
31141
31152
  useEffect(() => {
31142
- if (introductionScreens == null ? void 0 : introductionScreens.length) {
31143
- userEvents.addEvent("Landed on page", {
31144
- actionLevel: "task",
31145
- actionType: "start"
31146
- });
31147
- } else {
31153
+ userEvents.addEvent("Landed on page", {
31154
+ actionLevel: "task",
31155
+ actionType: "start"
31156
+ });
31157
+ }, []);
31158
+ useEffect(() => {
31159
+ if (!(introductionScreens == null ? void 0 : introductionScreens.length)) {
31148
31160
  onExitIntroduction();
31149
31161
  }
31150
- }, [introductionScreens]);
31162
+ }, [introductionScreens, onExitIntroduction]);
31151
31163
  const translationKeys = {
31152
31164
  skip: "goToOverviewFromIntroduction",
31153
31165
  back: "back",
@@ -31212,7 +31224,7 @@ const Introduction = ({
31212
31224
  onClick: () => {
31213
31225
  userEvents.addEvent("Success", {
31214
31226
  actionLevel: "task",
31215
- actionType: "start",
31227
+ actionType: "submit",
31216
31228
  label: translationKeys.start
31217
31229
  });
31218
31230
  onExitIntroduction();
@@ -31640,6 +31652,7 @@ const hasPayoutAccount = (legalEntityResponse) => {
31640
31652
  return Boolean((_a = legalEntityResponse.transferInstruments) == null ? void 0 : _a.length);
31641
31653
  };
31642
31654
  const TaskListItem = ({
31655
+ titleKey,
31643
31656
  title,
31644
31657
  icon,
31645
31658
  status,
@@ -31656,18 +31669,31 @@ const TaskListItem = ({
31656
31669
  removeEntity,
31657
31670
  isRemoveDisabled = false,
31658
31671
  handleIsRemoveDisabled,
31659
- testId
31672
+ testId,
31673
+ enableTracking = true
31660
31674
  }) => {
31675
+ const { i18n } = useI18nContext();
31661
31676
  const shouldShowErrorAlert = showErrorAlerts === "always" || showErrorAlerts === "onErrorStatus" && status === TaskStatus.ERROR;
31662
31677
  const [isStatusRemoving, setIsStatusRemoving] = useState(false);
31678
+ const handleNavigateToTask = () => {
31679
+ if (enableTracking) {
31680
+ userEvents.addEvent("Clicked button", {
31681
+ actionLevel: "journey",
31682
+ actionType: "open",
31683
+ task: void 0,
31684
+ label: titleKey
31685
+ });
31686
+ }
31687
+ onNavigateToTask == null ? void 0 : onNavigateToTask();
31688
+ };
31663
31689
  return /* @__PURE__ */ jsx(
31664
31690
  Card,
31665
31691
  {
31666
31692
  stateful: onNavigateToTask && !loading && !disabled,
31667
31693
  warning: showWarningAlert,
31668
31694
  warningMessage,
31669
- onClick: loading ? void 0 : onNavigateToTask,
31670
- onKeyDown: handleKeys(["Enter"], onNavigateToTask ?? noop),
31695
+ onClick: loading ? void 0 : handleNavigateToTask,
31696
+ onKeyDown: handleKeys(["Enter"], handleNavigateToTask ?? noop),
31671
31697
  className: "adyen-task",
31672
31698
  disabled,
31673
31699
  children: /* @__PURE__ */ jsxs(
@@ -31681,7 +31707,7 @@ const TaskListItem = ({
31681
31707
  /* @__PURE__ */ jsxs("div", { className: "adyen-task-item__header", children: [
31682
31708
  /* @__PURE__ */ jsxs("div", { className: "adyen-task-item__heading", children: [
31683
31709
  /* @__PURE__ */ jsx("span", { className: "adyen-task-item__icon-wrapper", children: /* @__PURE__ */ jsx(Icon, { name: icon }) }),
31684
- /* @__PURE__ */ jsx("div", { className: "adyen-task-item__body", children: /* @__PURE__ */ jsx("span", { className: "adyen-task-item__title", children: title }) })
31710
+ /* @__PURE__ */ jsx("div", { className: "adyen-task-item__body", children: /* @__PURE__ */ jsx("span", { className: "adyen-task-item__title", children: title || i18n.get(titleKey) }) })
31685
31711
  ] }),
31686
31712
  info && /* @__PURE__ */ jsxs("div", { className: "adyen-task-item__info", children: [
31687
31713
  /* @__PURE__ */ jsx(Icon, { name: "info-circle" }),
@@ -31740,6 +31766,7 @@ const PayoutAccountTaskListItem = ({
31740
31766
  disabled: isInstantVerificationAccount && status === TaskStatus.PROCESSING,
31741
31767
  onNavigateToTask: isInstantVerificationAccount ? void 0 : onNavigateToTask,
31742
31768
  icon: "payout",
31769
+ titleKey: "bankAccountNumber",
31743
31770
  title: obscuredAccountNumber,
31744
31771
  status,
31745
31772
  problems: (_a = capabilityProblems == null ? void 0 : capabilityProblems.BankAccount) == null ? void 0 : _a[account.id],
@@ -31898,7 +31925,7 @@ function TaskListComponent({
31898
31925
  {
31899
31926
  onNavigateToTask: handleOnNavigateToTaskIndividual,
31900
31927
  icon: "decision-maker",
31901
- title: hasTrust ? i18n.get("trusteePersonalDetails") : i18n.get("personalDetails"),
31928
+ titleKey: hasTrust ? "trusteePersonalDetails" : "personalDetails",
31902
31929
  status: getTaskStatus(
31903
31930
  EntityType.LEGAL_ENTITY,
31904
31931
  capabilityProblems,
@@ -31913,7 +31940,7 @@ function TaskListComponent({
31913
31940
  {
31914
31941
  onNavigateToTask: handleOnNavigateToTaskLegalRepresentative,
31915
31942
  icon: "decision-maker",
31916
- title: i18n.get("legalRepresentative"),
31943
+ titleKey: "legalRepresentative",
31917
31944
  status: legalRepresentative ? getTaskStatus(
31918
31945
  EntityType.LEGAL_ENTITY,
31919
31946
  capabilityProblems,
@@ -31927,9 +31954,7 @@ function TaskListComponent({
31927
31954
  {
31928
31955
  onNavigateToTask: handleOnNavigateToSoleProp,
31929
31956
  icon: "company",
31930
- title: i18n.get(
31931
- canChangeEntityType ? "soleProprietorshipDetails" : "soleProprietorDetails"
31932
- ),
31957
+ titleKey: canChangeEntityType ? "soleProprietorshipDetails" : "soleProprietorDetails",
31933
31958
  status: getTaskStatus(
31934
31959
  EntityType.LEGAL_ENTITY,
31935
31960
  capabilityProblems,
@@ -31945,7 +31970,7 @@ function TaskListComponent({
31945
31970
  testId: TaskTypes.COMPANY,
31946
31971
  onNavigateToTask: handleOnNavigateToTaskCompany,
31947
31972
  icon: "company",
31948
- title: hasTrust ? i18n.get("companyTrusteeDetails") : i18n.get("companyDetails"),
31973
+ titleKey: hasTrust ? "companyTrusteeDetails" : "companyDetails",
31949
31974
  status: getTaskStatus(
31950
31975
  EntityType.LEGAL_ENTITY,
31951
31976
  capabilityProblems,
@@ -31961,7 +31986,7 @@ function TaskListComponent({
31961
31986
  testId: TaskTypes.BUSINESS_DETAILS,
31962
31987
  onNavigateToTask: handleOnNavigateToTaskBusinessDetails,
31963
31988
  icon: "company",
31964
- title: hasTrust ? i18n.get("businessTrusteeDetails") : i18n.get("businessDetails"),
31989
+ titleKey: hasTrust ? "businessTrusteeDetails" : "businessDetails",
31965
31990
  status: getTaskStatus(
31966
31991
  EntityType.LEGAL_ENTITY,
31967
31992
  capabilityProblems,
@@ -31976,7 +32001,7 @@ function TaskListComponent({
31976
32001
  {
31977
32002
  onNavigateToTask: handleOnNavigateToTaskDecisionMaker,
31978
32003
  icon: "decision-maker",
31979
- title: i18n.get("decisionMakers"),
32004
+ titleKey: "decisionMakers",
31980
32005
  status: hasMinRequiredDecisionMakerCount(legalEntityResponse) ? getTaskStatus(
31981
32006
  EntityType.LEGAL_ENTITY,
31982
32007
  capabilityProblems,
@@ -31996,7 +32021,7 @@ function TaskListComponent({
31996
32021
  {
31997
32022
  onNavigateToTask: handleOnNavigateToTaskTrust,
31998
32023
  icon: "trust",
31999
- title: i18n.get("trustDetails"),
32024
+ titleKey: "trustDetails",
32000
32025
  status: getTaskStatus(
32001
32026
  EntityType.LEGAL_ENTITY,
32002
32027
  capabilityProblems,
@@ -32011,7 +32036,7 @@ function TaskListComponent({
32011
32036
  {
32012
32037
  onNavigateToTask: handleOnNavigateToTaskTrustMember,
32013
32038
  icon: "decision-maker",
32014
- title: i18n.get("trustMembers"),
32039
+ titleKey: "trustMembers",
32015
32040
  status: hasRequiredTrustMemberCount2 ? getTaskStatus(
32016
32041
  EntityType.LEGAL_ENTITY,
32017
32042
  capabilityProblems,
@@ -32059,7 +32084,7 @@ function TaskListComponent({
32059
32084
  {
32060
32085
  onNavigateToTask: () => handleOnNavigateToTaskPayout(),
32061
32086
  icon: "payout",
32062
- title: canChangeEntityType ? i18n.get("bankAccountDetails") : i18n.get(hasPayinTaskNotPayout ? "payinDetails" : "payoutDetails"),
32087
+ titleKey: canChangeEntityType ? "bankAccountDetails" : hasPayinTaskNotPayout ? "payinDetails" : "payoutDetails",
32063
32088
  status: hasPayoutAccount(legalEntityResponse) ? getTaskStatus(
32064
32089
  EntityType.BANK_ACCOUNT,
32065
32090
  capabilityProblems,
@@ -32078,7 +32103,7 @@ function TaskListComponent({
32078
32103
  {
32079
32104
  onNavigateToTask: handleOnNavigateToServiceAgreement,
32080
32105
  icon: "contract",
32081
- title: i18n.get("signServiceAgreement"),
32106
+ titleKey: "signServiceAgreement",
32082
32107
  disabled: areServiceAgreementTasksDisabled,
32083
32108
  status: (serviceAgreementTypes == null ? void 0 : serviceAgreementTypes.length) ? TaskStatus.SIGN : TaskStatus.SIGNED,
32084
32109
  info: areServiceAgreementTasksDisabled ? i18n.get("requiresSignatory") : null
@@ -32089,7 +32114,7 @@ function TaskListComponent({
32089
32114
  {
32090
32115
  onNavigateToTask: handleOnNavigateToPci,
32091
32116
  icon: "pci",
32092
- title: i18n.get("pciDssQuestionnaire"),
32117
+ titleKey: "pciDssQuestionnaire",
32093
32118
  status: canDownloadPci ? TaskStatus.DOWNLOAD : TaskStatus.SIGN,
32094
32119
  statusLabel: canDownloadPci && i18n.get("downloadACopy"),
32095
32120
  downloadHandler: onPciDownload,
@@ -32103,7 +32128,7 @@ function TaskListComponent({
32103
32128
  {
32104
32129
  onNavigateToTask: handleOnNavigateToTaskReview,
32105
32130
  icon: "review",
32106
- title: i18n.get("submitReviewOfYourData"),
32131
+ titleKey: "submitReviewOfYourData",
32107
32132
  status: TaskStatus.SUBMIT,
32108
32133
  problems: (_m = capabilityProblems == null ? void 0 : capabilityProblems.LegalEntity) == null ? void 0 : _m[legalEntityResponse.id],
32109
32134
  showErrorAlerts: "always"
@@ -32781,7 +32806,7 @@ function IndividualDropinComponent({
32781
32806
  legalEntityId: updatedLegalEntity.id,
32782
32807
  entityType: updatedLegalEntity.type,
32783
32808
  countryOfRegistration: ((_c2 = dataSubmitted.personalDetails) == null ? void 0 : _c2.residencyCountry) || null,
32784
- idDocumentType: idDocumentType || null
32809
+ documentType: idDocumentType || null
32785
32810
  });
32786
32811
  }
32787
32812
  return updatedLegalEntity;
@@ -32893,7 +32918,7 @@ function IndividualDropinComponent({
32893
32918
  actionLevel: "task",
32894
32919
  actionType: "submit",
32895
32920
  countryOfRegistration: ((_b2 = dataSubmitted == null ? void 0 : dataSubmitted.personalDetails) == null ? void 0 : _b2.residencyCountry) || null,
32896
- idDocumentType: idDocumentType || null
32921
+ documentType: idDocumentType || null
32897
32922
  });
32898
32923
  legalEntity.entityAssociations = filterOutUnwantedAssociationsIfRootLE(
32899
32924
  taskType,
@@ -33614,6 +33639,10 @@ function PayoutDetailsDropinComponent({
33614
33639
  if (trustedTransferInstrumentId) {
33615
33640
  externalOnSubmit == null ? void 0 : externalOnSubmit({ ...data, id: trustedTransferInstrumentId });
33616
33641
  }
33642
+ userEvents.addEvent("Success", {
33643
+ actionLevel: "task",
33644
+ actionType: "submit"
33645
+ });
33617
33646
  navigateBackToTaskList == null ? void 0 : navigateBackToTaskList();
33618
33647
  }
33619
33648
  });
@@ -36065,7 +36094,6 @@ function DropinComposerComponent({
36065
36094
  updateLegalEntityAndCapabilityProblems(legalEntity);
36066
36095
  if (legalEntity) {
36067
36096
  userEvents.updateBaseTrackingPayload({
36068
- legalEntityId: legalEntity.id,
36069
36097
  entityType: legalEntity.type,
36070
36098
  capabilities: Object.keys(legalEntity.capabilities),
36071
36099
  countryCode: getLegalEntityCountry(legalEntity)
@@ -36367,6 +36395,9 @@ function DropinComposerComponent({
36367
36395
  actionType: "start"
36368
36396
  });
36369
36397
  }, []);
36398
+ useEffect(() => {
36399
+ userEvents.updateBaseTrackingPayload({ task: currentTask });
36400
+ }, [currentTask]);
36370
36401
  useLayoutEffect(() => {
36371
36402
  const fetchConfiguration = async () => {
36372
36403
  const data = await getConfiguration2({
@@ -39681,7 +39712,7 @@ const ConfigurationApiProvider = ({
39681
39712
  }) => {
39682
39713
  const authContext = useAuthContext();
39683
39714
  const { isEmbeddedDropin, loadingContext } = authContext;
39684
- const sdkVersion = "2.61.1";
39715
+ const sdkVersion = "2.62.0";
39685
39716
  useAnalytics({
39686
39717
  onUserEvent,
39687
39718
  legalEntityId: rootLegalEntityId,
@@ -40354,7 +40385,7 @@ const DebugModal = ({ rootLegalEntityId, onExit, getRootLegalEntity }) => {
40354
40385
  };
40355
40386
  const copyToClipboard = async () => {
40356
40387
  const toCopy = {
40357
- sdkVersion: "2.61.1",
40388
+ sdkVersion: "2.62.0",
40358
40389
  experiments: Object.fromEntries(allExperimentsWithValues),
40359
40390
  settings: Object.fromEntries(allSettingsWithValues)
40360
40391
  };
@@ -40419,7 +40450,7 @@ const DebugModal = ({ rootLegalEntityId, onExit, getRootLegalEntity }) => {
40419
40450
  /* @__PURE__ */ jsx("div", { className: "adyen-kyc-debug-modal__meta", children: /* @__PURE__ */ jsx("table", { children: /* @__PURE__ */ jsxs("tbody", { children: [
40420
40451
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", { children: [
40421
40452
  /* @__PURE__ */ jsx("span", { className: "adyen-kyc-debug-modal__table-key", children: "SDK version" }),
40422
- /* @__PURE__ */ jsx(Tag, { variant: "green", className: "adyen-kyc-tag--large", children: "2.61.1" })
40453
+ /* @__PURE__ */ jsx(Tag, { variant: "green", className: "adyen-kyc-tag--large", children: "2.62.0" })
40423
40454
  ] }) }),
40424
40455
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", { children: [
40425
40456
  /* @__PURE__ */ jsx("span", { className: "adyen-kyc-debug-modal__table-key", children: "rootLegalEntityId" }),
@@ -40544,14 +40575,11 @@ const getBaseTracking = (componentProps) => {
40544
40575
  const { legalEntityResponse } = componentProps;
40545
40576
  return {
40546
40577
  entityType: legalEntityResponse.type,
40547
- legalEntityId: legalEntityResponse.id,
40548
40578
  capabilities: Object.keys(legalEntityResponse.capabilities || {}),
40549
40579
  countryCode: getLegalEntityCountry(legalEntityResponse)
40550
40580
  };
40551
40581
  }
40552
- return {
40553
- legalEntityId: componentProps.legalEntityId
40554
- };
40582
+ return {};
40555
40583
  };
40556
40584
  class UIElement extends BaseElement {
40557
40585
  constructor() {
@@ -2,6 +2,7 @@ import type { EntityProblems } from '../../../core/models/errors/entity-problems
2
2
  import type { FormVerificationErrors } from '../../../core/models/errors/form-verification-errors';
3
3
  import type { FormModelWithValidity } from '../../../core/models/form';
4
4
  import type { TranslationKey } from '../../../language/types';
5
+ import type { TrackNavigationProps } from '../../../utils/trackNavigation';
5
6
  export interface FormNavigationProps {
6
7
  forms: FormModelWithValidity[];
7
8
  activeForm: FormModelWithValidity;
@@ -13,11 +14,7 @@ export interface FormNavigationProps {
13
14
  verificationErrors?: {
14
15
  [formId: string]: FormVerificationErrors;
15
16
  };
16
- trackNavigation?: (props: {
17
- fromForm: TranslationKey;
18
- toForm: TranslationKey;
19
- component: string;
20
- }) => void;
17
+ trackNavigation?: (props: TrackNavigationProps) => void;
21
18
  }
22
19
  export interface FormNavigationItemProps {
23
20
  form: FormModelWithValidity;
@@ -1,4 +1,4 @@
1
1
  import '../TaskListItem.scss';
2
2
  import type { TaskListItemProps } from '../types';
3
- declare const TaskListItem: ({ title, icon, status, statusLabel, onNavigateToTask, disabled, problems, downloadHandler, info, loading, showErrorAlerts, showWarningAlert, warningMessage, removeEntity, isRemoveDisabled, handleIsRemoveDisabled, testId, }: TaskListItemProps) => import("preact").JSX.Element;
3
+ declare const TaskListItem: ({ titleKey, title, icon, status, statusLabel, onNavigateToTask, disabled, problems, downloadHandler, info, loading, showErrorAlerts, showWarningAlert, warningMessage, removeEntity, isRemoveDisabled, handleIsRemoveDisabled, testId, enableTracking, }: TaskListItemProps) => import("preact").JSX.Element;
4
4
  export default TaskListItem;
@@ -4,6 +4,7 @@ import type { PciStatus } from '../../core/models/api/contracts';
4
4
  import type { ExistingLegalEntity } from '../../core/models/api/legal-entity';
5
5
  import type { CapabilityProblems } from '../../core/models/errors/capability-problems';
6
6
  import type { EntityProblems } from '../../core/models/errors/entity-problems';
7
+ import type { TranslationKey } from '../../language/types';
7
8
  import type { ServiceAgreementAcceptanceInfo, ServiceAgreementType } from '../Dropins/ServiceAgreementDropinComponent/types';
8
9
  import type { IconName } from '../internal/Icon/Icon';
9
10
  import type { ActionsMenuOption } from '../internal/Menu/ActionsMenu';
@@ -74,7 +75,8 @@ export interface TaskListGroupProps {
74
75
  }
75
76
  export interface TaskListItemProps extends TaskStatusProps {
76
77
  icon: IconName;
77
- title: string;
78
+ titleKey: TranslationKey;
79
+ title?: string;
78
80
  statusLabel?: string;
79
81
  disabled?: boolean;
80
82
  problems?: EntityProblems;
@@ -89,4 +91,5 @@ export interface TaskListItemProps extends TaskStatusProps {
89
91
  isRemoveDisabled?: boolean;
90
92
  handleIsRemoveDisabled?: Dispatch<StateUpdater<boolean>>;
91
93
  testId?: string;
94
+ enableTracking?: boolean;
92
95
  }
@@ -10,7 +10,8 @@ export interface FilePickerProps extends FileValidationOptions {
10
10
  errorMessage?: TranslationKey;
11
11
  multiple?: boolean;
12
12
  label?: string;
13
+ name: string;
13
14
  iconPrefix?: string;
14
15
  enableTracking?: boolean;
15
16
  }
16
- export declare function FilePicker({ files, setFiles, isValid, errorMessage, multiple, label, iconPrefix, enableTracking, allowedFileTypes, maxSize, isOptional, maxNumberOfFiles, }: FilePickerProps): JSX.Element;
17
+ export declare function FilePicker({ files, setFiles, isValid, errorMessage, multiple, label, name, iconPrefix, enableTracking, allowedFileTypes, maxSize, isOptional, maxNumberOfFiles, }: FilePickerProps): JSX.Element;
@@ -20,5 +20,4 @@ export interface DropzoneFileProps {
20
20
  errorMessage?: TranslationKey;
21
21
  onDelete: () => void;
22
22
  iconPrefix?: string;
23
- label?: string;
24
23
  }
@@ -1,12 +1,8 @@
1
1
  import type { EntityProblems } from '../../../core/models/errors/entity-problems';
2
2
  import type { FormModel } from '../../../core/models/form';
3
- import type { TranslationKey } from '../../../language/types';
3
+ import type { TrackNavigationProps } from '../../../utils/trackNavigation';
4
4
  export interface SummaryProps<Schema> {
5
- trackNavigation?: (props: {
6
- fromForm: TranslationKey;
7
- toForm: TranslationKey;
8
- component: string;
9
- }) => void;
5
+ trackNavigation?: (props: TrackNavigationProps) => void;
10
6
  data: Schema;
11
7
  forms: FormModel[];
12
8
  omittedKeys?: string[];
@@ -9,7 +9,7 @@ type ActionLevel = 'journey' | 'task' | 'page' | 'field';
9
9
  /**
10
10
  * The type of action associated with the event
11
11
  */
12
- type ActionType = 'start' | 'submit' | 'save' | 'add' | 'edit' | 'remove' | 'open' | 'close' | 'next' | 'back' | 'skip' | 'download' | 'upload' | 'sign' | 'navigate' | 'blur' | 'input' | 'focus' | 'change' | 'select' | 'alert';
12
+ export type ActionType = 'start' | 'submit' | 'save' | 'add' | 'edit' | 'remove' | 'open' | 'close' | 'next' | 'back' | 'skip' | 'download' | 'upload' | 'sign' | 'navigate' | 'blur' | 'input' | 'focus' | 'change' | 'select' | 'alert';
13
13
  /**
14
14
  * The base event properties that are sent with every event
15
15
  */
@@ -18,7 +18,6 @@ type BaseEventProperties = {
18
18
  subCategory: 'hosted onboarding';
19
19
  countryCode?: string;
20
20
  capabilities?: string[];
21
- legalEntityId?: string;
22
21
  entityType?: LegalEntityType;
23
22
  task?: TaskTypes;
24
23
  };
@@ -66,13 +65,19 @@ declare class UserEvents {
66
65
  */
67
66
  addEvent(eventName: EventName, properties: AdditionalEventProperties): void;
68
67
  /**
69
- * Starts a timer for an event to measure the time it takes for an event to occur. Time is ended when `addEvent` is executed with the same key
68
+ * Adds an event with context specific to page-related events
70
69
  */
71
- startEvent(eventName: EventName): void;
70
+ addPageEvent(eventName: EventName, properties: SetOptional<AdditionalEventProperties, 'actionLevel'>): void;
72
71
  /**
73
72
  * Adds an event with context specific to field-related events
74
73
  */
75
- addFieldEvent(eventName: EventName, properties: SetOptional<AdditionalEventProperties, 'actionLevel'>): void;
74
+ addFieldEvent(eventName: EventName, properties: SetOptional<AdditionalEventProperties, 'actionLevel'> & {
75
+ field?: string;
76
+ }): void;
77
+ /**
78
+ * Starts a timer for an event to measure the time it takes for an event to occur. Time is ended when `addEvent` is executed with the same key
79
+ */
80
+ startEvent(eventName: EventName): void;
76
81
  /**
77
82
  * Subscribes a callback to analytics events. It gets called every time
78
83
  * one of the above public methods get called, and the event data is passed back as an array.
@@ -1,8 +1,10 @@
1
- import type { BaseTrackingPayload } from '../core/analytics';
1
+ import type { ActionType, AdditionalEventProperties } from '../core/user-events';
2
2
  import type { TranslationKey } from '../language/types';
3
- export declare const trackNavigation: ({ fromForm, toForm, component, baseTrackingPayload, }: {
4
- fromForm: TranslationKey;
5
- toForm: TranslationKey;
6
- component: string;
7
- baseTrackingPayload?: BaseTrackingPayload;
8
- }) => void;
3
+ export interface TrackNavigationProps {
4
+ actionType: ActionType;
5
+ toForm?: TranslationKey;
6
+ label: string;
7
+ returnValue?: 'success' | 'validation error';
8
+ baseTrackingPayload?: Partial<AdditionalEventProperties>;
9
+ }
10
+ export declare const trackNavigation: ({ actionType, toForm, label, returnValue, baseTrackingPayload, }: TrackNavigationProps) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adyen/kyc-components",
3
- "version": "2.61.1",
3
+ "version": "2.62.0",
4
4
  "keywords": [
5
5
  "adyen",
6
6
  "adyen-kyc",