@zeniai/client-epic-state 5.1.4 → 5.1.5-betaJK1

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 (103) hide show
  1. package/lib/entity/company/companyPayload.d.ts +4 -0
  2. package/lib/entity/company/companyPayload.js +6 -0
  3. package/lib/entity/company/companyStateTypes.d.ts +7 -0
  4. package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +1 -0
  5. package/lib/entity/paymentAccount/paymentAccountSelector.js +9 -0
  6. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  7. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  8. package/lib/entity/task/taskPayload.d.ts +1 -0
  9. package/lib/entity/task/taskPayload.js +1 -0
  10. package/lib/entity/task/taskReducer.d.ts +5 -1
  11. package/lib/entity/task/taskReducer.js +8 -2
  12. package/lib/entity/task/taskState.d.ts +1 -0
  13. package/lib/entity/tenant/epic/deleteConnectionEpic.d.ts +1 -1
  14. package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.d.ts +21 -0
  15. package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.js +59 -0
  16. package/lib/entity/tenant/epic/saveAPIKeyConnectionEpic.d.ts +1 -1
  17. package/lib/entity/tenant/epic/saveConnectorCredentialsEpic.d.ts +3 -3
  18. package/lib/entity/tenant/epic/saveOAuthConnectionEpic.d.ts +1 -1
  19. package/lib/entity/tenant/tenantPayload.d.ts +1 -0
  20. package/lib/entity/tenant/tenantReducer.d.ts +38 -25
  21. package/lib/entity/tenant/tenantReducer.js +65 -5
  22. package/lib/entity/tenant/tenantState.d.ts +1 -0
  23. package/lib/epic.d.ts +8 -1
  24. package/lib/epic.js +9 -1
  25. package/lib/esm/entity/company/companyPayload.js +6 -0
  26. package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +8 -0
  27. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  28. package/lib/esm/entity/task/taskPayload.js +1 -0
  29. package/lib/esm/entity/task/taskReducer.js +7 -1
  30. package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +55 -0
  31. package/lib/esm/entity/tenant/tenantReducer.js +63 -3
  32. package/lib/esm/epic.js +9 -1
  33. package/lib/esm/index.js +13 -9
  34. package/lib/esm/view/fileView/epic/deleteFileEpic.js +2 -2
  35. package/lib/esm/view/fileView/epic/deleteFileListEpic.js +2 -2
  36. package/lib/esm/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +40 -0
  37. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +29 -0
  38. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +40 -0
  39. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +24 -18
  40. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +29 -17
  41. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +223 -51
  42. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewSelector.js +24 -12
  43. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewState.js +37 -6
  44. package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +58 -0
  45. package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +77 -0
  46. package/lib/esm/view/spendManagement/commonSetup/kycKybAutofillActions.js +14 -0
  47. package/lib/esm/view/spendManagement/commonSetup/kycKybParseMapper.js +207 -0
  48. package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +106 -52
  49. package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +6 -1
  50. package/lib/esm/view/spendManagement/commonSetup/types/kycKybAutofill.js +41 -0
  51. package/lib/esm/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +80 -0
  52. package/lib/esm/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +36 -0
  53. package/lib/esm/view/taskManager/taskDetailView/epics/fetchTaskDetailEpic.js +13 -0
  54. package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +56 -2
  55. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +19 -8
  56. package/lib/index.d.ts +17 -13
  57. package/lib/index.js +67 -35
  58. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  59. package/lib/view/fileView/epic/deleteFileEpic.js +1 -1
  60. package/lib/view/fileView/epic/deleteFileListEpic.js +1 -1
  61. package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.d.ts +7 -0
  62. package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +44 -0
  63. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.d.ts +8 -0
  64. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +33 -0
  65. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.d.ts +9 -0
  66. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +44 -0
  67. package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +24 -18
  68. package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.d.ts +2 -2
  69. package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +27 -15
  70. package/lib/view/onboardingView/customerView/onboardingCustomerViewPayload.d.ts +3 -0
  71. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +44 -5
  72. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +225 -52
  73. package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.d.ts +6 -1
  74. package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.js +27 -12
  75. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +52 -8
  76. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.js +39 -7
  77. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +28 -0
  78. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +62 -0
  79. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.d.ts +9 -0
  80. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +81 -0
  81. package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.d.ts +24 -0
  82. package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.js +17 -0
  83. package/lib/view/spendManagement/commonSetup/kycKybParseMapper.d.ts +29 -0
  84. package/lib/view/spendManagement/commonSetup/kycKybParseMapper.js +215 -0
  85. package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +28 -2
  86. package/lib/view/spendManagement/commonSetup/setupViewReducer.js +107 -53
  87. package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +7 -2
  88. package/lib/view/spendManagement/commonSetup/setupViewSelector.js +6 -1
  89. package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +19 -0
  90. package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.d.ts +154 -0
  91. package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.js +46 -0
  92. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.d.ts +9 -0
  93. package/lib/view/taskManager/taskDetailView/epics/createSubTaskEpic.js +84 -0
  94. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.d.ts +8 -0
  95. package/lib/view/taskManager/taskDetailView/epics/fetchSubTasksEpic.js +40 -0
  96. package/lib/view/taskManager/taskDetailView/epics/fetchTaskDetailEpic.d.ts +2 -1
  97. package/lib/view/taskManager/taskDetailView/epics/fetchTaskDetailEpic.js +13 -0
  98. package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +13 -0
  99. package/lib/view/taskManager/taskDetailView/taskDetailReducer.d.ts +14 -2
  100. package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +57 -3
  101. package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +2 -1
  102. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +17 -6
  103. package/package.json +1 -1
@@ -18,7 +18,7 @@ import { getOnboardingCustomerView } from '../../onboardingCustomerViewSelector'
18
18
  export const updateOnboardingCustomerViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(updateOnboardingCustomerView.match), mergeMap((action) => {
19
19
  const { companyId, officerType, sendForVerification, reCalculateCurrentStep = false, isBillingAddressUpdate, } = action.payload;
20
20
  const { onboardingCustomerViewState } = state$.value;
21
- const { companyDetails, primaryContactDetails, companyOfficerUpdateStatus, currentStep, } = onboardingCustomerViewState;
21
+ const { companyDetails, primaryContactDetails, companyOfficerUpdateStatus, currentStep, currentSubStep, } = onboardingCustomerViewState;
22
22
  const companyLocalData = companyDetails.localData;
23
23
  const primaryContactLocalData = primaryContactDetails.localData;
24
24
  let companyOfficerLocalData;
@@ -52,8 +52,12 @@ export const updateOnboardingCustomerViewEpic = (actions$, state$, zeniAPI) => a
52
52
  Boolean(companyOfficerLocalData.email) === true // Don't save Empty Company Officer details
53
53
  ? toBusinessVerificationOfficerDataPayload(companyOfficerLocalData, false, companyOfficerAddressToCreate)
54
54
  : {};
55
+ // Verification step has two sub-steps that share currentStep but save
56
+ // different payloads — currentSubStep is the source of truth here.
57
+ const isOfficerSave = currentStep === 'verification' &&
58
+ currentSubStep === 'company_officer';
55
59
  if (isBillingAddressUpdate === false) {
56
- if (currentStep === 'company_officer') {
60
+ if (isOfficerSave) {
57
61
  payload = {
58
62
  company: toBusinessVerificationMinimalCompanyDataPayload(companyLocalData),
59
63
  company_officer,
@@ -66,6 +70,11 @@ export const updateOnboardingCustomerViewEpic = (actions$, state$, zeniAPI) => a
66
70
  };
67
71
  }
68
72
  }
73
+ const section = isBillingAddressUpdate === true
74
+ ? 'setup_billing'
75
+ : isOfficerSave
76
+ ? 'company_officer'
77
+ : 'company_details';
69
78
  const messageSectionMapper = {
70
79
  company_officer: {
71
80
  sendForVerification: 'onboarding_customer_identity_verification_submit',
@@ -75,23 +84,20 @@ export const updateOnboardingCustomerViewEpic = (actions$, state$, zeniAPI) => a
75
84
  sendForVerification: 'onboarding_customer_business_verification_submit',
76
85
  save: 'onboarding_customer_business_verification_save',
77
86
  },
78
- link_payment_account: {
87
+ setup_billing: {
79
88
  save: 'billing_address_view',
80
89
  sendForVerification: 'billing_address_view',
81
90
  },
82
91
  };
83
92
  let messageSection;
84
93
  if (isBillingAddressUpdate === true) {
85
- messageSection = messageSectionMapper[currentStep].save;
94
+ messageSection = messageSectionMapper[section].save;
95
+ }
96
+ else if (sendForVerification === true) {
97
+ messageSection = messageSectionMapper[section].sendForVerification;
86
98
  }
87
99
  else {
88
- if (sendForVerification === true) {
89
- messageSection =
90
- messageSectionMapper[currentStep].sendForVerification;
91
- }
92
- else {
93
- messageSection = messageSectionMapper[currentStep].save;
94
- }
100
+ messageSection = messageSectionMapper[section].save;
95
101
  }
96
102
  return zeniAPI
97
103
  .putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, payload)
@@ -114,18 +120,18 @@ export const updateOnboardingCustomerViewEpic = (actions$, state$, zeniAPI) => a
114
120
  const externalConnections = currentTenant.externalConnections;
115
121
  const isQBOConnection = externalConnections?.accounting?.some((connection) => connection.connectionName.match(/quickbooks/i)) ?? false;
116
122
  const { allSteps } = getOnboardingCustomerView(state$.value, companyId);
117
- if (currentStep === 'link_payment_account') {
123
+ if (currentStep === 'setup_billing') {
118
124
  if (isQBOConnection === true &&
119
- allSteps.includes('qbo_connection')) {
120
- actions.push(updateCurrentStep({ step: 'qbo_connection' }));
125
+ allSteps.includes('connect_ledger')) {
126
+ actions.push(updateCurrentStep({ step: 'connect_ledger' }));
121
127
  }
122
128
  else {
123
- actions.push(updateCurrentStep({ step: 'company_officer' }));
129
+ actions.push(updateCurrentStep({ step: 'verification' }));
124
130
  }
125
131
  }
126
- if (currentStep === 'company_officer') {
127
- actions.push(updateCurrentStep({ step: 'company_details' }));
128
- }
132
+ // The officer→details transition is now a sub-step change
133
+ // handled by the page (currentSubStep dispatch). No
134
+ // currentStep update needed for that traversal anymore.
129
135
  actions.push(updateOnboardingCustomerViewLocalStoreData({
130
136
  companyId: response.data.companies[0].company_id,
131
137
  currentStep,
@@ -12,11 +12,11 @@ import { newAddressInLocalStore, resetNewAddressesInLocalStore, } from '../../..
12
12
  import { toAddressViewLocalData } from '../../../../addressView/toAddressViewLocalData';
13
13
  import { getCompanyView } from '../../../../companyView/selectorHelpers/getCompanyView';
14
14
  import { toSetupViewLocalData } from '../../../../spendManagement/commonSetup/epic/setup/updateSetupViewLocalStoreDataEpic';
15
- import { clearOnboardingCustomerViewDataInLocalStore, saveOnboardingCustomerViewDataInLocalStore, updateCurrentStep, updateOnboardingCustomerViewLocalStoreData, } from '../../onboardingCustomerViewReducer';
16
- import { isOfficerDetailsCompleted, onboardingStepsData, } from '../../onboardingCustomerViewSelector';
15
+ import { clearOnboardingCustomerViewDataInLocalStore, saveOnboardingCustomerViewDataInLocalStore, updateCurrentStep, updateCurrentSubStep, updateOnboardingCustomerViewLocalStoreData, } from '../../onboardingCustomerViewReducer';
16
+ import { onboardingStepsData } from '../../onboardingCustomerViewSelector';
17
17
  export const updateOnboardingCustomerViewLocalStoreDataEpic = (actions$, state$) => actions$.pipe(filter(updateOnboardingCustomerViewLocalStoreData.match), mergeMap((action) => {
18
18
  const { companyId, currentStep, reCalculateCurrentStep } = action.payload;
19
- const { companyState, companyViewState, fileState, userState, userRoleState, onboardingCustomerViewState, subscriptionPaymentAccountState, paymentAccountState, addressState, } = state$.value;
19
+ const { companyState, companyViewState, userState, userRoleState, onboardingCustomerViewState, subscriptionPaymentAccountState, paymentAccountState, addressState, } = state$.value;
20
20
  const { subscriptionPaymentAccountIds } = onboardingCustomerViewState;
21
21
  const subscriptionIDs = recordGet(companyViewState.passportView.subscriptionIDsByCompanyID, companyId, undefined);
22
22
  const companyView = getCompanyView(state$.value, companyId, subscriptionIDs ?? []);
@@ -36,7 +36,12 @@ export const updateOnboardingCustomerViewLocalStoreDataEpic = (actions$, state$)
36
36
  const onboardingCustomerViewLocalData = toOnboardingCustomerViewLocalData(company, companyOfficers, companyOfficerRoles, primaryContact);
37
37
  const { companyDetails, officers, primaryContactDetails } = onboardingCustomerViewLocalData;
38
38
  let updatedCompanyDetails = companyDetails;
39
- if (currentStep === 'company_officer' &&
39
+ // After an officer sub-step save inside the verification step, propagate
40
+ // the latest syncToken into the cached company-details local data so the
41
+ // user's next details-save doesn't 409.
42
+ const isOfficerSave = currentStep === 'verification' &&
43
+ onboardingCustomerViewState.currentSubStep === 'company_officer';
44
+ if (isOfficerSave &&
40
45
  onboardingCustomerViewState.companyDetails.localData != null) {
41
46
  const { companyInfo } = company;
42
47
  const { syncToken } = companyInfo;
@@ -45,7 +50,7 @@ export const updateOnboardingCustomerViewLocalStoreDataEpic = (actions$, state$)
45
50
  syncToken,
46
51
  };
47
52
  }
48
- let updatedCurrentStep = 'link_payment_account';
53
+ let updatedCurrentStep = 'setup_billing';
49
54
  let subscriptionPaymentAccount;
50
55
  const { companyOnboardingInfo } = company;
51
56
  const accountingConnectionCreationMode = companyOnboardingInfo?.onboardingInfo
@@ -72,18 +77,17 @@ export const updateOnboardingCustomerViewLocalStoreDataEpic = (actions$, state$)
72
77
  cardPaymentViewState.cardPaymentsIds.length > 0) &&
73
78
  companyView?.company.company.companyOnboardingInfo
74
79
  .subscriptionBillingAddressId != null) {
75
- updatedCurrentStep = 'qbo_connection';
76
- if (isValidConnection) {
77
- updatedCurrentStep = 'company_officer';
78
- let officerIndex = companyOfficers.length > 0
79
- ? officers.findIndex((officer) => officer?.isSelectedForVerification === true)
80
- : 0;
81
- if (officerIndex === -1) {
82
- officerIndex = 0;
83
- }
84
- if (isOfficerDetailsCompleted(companyOfficers, companyOfficerRoles, officers[officerIndex], fileState)) {
85
- updatedCurrentStep = 'company_details';
86
- }
80
+ updatedCurrentStep = 'connect_ledger';
81
+ const isOnboardingAiActivationViewed = companyOnboardingInfo?.onboardingInfo
82
+ ?.onboardingAiActivationInfo?.isOnboardingAiActivationViewed ??
83
+ false;
84
+ // Past the ledger step we always sit on connect_data_source —
85
+ // it has many integrations, so we treat it as never auto-complete
86
+ // and only advance to verification on an explicit user dispatch.
87
+ // While the AI activation interstitial hasn't been viewed yet,
88
+ // stay on connect_ledger so the interstitial gets its chance.
89
+ if (isValidConnection && isOnboardingAiActivationViewed) {
90
+ updatedCurrentStep = 'connect_data_source';
87
91
  }
88
92
  }
89
93
  }
@@ -105,6 +109,14 @@ export const updateOnboardingCustomerViewLocalStoreDataEpic = (actions$, state$)
105
109
  }
106
110
  if (reCalculateCurrentStep === true) {
107
111
  fetchActions.push(updateCurrentStep({ step: updatedCurrentStep }));
112
+ // Whenever the recalc lands the user on a different step, reset
113
+ // the sub-step to the step's landing sub-state — otherwise a
114
+ // stale subStep (e.g. 'default' carried over from another step)
115
+ // leaves verification rendering an empty form.
116
+ if (updatedCurrentStep !== onboardingCustomerViewState.currentStep) {
117
+ const targetSubStep = updatedCurrentStep === 'verification' ? 'unlock-stack' : 'default';
118
+ fetchActions.push(updateCurrentSubStep({ subStep: targetSubStep }));
119
+ }
108
120
  }
109
121
  }
110
122
  if (companyView != null) {
@@ -1,5 +1,7 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import { date } from '../../../zeniDayJS';
3
+ import { parseUploadedKybDocument, parseUploadedKybDocumentFailure, parseUploadedKycDocument, parseUploadedKycDocumentFailure, } from '../../spendManagement/commonSetup/kycKybAutofillActions';
4
+ import { emptyAiAgentsActivationSubview, } from './onboardingCustomerViewState';
3
5
  const initialStatus = {
4
6
  fetchState: 'Not-Started',
5
7
  error: undefined,
@@ -8,62 +10,33 @@ export const initialState = {
8
10
  updateStatus: initialStatus,
9
11
  saveStatus: initialStatus,
10
12
  dashboardLoadedStatus: initialStatus,
11
- currentStep: 'link_payment_account',
13
+ currentStep: 'setup_billing',
14
+ currentSubStep: 'default',
15
+ parsingDocumentFileIds: [],
12
16
  companyDetails: {
17
+ autoFilledFields: [],
13
18
  localData: undefined,
14
19
  },
15
- companyOfficerUpdateStatus: {
16
- Officer_1: {
20
+ companyOfficerUpdateStatus: (() => {
21
+ const emptyOfficerSlot = {
22
+ autoFilledFields: [],
17
23
  localData: undefined,
18
24
  sendOtpStatus: initialStatus,
19
25
  otpverificationStatus: initialStatus,
20
- },
21
- Officer_2: {
22
- localData: undefined,
23
- sendOtpStatus: initialStatus,
24
- otpverificationStatus: initialStatus,
25
- },
26
- Officer_3: {
27
- localData: undefined,
28
- sendOtpStatus: initialStatus,
29
- otpverificationStatus: initialStatus,
30
- },
31
- Officer_4: {
32
- localData: undefined,
33
- sendOtpStatus: initialStatus,
34
- otpverificationStatus: initialStatus,
35
- },
36
- Officer_5: {
37
- localData: undefined,
38
- sendOtpStatus: initialStatus,
39
- otpverificationStatus: initialStatus,
40
- },
41
- Officer_6: {
42
- localData: undefined,
43
- sendOtpStatus: initialStatus,
44
- otpverificationStatus: initialStatus,
45
- },
46
- Officer_7: {
47
- localData: undefined,
48
- sendOtpStatus: initialStatus,
49
- otpverificationStatus: initialStatus,
50
- },
51
- Officer_8: {
52
- localData: undefined,
53
- sendOtpStatus: initialStatus,
54
- otpverificationStatus: initialStatus,
55
- },
56
- Officer_9: {
57
- localData: undefined,
58
- sendOtpStatus: initialStatus,
59
- otpverificationStatus: initialStatus,
60
- },
61
- Officer_10: {
62
- localData: undefined,
63
- sendOtpStatus: initialStatus,
64
- otpverificationStatus: initialStatus,
65
- },
66
- },
26
+ };
27
+ return {
28
+ Officer_1: { ...emptyOfficerSlot },
29
+ Officer_2: { ...emptyOfficerSlot },
30
+ Officer_3: { ...emptyOfficerSlot },
31
+ Officer_4: { ...emptyOfficerSlot },
32
+ Officer_5: { ...emptyOfficerSlot },
33
+ Officer_6: { ...emptyOfficerSlot },
34
+ Officer_7: { ...emptyOfficerSlot },
35
+ Officer_8: { ...emptyOfficerSlot },
36
+ Officer_9: { ...emptyOfficerSlot },
37
+ Officer_10: { ...emptyOfficerSlot },
38
+ };
39
+ })(),
67
40
  primaryContactDetails: {},
68
41
  paymentAccountDetails: {
69
42
  fetchStatus: initialStatus,
@@ -91,6 +64,7 @@ export const initialState = {
91
64
  },
92
65
  fetchState: 'Not-Started',
93
66
  error: undefined,
67
+ aiAgentsActivation: { ...emptyAiAgentsActivationSubview },
94
68
  uiState: {
95
69
  isQBOPopupOpen: false,
96
70
  isCardPaymentPopupOpen: false,
@@ -143,6 +117,9 @@ const onboardingCustomerView = createSlice({
143
117
  updateCurrentStep(draft, action) {
144
118
  draft.currentStep = action.payload.step;
145
119
  },
120
+ updateCurrentSubStep(draft, action) {
121
+ draft.currentSubStep = action.payload.subStep;
122
+ },
146
123
  updateOnboardingCustomerViewAccountDetails: {
147
124
  prepare(paymentAccountIds, subscriptionPaymentAccountIds) {
148
125
  return { payload: { paymentAccountIds, subscriptionPaymentAccountIds } };
@@ -180,6 +157,126 @@ const onboardingCustomerView = createSlice({
180
157
  };
181
158
  },
182
159
  },
160
+ acknowledgeOnboardingAiFinanceTeam: {
161
+ reducer(draft) {
162
+ draft.aiFinanceTeamAcknowledgementStatus = {
163
+ fetchState: 'In-Progress',
164
+ error: undefined,
165
+ };
166
+ },
167
+ prepare(companyId) {
168
+ return {
169
+ payload: { companyId },
170
+ };
171
+ },
172
+ },
173
+ acknowledgeOnboardingAiFinanceTeamSuccess(draft) {
174
+ draft.aiFinanceTeamAcknowledgementStatus = {
175
+ fetchState: 'Completed',
176
+ error: undefined,
177
+ };
178
+ },
179
+ acknowledgeOnboardingAiFinanceTeamFailure: {
180
+ reducer(draft, action) {
181
+ draft.aiFinanceTeamAcknowledgementStatus = {
182
+ fetchState: 'Error',
183
+ error: action.payload,
184
+ };
185
+ },
186
+ prepare(error) {
187
+ return {
188
+ payload: error,
189
+ };
190
+ },
191
+ },
192
+ acknowledgeOnboardingAiActivationViewed: {
193
+ reducer(draft) {
194
+ draft.aiActivationViewedAcknowledgementStatus = {
195
+ fetchState: 'In-Progress',
196
+ error: undefined,
197
+ };
198
+ },
199
+ prepare(companyId) {
200
+ return {
201
+ payload: { companyId },
202
+ };
203
+ },
204
+ },
205
+ acknowledgeOnboardingAiActivationViewedSuccess(draft) {
206
+ draft.aiActivationViewedAcknowledgementStatus = {
207
+ fetchState: 'Completed',
208
+ error: undefined,
209
+ };
210
+ },
211
+ acknowledgeOnboardingAiActivationViewedFailure: {
212
+ reducer(draft, action) {
213
+ draft.aiActivationViewedAcknowledgementStatus = {
214
+ fetchState: 'Error',
215
+ error: action.payload,
216
+ };
217
+ },
218
+ prepare(error) {
219
+ return {
220
+ payload: error,
221
+ };
222
+ },
223
+ },
224
+ fetchAiAgentsActivationStatus(draft) {
225
+ draft.aiAgentsActivation.fetchStatus = {
226
+ fetchState: 'In-Progress',
227
+ error: undefined,
228
+ };
229
+ },
230
+ fetchAiAgentsActivationStatusSuccess: {
231
+ reducer(draft, action) {
232
+ draft.aiAgentsActivation.fetchStatus = {
233
+ fetchState: 'Completed',
234
+ error: undefined,
235
+ };
236
+ draft.aiAgentsActivation.phases = action.payload.phases;
237
+ draft.aiAgentsActivation.counts = action.payload.counts;
238
+ },
239
+ prepare(payload) {
240
+ return { payload };
241
+ },
242
+ },
243
+ fetchAiAgentsActivationStatusFailure: {
244
+ reducer(draft, action) {
245
+ draft.aiAgentsActivation.fetchStatus = {
246
+ fetchState: 'Error',
247
+ error: action.payload,
248
+ };
249
+ },
250
+ prepare(error) {
251
+ return { payload: error };
252
+ },
253
+ },
254
+ aiAgentsActivationCountsUpdated: {
255
+ reducer(draft, action) {
256
+ draft.aiAgentsActivation.counts = {
257
+ ...draft.aiAgentsActivation.counts,
258
+ ...action.payload,
259
+ };
260
+ },
261
+ prepare(payload) {
262
+ return { payload };
263
+ },
264
+ },
265
+ aiAgentsActivationPhaseChanged: {
266
+ reducer(draft, action) {
267
+ const target = draft.aiAgentsActivation.phases;
268
+ const index = target.findIndex((phase) => phase.key === action.payload.key);
269
+ if (index === -1) {
270
+ target.push(action.payload);
271
+ }
272
+ else {
273
+ target[index] = { ...target[index], ...action.payload };
274
+ }
275
+ },
276
+ prepare(payload) {
277
+ return { payload };
278
+ },
279
+ },
183
280
  updateOnboardingCustomerViewDashboardLoaded: {
184
281
  reducer(draft) {
185
282
  draft.dashboardLoadedStatus = {
@@ -592,7 +689,82 @@ const onboardingCustomerView = createSlice({
592
689
  clearOnboardingCustomerView(draft) {
593
690
  Object.assign(draft, initialState);
594
691
  },
692
+ /** Merge AI-parsed officer fields into the officer's onboarding localData. */
693
+ applyKycDocumentAutofillForOnboarding: {
694
+ reducer(draft, action) {
695
+ const { officerType, values, autoFilledFieldNames, fileId } = action.payload;
696
+ const slot = draft.companyOfficerUpdateStatus[officerType];
697
+ slot.localData = Object.assign({}, slot.localData, values);
698
+ slot.autoFilledFields = Array.from(new Set([...(slot.autoFilledFields ?? []), ...autoFilledFieldNames]));
699
+ draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
700
+ },
701
+ prepare(payload) {
702
+ return { payload };
703
+ },
704
+ },
705
+ /** Merge AI-parsed company fields into companyDetails onboarding localData. */
706
+ applyKybDocumentAutofillForOnboarding: {
707
+ reducer(draft, action) {
708
+ const { values, autoFilledFieldNames, fileId } = action.payload;
709
+ draft.companyDetails.localData = Object.assign({}, draft.companyDetails.localData, values);
710
+ const prev = draft.companyDetails.autoFilledFields ?? [];
711
+ draft.companyDetails.autoFilledFields = Array.from(new Set([...prev, ...autoFilledFieldNames]));
712
+ draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
713
+ },
714
+ prepare(payload) {
715
+ return { payload };
716
+ },
717
+ },
718
+ /** Wipe AI-autofill badges during onboarding. */
719
+ clearKycKybAutofillForOnboarding: {
720
+ reducer(draft, action) {
721
+ const { officerType } = action.payload;
722
+ if (officerType != null) {
723
+ draft.companyOfficerUpdateStatus[officerType].autoFilledFields = [];
724
+ }
725
+ else {
726
+ draft.companyDetails.autoFilledFields = [];
727
+ Object.keys(draft.companyOfficerUpdateStatus).forEach((key) => {
728
+ draft.companyOfficerUpdateStatus[key].autoFilledFields = [];
729
+ });
730
+ }
731
+ },
732
+ prepare(payload = {}) {
733
+ return { payload };
734
+ },
735
+ },
736
+ },
737
+ extraReducers: (builder) => {
738
+ const addParsingFileId = (draft, fileId) => {
739
+ draft.parsingDocumentFileIds = draft.parsingDocumentFileIds ?? [];
740
+ if (!draft.parsingDocumentFileIds.includes(fileId)) {
741
+ draft.parsingDocumentFileIds.push(fileId);
742
+ }
743
+ };
744
+ const removeParsingFileId = (draft, fileId) => {
745
+ draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
746
+ };
747
+ builder.addCase(parseUploadedKycDocument, (draft, action) => {
748
+ if (action.payload.target === 'onboarding') {
749
+ addParsingFileId(draft, action.payload.fileId);
750
+ }
751
+ });
752
+ builder.addCase(parseUploadedKybDocument, (draft, action) => {
753
+ if (action.payload.target === 'onboarding') {
754
+ addParsingFileId(draft, action.payload.fileId);
755
+ }
756
+ });
757
+ builder.addCase(parseUploadedKycDocumentFailure, (draft, action) => {
758
+ if (action.payload.target === 'onboarding') {
759
+ removeParsingFileId(draft, action.payload.fileId);
760
+ }
761
+ });
762
+ builder.addCase(parseUploadedKybDocumentFailure, (draft, action) => {
763
+ if (action.payload.target === 'onboarding') {
764
+ removeParsingFileId(draft, action.payload.fileId);
765
+ }
766
+ });
595
767
  },
596
768
  });
597
- export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, updateOnboardingCustomerViewDashboardLoaded, updateOnboardingCustomerViewDashboardLoadedSuccess, updateOnboardingCustomerViewDashboardLoadedFailure, updateOnboardingCustomerView, updateOnboardingCustomerViewSuccess, updateOnboardingCustomerViewFailure, updateOnboardingPaymentAccountStatus, updateOnboardingPaymentAccountStatusSuccess, updateOnboardingPaymentAccountStatusFailure, updateOnboardingPaymentAccountLoginStatus, updateOnboardingPaymentAccountLoginStatusSuccess, updateOnboardingPaymentAccountLoginStatusFailure, establishOnboardingPlaidConnection, establishOnboardingPlaidConnectionSuccess, establishOnboardingPlaidConnectionFailure, getOnboardingPlaidLinkToken, getOnboardingPlaidLinkTokenSuccess, getOnboardingPlaidLinkTokenFailure, updateCurrentStep, updateOnboardingCustomerViewAccountDetails, updateOnboardingCustomerViewLocalStoreData, saveOnboardingCustomerViewDataInLocalStore, saveOnboardingCompnayOfficerPhoneInLocalStore, updateOnboardingCustomerViewUIState, sendOnboardingOfficerOtp, sendOnboardingOfficerOtpSuccess, sendOnboardingOfficerOtpFailure, resendOnboardingOfficerOtp, verifyOnboardingOfficerOtp, verifyOnboardingOfficerOtpSuccess, verifyOnboardingOfficerOtpFailure, clearOnboardingCustomerViewDataInLocalStore, clearOnboardingCustomerView, } = onboardingCustomerView.actions;
769
+ export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, acknowledgeOnboardingAiFinanceTeam, acknowledgeOnboardingAiFinanceTeamSuccess, acknowledgeOnboardingAiFinanceTeamFailure, acknowledgeOnboardingAiActivationViewed, acknowledgeOnboardingAiActivationViewedSuccess, acknowledgeOnboardingAiActivationViewedFailure, fetchAiAgentsActivationStatus, fetchAiAgentsActivationStatusSuccess, fetchAiAgentsActivationStatusFailure, aiAgentsActivationCountsUpdated, aiAgentsActivationPhaseChanged, updateOnboardingCustomerViewDashboardLoaded, updateOnboardingCustomerViewDashboardLoadedSuccess, updateOnboardingCustomerViewDashboardLoadedFailure, updateOnboardingCustomerView, updateOnboardingCustomerViewSuccess, updateOnboardingCustomerViewFailure, updateOnboardingPaymentAccountStatus, updateOnboardingPaymentAccountStatusSuccess, updateOnboardingPaymentAccountStatusFailure, updateOnboardingPaymentAccountLoginStatus, updateOnboardingPaymentAccountLoginStatusSuccess, updateOnboardingPaymentAccountLoginStatusFailure, establishOnboardingPlaidConnection, establishOnboardingPlaidConnectionSuccess, establishOnboardingPlaidConnectionFailure, getOnboardingPlaidLinkToken, getOnboardingPlaidLinkTokenSuccess, getOnboardingPlaidLinkTokenFailure, updateCurrentStep, updateCurrentSubStep, updateOnboardingCustomerViewAccountDetails, updateOnboardingCustomerViewLocalStoreData, saveOnboardingCustomerViewDataInLocalStore, saveOnboardingCompnayOfficerPhoneInLocalStore, updateOnboardingCustomerViewUIState, sendOnboardingOfficerOtp, sendOnboardingOfficerOtpSuccess, sendOnboardingOfficerOtpFailure, resendOnboardingOfficerOtp, verifyOnboardingOfficerOtp, verifyOnboardingOfficerOtpSuccess, verifyOnboardingOfficerOtpFailure, clearOnboardingCustomerViewDataInLocalStore, clearOnboardingCustomerView, applyKycDocumentAutofillForOnboarding, applyKybDocumentAutofillForOnboarding, clearKycKybAutofillForOnboarding, } = onboardingCustomerView.actions;
598
770
  export default onboardingCustomerView.reducer;
@@ -8,10 +8,10 @@ import { getUserRoleByUserIds } from '../../../entity/userRole/userRoleSelector'
8
8
  import { getCompanyConfig } from '../../companyConfigView/companyConfigSelector';
9
9
  import { getCompanyView } from '../../companyView/selectorHelpers/getCompanyView';
10
10
  import { getCompanyAndIdentityDetails, } from '../../spendManagement/commonSetup/setupViewSelector';
11
- import { ALL_ONBOARDING_STEPS, ALL_ZENI_USER_ONBOARDING_STEPS, REQUIRED_ONBOARDING_STEPS, ZENI_USER_REQUIRED_ONBOARDING_STEPS, toOnboardingStepType, } from './onboardingCustomerViewState';
11
+ import { ALL_ONBOARDING_STEPS, ALL_ZENI_USER_ONBOARDING_STEPS, REQUIRED_ONBOARDING_STEPS, ZENI_USER_REQUIRED_ONBOARDING_STEPS, emptyAiAgentsActivationSubview, toOnboardingStepType, } from './onboardingCustomerViewState';
12
12
  export function getOnboardingCustomerView(state, companyId) {
13
13
  const { fileState, paymentAccountState, onboardingCustomerViewState, userState, userRoleState, subscriptionPaymentAccountState, companyConfigState, cardPaymentViewState, countryListState, addressViewState, } = state;
14
- const { companyDetails, companyOfficerUpdateStatus, primaryContactDetails, subscriptionPaymentAccountIds, paymentAccountDetails, plaidConnectionDetails, updateStatus, saveStatus, currentStep, uiState, fetchState, error, } = onboardingCustomerViewState;
14
+ const { companyDetails, companyOfficerUpdateStatus, primaryContactDetails, subscriptionPaymentAccountIds, paymentAccountDetails, plaidConnectionDetails, parsingDocumentFileIds, updateStatus, saveStatus, currentStep, currentSubStep, uiState, fetchState, error, } = onboardingCustomerViewState;
15
15
  const { paymentAccountIds } = paymentAccountDetails;
16
16
  let subscriptionPaymentAccount;
17
17
  let paymentAccount;
@@ -54,6 +54,7 @@ export function getOnboardingCustomerView(state, companyId) {
54
54
  companyDetails,
55
55
  companyOfficerUpdateStatus,
56
56
  primaryContactDetails,
57
+ parsingDocumentFileIds,
57
58
  });
58
59
  const companyAddress = addressViewState.newAddressState?.company_address;
59
60
  if (companyAddress == null &&
@@ -73,7 +74,7 @@ export function getOnboardingCustomerView(state, companyId) {
73
74
  cardPaymentViewState.cardPaymentsIds.length > 0) &&
74
75
  companyView?.company.company.companyOnboardingInfo
75
76
  .subscriptionBillingAddressId != null) {
76
- completedSteps.push('link_payment_account');
77
+ completedSteps.push('setup_billing');
77
78
  }
78
79
  const isPaymentVerified = (paymentAccount?.providerVerificationStatus?.code?.includes('verified') ===
79
80
  true &&
@@ -84,24 +85,25 @@ export function getOnboardingCustomerView(state, companyId) {
84
85
  .subscriptionBillingAddressId != null;
85
86
  if ((isPaymentVerified || hasSubscriptionBillingAddress) &&
86
87
  !(isPaymentVerified && hasSubscriptionBillingAddress)) {
87
- halfCompletedSteps.push('link_payment_account');
88
+ halfCompletedSteps.push('setup_billing');
88
89
  }
89
90
  const isValidConnection = externalConnections?.accounting[0]?.isValid ?? false;
90
91
  if (isValidConnection) {
91
- completedSteps.push('qbo_connection');
92
+ completedSteps.push('connect_ledger');
92
93
  }
93
- if (companyDetails.localData != null &&
94
+ const isCompanyDetailsDone = companyDetails.localData != null &&
94
95
  primaryContactDetails.localData != null &&
95
- isCompanyDetailsCompleted(fileState, companyView, primaryContact)) {
96
- completedSteps.push('company_details');
97
- }
96
+ isCompanyDetailsCompleted(fileState, companyView, primaryContact);
98
97
  const officerIndex = companyOfficers.length > 0
99
98
  ? Object.values(companyOfficerLocalData).findIndex((officer) => officer?.isSelectedForVerification === true)
100
99
  : 0;
101
100
  const selectedOfficerType = `Officer_${officerIndex < 0 ? 1 : officerIndex + 1}`;
102
- if (companyOfficerLocalData[selectedOfficerType] != null &&
103
- isOfficerDetailsCompleted(companyOfficers, companyOfficerRoles, companyOfficerLocalData[selectedOfficerType], fileState)) {
104
- completedSteps.push('company_officer');
101
+ const isOfficerDone = companyOfficerLocalData[selectedOfficerType] != null &&
102
+ isOfficerDetailsCompleted(companyOfficers, companyOfficerRoles, companyOfficerLocalData[selectedOfficerType], fileState);
103
+ // The verification step (single sidebar step) is only "complete" once both
104
+ // the company-officer and company-details sub-steps are fully filled in.
105
+ if (isCompanyDetailsDone && isOfficerDone) {
106
+ completedSteps.push('verification');
105
107
  }
106
108
  const { allStepsData, requiredStepsData } = onboardingStepsData(isValidConnection, currentTenant?.productSettings ?? [], accountingConnectionCreationMode);
107
109
  const allRequiredStepsCompleted = requiredStepsData.every((step) => {
@@ -119,6 +121,7 @@ export function getOnboardingCustomerView(state, companyId) {
119
121
  return {
120
122
  companyDetailsLocalData,
121
123
  companyOfficerLocalData,
124
+ parsingDocumentFileIds,
122
125
  subscriptionBillingAddress: subscriptionBillingAddress?.addressToCreate,
123
126
  companyView,
124
127
  allNationalityCountries,
@@ -127,6 +130,7 @@ export function getOnboardingCustomerView(state, companyId) {
127
130
  officer: isOfficerDetailsSavePending(companyOfficers, companyOfficerRoles, fileState, companyOfficerLocalData[selectedOfficerType]),
128
131
  },
129
132
  currentStep,
133
+ currentSubStep,
130
134
  completedSteps,
131
135
  halfCompletedSteps,
132
136
  allRequiredStepsCompleted,
@@ -323,3 +327,11 @@ export const getProductSettingsString = (productSettings) => {
323
327
  .map((key) => productKeyMap[key])
324
328
  .join(',');
325
329
  };
330
+ const fromActivationView = (state) =>
331
+ // Fall back to the empty subview so state hydrated from an older persisted
332
+ // version (before aiAgentsActivation existed) doesn't crash on .phases/.counts.
333
+ state.onboardingCustomerViewState.aiAgentsActivation ??
334
+ emptyAiAgentsActivationSubview;
335
+ export const getAiAgentsActivationSubview = (state) => fromActivationView(state);
336
+ export const getAiAgentsActivationPhases = (state) => fromActivationView(state).phases;
337
+ export const getAiAgentsActivationCounts = (state) => fromActivationView(state).counts;
@@ -1,17 +1,18 @@
1
1
  import { stringToUnion } from '../../../commonStateTypes/stringToUnion';
2
- export const ZENI_USER_REQUIRED_ONBOARDING_STEPS = [
3
- 'link_payment_account',
4
- ];
2
+ // Onboarding steps are the 4 top-level surfaces. Officer + details verification
3
+ // live as sub-steps under `verification` (state machine in CustomerOnboardingPage).
4
+ // The optional data-source step is its own surface; the legacy connect-data-source
5
+ // sub-step under the old `qbo_connection` no longer exists.
6
+ export const ZENI_USER_REQUIRED_ONBOARDING_STEPS = ['setup_billing'];
5
7
  export const CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO = [
6
- 'qbo_connection',
8
+ 'connect_ledger',
7
9
  ];
8
10
  export const REQUIRED_ONBOARDING_STEPS = [
9
11
  ...ZENI_USER_REQUIRED_ONBOARDING_STEPS,
10
12
  ...CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO,
11
13
  ];
12
14
  export const ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT = [
13
- 'company_officer',
14
- 'company_details',
15
+ 'verification',
15
16
  ];
16
17
  export const ALL_ZENI_USER_ONBOARDING_STEPS = [
17
18
  ...ZENI_USER_REQUIRED_ONBOARDING_STEPS,
@@ -19,10 +20,40 @@ export const ALL_ZENI_USER_ONBOARDING_STEPS = [
19
20
  ];
20
21
  export const ALL_CUSTOMER_ONBOARDING_STEPS_WITH_QBO = [
21
22
  ...CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO,
23
+ 'connect_data_source',
22
24
  ...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
23
25
  ];
24
26
  export const ALL_ONBOARDING_STEPS = [
25
27
  ...REQUIRED_ONBOARDING_STEPS,
28
+ 'connect_data_source',
26
29
  ...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
27
30
  ];
28
31
  export const toOnboardingStepType = (v) => stringToUnion(v, ALL_ONBOARDING_STEPS);
32
+ // Per-step sub-state. Lives in Redux so the save epic can tell, for example,
33
+ // an officer-form save from a company-details save while both share
34
+ // currentStep = 'verification'.
35
+ // - 'default' generic landing sub-state.
36
+ // - 'ai-activating' connect_ledger interstitial during AI activation.
37
+ // - 'unlock-stack' verification landing — VerifyUnlockFinancialStackPage.
38
+ // - 'company_officer' verification → officer form.
39
+ // - 'company_details' verification → company details form.
40
+ export const ALL_ONBOARDING_SUB_STEPS = [
41
+ 'default',
42
+ 'ai-activating',
43
+ 'unlock-stack',
44
+ 'company_officer',
45
+ 'company_details',
46
+ ];
47
+ export const toOnboardingSubStepType = (v) => stringToUnion(v, ALL_ONBOARDING_SUB_STEPS);
48
+ export const emptyAiAgentsActivationCounts = {
49
+ customerCount: 0,
50
+ glAccountCount: 0,
51
+ targetTransactionCount: 0,
52
+ transactionCount: 0,
53
+ vendorCount: 0,
54
+ };
55
+ export const emptyAiAgentsActivationSubview = {
56
+ counts: emptyAiAgentsActivationCounts,
57
+ fetchStatus: { fetchState: 'Not-Started', error: undefined },
58
+ phases: [],
59
+ };