@zeniai/client-epic-state 5.0.77-betaAR2 → 5.0.77-betaAR3

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 (22) hide show
  1. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +26 -11
  2. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +9 -4
  3. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +7 -6
  4. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +14 -6
  5. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +60 -0
  6. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +8 -2
  7. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +6 -2
  8. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +13 -4
  9. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +25 -10
  10. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.d.ts +7 -3
  11. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +26 -11
  12. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +9 -4
  13. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +7 -6
  14. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +13 -5
  15. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +39 -0
  16. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +62 -1
  17. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +8 -2
  18. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +6 -2
  19. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +12 -3
  20. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.d.ts +7 -3
  21. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +25 -10
  22. package/package.json +1 -1
@@ -26,8 +26,11 @@ const billPaySetupApproverView = createSlice({
26
26
  draft.fetchState = 'In-Progress';
27
27
  draft.error = undefined;
28
28
  },
29
- prepare(cacheOverride = false, includeUserRoles = true) {
30
- return { payload: { cacheOverride, includeUserRoles } };
29
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
30
+ // (`approval_rule_v3_config` dynamic config) and picks the v1 vs
31
+ // v2 endpoint in the fetch epic.
32
+ prepare(cacheOverride = false, includeUserRoles = true, useV3 = false) {
33
+ return { payload: { cacheOverride, includeUserRoles, useV3 } };
31
34
  },
32
35
  },
33
36
  fetchBillPaySetupApproverViewSuccess: {
@@ -112,8 +115,11 @@ const billPaySetupApproverView = createSlice({
112
115
  error: undefined,
113
116
  };
114
117
  },
115
- prepare(approvalRuleId) {
116
- return { payload: { approvalRuleId } };
118
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
119
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
120
+ // can pick the v1 vs v2 endpoint.
121
+ prepare(approvalRuleId, useV3 = false) {
122
+ return { payload: { approvalRuleId, useV3 } };
117
123
  },
118
124
  },
119
125
  deleteBillPayApprovalRuleSuccess: {
@@ -145,13 +151,22 @@ const billPaySetupApproverView = createSlice({
145
151
  };
146
152
  },
147
153
  },
148
- saveBillPaySetupApproverViewUpdates(draft) {
149
- if (draft.billPaySetupApproverViewUpdateData != null) {
150
- draft.billPaySetupApproverViewUpdateData.updateStatus = {
151
- fetchState: 'In-Progress',
152
- error: undefined,
153
- };
154
- }
154
+ saveBillPaySetupApproverViewUpdates: {
155
+ // Approval Rules 3.0 `useV3` is sourced from the
156
+ // `approval_rule_v3_config` dynamic config in the screen
157
+ // connector. The epic reads it off the action payload to pick
158
+ // the v1 or v2 endpoint and the matching write-side mapper.
159
+ reducer(draft, _action) {
160
+ if (draft.billPaySetupApproverViewUpdateData != null) {
161
+ draft.billPaySetupApproverViewUpdateData.updateStatus = {
162
+ fetchState: 'In-Progress',
163
+ error: undefined,
164
+ };
165
+ }
166
+ },
167
+ prepare(useV3) {
168
+ return { payload: { useV3 } };
169
+ },
155
170
  },
156
171
  saveBillPaySetupApproverViewUpdatesSuccess: {
157
172
  reducer(draft, action) {
@@ -6,11 +6,16 @@ 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
+ const endpoint = useV3
12
+ ? // ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
13
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
14
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
10
15
  return zeniAPI
11
- .deleteAndGetJSON(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`,
12
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`,
13
- { approval_rule_id: approvalRuleId })
16
+ .deleteAndGetJSON(endpoint, {
17
+ approval_rule_id: approvalRuleId,
18
+ })
14
19
  .pipe(mergeMap((response) => {
15
20
  if (isSuccessResponse(response) && response.data != null) {
16
21
  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,11 +14,12 @@ 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(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
19
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`
20
- )
21
- .pipe(mergeMap((response) => {
17
+ // Approval Rules 3.0 — flag-gated endpoint selection.
18
+ const endpoint = useV3
19
+ ? // ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
20
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
21
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
22
+ return zeniAPI.getJSON(endpoint).pipe(mergeMap((response) => {
22
23
  if (isSuccessResponse(response) && response.data != null) {
23
24
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
24
25
  const actions = [
@@ -5,17 +5,25 @@ 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
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
24
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
15
25
  return zeniAPI
16
- .postAndGetJSON(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`,
17
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`,
18
- payload)
26
+ .postAndGetJSON(endpoint, payload)
19
27
  .pipe(mergeMap((response) => {
20
28
  if (isSuccessResponse(response) && response.data != null) {
21
29
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -89,3 +89,63 @@ export const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
89
89
  }
90
90
  return payload;
91
91
  };
92
+ /**
93
+ * V1 wire mapper — used when `approval_rule_v3_config` resolves to OFF
94
+ * for the current tenant. Translates the form-side amount criteria into
95
+ * the legacy `{rangeType, rangeEntity, range: {min, max}}` shape. The
96
+ * V1 backend does not understand vendor / department criteria or the
97
+ * rule-level 3.0 fields, so those are dropped on the wire.
98
+ *
99
+ * The form-side amount slot is always read as a `range`-style criteria
100
+ * here: V1 schemas only supported ranges, so an absent `min` or `max`
101
+ * falls back to `0` / `Number.MAX_SAFE_INTEGER`.
102
+ */
103
+ export const toApprovalChangableInfoPayloadV1 = (approverViewUpdateData) => {
104
+ const amount = approverViewUpdateData.criteria?.amount;
105
+ const minAmount = amount?.min;
106
+ const maxAmount = amount?.max;
107
+ const currencyCode = minAmount?.currencyCode ?? maxAmount?.currencyCode ?? 'USD';
108
+ const currencySymbol = minAmount?.currencySymbol ?? maxAmount?.currencySymbol ?? '$';
109
+ const steps = approverViewUpdateData.steps.map((step) => {
110
+ return {
111
+ action: step.action,
112
+ operator: step.operator,
113
+ actors: step.actors
114
+ .filter((actor) => actor.subType !== 'admin')
115
+ .map((actor) => {
116
+ return {
117
+ type: actor.type,
118
+ id: actor.userId ?? null,
119
+ sub_type: actor.subType ?? null,
120
+ id_type: actor.idType ?? null,
121
+ is_implicit_actor: actor.isImplicitActor ?? false,
122
+ };
123
+ }),
124
+ };
125
+ });
126
+ const isUpdate = approverViewUpdateData.approvalRuleId != null;
127
+ const payload = {
128
+ steps,
129
+ is_applicable_on_pending_approval_entity: approverViewUpdateData.isApplicableOnPendingApprovalEntity ?? true,
130
+ criteria: {
131
+ rangeType: 'range',
132
+ rangeEntity: 'currency',
133
+ range: {
134
+ min: {
135
+ amount: minAmount?.amount ?? 0,
136
+ currencyCode,
137
+ currencySymbol,
138
+ },
139
+ max: {
140
+ amount: maxAmount?.amount ?? Number.MAX_SAFE_INTEGER,
141
+ currencyCode,
142
+ currencySymbol,
143
+ },
144
+ },
145
+ },
146
+ };
147
+ if (isUpdate) {
148
+ payload.approval_rule_id = approverViewUpdateData.approvalRuleId;
149
+ }
150
+ return payload;
151
+ };
@@ -6,9 +6,15 @@ import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { deleteRemiApprovalRule, deleteRemiApprovalRuleFailure, deleteRemiApprovalRuleSuccess, } from '../remiSetupApproverViewReducer';
8
8
  export const deleteRemiApprovalRuleEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(deleteRemiApprovalRule.match), switchMap((action) => {
9
- const { approvalRuleId } = action.payload;
9
+ const { approvalRuleId, useV3 } = action.payload;
10
+ // Approval Rules 3.0 — flag-gated endpoint selection.
11
+ const endpoint = useV3
12
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
13
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
10
14
  return zeniAPI
11
- .deleteAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`, { approval_rule_id: approvalRuleId })
15
+ .deleteAndGetJSON(endpoint, {
16
+ approval_rule_id: approvalRuleId,
17
+ })
12
18
  .pipe(mergeMap((response) => {
13
19
  if (isSuccessResponse(response) && response.data != null) {
14
20
  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 { fetchRemiSetupApproverView, fetchRemiSetupApproverViewFailure, fetchRemiSetupApproverViewSuccess, } from '../remiSetupApproverViewReducer';
8
8
  export const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchRemiSetupApproverView.match), switchMap((action) => {
9
- const { cacheOverride, resolveAttributeToUser, includeImplicitActors } = action.payload;
9
+ const { cacheOverride, resolveAttributeToUser, includeImplicitActors, useV3, } = action.payload;
10
10
  const { remiSetupApproverViewState, approvalRuleState } = state$.value;
11
11
  const approvalRules = getApprovalRulesByIds(approvalRuleState, remiSetupApproverViewState.approvalRuleIds);
12
12
  if (cacheOverride === true ||
@@ -14,8 +14,12 @@ export const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => act
14
14
  remiSetupApproverViewState.approvalRuleIds.length ||
15
15
  (remiSetupApproverViewState.hasValidState() === false &&
16
16
  remiSetupApproverViewState.fetchState !== 'In-Progress')) {
17
+ // Approval Rules 3.0 — flag-gated endpoint selection.
18
+ const basePath = useV3
19
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
20
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
17
21
  return zeniAPI
18
- .getJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
22
+ .getJSON(`${basePath}?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
19
23
  .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);
@@ -4,16 +4,25 @@ import { updateApprovalRules } from '../../../../../entity/approvalRule/approval
4
4
  import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
5
  import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
- import { toApprovalChangableInfoPayload } from '../../../billPay/billPaySetupApproverView/types/commonPayload';
7
+ import { toApprovalChangableInfoPayload, toApprovalChangableInfoPayloadV1, } from '../../../billPay/billPaySetupApproverView/types/commonPayload';
8
8
  import { saveRemiSetupApproverViewUpdates, saveRemiSetupApproverViewUpdatesFailure, saveRemiSetupApproverViewUpdatesSuccess, } from '../remiSetupApproverViewReducer';
9
- export const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveRemiSetupApproverViewUpdates.match), switchMap(() => {
9
+ export const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveRemiSetupApproverViewUpdates.match), switchMap((action) => {
10
10
  const { remiSetupApproverViewState } = state$.value;
11
11
  const remiSetupApproverViewUpdateData = remiSetupApproverViewState.remiSetupApproverViewUpdateData;
12
12
  if (remiSetupApproverViewUpdateData != null &&
13
13
  remiSetupApproverViewUpdateData.data != null) {
14
- const payload = toApprovalChangableInfoPayload(remiSetupApproverViewUpdateData.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(remiSetupApproverViewUpdateData.data)
20
+ : toApprovalChangableInfoPayloadV1(remiSetupApproverViewUpdateData.data);
21
+ const endpoint = useV3
22
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
23
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
15
24
  return zeniAPI
16
- .postAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/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);
@@ -26,12 +26,16 @@ const remiSetupApproverView = createSlice({
26
26
  draft.fetchState = 'In-Progress';
27
27
  draft.error = undefined;
28
28
  },
29
- prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false) {
29
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
30
+ // (`approval_rule_v3_config` dynamic config) and picks v1 vs v2
31
+ // endpoint in the fetch epic.
32
+ prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false, useV3 = false) {
30
33
  return {
31
34
  payload: {
32
35
  cacheOverride,
33
36
  resolveAttributeToUser,
34
37
  includeImplicitActors,
38
+ useV3,
35
39
  },
36
40
  };
37
41
  },
@@ -134,8 +138,11 @@ const remiSetupApproverView = createSlice({
134
138
  error: undefined,
135
139
  };
136
140
  },
137
- prepare(approvalRuleId) {
138
- return { payload: { approvalRuleId } };
141
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
142
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
143
+ // can pick the v1 vs v2 endpoint.
144
+ prepare(approvalRuleId, useV3 = false) {
145
+ return { payload: { approvalRuleId, useV3 } };
139
146
  },
140
147
  },
141
148
  deleteRemiApprovalRuleSuccess: {
@@ -167,13 +174,21 @@ const remiSetupApproverView = createSlice({
167
174
  };
168
175
  },
169
176
  },
170
- saveRemiSetupApproverViewUpdates(draft) {
171
- if (draft.remiSetupApproverViewUpdateData != null) {
172
- draft.remiSetupApproverViewUpdateData.updateStatus = {
173
- fetchState: 'In-Progress',
174
- error: undefined,
175
- };
176
- }
177
+ saveRemiSetupApproverViewUpdates: {
178
+ // Approval Rules 3.0 `useV3` sourced from
179
+ // `approval_rule_v3_config` dynamic config in the screen
180
+ // connector; epic uses it to pick v1 vs v2 URL + mapper.
181
+ reducer(draft, _action) {
182
+ if (draft.remiSetupApproverViewUpdateData != null) {
183
+ draft.remiSetupApproverViewUpdateData.updateStatus = {
184
+ fetchState: 'In-Progress',
185
+ error: undefined,
186
+ };
187
+ }
188
+ },
189
+ prepare(useV3) {
190
+ return { payload: { useV3 } };
191
+ },
177
192
  },
178
193
  saveRemiSetupApproverViewUpdatesSuccess: {
179
194
  reducer(draft, action) {
@@ -2,9 +2,10 @@ import { ZeniAPIStatus } from '../../../../responsePayload';
2
2
  import { BillPaySetupApproverViewState } from './billPaySetupApproverViewState';
3
3
  import { ApprovalRuleCreateData, ApprovalRuleUpdateData } from './types/commonState';
4
4
  export declare const initialState: BillPaySetupApproverViewState;
5
- export declare const fetchBillPaySetupApproverView: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, includeUserRoles?: any], {
5
+ export declare const fetchBillPaySetupApproverView: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, includeUserRoles?: any, useV3?: any], {
6
6
  cacheOverride: any;
7
7
  includeUserRoles: any;
8
+ useV3: any;
8
9
  }, "billPaySetupApproverView/fetchBillPaySetupApproverView", never, never>, fetchBillPaySetupApproverViewSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[]], {
9
10
  approvalRuleIds: string[];
10
11
  }, "billPaySetupApproverView/fetchBillPaySetupApproverViewSuccess", never, never>, fetchBillPaySetupApproverViewFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[status: ZeniAPIStatus<Record<string, unknown>>], ZeniAPIStatus<Record<string, unknown>>, "billPaySetupApproverView/fetchBillPaySetupApproverViewFailure", never, never>, fetchBillPayApproversDetails: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, includeUserRoles?: any], {
@@ -18,15 +19,18 @@ export declare const fetchBillPaySetupApproverView: import("@reduxjs/toolkit").A
18
19
  attributes: ("manager" | "vendor_owner" | "manager_of_manager")[];
19
20
  }, "billPaySetupApproverView/fetchBillPayApproversListSuccess", never, never>, fetchBillPayApproversListFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[status: ZeniAPIStatus<Record<string, unknown>>], {
20
21
  status: ZeniAPIStatus<Record<string, unknown>>;
21
- }, "billPaySetupApproverView/fetchBillPayApproversListFailure", never, never>, deleteBillPayApprovalRule: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string], {
22
+ }, "billPaySetupApproverView/fetchBillPayApproversListFailure", never, never>, deleteBillPayApprovalRule: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string, useV3?: any], {
22
23
  approvalRuleId: string;
24
+ useV3: any;
23
25
  }, "billPaySetupApproverView/deleteBillPayApprovalRule", never, never>, deleteBillPayApprovalRuleSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[deletedApprovalRuleId: string, approvalRuleIds: string[]], {
24
26
  deletedApprovalRuleId: string;
25
27
  approvalRuleIds: string[];
26
28
  }, "billPaySetupApproverView/deleteBillPayApprovalRuleSuccess", never, never>, deleteBillPayApprovalRuleFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
27
29
  approvalRuleId: string;
28
30
  status: ZeniAPIStatus<Record<string, unknown>>;
29
- }, "billPaySetupApproverView/deleteBillPayApprovalRuleFailure", never, never>, saveBillPaySetupApproverViewUpdates: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"billPaySetupApproverView/saveBillPaySetupApproverViewUpdates">, saveBillPaySetupApproverViewUpdatesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[], affectedEntityIds?: string[] | undefined, newApprovalRuleId?: string | undefined], {
31
+ }, "billPaySetupApproverView/deleteBillPayApprovalRuleFailure", never, never>, saveBillPaySetupApproverViewUpdates: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[useV3: boolean], {
32
+ useV3: boolean;
33
+ }, "billPaySetupApproverView/saveBillPaySetupApproverViewUpdates", never, never>, saveBillPaySetupApproverViewUpdatesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[], affectedEntityIds?: string[] | undefined, newApprovalRuleId?: string | undefined], {
30
34
  approvalRuleIds: string[];
31
35
  affectedEntityIds: string[] | undefined;
32
36
  newApprovalRuleId: string | undefined;
@@ -30,8 +30,11 @@ const billPaySetupApproverView = (0, toolkit_1.createSlice)({
30
30
  draft.fetchState = 'In-Progress';
31
31
  draft.error = undefined;
32
32
  },
33
- prepare(cacheOverride = false, includeUserRoles = true) {
34
- return { payload: { cacheOverride, includeUserRoles } };
33
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
34
+ // (`approval_rule_v3_config` dynamic config) and picks the v1 vs
35
+ // v2 endpoint in the fetch epic.
36
+ prepare(cacheOverride = false, includeUserRoles = true, useV3 = false) {
37
+ return { payload: { cacheOverride, includeUserRoles, useV3 } };
35
38
  },
36
39
  },
37
40
  fetchBillPaySetupApproverViewSuccess: {
@@ -116,8 +119,11 @@ const billPaySetupApproverView = (0, toolkit_1.createSlice)({
116
119
  error: undefined,
117
120
  };
118
121
  },
119
- prepare(approvalRuleId) {
120
- return { payload: { approvalRuleId } };
122
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
123
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
124
+ // can pick the v1 vs v2 endpoint.
125
+ prepare(approvalRuleId, useV3 = false) {
126
+ return { payload: { approvalRuleId, useV3 } };
121
127
  },
122
128
  },
123
129
  deleteBillPayApprovalRuleSuccess: {
@@ -149,13 +155,22 @@ const billPaySetupApproverView = (0, toolkit_1.createSlice)({
149
155
  };
150
156
  },
151
157
  },
152
- saveBillPaySetupApproverViewUpdates(draft) {
153
- if (draft.billPaySetupApproverViewUpdateData != null) {
154
- draft.billPaySetupApproverViewUpdateData.updateStatus = {
155
- fetchState: 'In-Progress',
156
- error: undefined,
157
- };
158
- }
158
+ saveBillPaySetupApproverViewUpdates: {
159
+ // Approval Rules 3.0 `useV3` is sourced from the
160
+ // `approval_rule_v3_config` dynamic config in the screen
161
+ // connector. The epic reads it off the action payload to pick
162
+ // the v1 or v2 endpoint and the matching write-side mapper.
163
+ reducer(draft, _action) {
164
+ if (draft.billPaySetupApproverViewUpdateData != null) {
165
+ draft.billPaySetupApproverViewUpdateData.updateStatus = {
166
+ fetchState: 'In-Progress',
167
+ error: undefined,
168
+ };
169
+ }
170
+ },
171
+ prepare(useV3) {
172
+ return { payload: { useV3 } };
173
+ },
159
174
  },
160
175
  saveBillPaySetupApproverViewUpdatesSuccess: {
161
176
  reducer(draft, action) {
@@ -9,11 +9,16 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const billPaySetupApproverViewReducer_1 = require("../billPaySetupApproverViewReducer");
11
11
  const deleteBillPayApprovalRuleEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(billPaySetupApproverViewReducer_1.deleteBillPayApprovalRule.match), (0, operators_1.switchMap)((action) => {
12
- const { approvalRuleId } = action.payload;
12
+ const { approvalRuleId, useV3 } = action.payload;
13
+ // Approval Rules 3.0 — flag-gated endpoint selection.
14
+ const endpoint = useV3
15
+ ? // ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
16
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
17
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
13
18
  return zeniAPI
14
- .deleteAndGetJSON(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`,
15
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`,
16
- { approval_rule_id: approvalRuleId })
19
+ .deleteAndGetJSON(endpoint, {
20
+ approval_rule_id: approvalRuleId,
21
+ })
17
22
  .pipe((0, operators_1.mergeMap)((response) => {
18
23
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
19
24
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -9,7 +9,7 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const billPaySetupApproverViewReducer_1 = require("../billPaySetupApproverViewReducer");
11
11
  const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(billPaySetupApproverViewReducer_1.fetchBillPaySetupApproverView.match), (0, operators_1.switchMap)((action) => {
12
- const { cacheOverride } = action.payload;
12
+ const { cacheOverride, useV3 } = action.payload;
13
13
  const { billPaySetupApproverViewState, approvalRuleState } = state$.value;
14
14
  const approvalRules = (0, approvalRuleSelector_1.getApprovalRulesByIds)(approvalRuleState, billPaySetupApproverViewState.approvalRuleIds);
15
15
  if (cacheOverride === true ||
@@ -17,11 +17,12 @@ const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) => actions
17
17
  billPaySetupApproverViewState.approvalRuleIds.length ||
18
18
  (billPaySetupApproverViewState.hasValidState() === false &&
19
19
  billPaySetupApproverViewState.fetchState !== 'In-Progress')) {
20
- return zeniAPI
21
- .getJSON(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
22
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`
23
- )
24
- .pipe((0, operators_1.mergeMap)((response) => {
20
+ // Approval Rules 3.0 — flag-gated endpoint selection.
21
+ const endpoint = useV3
22
+ ? // ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
23
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
24
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
25
+ return zeniAPI.getJSON(endpoint).pipe((0, operators_1.mergeMap)((response) => {
25
26
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
26
27
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
27
28
  const actions = [
@@ -9,16 +9,24 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const billPaySetupApproverViewReducer_1 = require("../billPaySetupApproverViewReducer");
11
11
  const commonPayload_1 = require("../types/commonPayload");
12
- const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(billPaySetupApproverViewReducer_1.saveBillPaySetupApproverViewUpdates.match), (0, operators_1.switchMap)(() => {
12
+ const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(billPaySetupApproverViewReducer_1.saveBillPaySetupApproverViewUpdates.match), (0, operators_1.switchMap)((action) => {
13
13
  const { billPaySetupApproverViewState } = state$.value;
14
14
  const billPaySetupApproverViewUpdateData = billPaySetupApproverViewState.billPaySetupApproverViewUpdateData;
15
15
  if (billPaySetupApproverViewUpdateData != null &&
16
16
  billPaySetupApproverViewUpdateData.data != null) {
17
- const payload = (0, commonPayload_1.toApprovalChangableInfoPayload)(billPaySetupApproverViewUpdateData.data);
17
+ // Approval Rules 3.0 — gate URL + write-side payload mapper on
18
+ // the `approval_rule_v3_config` dynamic config. `useV3` arrives
19
+ // on the action payload from the screen connector.
20
+ const { useV3 } = action.payload;
21
+ const payload = useV3
22
+ ? (0, commonPayload_1.toApprovalChangableInfoPayload)(billPaySetupApproverViewUpdateData.data)
23
+ : (0, commonPayload_1.toApprovalChangableInfoPayloadV1)(billPaySetupApproverViewUpdateData.data);
24
+ const endpoint = useV3
25
+ ? // ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
26
+ `https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`
27
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
18
28
  return zeniAPI
19
- .postAndGetJSON(`https://dev.api.zeni.ai/version/approval/tarun/1.0/bill-pay/approval-rules-v2`,
20
- // `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`,
21
- payload)
29
+ .postAndGetJSON(endpoint, payload)
22
30
  .pipe((0, operators_1.mergeMap)((response) => {
23
31
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
24
32
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -26,5 +26,44 @@ interface ApprovalUpdatableInfoPayload {
26
26
  name?: string;
27
27
  separation_of_duties?: boolean;
28
28
  }
29
+ /**
30
+ * V1 / pre-3.0 wire shape. Kept so the rollback flag (gated by
31
+ * `approval_rule_v3_config` dynamic config) can target the original
32
+ * `/approval-rules` endpoint with the legacy `{rangeType, rangeEntity, range}`
33
+ * criteria. None of the 3.0 rule-level fields are sent.
34
+ */
35
+ interface ApprovalUpdatableInfoPayloadV1 {
36
+ criteria: {
37
+ range: {
38
+ max: {
39
+ amount: number;
40
+ currencyCode: string;
41
+ currencySymbol: string;
42
+ };
43
+ min: {
44
+ amount: number;
45
+ currencyCode: string;
46
+ currencySymbol: string;
47
+ };
48
+ };
49
+ rangeEntity: 'currency';
50
+ rangeType: 'range';
51
+ };
52
+ is_applicable_on_pending_approval_entity: boolean;
53
+ steps: ApproverViewStepPayload[];
54
+ approval_rule_id?: ID;
55
+ }
29
56
  export declare const toApprovalChangableInfoPayload: (approverViewUpdateData: ApprovalRuleUpdateData | ApprovalRuleCreateData) => Partial<ApprovalUpdatableInfoPayload>;
57
+ /**
58
+ * V1 wire mapper — used when `approval_rule_v3_config` resolves to OFF
59
+ * for the current tenant. Translates the form-side amount criteria into
60
+ * the legacy `{rangeType, rangeEntity, range: {min, max}}` shape. The
61
+ * V1 backend does not understand vendor / department criteria or the
62
+ * rule-level 3.0 fields, so those are dropped on the wire.
63
+ *
64
+ * The form-side amount slot is always read as a `range`-style criteria
65
+ * here: V1 schemas only supported ranges, so an absent `min` or `max`
66
+ * falls back to `0` / `Number.MAX_SAFE_INTEGER`.
67
+ */
68
+ export declare const toApprovalChangableInfoPayloadV1: (approverViewUpdateData: ApprovalRuleUpdateData | ApprovalRuleCreateData) => Partial<ApprovalUpdatableInfoPayloadV1>;
30
69
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toApprovalChangableInfoPayload = void 0;
3
+ exports.toApprovalChangableInfoPayloadV1 = exports.toApprovalChangableInfoPayload = void 0;
4
4
  const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
5
5
  // Form-side criteria is a structured object with optional slots for
6
6
  // amount / vendor / department; flatten it into the wire format's
@@ -93,3 +93,64 @@ const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
93
93
  return payload;
94
94
  };
95
95
  exports.toApprovalChangableInfoPayload = toApprovalChangableInfoPayload;
96
+ /**
97
+ * V1 wire mapper — used when `approval_rule_v3_config` resolves to OFF
98
+ * for the current tenant. Translates the form-side amount criteria into
99
+ * the legacy `{rangeType, rangeEntity, range: {min, max}}` shape. The
100
+ * V1 backend does not understand vendor / department criteria or the
101
+ * rule-level 3.0 fields, so those are dropped on the wire.
102
+ *
103
+ * The form-side amount slot is always read as a `range`-style criteria
104
+ * here: V1 schemas only supported ranges, so an absent `min` or `max`
105
+ * falls back to `0` / `Number.MAX_SAFE_INTEGER`.
106
+ */
107
+ const toApprovalChangableInfoPayloadV1 = (approverViewUpdateData) => {
108
+ const amount = approverViewUpdateData.criteria?.amount;
109
+ const minAmount = amount?.min;
110
+ const maxAmount = amount?.max;
111
+ const currencyCode = minAmount?.currencyCode ?? maxAmount?.currencyCode ?? 'USD';
112
+ const currencySymbol = minAmount?.currencySymbol ?? maxAmount?.currencySymbol ?? '$';
113
+ const steps = approverViewUpdateData.steps.map((step) => {
114
+ return {
115
+ action: step.action,
116
+ operator: step.operator,
117
+ actors: step.actors
118
+ .filter((actor) => actor.subType !== 'admin')
119
+ .map((actor) => {
120
+ return {
121
+ type: actor.type,
122
+ id: actor.userId ?? null,
123
+ sub_type: actor.subType ?? null,
124
+ id_type: actor.idType ?? null,
125
+ is_implicit_actor: actor.isImplicitActor ?? false,
126
+ };
127
+ }),
128
+ };
129
+ });
130
+ const isUpdate = approverViewUpdateData.approvalRuleId != null;
131
+ const payload = {
132
+ steps,
133
+ is_applicable_on_pending_approval_entity: approverViewUpdateData.isApplicableOnPendingApprovalEntity ?? true,
134
+ criteria: {
135
+ rangeType: 'range',
136
+ rangeEntity: 'currency',
137
+ range: {
138
+ min: {
139
+ amount: minAmount?.amount ?? 0,
140
+ currencyCode,
141
+ currencySymbol,
142
+ },
143
+ max: {
144
+ amount: maxAmount?.amount ?? Number.MAX_SAFE_INTEGER,
145
+ currencyCode,
146
+ currencySymbol,
147
+ },
148
+ },
149
+ },
150
+ };
151
+ if (isUpdate) {
152
+ payload.approval_rule_id = approverViewUpdateData.approvalRuleId;
153
+ }
154
+ return payload;
155
+ };
156
+ exports.toApprovalChangableInfoPayloadV1 = toApprovalChangableInfoPayloadV1;
@@ -9,9 +9,15 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const remiSetupApproverViewReducer_1 = require("../remiSetupApproverViewReducer");
11
11
  const deleteRemiApprovalRuleEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(remiSetupApproverViewReducer_1.deleteRemiApprovalRule.match), (0, operators_1.switchMap)((action) => {
12
- const { approvalRuleId } = action.payload;
12
+ const { approvalRuleId, useV3 } = action.payload;
13
+ // Approval Rules 3.0 — flag-gated endpoint selection.
14
+ const endpoint = useV3
15
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
16
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
13
17
  return zeniAPI
14
- .deleteAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`, { approval_rule_id: approvalRuleId })
18
+ .deleteAndGetJSON(endpoint, {
19
+ approval_rule_id: approvalRuleId,
20
+ })
15
21
  .pipe((0, operators_1.mergeMap)((response) => {
16
22
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
17
23
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -9,7 +9,7 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const remiSetupApproverViewReducer_1 = require("../remiSetupApproverViewReducer");
11
11
  const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(remiSetupApproverViewReducer_1.fetchRemiSetupApproverView.match), (0, operators_1.switchMap)((action) => {
12
- const { cacheOverride, resolveAttributeToUser, includeImplicitActors } = action.payload;
12
+ const { cacheOverride, resolveAttributeToUser, includeImplicitActors, useV3, } = action.payload;
13
13
  const { remiSetupApproverViewState, approvalRuleState } = state$.value;
14
14
  const approvalRules = (0, approvalRuleSelector_1.getApprovalRulesByIds)(approvalRuleState, remiSetupApproverViewState.approvalRuleIds);
15
15
  if (cacheOverride === true ||
@@ -17,8 +17,12 @@ const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.p
17
17
  remiSetupApproverViewState.approvalRuleIds.length ||
18
18
  (remiSetupApproverViewState.hasValidState() === false &&
19
19
  remiSetupApproverViewState.fetchState !== 'In-Progress')) {
20
+ // Approval Rules 3.0 — flag-gated endpoint selection.
21
+ const basePath = useV3
22
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
23
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
20
24
  return zeniAPI
21
- .getJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
25
+ .getJSON(`${basePath}?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
22
26
  .pipe((0, operators_1.mergeMap)((response) => {
23
27
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
24
28
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -9,14 +9,23 @@ const userReducer_1 = require("../../../../../entity/user/userReducer");
9
9
  const responsePayload_1 = require("../../../../../responsePayload");
10
10
  const commonPayload_1 = require("../../../billPay/billPaySetupApproverView/types/commonPayload");
11
11
  const remiSetupApproverViewReducer_1 = require("../remiSetupApproverViewReducer");
12
- const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(remiSetupApproverViewReducer_1.saveRemiSetupApproverViewUpdates.match), (0, operators_1.switchMap)(() => {
12
+ const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(remiSetupApproverViewReducer_1.saveRemiSetupApproverViewUpdates.match), (0, operators_1.switchMap)((action) => {
13
13
  const { remiSetupApproverViewState } = state$.value;
14
14
  const remiSetupApproverViewUpdateData = remiSetupApproverViewState.remiSetupApproverViewUpdateData;
15
15
  if (remiSetupApproverViewUpdateData != null &&
16
16
  remiSetupApproverViewUpdateData.data != null) {
17
- const payload = (0, commonPayload_1.toApprovalChangableInfoPayload)(remiSetupApproverViewUpdateData.data);
17
+ // Approval Rules 3.0 — gate URL + write-side payload mapper on
18
+ // the `approval_rule_v3_config` dynamic config. `useV3` arrives
19
+ // on the action payload from the screen connector.
20
+ const { useV3 } = action.payload;
21
+ const payload = useV3
22
+ ? (0, commonPayload_1.toApprovalChangableInfoPayload)(remiSetupApproverViewUpdateData.data)
23
+ : (0, commonPayload_1.toApprovalChangableInfoPayloadV1)(remiSetupApproverViewUpdateData.data);
24
+ const endpoint = useV3
25
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
26
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
18
27
  return zeniAPI
19
- .postAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`, payload)
28
+ .postAndGetJSON(endpoint, payload)
20
29
  .pipe((0, operators_1.mergeMap)((response) => {
21
30
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
22
31
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -2,10 +2,11 @@ import { ZeniAPIStatus } from '../../../../responsePayload';
2
2
  import { ApprovalRuleCreateData, ApprovalRuleUpdateData } from '../../billPay/billPaySetupApproverView/types/commonState';
3
3
  import { RemiSetupApproverViewState } from './remiSetupApproverViewState';
4
4
  export declare const initialState: RemiSetupApproverViewState;
5
- export declare const fetchRemiSetupApproverView: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, resolveAttributeToUser?: any, includeImplicitActors?: any], {
5
+ export declare const fetchRemiSetupApproverView: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, resolveAttributeToUser?: any, includeImplicitActors?: any, useV3?: any], {
6
6
  cacheOverride: any;
7
7
  resolveAttributeToUser: any;
8
8
  includeImplicitActors: any;
9
+ useV3: any;
9
10
  }, "remiSetupApproverView/fetchRemiSetupApproverView", never, never>, fetchRemiSetupApproverViewSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[]], {
10
11
  approvalRuleIds: string[];
11
12
  }, "remiSetupApproverView/fetchRemiSetupApproverViewSuccess", never, never>, fetchRemiSetupApproverViewFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[status: ZeniAPIStatus<Record<string, unknown>>], ZeniAPIStatus<Record<string, unknown>>, "remiSetupApproverView/fetchRemiSetupApproverViewFailure", never, never>, fetchRemiApproversDetails: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[cacheOverride?: any, includeUserRoles?: any, includeAttributesUserIds?: any, lastUpdatedByUserId?: any], {
@@ -24,15 +25,18 @@ export declare const fetchRemiSetupApproverView: import("@reduxjs/toolkit").Acti
24
25
  attributeSubTypeToUserIdMapping: Record<"manager" | "vendor_owner" | "manager_of_manager", string> | undefined;
25
26
  }, "remiSetupApproverView/fetchRemiApproversListSuccess", never, never>, fetchRemiApproversListFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[status: ZeniAPIStatus<Record<string, unknown>>], {
26
27
  status: ZeniAPIStatus<Record<string, unknown>>;
27
- }, "remiSetupApproverView/fetchRemiApproversListFailure", never, never>, deleteRemiApprovalRule: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string], {
28
+ }, "remiSetupApproverView/fetchRemiApproversListFailure", never, never>, deleteRemiApprovalRule: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string, useV3?: any], {
28
29
  approvalRuleId: string;
30
+ useV3: any;
29
31
  }, "remiSetupApproverView/deleteRemiApprovalRule", never, never>, deleteRemiApprovalRuleSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[deletedApprovalRuleId: string, approvalRuleIds: string[]], {
30
32
  deletedApprovalRuleId: string;
31
33
  approvalRuleIds: string[];
32
34
  }, "remiSetupApproverView/deleteRemiApprovalRuleSuccess", never, never>, deleteRemiApprovalRuleFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
33
35
  approvalRuleId: string;
34
36
  status: ZeniAPIStatus<Record<string, unknown>>;
35
- }, "remiSetupApproverView/deleteRemiApprovalRuleFailure", never, never>, saveRemiSetupApproverViewUpdates: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"remiSetupApproverView/saveRemiSetupApproverViewUpdates">, saveRemiSetupApproverViewUpdatesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[], affectedEntityIds?: string[] | undefined, newApprovalRuleId?: string | undefined], {
37
+ }, "remiSetupApproverView/deleteRemiApprovalRuleFailure", never, never>, saveRemiSetupApproverViewUpdates: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[useV3: boolean], {
38
+ useV3: boolean;
39
+ }, "remiSetupApproverView/saveRemiSetupApproverViewUpdates", never, never>, saveRemiSetupApproverViewUpdatesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[approvalRuleIds: string[], affectedEntityIds?: string[] | undefined, newApprovalRuleId?: string | undefined], {
36
40
  approvalRuleIds: string[];
37
41
  affectedEntityIds: string[] | undefined;
38
42
  newApprovalRuleId: string | undefined;
@@ -30,12 +30,16 @@ const remiSetupApproverView = (0, toolkit_1.createSlice)({
30
30
  draft.fetchState = 'In-Progress';
31
31
  draft.error = undefined;
32
32
  },
33
- prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false) {
33
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
34
+ // (`approval_rule_v3_config` dynamic config) and picks v1 vs v2
35
+ // endpoint in the fetch epic.
36
+ prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false, useV3 = false) {
34
37
  return {
35
38
  payload: {
36
39
  cacheOverride,
37
40
  resolveAttributeToUser,
38
41
  includeImplicitActors,
42
+ useV3,
39
43
  },
40
44
  };
41
45
  },
@@ -138,8 +142,11 @@ const remiSetupApproverView = (0, toolkit_1.createSlice)({
138
142
  error: undefined,
139
143
  };
140
144
  },
141
- prepare(approvalRuleId) {
142
- return { payload: { approvalRuleId } };
145
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
146
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
147
+ // can pick the v1 vs v2 endpoint.
148
+ prepare(approvalRuleId, useV3 = false) {
149
+ return { payload: { approvalRuleId, useV3 } };
143
150
  },
144
151
  },
145
152
  deleteRemiApprovalRuleSuccess: {
@@ -171,13 +178,21 @@ const remiSetupApproverView = (0, toolkit_1.createSlice)({
171
178
  };
172
179
  },
173
180
  },
174
- saveRemiSetupApproverViewUpdates(draft) {
175
- if (draft.remiSetupApproverViewUpdateData != null) {
176
- draft.remiSetupApproverViewUpdateData.updateStatus = {
177
- fetchState: 'In-Progress',
178
- error: undefined,
179
- };
180
- }
181
+ saveRemiSetupApproverViewUpdates: {
182
+ // Approval Rules 3.0 `useV3` sourced from
183
+ // `approval_rule_v3_config` dynamic config in the screen
184
+ // connector; epic uses it to pick v1 vs v2 URL + mapper.
185
+ reducer(draft, _action) {
186
+ if (draft.remiSetupApproverViewUpdateData != null) {
187
+ draft.remiSetupApproverViewUpdateData.updateStatus = {
188
+ fetchState: 'In-Progress',
189
+ error: undefined,
190
+ };
191
+ }
192
+ },
193
+ prepare(useV3) {
194
+ return { payload: { useV3 } };
195
+ },
181
196
  },
182
197
  saveRemiSetupApproverViewUpdatesSuccess: {
183
198
  reducer(draft, action) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.0.77-betaAR2",
3
+ "version": "5.0.77-betaAR3",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",