@zeniai/client-epic-state 5.0.85-beta1ND → 5.0.85-betaAR1

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 (124) hide show
  1. package/lib/commonStateTypes/animations.d.ts +1 -1
  2. package/lib/commonStateTypes/animations.js +0 -1
  3. package/lib/entity/approvalRule/approvalRuleConflict.d.ts +56 -0
  4. package/lib/entity/approvalRule/approvalRuleConflict.js +77 -0
  5. package/lib/entity/approvalRule/approvalRulePayload.d.ts +34 -5
  6. package/lib/entity/approvalRule/approvalRulePayload.js +130 -10
  7. package/lib/entity/approvalRule/approvalRuleSelector.d.ts +25 -1
  8. package/lib/entity/approvalRule/approvalRuleSelector.js +40 -0
  9. package/lib/entity/approvalRule/approvalRuleState.d.ts +59 -7
  10. package/lib/entity/company/companyPayload.d.ts +0 -2
  11. package/lib/entity/company/companyPayload.js +0 -2
  12. package/lib/entity/company/companyStateTypes.d.ts +0 -2
  13. package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +0 -1
  14. package/lib/entity/paymentAccount/paymentAccountSelector.js +0 -4
  15. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  16. package/lib/entity/snackbar/snackbarTypes.js +2 -0
  17. package/lib/entity/tenant/epic/deleteConnectionEpic.d.ts +1 -1
  18. package/lib/entity/tenant/epic/saveAPIKeyConnectionEpic.d.ts +1 -1
  19. package/lib/entity/tenant/epic/saveConnectorCredentialsEpic.d.ts +3 -3
  20. package/lib/entity/tenant/epic/saveOAuthConnectionEpic.d.ts +1 -1
  21. package/lib/entity/tenant/tenantPayload.d.ts +0 -1
  22. package/lib/entity/tenant/tenantReducer.d.ts +25 -38
  23. package/lib/entity/tenant/tenantReducer.js +5 -65
  24. package/lib/entity/tenant/tenantState.d.ts +0 -1
  25. package/lib/epic.d.ts +5 -7
  26. package/lib/epic.js +5 -8
  27. package/lib/esm/commonStateTypes/animations.js +0 -1
  28. package/lib/esm/entity/approvalRule/approvalRuleConflict.js +74 -0
  29. package/lib/esm/entity/approvalRule/approvalRulePayload.js +130 -10
  30. package/lib/esm/entity/approvalRule/approvalRuleSelector.js +35 -0
  31. package/lib/esm/entity/company/companyPayload.js +0 -2
  32. package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +0 -3
  33. package/lib/esm/entity/snackbar/snackbarTypes.js +2 -0
  34. package/lib/esm/entity/tenant/tenantReducer.js +3 -63
  35. package/lib/esm/epic.js +5 -8
  36. package/lib/esm/index.js +15 -16
  37. package/lib/esm/view/createTransferEntry/epics/createTransferEntryEpic.js +1 -7
  38. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +50 -202
  39. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewSelector.js +1 -17
  40. package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewState.js +0 -13
  41. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +74 -12
  42. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +10 -2
  43. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +8 -4
  44. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +11 -7
  45. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.js +54 -0
  46. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +13 -4
  47. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +122 -16
  48. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +7 -2
  49. package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +52 -105
  50. package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +1 -6
  51. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +10 -2
  52. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +8 -2
  53. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +11 -7
  54. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.js +49 -0
  55. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +13 -4
  56. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +63 -11
  57. package/lib/index.d.ts +17 -19
  58. package/lib/index.js +45 -55
  59. package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +2 -2
  60. package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
  61. package/lib/view/createTransferEntry/epics/createTransferEntryEpic.js +1 -7
  62. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  63. package/lib/view/onboardingView/customerView/onboardingCustomerViewPayload.d.ts +0 -3
  64. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +4 -45
  65. package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +51 -204
  66. package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.d.ts +1 -8
  67. package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.js +2 -24
  68. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +0 -42
  69. package/lib/view/onboardingView/customerView/onboardingCustomerViewState.js +1 -14
  70. package/lib/view/people/peopleTypes.d.ts +1 -1
  71. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.d.ts +14 -3
  72. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +75 -13
  73. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewState.d.ts +8 -0
  74. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +10 -2
  75. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +8 -4
  76. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +10 -6
  77. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.d.ts +23 -0
  78. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.js +58 -0
  79. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +12 -3
  80. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +50 -1
  81. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +124 -17
  82. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonState.d.ts +31 -5
  83. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +7 -2
  84. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  85. package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +2 -28
  86. package/lib/view/spendManagement/commonSetup/setupViewReducer.js +53 -106
  87. package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +2 -7
  88. package/lib/view/spendManagement/commonSetup/setupViewSelector.js +1 -6
  89. package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +0 -19
  90. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +10 -2
  91. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +8 -2
  92. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +10 -6
  93. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.d.ts +14 -0
  94. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.js +53 -0
  95. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +12 -3
  96. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.d.ts +14 -3
  97. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +64 -12
  98. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewState.d.ts +5 -0
  99. package/lib/view/taskManager/taskListView/taskList.d.ts +3 -3
  100. package/package.json +1 -1
  101. package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.d.ts +0 -21
  102. package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.js +0 -54
  103. package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +0 -50
  104. package/lib/esm/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +0 -45
  105. package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +0 -40
  106. package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +0 -52
  107. package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +0 -59
  108. package/lib/esm/view/spendManagement/commonSetup/kycKybAutofillActions.js +0 -14
  109. package/lib/esm/view/spendManagement/commonSetup/kycKybParseMapper.js +0 -205
  110. package/lib/esm/view/spendManagement/commonSetup/types/kycKybAutofill.js +0 -28
  111. package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.d.ts +0 -7
  112. package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +0 -49
  113. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.d.ts +0 -9
  114. package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +0 -44
  115. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +0 -28
  116. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +0 -56
  117. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.d.ts +0 -30
  118. package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +0 -63
  119. package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.d.ts +0 -33
  120. package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.js +0 -17
  121. package/lib/view/spendManagement/commonSetup/kycKybParseMapper.d.ts +0 -24
  122. package/lib/view/spendManagement/commonSetup/kycKybParseMapper.js +0 -213
  123. package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.d.ts +0 -125
  124. package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.js +0 -32
@@ -1,7 +1,5 @@
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';
5
3
  const initialStatus = {
6
4
  fetchState: 'Not-Started',
7
5
  error: undefined,
@@ -11,31 +9,61 @@ export const initialState = {
11
9
  saveStatus: initialStatus,
12
10
  dashboardLoadedStatus: initialStatus,
13
11
  currentStep: 'link_payment_account',
14
- parsingDocumentFileIds: [],
15
12
  companyDetails: {
16
- autoFilledFields: [],
17
13
  localData: undefined,
18
14
  },
19
- companyOfficerUpdateStatus: (() => {
20
- const emptyOfficerSlot = {
21
- autoFilledFields: [],
15
+ companyOfficerUpdateStatus: {
16
+ Officer_1: {
22
17
  localData: undefined,
23
18
  sendOtpStatus: initialStatus,
24
19
  otpverificationStatus: initialStatus,
25
- };
26
- return {
27
- Officer_1: { ...emptyOfficerSlot },
28
- Officer_2: { ...emptyOfficerSlot },
29
- Officer_3: { ...emptyOfficerSlot },
30
- Officer_4: { ...emptyOfficerSlot },
31
- Officer_5: { ...emptyOfficerSlot },
32
- Officer_6: { ...emptyOfficerSlot },
33
- Officer_7: { ...emptyOfficerSlot },
34
- Officer_8: { ...emptyOfficerSlot },
35
- Officer_9: { ...emptyOfficerSlot },
36
- Officer_10: { ...emptyOfficerSlot },
37
- };
38
- })(),
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
+ },
39
67
  primaryContactDetails: {},
40
68
  paymentAccountDetails: {
41
69
  fetchStatus: initialStatus,
@@ -63,7 +91,6 @@ export const initialState = {
63
91
  },
64
92
  fetchState: 'Not-Started',
65
93
  error: undefined,
66
- aiAgentsActivation: { ...emptyAiAgentsActivationSubview },
67
94
  uiState: {
68
95
  isQBOPopupOpen: false,
69
96
  isCardPaymentPopupOpen: false,
@@ -153,111 +180,6 @@ const onboardingCustomerView = createSlice({
153
180
  };
154
181
  },
155
182
  },
156
- acknowledgeOnboardingAiFinanceTeam: {
157
- reducer(draft) {
158
- draft.aiFinanceTeamAcknowledgementStatus = {
159
- fetchState: 'In-Progress',
160
- error: undefined,
161
- };
162
- },
163
- prepare(companyId) {
164
- return {
165
- payload: { companyId },
166
- };
167
- },
168
- },
169
- acknowledgeOnboardingAiFinanceTeamSuccess(draft) {
170
- draft.aiFinanceTeamAcknowledgementStatus = {
171
- fetchState: 'Completed',
172
- error: undefined,
173
- };
174
- },
175
- acknowledgeOnboardingAiFinanceTeamFailure: {
176
- reducer(draft, action) {
177
- draft.aiFinanceTeamAcknowledgementStatus = {
178
- fetchState: 'Error',
179
- error: action.payload,
180
- };
181
- },
182
- prepare(error) {
183
- return {
184
- payload: error,
185
- };
186
- },
187
- },
188
- fetchAiAgentsActivationStatus(draft) {
189
- draft.aiAgentsActivation.fetchStatus = {
190
- fetchState: 'In-Progress',
191
- error: undefined,
192
- };
193
- },
194
- fetchAiAgentsActivationStatusSuccess: {
195
- reducer(draft, action) {
196
- draft.aiAgentsActivation.fetchStatus = {
197
- fetchState: 'Completed',
198
- error: undefined,
199
- };
200
- draft.aiAgentsActivation.ledgerPhases = action.payload.ledgerPhases;
201
- draft.aiAgentsActivation.backgroundPhases =
202
- action.payload.backgroundPhases;
203
- draft.aiAgentsActivation.counts = action.payload.counts;
204
- },
205
- prepare(payload) {
206
- return { payload };
207
- },
208
- },
209
- fetchAiAgentsActivationStatusFailure: {
210
- reducer(draft, action) {
211
- draft.aiAgentsActivation.fetchStatus = {
212
- fetchState: 'Error',
213
- error: action.payload,
214
- };
215
- },
216
- prepare(error) {
217
- return { payload: error };
218
- },
219
- },
220
- aiAgentsActivationCountsUpdated: {
221
- reducer(draft, action) {
222
- draft.aiAgentsActivation.counts = {
223
- ...draft.aiAgentsActivation.counts,
224
- ...action.payload,
225
- };
226
- },
227
- prepare(payload) {
228
- return { payload };
229
- },
230
- },
231
- aiAgentsActivationPhaseChanged: {
232
- reducer(draft, action) {
233
- const target = action.payload.section === 'ledger'
234
- ? draft.aiAgentsActivation.ledgerPhases
235
- : draft.aiAgentsActivation.backgroundPhases;
236
- const index = target.findIndex((phase) => phase.key === action.payload.key);
237
- if (index === -1) {
238
- target.push(action.payload);
239
- }
240
- else {
241
- target[index] = { ...target[index], ...action.payload };
242
- }
243
- },
244
- prepare(payload) {
245
- return { payload };
246
- },
247
- },
248
- aiAgentsActivationSectionReady: {
249
- reducer(draft, action) {
250
- const target = action.payload.section === 'ledger'
251
- ? draft.aiAgentsActivation.ledgerPhases
252
- : draft.aiAgentsActivation.backgroundPhases;
253
- target.forEach((phase) => {
254
- phase.status = 'ready';
255
- });
256
- },
257
- prepare(payload) {
258
- return { payload };
259
- },
260
- },
261
183
  updateOnboardingCustomerViewDashboardLoaded: {
262
184
  reducer(draft) {
263
185
  draft.dashboardLoadedStatus = {
@@ -670,81 +592,7 @@ const onboardingCustomerView = createSlice({
670
592
  clearOnboardingCustomerView(draft) {
671
593
  Object.assign(draft, initialState);
672
594
  },
673
- /** Merge AI-parsed officer fields into the officer's onboarding localData. */
674
- applyKycDocumentAutofillForOnboarding: {
675
- reducer(draft, action) {
676
- const { officerType, values, autoFilledFieldNames, fileId } = action.payload;
677
- const slot = draft.companyOfficerUpdateStatus[officerType];
678
- slot.localData = Object.assign({}, slot.localData, values);
679
- slot.autoFilledFields = Array.from(new Set([...slot.autoFilledFields, ...autoFilledFieldNames]));
680
- draft.parsingDocumentFileIds = draft.parsingDocumentFileIds.filter((id) => id !== fileId);
681
- },
682
- prepare(payload) {
683
- return { payload };
684
- },
685
- },
686
- /** Merge AI-parsed company fields into companyDetails onboarding localData. */
687
- applyKybDocumentAutofillForOnboarding: {
688
- reducer(draft, action) {
689
- const { values, autoFilledFieldNames, fileId } = action.payload;
690
- draft.companyDetails.localData = Object.assign({}, draft.companyDetails.localData, values);
691
- const prev = draft.companyDetails.autoFilledFields ?? [];
692
- draft.companyDetails.autoFilledFields = Array.from(new Set([...prev, ...autoFilledFieldNames]));
693
- draft.parsingDocumentFileIds = draft.parsingDocumentFileIds.filter((id) => id !== fileId);
694
- },
695
- prepare(payload) {
696
- return { payload };
697
- },
698
- },
699
- /** Wipe AI-autofill badges during onboarding. */
700
- clearKycKybAutofillForOnboarding: {
701
- reducer(draft, action) {
702
- const { officerType } = action.payload;
703
- if (officerType != null) {
704
- draft.companyOfficerUpdateStatus[officerType].autoFilledFields = [];
705
- }
706
- else {
707
- draft.companyDetails.autoFilledFields = [];
708
- Object.keys(draft.companyOfficerUpdateStatus).forEach((key) => {
709
- draft.companyOfficerUpdateStatus[key].autoFilledFields = [];
710
- });
711
- }
712
- },
713
- prepare(payload = {}) {
714
- return { payload };
715
- },
716
- },
717
- },
718
- extraReducers: (builder) => {
719
- const addParsingFileId = (draft, fileId) => {
720
- if (!draft.parsingDocumentFileIds.includes(fileId)) {
721
- draft.parsingDocumentFileIds.push(fileId);
722
- }
723
- };
724
- const removeParsingFileId = (draft, fileId) => {
725
- draft.parsingDocumentFileIds = draft.parsingDocumentFileIds.filter((id) => id !== fileId);
726
- };
727
- builder.addCase(parseUploadedKycDocument, (draft, action) => {
728
- if (action.payload.target === 'onboarding') {
729
- addParsingFileId(draft, action.payload.fileId);
730
- }
731
- });
732
- builder.addCase(parseUploadedKybDocument, (draft, action) => {
733
- if (action.payload.target === 'onboarding') {
734
- addParsingFileId(draft, action.payload.fileId);
735
- }
736
- });
737
- builder.addCase(parseUploadedKycDocumentFailure, (draft, action) => {
738
- if (action.payload.target === 'onboarding') {
739
- removeParsingFileId(draft, action.payload.fileId);
740
- }
741
- });
742
- builder.addCase(parseUploadedKybDocumentFailure, (draft, action) => {
743
- if (action.payload.target === 'onboarding') {
744
- removeParsingFileId(draft, action.payload.fileId);
745
- }
746
- });
747
595
  },
748
596
  });
749
- export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, acknowledgeOnboardingAiFinanceTeam, acknowledgeOnboardingAiFinanceTeamSuccess, acknowledgeOnboardingAiFinanceTeamFailure, fetchAiAgentsActivationStatus, fetchAiAgentsActivationStatusSuccess, fetchAiAgentsActivationStatusFailure, aiAgentsActivationCountsUpdated, aiAgentsActivationPhaseChanged, aiAgentsActivationSectionReady, 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, applyKycDocumentAutofillForOnboarding, applyKybDocumentAutofillForOnboarding, clearKycKybAutofillForOnboarding, } = onboardingCustomerView.actions;
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;
750
598
  export default onboardingCustomerView.reducer;
@@ -11,7 +11,7 @@ import { getCompanyAndIdentityDetails, } from '../../spendManagement/commonSetup
11
11
  import { ALL_ONBOARDING_STEPS, ALL_ZENI_USER_ONBOARDING_STEPS, REQUIRED_ONBOARDING_STEPS, ZENI_USER_REQUIRED_ONBOARDING_STEPS, 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, parsingDocumentFileIds, updateStatus, saveStatus, currentStep, uiState, fetchState, error, } = onboardingCustomerViewState;
14
+ const { companyDetails, companyOfficerUpdateStatus, primaryContactDetails, subscriptionPaymentAccountIds, paymentAccountDetails, plaidConnectionDetails, updateStatus, saveStatus, currentStep, uiState, fetchState, error, } = onboardingCustomerViewState;
15
15
  const { paymentAccountIds } = paymentAccountDetails;
16
16
  let subscriptionPaymentAccount;
17
17
  let paymentAccount;
@@ -54,7 +54,6 @@ export function getOnboardingCustomerView(state, companyId) {
54
54
  companyDetails,
55
55
  companyOfficerUpdateStatus,
56
56
  primaryContactDetails,
57
- parsingDocumentFileIds,
58
57
  });
59
58
  const companyAddress = addressViewState.newAddressState?.company_address;
60
59
  if (companyAddress == null &&
@@ -120,7 +119,6 @@ export function getOnboardingCustomerView(state, companyId) {
120
119
  return {
121
120
  companyDetailsLocalData,
122
121
  companyOfficerLocalData,
123
- parsingDocumentFileIds,
124
122
  subscriptionBillingAddress: subscriptionBillingAddress?.addressToCreate,
125
123
  companyView,
126
124
  allNationalityCountries,
@@ -325,17 +323,3 @@ export const getProductSettingsString = (productSettings) => {
325
323
  .map((key) => productKeyMap[key])
326
324
  .join(',');
327
325
  };
328
- const fromActivationView = (state) => state.onboardingCustomerViewState.aiAgentsActivation;
329
- export const getAiAgentsActivationSubview = (state) => fromActivationView(state);
330
- export const getAiAgentsActivationLedgerPhases = (state) => fromActivationView(state).ledgerPhases;
331
- export const getAiAgentsActivationBackgroundPhases = (state) => fromActivationView(state).backgroundPhases;
332
- export const getAiAgentsActivationCounts = (state) => fromActivationView(state).counts;
333
- const SECTION_ROW_STATUS_FALLBACK = 'idle';
334
- const phaseStatusToRowStatus = (status) => {
335
- if (status === 'ready') {
336
- return 'building';
337
- }
338
- return status;
339
- };
340
- export const getAiAgentsActivationLedgerRowStatuses = (state) => fromActivationView(state).ledgerPhases.map((phase) => phaseStatusToRowStatus(phase.status ?? SECTION_ROW_STATUS_FALLBACK));
341
- export const getAiAgentsActivationBackgroundRowStatuses = (state) => fromActivationView(state).backgroundPhases.map((phase) => phaseStatusToRowStatus(phase.status ?? SECTION_ROW_STATUS_FALLBACK));
@@ -26,16 +26,3 @@ export const ALL_ONBOARDING_STEPS = [
26
26
  ...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
27
27
  ];
28
28
  export const toOnboardingStepType = (v) => stringToUnion(v, ALL_ONBOARDING_STEPS);
29
- export const emptyAiAgentsActivationCounts = {
30
- customerCount: 0,
31
- glAccountCount: 0,
32
- targetTransactionCount: 0,
33
- transactionCount: 0,
34
- vendorCount: 0,
35
- };
36
- export const emptyAiAgentsActivationSubview = {
37
- backgroundPhases: [],
38
- counts: emptyAiAgentsActivationCounts,
39
- fetchStatus: { fetchState: 'Not-Started', error: undefined },
40
- ledgerPhases: [],
41
- };
@@ -13,6 +13,7 @@ export const initialState = {
13
13
  newApprovalRuleId: undefined,
14
14
  approvalRulesDeleteStatusById: {},
15
15
  billPaySetupApproverViewUpdateData: undefined,
16
+ reorderStatus: { fetchState: 'Not-Started', error: undefined },
16
17
  hasValidState() {
17
18
  return this.fetchState === 'Completed';
18
19
  },
@@ -26,8 +27,11 @@ const billPaySetupApproverView = createSlice({
26
27
  draft.fetchState = 'In-Progress';
27
28
  draft.error = undefined;
28
29
  },
29
- prepare(cacheOverride = false, includeUserRoles = true) {
30
- return { payload: { cacheOverride, includeUserRoles } };
30
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
31
+ // (`approval_rule_v3_config` dynamic config) and picks the v1 vs
32
+ // v2 endpoint in the fetch epic.
33
+ prepare(cacheOverride = false, includeUserRoles = true, useV3 = false) {
34
+ return { payload: { cacheOverride, includeUserRoles, useV3 } };
31
35
  },
32
36
  },
33
37
  fetchBillPaySetupApproverViewSuccess: {
@@ -112,8 +116,11 @@ const billPaySetupApproverView = createSlice({
112
116
  error: undefined,
113
117
  };
114
118
  },
115
- prepare(approvalRuleId) {
116
- return { payload: { approvalRuleId } };
119
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
120
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
121
+ // can pick the v1 vs v2 endpoint.
122
+ prepare(approvalRuleId, useV3 = false) {
123
+ return { payload: { approvalRuleId, useV3 } };
117
124
  },
118
125
  },
119
126
  deleteBillPayApprovalRuleSuccess: {
@@ -145,13 +152,68 @@ const billPaySetupApproverView = createSlice({
145
152
  };
146
153
  },
147
154
  },
148
- saveBillPaySetupApproverViewUpdates(draft) {
149
- if (draft.billPaySetupApproverViewUpdateData != null) {
150
- draft.billPaySetupApproverViewUpdateData.updateStatus = {
151
- fetchState: 'In-Progress',
152
- error: undefined,
153
- };
154
- }
155
+ /**
156
+ * Approval Rules 3.0 list-page drag-and-drop reorder.
157
+ *
158
+ * The trigger action carries the desired ordering as an ID list.
159
+ * The reducer optimistically replaces 'approvalRuleIds' so the
160
+ * list page renders the new order immediately; the epic then
161
+ * fires the PUT and either confirms (success — pulls updated
162
+ * priorities from the response) or recovers (failure — refetches
163
+ * the view so we don't strand a stale local order).
164
+ */
165
+ reorderBillPayApprovalRules: {
166
+ reducer(draft, action) {
167
+ const { approvalRuleIds } = action.payload;
168
+ draft.reorderStatus = { fetchState: 'In-Progress', error: undefined };
169
+ // Optimistic: render new order immediately. On failure, the
170
+ // epic dispatches fetchBillPaySetupApproverView to restore.
171
+ draft.approvalRuleIds = approvalRuleIds;
172
+ },
173
+ prepare(approvalRuleIds, useV3 = false) {
174
+ return { payload: { approvalRuleIds, useV3 } };
175
+ },
176
+ },
177
+ reorderBillPayApprovalRulesSuccess: {
178
+ reducer(draft, action) {
179
+ const { approvalRuleIds } = action.payload;
180
+ draft.reorderStatus = { fetchState: 'Completed', error: undefined };
181
+ // The API response is authoritative — overwrite with the
182
+ // server's reported order in case it normalised anything.
183
+ draft.approvalRuleIds = approvalRuleIds;
184
+ },
185
+ prepare(approvalRuleIds) {
186
+ return { payload: { approvalRuleIds } };
187
+ },
188
+ },
189
+ reorderBillPayApprovalRulesFailure: {
190
+ reducer(draft, action) {
191
+ const { status } = action.payload;
192
+ draft.reorderStatus = { fetchState: 'Error', error: status };
193
+ },
194
+ prepare(status) {
195
+ return { payload: { status } };
196
+ },
197
+ },
198
+ saveBillPaySetupApproverViewUpdates: {
199
+ // Approval Rules 3.0 — `useV3` is sourced from the
200
+ // `approval_rule_v3_config` dynamic config in the screen
201
+ // connector. The reducer doesn't read it (the field only
202
+ // matters in the save epic), but it must be declared so the
203
+ // action's payload type is correctly inferred for downstream
204
+ // consumers.
205
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
206
+ reducer(draft, _action) {
207
+ if (draft.billPaySetupApproverViewUpdateData != null) {
208
+ draft.billPaySetupApproverViewUpdateData.updateStatus = {
209
+ fetchState: 'In-Progress',
210
+ error: undefined,
211
+ };
212
+ }
213
+ },
214
+ prepare(useV3) {
215
+ return { payload: { useV3 } };
216
+ },
155
217
  },
156
218
  saveBillPaySetupApproverViewUpdatesSuccess: {
157
219
  reducer(draft, action) {
@@ -240,5 +302,5 @@ const billPaySetupApproverView = createSlice({
240
302
  },
241
303
  },
242
304
  });
243
- export const { fetchBillPaySetupApproverView, fetchBillPaySetupApproverViewSuccess, fetchBillPaySetupApproverViewFailure, fetchBillPayApproversDetails, fetchBillPayApproversList, fetchBillPayApproversListSuccess, fetchBillPayApproversListFailure, deleteBillPayApprovalRule, deleteBillPayApprovalRuleSuccess, deleteBillPayApprovalRuleFailure, saveBillPaySetupApproverViewUpdates, saveBillPaySetupApproverViewUpdatesSuccess, saveBillPaySetupApproverViewUpdatesFailure, initializeBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, setListeningToPusherEvent, clearBillPaySetupApproverView, } = billPaySetupApproverView.actions;
305
+ export const { fetchBillPaySetupApproverView, fetchBillPaySetupApproverViewSuccess, fetchBillPaySetupApproverViewFailure, fetchBillPayApproversDetails, fetchBillPayApproversList, fetchBillPayApproversListSuccess, fetchBillPayApproversListFailure, deleteBillPayApprovalRule, deleteBillPayApprovalRuleSuccess, deleteBillPayApprovalRuleFailure, reorderBillPayApprovalRules, reorderBillPayApprovalRulesSuccess, reorderBillPayApprovalRulesFailure, saveBillPaySetupApproverViewUpdates, saveBillPaySetupApproverViewUpdatesSuccess, saveBillPaySetupApproverViewUpdatesFailure, initializeBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, setListeningToPusherEvent, clearBillPaySetupApproverView, } = billPaySetupApproverView.actions;
244
306
  export default billPaySetupApproverView.reducer;
@@ -6,9 +6,17 @@ import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { deleteBillPayApprovalRule, deleteBillPayApprovalRuleFailure, deleteBillPayApprovalRuleSuccess, } from '../billPaySetupApproverViewReducer';
8
8
  export const deleteBillPayApprovalRuleEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(deleteBillPayApprovalRule.match), switchMap((action) => {
9
- const { approvalRuleId } = action.payload;
9
+ const { approvalRuleId, useV3 } = action.payload;
10
+ // Approval Rules 3.0 — flag-gated endpoint selection.
11
+ // Explicit `=== true` keeps `strict-boolean-expressions` happy
12
+ // when RTK's payload type widens to `any` in some configs.
13
+ const endpoint = useV3 === true
14
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
15
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
10
16
  return zeniAPI
11
- .deleteAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`, { approval_rule_id: approvalRuleId })
17
+ .deleteAndGetJSON(endpoint, {
18
+ approval_rule_id: approvalRuleId,
19
+ })
12
20
  .pipe(mergeMap((response) => {
13
21
  if (isSuccessResponse(response) && response.data != null) {
14
22
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -6,7 +6,7 @@ import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { fetchBillPaySetupApproverView, fetchBillPaySetupApproverViewFailure, fetchBillPaySetupApproverViewSuccess, } from '../billPaySetupApproverViewReducer';
8
8
  export const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchBillPaySetupApproverView.match), switchMap((action) => {
9
- const { cacheOverride } = action.payload;
9
+ const { cacheOverride, useV3 } = action.payload;
10
10
  const { billPaySetupApproverViewState, approvalRuleState } = state$.value;
11
11
  const approvalRules = getApprovalRulesByIds(approvalRuleState, billPaySetupApproverViewState.approvalRuleIds);
12
12
  if (cacheOverride === true ||
@@ -14,9 +14,13 @@ export const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) =>
14
14
  billPaySetupApproverViewState.approvalRuleIds.length ||
15
15
  (billPaySetupApproverViewState.hasValidState() === false &&
16
16
  billPaySetupApproverViewState.fetchState !== 'In-Progress')) {
17
- return zeniAPI
18
- .getJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`)
19
- .pipe(mergeMap((response) => {
17
+ // Approval Rules 3.0 — flag-gated endpoint selection.
18
+ // Explicit `=== true` keeps `strict-boolean-expressions` happy
19
+ // when RTK's payload type widens to `any` in some configs.
20
+ const endpoint = useV3 === true
21
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
22
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
23
+ return zeniAPI.getJSON(endpoint).pipe(mergeMap((response) => {
20
24
  if (isSuccessResponse(response) && response.data != null) {
21
25
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
22
26
  const actions = [
@@ -1,6 +1,6 @@
1
1
  import { from } from 'rxjs';
2
2
  import { filter, mergeMap } from 'rxjs/operators';
3
- import { getApprovalRuleById } from '../../../../../entity/approvalRule/approvalRuleSelector';
3
+ import { getAmountCriteria, getApprovalRuleById, getDepartmentCriteria, getVendorCriteria, } from '../../../../../entity/approvalRule/approvalRuleSelector';
4
4
  import { clearBillPaySetupApproverViewUpdateData, initializeBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdateData, } from '../billPaySetupApproverViewReducer';
5
5
  export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state$) => actions$.pipe(filter(initializeBillPaySetupApproverViewUpdateData.match), mergeMap((action) => {
6
6
  const { approvalRuleId } = action.payload;
@@ -8,16 +8,20 @@ export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state
8
8
  if (approvalRuleId != null) {
9
9
  const approvalRule = getApprovalRuleById(state$.value.approvalRuleState, approvalRuleId);
10
10
  if (approvalRule != null) {
11
- const criteria = approvalRule.criteria[0];
12
- const range = criteria?.range;
13
11
  const billPaySetupApproverViewUpdateData = {
14
12
  approvalRuleId,
15
13
  steps: approvalRule.steps,
16
14
  criteria: {
17
- rangeType: criteria?.rangeType,
18
- rangeEntity: criteria?.rangeEntity,
19
- range,
15
+ amount: getAmountCriteria(approvalRule.criteria),
16
+ vendor: getVendorCriteria(approvalRule.criteria),
17
+ department: getDepartmentCriteria(approvalRule.criteria),
20
18
  },
19
+ // Approval Rules 3.0 — seed rule-level fields so the form can
20
+ // round-trip them on edit. Each may be undefined on legacy rules.
21
+ name: approvalRule.name,
22
+ description: approvalRule.description,
23
+ separationOfDuties: approvalRule.separationOfDuties,
24
+ isFallback: approvalRule.isFallback,
21
25
  };
22
26
  fetchActions.push(clearBillPaySetupApproverViewUpdateData(), saveBillPaySetupApproverViewUpdateData(billPaySetupApproverViewUpdateData));
23
27
  }
@@ -25,7 +29,7 @@ export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state
25
29
  else {
26
30
  const billPaySetupApproverViewCreateData = {
27
31
  steps: [],
28
- criteria: undefined,
32
+ criteria: {},
29
33
  };
30
34
  fetchActions.push(clearBillPaySetupApproverViewUpdateData(), saveBillPaySetupApproverViewUpdateData(billPaySetupApproverViewCreateData));
31
35
  }
@@ -0,0 +1,54 @@
1
+ import { from } from 'rxjs';
2
+ import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
+ import { updateApprovalRules } from '../../../../../entity/approvalRule/approvalRuleReducer';
4
+ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
6
+ import { fetchBillPaySetupApproverView, reorderBillPayApprovalRules, reorderBillPayApprovalRulesFailure, reorderBillPayApprovalRulesSuccess, } from '../billPaySetupApproverViewReducer';
7
+ export const reorderBillPayApprovalRulesEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(reorderBillPayApprovalRules.match), switchMap((action) => {
8
+ const { approvalRuleIds, useV3 } = action.payload;
9
+ // Approval Rules 3.0 — flag-gated endpoint selection. Mirrors
10
+ // the pattern used by delete + fetch epics: the v3 dev host
11
+ // until the production base URL ships the v2 reorder route.
12
+ const endpoint = `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2/reorder`;
13
+ return zeniAPI
14
+ .putAndGetJSON(endpoint, {
15
+ rule_ids: approvalRuleIds,
16
+ })
17
+ .pipe(mergeMap((response) => {
18
+ if (isSuccessResponse(response) && response.data != null) {
19
+ const serverOrderedIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
20
+ const actions = [
21
+ updateApprovalRules(response.data.approval_rules),
22
+ reorderBillPayApprovalRulesSuccess(serverOrderedIds),
23
+ openSnackbar({
24
+ messageSection: `bill_pay_approval_reorder`,
25
+ messageText: 'success',
26
+ type: 'success',
27
+ }),
28
+ ];
29
+ return from(actions);
30
+ }
31
+ else {
32
+ const recovery = [
33
+ reorderBillPayApprovalRulesFailure(response.status),
34
+ openSnackbar({
35
+ messageSection: `bill_pay_approval_reorder`,
36
+ messageText: 'failed',
37
+ type: 'error',
38
+ }),
39
+ // Refetch to revert the optimistic order to server truth.
40
+ fetchBillPaySetupApproverView(true, true, useV3),
41
+ ];
42
+ return from(recovery);
43
+ }
44
+ }), catchError((error) => from([
45
+ reorderBillPayApprovalRulesFailure(createZeniAPIStatus('Unexpected Error', 'Reorder Bill Pay Approval Rules errored out' +
46
+ JSON.stringify(error))),
47
+ openSnackbar({
48
+ messageSection: `bill_pay_approval_reorder`,
49
+ messageText: 'failed',
50
+ type: 'error',
51
+ }),
52
+ fetchBillPaySetupApproverView(true, true, useV3),
53
+ ])));
54
+ }));
@@ -5,15 +5,24 @@ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
5
  import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { saveBillPaySetupApproverViewUpdates, saveBillPaySetupApproverViewUpdatesFailure, saveBillPaySetupApproverViewUpdatesSuccess, } from '../billPaySetupApproverViewReducer';
8
- import { toApprovalChangableInfoPayload } from '../types/commonPayload';
9
- export const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveBillPaySetupApproverViewUpdates.match), switchMap(() => {
8
+ import { toApprovalChangableInfoPayload, toApprovalChangableInfoPayloadV1, } from '../types/commonPayload';
9
+ export const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveBillPaySetupApproverViewUpdates.match), switchMap((action) => {
10
10
  const { billPaySetupApproverViewState } = state$.value;
11
11
  const billPaySetupApproverViewUpdateData = billPaySetupApproverViewState.billPaySetupApproverViewUpdateData;
12
12
  if (billPaySetupApproverViewUpdateData != null &&
13
13
  billPaySetupApproverViewUpdateData.data != null) {
14
- const payload = toApprovalChangableInfoPayload(billPaySetupApproverViewUpdateData.data);
14
+ // Approval Rules 3.0 — gate URL + write-side payload mapper on
15
+ // the `approval_rule_v3_config` dynamic config. `useV3` arrives
16
+ // on the action payload from the screen connector.
17
+ const { useV3 } = action.payload;
18
+ const payload = useV3
19
+ ? toApprovalChangableInfoPayload(billPaySetupApproverViewUpdateData.data)
20
+ : toApprovalChangableInfoPayloadV1(billPaySetupApproverViewUpdateData.data);
21
+ const endpoint = useV3
22
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
23
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
15
24
  return zeniAPI
16
- .postAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`, payload)
25
+ .postAndGetJSON(endpoint, payload)
17
26
  .pipe(mergeMap((response) => {
18
27
  if (isSuccessResponse(response) && response.data != null) {
19
28
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);