@zeniai/client-epic-state 5.1.68-beta0RR → 5.1.68-betaDI1

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 (47) hide show
  1. package/lib/commonPayloadTypes/commonPayload.d.ts +4 -25
  2. package/lib/esm/index.js +3 -8
  3. package/lib/esm/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +4 -2
  4. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewPayload.js +7 -2
  5. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewReducer.js +47 -2
  6. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewSelector.js +9 -0
  7. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewState.js +1 -0
  8. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.js +3 -7
  9. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.js +34 -56
  10. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/epics/submitIntlVerificationEpic.js +7 -2
  11. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.js +8 -55
  12. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer.js +7 -23
  13. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector.js +15 -39
  14. package/lib/index.d.ts +4 -10
  15. package/lib/index.js +15 -32
  16. package/lib/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.d.ts +5 -2
  17. package/lib/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +3 -1
  18. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.d.ts +1 -0
  19. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.js +7 -2
  20. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.d.ts +6 -1
  21. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.js +48 -3
  22. package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.js +9 -0
  23. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.d.ts +1 -0
  24. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.js +1 -0
  25. package/lib/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.d.ts +3 -3
  26. package/lib/view/spendManagement/billPay/internationalWireVerification/epics/fetchIntlVerificationFormEpic.js +2 -6
  27. package/lib/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.d.ts +1 -2
  28. package/lib/view/spendManagement/billPay/internationalWireVerification/epics/initializeIntlVerificationFormEpic.js +33 -55
  29. package/lib/view/spendManagement/billPay/internationalWireVerification/epics/submitIntlVerificationEpic.js +7 -2
  30. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.d.ts +1 -24
  31. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload.js +9 -59
  32. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer.js +6 -22
  33. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector.js +15 -39
  34. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationState.d.ts +1 -20
  35. package/package.json +1 -1
  36. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.js +0 -164
  37. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.js +0 -45
  38. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.js +0 -105
  39. package/lib/esm/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.js +0 -189
  40. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.d.ts +0 -4
  41. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData.js +0 -168
  42. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.d.ts +0 -43
  43. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants.js +0 -48
  44. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.d.ts +0 -29
  45. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers.js +0 -115
  46. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.d.ts +0 -32
  47. package/lib/view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload.js +0 -194
@@ -10,31 +10,10 @@ export interface AllowedValueWithCodeOptionalPayload {
10
10
  export declare function isAllowedValueWithCodePayload(allowedValueWithCodePayload: any): allowedValueWithCodePayload is AllowedValueWithCodePayload;
11
11
  export declare function isAllowedValueWithCodeOptionalPayload(allowedValueWithCodePayload: any): allowedValueWithCodePayload is AllowedValueWithCodeOptionalPayload;
12
12
  export declare function toAllowedValueWithCode(allowedValueWithCodePayload: AllowedValueWithCodePayload): AllowedValueWithCode;
13
- export interface LabelValueCodeDescriptionPayload {
14
- code: string;
15
- description: string;
16
- }
17
- export interface LabelValueFileOptionPayload {
18
- file_id: string;
19
- option?: string;
20
- }
21
- export interface LabelValuePersonNamePayload {
22
- first_name?: string;
23
- last_name?: string;
24
- }
25
- export interface LabelValuePersonPayload {
26
- company_role?: string;
27
- date_of_birth?: string;
28
- email?: string;
29
- name?: LabelValuePersonNamePayload;
30
- nationality?: string;
31
- ownership_percentage?: number;
32
- proof_of_address?: LabelValueFileOptionPayload[];
33
- proof_of_identity?: LabelValueFileOptionPayload[];
34
- ssn?: string;
35
- }
36
- export type LabelValueCodesValuesPayload = string | string[] | LabelValueCodeDescriptionPayload | LabelValueCodeDescriptionPayload[] | LabelValueFileOptionPayload | LabelValueFileOptionPayload[] | LabelValuePersonPayload | LabelValuePersonPayload[];
37
13
  export interface LabelValueCodesPayload {
38
14
  label: string;
39
- values: LabelValueCodesValuesPayload;
15
+ values: {
16
+ code: string;
17
+ description: string;
18
+ }[] | string[];
40
19
  }
package/lib/esm/index.js CHANGED
@@ -212,7 +212,7 @@ import { isNetBurnOrIncomeClassesViewCalculatedSectionID, isNetBurnOrIncomeClass
212
212
  import { toAverageMonthsCount } from './view/netBurnOrIncomeStoryCard/epic/updateNetBurnOrIncomeStoryCardSettingsEpic';
213
213
  import { fetchNetBurnOrIncomeStoryCard, updateNetBurnOrIncomeStoryCardSettings, } from './view/netBurnOrIncomeStoryCard/netBurnOrIncomeStoryCardReducer';
214
214
  import { getNetBurnOrIncomeStoryCardReport } from './view/netBurnOrIncomeStoryCard/netBurnOrIncomeStoryCardSelector';
215
- import { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, setGroupFrequency, toggleEventChannel, } from './view/notificationPreferencesView/notificationPreferencesViewReducer';
215
+ import { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, } from './view/notificationPreferencesView/notificationPreferencesViewReducer';
216
216
  import { getEffectiveNotificationPreferences, getNotificationLocalOverrides, getNotificationPreferencesSaveState, hasUnsavedNotificationPreferences, } from './view/notificationPreferencesView/notificationPreferencesViewSelector';
217
217
  import { fetchNotificationUnreadCount, fetchNotificationUnreadCountSuccess, fetchNotificationView, updateNotificationViewAllNotificationsStatus, updateNotificationViewCurrentTabAndSubTab, updateNotificationViewNotificationStatus, updateNotificationViewSubTab, updateNotificationViewTabState, updateNotificationViewUIState, } from './view/notificationView/notificationViewReducer';
218
218
  import { getExternalNotificationsForSelectedSubTab, getNotificationView, getNotificationsForSelectedSubTab, } from './view/notificationView/notificationViewSelector';
@@ -297,7 +297,6 @@ import { convertAmountToHomeCurrency, discardBillUpdatesInLocalStore, discardOut
297
297
  import { checkIfCreatorIsApprover, getEditBillDetail, toPaymentToOption, } from './view/spendManagement/billPay/editBillView/editBillViewSelector';
298
298
  import { clearInternationalWire, createPaymentInstrument, createPaymentInstrumentUpdateStatus, deletePaymentInstrument, fetchInternationalWireDynamicForm, initializeDynamicForm, initializeInternationalWireLocalData, updateInternationalWireLocalStoreData, } from './view/spendManagement/billPay/internationalWire/internationalWireReducer';
299
299
  import { getInternationalWireView, } from './view/spendManagement/billPay/internationalWire/internationalWireSelector';
300
- import { InternationalWireVerificationFormOrder, sortVerificationFormFields, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationPayload';
301
300
  import { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationReducer';
302
301
  import { getIntlWireVerificationView, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSelector';
303
302
  import { fetchBillAttachment, fetchMagicLinkBankNameByRouting, fetchMagicLinkBankNameBySwift, fetchMagicLinkTenant, saveBankAccount, saveMagicLinkAddressInLocalStore, updateMagicLinkBankAccountLocalStoreData, updateMagicLinkInternationalBankAccountLocalStoreData, } from './view/spendManagement/billPay/magicLinkView/magicLinkViewReducer';
@@ -647,15 +646,11 @@ export { toNotificationModeStrict, updateCommentsNotifications, updateCommentsNo
647
646
  export { toNotificationSubTabTypeStrict, toNotificationTabTypeStrict, fetchNotificationView, fetchNotificationUnreadCount, fetchNotificationUnreadCountSuccess, updateNotificationViewAllNotificationsStatus, updateNotificationViewNotificationStatus, updateNotificationViewTabState, updateNotificationViewCurrentTabAndSubTab, updateNotificationViewSubTab, updateNotificationViewUIState, getNotificationView, getExternalNotificationsForSelectedSubTab, getNotificationsForSelectedSubTab, };
648
647
  export { clearFeatureNotificationView, fetchRegisteredInterests, notifyMeForFeature, getFeatureNotificationView, getRegisteredInterests, getRegisteredInterestsByFeature, isFeatureInterestRegistered, };
649
648
  export { pushToastNotification, getLastNotificationTime, getNotifications, };
650
- export { getEffectiveNotificationPreferences, getNotificationLocalOverrides, getNotificationPreferencesSaveState, getNotificationRegistry, hasUnsavedNotificationPreferences, clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, setGroupFrequency, toggleEventChannel, toNotificationChannel, toNotificationFrequency, };
649
+ export { getEffectiveNotificationPreferences, getNotificationLocalOverrides, getNotificationPreferencesSaveState, getNotificationRegistry, hasUnsavedNotificationPreferences, clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, toNotificationChannel, toNotificationFrequency, };
651
650
  export { getReferralListView, getInviteFormView, toReferralListViewSortKeyType, StatusTypes, AmountStatusTypes, DEFAULT_REFERRER_AMOUNT, fetchReferrals, sendReferralInvite, clearReferrals, saveReferralFormDataInLocalStore, updateReferralListSortUiState, resendReferralInvite, fetchRewardsPlan, getRewardsPlanCard, updateReferViewed, };
652
651
  export { ALL_WEEK_DAYS, SEMI_WEEKLY_REQUIRED_DAYS_COUNT, getMinAllowedEndDate, getRecurringEndDateFromCount, toDayOfWeek, toRecurringFrequency, };
653
652
  export { fetchCockpitContext, fetchCompanyTaskManagerView, fetchTaskManagerMetrics, getCompanyTaskManagerView, createTaskFromTaskGroupTemplate, };
654
- export { InternationalWireVerificationFormOrder, sortVerificationFormFields, fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, getIntlWireVerificationView, };
655
- export { InternationalWireVerificationBooleanWithSubfieldsFieldNameList, InternationalWireVerificationBooleanWithSubfieldsFieldNames, InternationalWireVerificationControllingPersonFieldName, InternationalWireVerificationFormFieldNames, InternationalWireVerificationStakeHolderFieldName, InternationalWireVerificationSubfieldNames, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationFieldConstants';
656
- export { IntlWireVerificationLocalDataSuffix, toIntlWireVerificationFormDetails, toIntlWireVerificationSubmitPayload, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationSubmitPayload';
657
- export { getStakeHolderOwnerIndicesFromLocalData, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireVerificationLocalDataHelpers';
658
- export { toVerificationFormLocalDataFromOnboardingDetails, } from './view/spendManagement/billPay/internationalWireVerification/internationalWireOnboardingDetailsToLocalData';
653
+ export { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, getIntlWireVerificationView, };
659
654
  export { fetchExpressPayInitialDetails, updateExpressPayFormLocalData, submitExpressPay, resetExpressPayLocalData, getExpressPayView, };
660
655
  export { acceptTreasuryTerms, fetchTreasurySetupView, clearTreasurySetupView, fetchTreasuryFunds, updatePortfolioAllocation, fetchPortfolioAllocation, updateFundAllocationLocalData, updateTreasuryPromoIntroClosedByOutsideClick, updateTreasuryPromoRemindMeLaterClicked, updateTreasuryVideoViewed, getTreasurySetupViewDetails, getTreasuryFundsMaximumYield, };
661
656
  // ── AI Accountant Entity ──
@@ -4,10 +4,12 @@ import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
5
5
  import { notificationPreferencesUrl } from '../notificationPreferencesEndpoint';
6
6
  import { mapPreferencesToPayload, } from '../notificationPreferencesViewPayload';
7
- import { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, saveNotificationPreferences, saveNotificationPreferencesFailure, saveNotificationPreferencesSuccess, setGroupFrequency, toggleEventChannel, } from '../notificationPreferencesViewReducer';
7
+ import { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, saveNotificationPreferences, saveNotificationPreferencesFailure, saveNotificationPreferencesSuccess, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, } from '../notificationPreferencesViewReducer';
8
8
  import { getNotificationLocalOverrides } from '../notificationPreferencesViewSelector';
9
9
  const DEBOUNCE_MS = 300;
10
- export const saveNotificationPreferencesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => toggleEventChannel.match(action) || setGroupFrequency.match(action)),
10
+ export const saveNotificationPreferencesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => toggleEventChannel.match(action) ||
11
+ setGroupFrequency.match(action) ||
12
+ setGroupChannelMaster.match(action)),
11
13
  // Coalesce bursts of toggles into a single PUT. Trade-off: rapid clickers
12
14
  // defer saves until they pause. Consider a max-wait wrapper if this
13
15
  // becomes a UX problem.
@@ -1,5 +1,5 @@
1
1
  import { toNotificationChannel, toNotificationFrequency, } from '../../entity/notificationRegistry/notificationRegistryState';
2
- const mapEventEnabledByChannel = (raw) => {
2
+ const mapChannelEnabledMap = (raw) => {
3
3
  if (raw == null) {
4
4
  return {};
5
5
  }
@@ -20,7 +20,8 @@ export const mapPayloadToPreferences = (payload) => {
20
20
  toNotificationFrequency(frequency),
21
21
  ]));
22
22
  return {
23
- eventEnabledByChannel: mapEventEnabledByChannel(payload?.event_enabled_by_channel),
23
+ eventEnabledByChannel: mapChannelEnabledMap(payload?.event_enabled_by_channel),
24
+ groupChannelEnabledByGroupId: mapChannelEnabledMap(payload?.group_channel_enabled_by_group_id),
24
25
  groupFrequencyByGroupId,
25
26
  };
26
27
  };
@@ -29,6 +30,10 @@ export const mapPreferencesToPayload = (preferences) => {
29
30
  if (Object.keys(preferences.eventEnabledByChannel).length > 0) {
30
31
  payload.event_enabled_by_channel = preferences.eventEnabledByChannel;
31
32
  }
33
+ if (Object.keys(preferences.groupChannelEnabledByGroupId).length > 0) {
34
+ payload.group_channel_enabled_by_group_id =
35
+ preferences.groupChannelEnabledByGroupId;
36
+ }
32
37
  if (Object.keys(preferences.groupFrequencyByGroupId).length > 0) {
33
38
  payload.group_frequency_by_group_id = preferences.groupFrequencyByGroupId;
34
39
  }
@@ -18,8 +18,18 @@ const mergePreferences = (base, patch) => {
18
18
  ...channels,
19
19
  };
20
20
  });
21
+ const groupChannelEnabledByGroupId = {
22
+ ...base.groupChannelEnabledByGroupId,
23
+ };
24
+ Object.entries(patch.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
25
+ groupChannelEnabledByGroupId[groupId] = {
26
+ ...(base.groupChannelEnabledByGroupId[groupId] ?? {}),
27
+ ...channels,
28
+ };
29
+ });
21
30
  return {
22
31
  eventEnabledByChannel,
32
+ groupChannelEnabledByGroupId,
23
33
  groupFrequencyByGroupId: {
24
34
  ...base.groupFrequencyByGroupId,
25
35
  ...patch.groupFrequencyByGroupId,
@@ -61,13 +71,38 @@ const subtractSavedOverrides = (current, saved) => {
61
71
  eventEnabledByChannel[eventId] = remainingChannels;
62
72
  }
63
73
  });
74
+ // Same value-equality subtraction as eventEnabledByChannel above — a
75
+ // group-channel master the user re-flipped while a PUT was in flight must
76
+ // survive so the next debounce cycle re-sends it.
77
+ const groupChannelEnabledByGroupId = {};
78
+ Object.entries(current.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
79
+ const savedChannels = saved.groupChannelEnabledByGroupId[groupId];
80
+ if (savedChannels == null) {
81
+ groupChannelEnabledByGroupId[groupId] = channels;
82
+ return;
83
+ }
84
+ const remainingChannels = {};
85
+ Object.keys(channels).forEach((channel) => {
86
+ if (!(channel in savedChannels) ||
87
+ channels[channel] !== savedChannels[channel]) {
88
+ remainingChannels[channel] = channels[channel];
89
+ }
90
+ });
91
+ if (Object.keys(remainingChannels).length > 0) {
92
+ groupChannelEnabledByGroupId[groupId] = remainingChannels;
93
+ }
94
+ });
64
95
  const groupFrequencyByGroupId = {};
65
96
  Object.entries(current.groupFrequencyByGroupId).forEach(([groupId, frequency]) => {
66
97
  if (saved.groupFrequencyByGroupId[groupId] !== frequency) {
67
98
  groupFrequencyByGroupId[groupId] = frequency;
68
99
  }
69
100
  });
70
- return { eventEnabledByChannel, groupFrequencyByGroupId };
101
+ return {
102
+ eventEnabledByChannel,
103
+ groupChannelEnabledByGroupId,
104
+ groupFrequencyByGroupId,
105
+ };
71
106
  };
72
107
  const notificationPreferencesView = createSlice({
73
108
  name: 'notificationPreferencesView',
@@ -204,6 +239,16 @@ const notificationPreferencesView = createSlice({
204
239
  draft.preferences = mergePreferences(draft.preferences, patch);
205
240
  draft.localOverrides = subtractSavedOverrides(draft.localOverrides, action.payload.savedOverrides);
206
241
  },
242
+ setGroupChannelMaster(draft, action) {
243
+ // Mirror of `toggleEventChannel` but scoped to the group-channel master
244
+ // held under `groupChannelEnabledByGroupId[groupId][channel]`.
245
+ const { channel, enabled, groupId } = action.payload;
246
+ const groupMap = {
247
+ ...(draft.localOverrides.groupChannelEnabledByGroupId[groupId] ?? {}),
248
+ };
249
+ groupMap[channel] = enabled;
250
+ draft.localOverrides.groupChannelEnabledByGroupId[groupId] = groupMap;
251
+ },
207
252
  setGroupFrequency(draft, action) {
208
253
  draft.localOverrides.groupFrequencyByGroupId[action.payload.groupId] =
209
254
  action.payload.frequency;
@@ -218,5 +263,5 @@ const notificationPreferencesView = createSlice({
218
263
  },
219
264
  },
220
265
  });
221
- export const { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, fetchNotificationPreferencesSuccess, saveNotificationPreferences, saveNotificationPreferencesFailure, saveNotificationPreferencesSuccess, setGroupFrequency, toggleEventChannel, } = notificationPreferencesView.actions;
266
+ export const { clearAllNotificationPreferencesView, clearNotificationPreferencesLocalOverrides, fetchNotificationPreferencesSuccess, saveNotificationPreferences, saveNotificationPreferencesFailure, saveNotificationPreferencesSuccess, setGroupChannelMaster, setGroupFrequency, toggleEventChannel, } = notificationPreferencesView.actions;
222
267
  export default notificationPreferencesView.reducer;
@@ -9,8 +9,16 @@ export const getEffectiveNotificationPreferences = (state) => {
9
9
  ...channels,
10
10
  };
11
11
  });
12
+ const mergedGroupChannelEnabledByGroupId = { ...view.preferences.groupChannelEnabledByGroupId };
13
+ Object.entries(view.localOverrides.groupChannelEnabledByGroupId).forEach(([groupId, channels]) => {
14
+ mergedGroupChannelEnabledByGroupId[groupId] = {
15
+ ...(view.preferences.groupChannelEnabledByGroupId[groupId] ?? {}),
16
+ ...channels,
17
+ };
18
+ });
12
19
  return {
13
20
  eventEnabledByChannel: mergedEventEnabledByChannel,
21
+ groupChannelEnabledByGroupId: mergedGroupChannelEnabledByGroupId,
14
22
  groupFrequencyByGroupId: {
15
23
  ...view.preferences.groupFrequencyByGroupId,
16
24
  ...view.localOverrides.groupFrequencyByGroupId,
@@ -21,5 +29,6 @@ export const getNotificationLocalOverrides = (state) => getView(state).localOver
21
29
  export const hasUnsavedNotificationPreferences = (state) => {
22
30
  const overrides = getView(state).localOverrides;
23
31
  return (Object.keys(overrides.eventEnabledByChannel).length > 0 ||
32
+ Object.keys(overrides.groupChannelEnabledByGroupId).length > 0 ||
24
33
  Object.keys(overrides.groupFrequencyByGroupId).length > 0);
25
34
  };
@@ -1,4 +1,5 @@
1
1
  export const emptyNotificationPreferences = () => ({
2
2
  eventEnabledByChannel: {},
3
+ groupChannelEnabledByGroupId: {},
3
4
  groupFrequencyByGroupId: {},
4
5
  });
@@ -1,9 +1,8 @@
1
1
  import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
4
- import { toVerificationFormLocalDataFromOnboardingDetails } from '../internationalWireOnboardingDetailsToLocalData';
5
- import { fetchInternationalVerificationForm, updateInternationalVerificationForm, updateVerificationFormFailure, updateVerificationFormLocalData, } from '../internationalWireVerificationReducer';
6
- export const fetchIntlVerificationFormEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchInternationalVerificationForm.match), switchMap((action) => {
4
+ import { fetchInternationalVerificationForm, initializeIntlVerificationForm, updateInternationalVerificationForm, updateVerificationFormFailure, } from '../internationalWireVerificationReducer';
5
+ export const fetchIntlVerificationFormEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchInternationalVerificationForm.match), switchMap((action) => {
7
6
  const query = {
8
7
  region: 'US',
9
8
  legal_type: 'BUSINESS',
@@ -12,14 +11,11 @@ export const fetchIntlVerificationFormEpic = (actions$, state$, zeniAPI) => acti
12
11
  .getJSON(`${zeniAPI.apiEndPoints.payMicroServiceBaseUrl}/1.0/international-wire/onboarding-fields?query=${encodeURIComponent(JSON.stringify(query))}`)
13
12
  .pipe(mergeMap((response) => {
14
13
  if (isSuccessResponse(response) && response.data != null) {
15
- const onboardingDataFromCompanyInfo = state$.value.companyState.companiesById[action.payload.companyId]
16
- ?.companyBillPayInfo?.internationalWireOnboardingDetails;
17
- const localData = toVerificationFormLocalDataFromOnboardingDetails(onboardingDataFromCompanyInfo, response.data.labels);
18
14
  return from([
19
15
  updateInternationalVerificationForm({
20
16
  internationalWireFormPayload: response.data.labels,
21
17
  }),
22
- updateVerificationFormLocalData(localData),
18
+ initializeIntlVerificationForm(action.payload.companyId, response.data.labels),
23
19
  ]);
24
20
  }
25
21
  else {
@@ -1,61 +1,39 @@
1
- import { EMPTY, from } from 'rxjs';
1
+ import { from } from 'rxjs';
2
2
  import { filter, mergeMap } from 'rxjs/operators';
3
- import { getCurrentTenant } from '../../../../../entity/tenant/tenantSelector';
4
- import { fetchBillPaySetupViewSuccess } from '../../billPaySetupView/billPaySetupViewReducer';
5
- import { InternationalWireVerificationBooleanWithSubfieldsFieldNames } from '../internationalWireVerificationFieldConstants';
6
- import { toVerificationFormLocalDataFromOnboardingDetails } from '../internationalWireOnboardingDetailsToLocalData';
7
3
  import { initializeIntlVerificationForm, updateVerificationFormLocalData, } from '../internationalWireVerificationReducer';
8
- const hasSavedPersonSubfieldData = (localData) =>
9
- // Person subfield keys follow `<field_name>_<index?>_<subfield>`
10
- // e.g. `stake_holder_0_email`, `controlling_person_email`.
11
- Object.keys(localData).some((key) => new RegExp(`^${InternationalWireVerificationBooleanWithSubfieldsFieldNames.stakeHolder}_\\d+_`).test(key) ||
12
- key.startsWith(`${InternationalWireVerificationBooleanWithSubfieldsFieldNames.controllingPerson}_`));
13
- const getPersonScopedLocalData = (localData) => Object.fromEntries(Object.entries(localData).filter(([key]) => {
14
- if (key === InternationalWireVerificationBooleanWithSubfieldsFieldNames.stakeHolder ||
15
- key ===
16
- InternationalWireVerificationBooleanWithSubfieldsFieldNames.controllingPerson) {
17
- return true;
18
- }
19
- return (key.startsWith(`${InternationalWireVerificationBooleanWithSubfieldsFieldNames.stakeHolder}_`) ||
20
- key.startsWith(`${InternationalWireVerificationBooleanWithSubfieldsFieldNames.controllingPerson}_`));
21
- }));
22
- export const initializeIntlVerificationFormEpic = (actions$, state$) => actions$.pipe(filter((action) => initializeIntlVerificationForm.match(action) ||
23
- fetchBillPaySetupViewSuccess.match(action)), mergeMap((action) => {
4
+ export const initializeIntlVerificationFormEpic = (actions$, state$) => actions$.pipe(filter(initializeIntlVerificationForm.match), mergeMap((action) => {
5
+ const { companyId, internationalWireFormPayload } = action.payload;
6
+ const actions = [];
24
7
  const state = state$.value;
25
- const formFieldLabelsFromState = state.internationalWireVerificationState.verificationFormFieldLabels;
26
- const formFieldLabels = initializeIntlVerificationForm.match(action) &&
27
- Object.keys(formFieldLabelsFromState).length === 0
28
- ? action.payload.internationalWireFormPayload
29
- : formFieldLabelsFromState;
30
- if (Object.keys(formFieldLabels).length === 0) {
31
- return EMPTY;
32
- }
33
- const companyId = initializeIntlVerificationForm.match(action) ?
34
- action.payload.companyId
35
- : getCurrentTenant(state)?.companyId;
36
- if (companyId == null) {
37
- return EMPTY;
38
- }
39
- const onboardingDataFromCompanyInfo = state.companyState.companiesById[companyId]?.companyBillPayInfo
40
- ?.internationalWireOnboardingDetails;
41
- const localDataFromCompany = toVerificationFormLocalDataFromOnboardingDetails(onboardingDataFromCompanyInfo, formFieldLabels);
42
- const existingLocalData = state.internationalWireVerificationState.verificationFormLocalData;
43
- if (fetchBillPaySetupViewSuccess.match(action)) {
44
- if (!hasSavedPersonSubfieldData(localDataFromCompany) ||
45
- hasSavedPersonSubfieldData(existingLocalData)) {
46
- return EMPTY;
8
+ const onboardingDataFromCompanyInfo = state.companyState.companiesById[companyId].companyBillPayInfo
9
+ .internationalWireOnboardingDetails;
10
+ const localData = {};
11
+ Object.keys(internationalWireFormPayload).forEach((formFieldKey) => {
12
+ const values = onboardingDataFromCompanyInfo != null
13
+ ? onboardingDataFromCompanyInfo[formFieldKey]?.values
14
+ : undefined;
15
+ if (values != null) {
16
+ localData[formFieldKey] =
17
+ internationalWireFormPayload[formFieldKey].type === 'enum'
18
+ ? internationalWireFormPayload[formFieldKey]
19
+ .is_multiple_values_allowed === false
20
+ ? typeof values[0] === 'object' && 'code' in values[0]
21
+ ? values[0].code
22
+ : ''
23
+ : values.map((value) => typeof value === 'object' && 'code' in value
24
+ ? value.code
25
+ : '')
26
+ : values[0];
27
+ }
28
+ else {
29
+ localData[formFieldKey] =
30
+ internationalWireFormPayload[formFieldKey].type === 'enum' &&
31
+ internationalWireFormPayload[formFieldKey]
32
+ .is_multiple_values_allowed === true
33
+ ? []
34
+ : '';
47
35
  }
48
- return from([
49
- updateVerificationFormLocalData({
50
- ...existingLocalData,
51
- ...getPersonScopedLocalData(localDataFromCompany),
52
- }),
53
- ]);
54
- }
55
- return from([
56
- updateVerificationFormLocalData({
57
- ...existingLocalData,
58
- ...localDataFromCompany,
59
- }),
60
- ]);
36
+ });
37
+ actions.push(updateVerificationFormLocalData(localData));
38
+ return from(actions);
61
39
  }));
@@ -3,7 +3,6 @@ import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { updateInternationalWireOnboardingStatus } from '../../../../../entity/company/companyReducer';
4
4
  import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
5
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
6
- import { toIntlWireVerificationSubmitPayload } from '../internationalWireVerificationSubmitPayload';
7
6
  import { submitInternationalVerificationForm, updateVerificationFormSubmissionStatus, } from '../internationalWireVerificationReducer';
8
7
  export const submitIntlVerificationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(submitInternationalVerificationForm.match), switchMap((action) => {
9
8
  const { internationalWireVerificationState } = state$.value;
@@ -11,7 +10,7 @@ export const submitIntlVerificationEpic = (actions$, state$, zeniAPI) => actions
11
10
  const localData = internationalWireVerificationState.verificationFormLocalData;
12
11
  if (localData != null) {
13
12
  return zeniAPI
14
- .postAndGetJSON(`${zeniAPI.apiEndPoints.payMicroServiceBaseUrl}/1.0/international-wire/onboarding`, toIntlWireVerificationSubmitPayload(localData))
13
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.payMicroServiceBaseUrl}/1.0/international-wire/onboarding`, toIntlWireVerificationPayload(localData))
15
14
  .pipe(mergeMap((response) => {
16
15
  const actions = [];
17
16
  if (isSuccessResponse(response) && response.data != null) {
@@ -55,3 +54,9 @@ export const submitIntlVerificationEpic = (actions$, state$, zeniAPI) => actions
55
54
  return from([]);
56
55
  }
57
56
  }));
57
+ const toIntlWireVerificationPayload = (localData) => {
58
+ return {
59
+ is_applicant_declaration: true,
60
+ form_details: localData,
61
+ };
62
+ };
@@ -1,62 +1,15 @@
1
- import { InternationalWireVerificationReadonlyHideableFieldNames, InternationalWireVerificationFormFieldNames, } from './internationalWireVerificationFieldConstants';
2
- import { hasBusinessOwnershipValueInLocalData } from './internationalWireVerificationLocalDataHelpers';
3
- export const InternationalWireVerificationFormOrder = [
4
- InternationalWireVerificationFormFieldNames.certificateOfGoodStanding,
5
- InternationalWireVerificationFormFieldNames.businessOwnership,
6
- InternationalWireVerificationFormFieldNames.companyProofOfAddress,
7
- InternationalWireVerificationFormFieldNames.companyOfficerProofOfAddress,
8
- InternationalWireVerificationFormFieldNames.companyRegistrationDate,
9
- InternationalWireVerificationFormFieldNames.annualTurnover,
10
- InternationalWireVerificationFormFieldNames.expectedTransactionVolume,
11
- InternationalWireVerificationFormFieldNames.employeeCount,
12
- InternationalWireVerificationFormFieldNames.intendedUseOfAccount,
13
- InternationalWireVerificationFormFieldNames.transactionCountries,
14
- InternationalWireVerificationFormFieldNames.stakeHolder,
15
- InternationalWireVerificationFormFieldNames.controllingPerson,
16
- ];
17
- const orderIndex = new Map(InternationalWireVerificationFormOrder.map((name, index) => [name, index]));
18
- const toFieldValues = (fieldValues) => fieldValues?.map(({ code, description }) => ({ code, description })) ?? [];
19
- const toSubField = (subfield) => ({
20
- label: subfield.label,
21
- placeholder: subfield.field_hint_text ?? '',
22
- type: subfield.type,
23
- fieldValues: toFieldValues(subfield.field_values),
24
- isMultipleOptionsSupported: subfield.is_multiple_options_supported,
25
- options: subfield.options,
26
- });
27
1
  export const toDynamicFormField = (key, payload) => ({
28
2
  name: key,
29
3
  label: payload.label,
30
4
  placeholder: payload.field_hint_text ?? '',
31
5
  isMultipleValuesAllowed: payload.is_multiple_values_allowed ?? false,
32
6
  type: payload.type,
33
- fieldValues: toFieldValues(payload.field_values),
34
- isMultipleOptionsSupported: payload.is_multiple_options_supported,
35
- options: payload.options,
36
- requirements: payload.requirements,
37
- default: payload.default,
38
- subfields: payload.subfields != null
39
- ? Object.fromEntries(Object.entries(payload.subfields).map(([subfieldKey, subfield]) => [
40
- subfieldKey,
41
- toSubField(subfield),
42
- ]))
43
- : undefined,
7
+ fieldValues: payload.field_values != null && payload.field_values.length > 0
8
+ ? payload.field_values.map((fieldValue) => {
9
+ return {
10
+ code: fieldValue.code,
11
+ description: fieldValue.description,
12
+ };
13
+ })
14
+ : [],
44
15
  });
45
- const readonlyHideableVerificationFormFieldNames = new Set(InternationalWireVerificationReadonlyHideableFieldNames);
46
- export const filterVerificationFormFieldsForReadonlyView = (fields, localData, isReadonly) => {
47
- if (!isReadonly || hasBusinessOwnershipValueInLocalData(localData)) {
48
- return fields;
49
- }
50
- return fields.filter((field) => !readonlyHideableVerificationFormFieldNames.has(field.name));
51
- };
52
- export const sortVerificationFormFields = (fields) => {
53
- return fields.slice().sort((a, b) => {
54
- const aIndex = orderIndex.get(a.name) ?? InternationalWireVerificationFormOrder.length;
55
- const bIndex = orderIndex.get(b.name) ?? InternationalWireVerificationFormOrder.length;
56
- if (aIndex !== bIndex) {
57
- return aIndex - bIndex;
58
- }
59
- return a.name.localeCompare(b.name);
60
- });
61
- };
62
- export const toVerificationFormFields = (internationalWireFormPayload) => sortVerificationFormFields(Object.keys(internationalWireFormPayload).map((key) => toDynamicFormField(key, internationalWireFormPayload[key])));
@@ -1,11 +1,9 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
- import { toVerificationFormFields, } from './internationalWireVerificationPayload';
3
- import { InternationalWireVerificationBooleanWithSubfieldsFieldNames } from './internationalWireVerificationFieldConstants';
2
+ import { toDynamicFormField, } from './internationalWireVerificationPayload';
4
3
  export const initialState = {
5
4
  verificationFormFetchState: {
6
5
  fetchState: 'Not-Started',
7
6
  },
8
- verificationFormFieldLabels: {},
9
7
  verificationFormFields: [],
10
8
  verificationFormLocalData: {},
11
9
  verificationFormSubmitState: {
@@ -33,8 +31,11 @@ const internationalWireVerification = createSlice({
33
31
  },
34
32
  updateInternationalVerificationForm(draft, action) {
35
33
  const { internationalWireFormPayload } = action.payload;
36
- draft.verificationFormFieldLabels = internationalWireFormPayload;
37
- draft.verificationFormFields = toVerificationFormFields(internationalWireFormPayload);
34
+ const verificationFormFields = [];
35
+ Object.keys(internationalWireFormPayload).forEach((key) => {
36
+ verificationFormFields.push(toDynamicFormField(key, internationalWireFormPayload[key]));
37
+ });
38
+ draft.verificationFormFields = verificationFormFields;
38
39
  draft.verificationFormFetchState.fetchState = 'Completed';
39
40
  },
40
41
  updateVerificationFormFailure(draft, action) {
@@ -43,26 +44,9 @@ const internationalWireVerification = createSlice({
43
44
  draft.verificationFormFetchState.error = error;
44
45
  },
45
46
  updateVerificationFormLocalData(draft, action) {
46
- const mergedLocalData = {
47
- ...draft.verificationFormLocalData,
47
+ draft.verificationFormLocalData = {
48
48
  ...action.payload,
49
49
  };
50
- if (action.payload[InternationalWireVerificationBooleanWithSubfieldsFieldNames.stakeHolder] === 'false') {
51
- Object.keys(mergedLocalData).forEach((key) => {
52
- if (key.startsWith(`${InternationalWireVerificationBooleanWithSubfieldsFieldNames.stakeHolder}_`)) {
53
- delete mergedLocalData[key];
54
- }
55
- });
56
- }
57
- if (action.payload[InternationalWireVerificationBooleanWithSubfieldsFieldNames
58
- .controllingPerson] === 'true') {
59
- Object.keys(mergedLocalData).forEach((key) => {
60
- if (key.startsWith(`${InternationalWireVerificationBooleanWithSubfieldsFieldNames.controllingPerson}_`)) {
61
- delete mergedLocalData[key];
62
- }
63
- });
64
- }
65
- draft.verificationFormLocalData = mergedLocalData;
66
50
  },
67
51
  submitInternationalVerificationForm: {
68
52
  reducer(draft) {
@@ -1,50 +1,26 @@
1
- import { getCompanyByCompanyId } from '../../../../entity/company/companySelector';
2
1
  import { getFilesByFileIds } from '../../../../entity/file/fileSelector';
3
- import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
4
2
  import { getFileDeleteStatusById, getFileUpdateNameStatusById, } from '../../../fileView/fileViewSelector';
5
- import { filterVerificationFormFieldsForReadonlyView } from './internationalWireVerificationPayload';
6
- const collectFileIdsFromLocalData = (localData) => {
7
- const fileIds = new Set();
8
- Object.values(localData).forEach((value) => {
9
- if (typeof value === 'string' && value.startsWith('file_')) {
10
- fileIds.add(value);
11
- return;
12
- }
13
- if (Array.isArray(value)) {
14
- value.forEach((item) => {
15
- if (typeof item === 'string' && item.startsWith('file_')) {
16
- fileIds.add(item);
17
- }
18
- });
19
- }
20
- });
21
- return Array.from(fileIds);
22
- };
23
3
  export const getIntlWireVerificationView = (state) => {
24
4
  const deleteFileStatusById = {};
25
5
  const updateFileStatusById = {};
26
- const { verificationFormFetchState, verificationFormFields, verificationFormLocalData, verificationFormSubmitState, } = state.internationalWireVerificationState;
27
- const fileIds = collectFileIdsFromLocalData(verificationFormLocalData);
28
- fileIds.forEach((fileId) => {
6
+ // field with type = file
7
+ const fileField = state.internationalWireVerificationState.verificationFormFields.find((field) => field.type === 'file');
8
+ let fileId;
9
+ if (fileField != null) {
10
+ fileId = state.internationalWireVerificationState.verificationFormLocalData[fileField.name];
11
+ }
12
+ if (fileId != null) {
29
13
  deleteFileStatusById[fileId] = getFileDeleteStatusById(state, fileId);
30
14
  updateFileStatusById[fileId] = getFileUpdateNameStatusById(state, fileId);
31
- });
32
- const userFiles = fileIds.length > 0 ? getFilesByFileIds(state.fileState, fileIds) : [];
33
- const fetchState = verificationFormFetchState.fetchState;
34
- const currentTenant = getCurrentTenant(state);
35
- const company = currentTenant?.companyId != null
36
- ? getCompanyByCompanyId(state.companyState, currentTenant.companyId)
37
- ?.company
38
- : undefined;
39
- const onboardingStatusCode = company?.companyBillPayInfo?.internationalWireOnboardingStatus?.code;
40
- const isReadonly = onboardingStatusCode != null &&
41
- onboardingStatusCode !== 'onboarding_status_not_started';
42
- const visibleVerificationFormFields = filterVerificationFormFieldsForReadonlyView(verificationFormFields, verificationFormLocalData, isReadonly);
15
+ }
16
+ let userFiles = [];
17
+ if (fileId != null) {
18
+ userFiles = getFilesByFileIds(state.fileState, [fileId]);
19
+ }
20
+ const fetchState = state.internationalWireVerificationState.verificationFormFetchState
21
+ .fetchState;
43
22
  return {
44
- verificationFormFetchState,
45
- verificationFormFields: visibleVerificationFormFields,
46
- verificationFormLocalData,
47
- verificationFormSubmitState,
23
+ ...state.internationalWireVerificationState,
48
24
  deleteFileStatusById,
49
25
  updateFileStatusById,
50
26
  userFiles,