@zeniai/client-epic-state 5.1.57-betaDI0 → 5.1.57-betaRD1

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 (100) hide show
  1. package/lib/coreEpics.js +2 -3
  2. package/lib/entity/chargeCard/chargeCard.d.ts +1 -1
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +2 -0
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +2 -0
  5. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -0
  6. package/lib/entity/jeSchedules/jeSchedulesSelector.js +11 -1
  7. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +2 -0
  8. package/lib/entity/tenant/clearAllEpic.d.ts +1 -3
  9. package/lib/entity/tenant/clearAllEpic.js +0 -4
  10. package/lib/entity/transaction/scheduleTransactionHelper.d.ts +15 -0
  11. package/lib/entity/transaction/scheduleTransactionHelper.js +43 -0
  12. package/lib/epic.d.ts +5 -2
  13. package/lib/epic.js +5 -2
  14. package/lib/esm/coreEpics.js +2 -3
  15. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +2 -0
  16. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +11 -1
  17. package/lib/esm/entity/tenant/clearAllEpic.js +0 -4
  18. package/lib/esm/entity/transaction/scheduleTransactionHelper.js +39 -0
  19. package/lib/esm/epic.js +5 -2
  20. package/lib/esm/index.js +6 -9
  21. package/lib/esm/reducer.js +0 -6
  22. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +15 -2
  23. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +21 -0
  24. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +110 -0
  25. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +53 -0
  26. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +22 -0
  27. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +152 -0
  28. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +126 -6
  29. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  30. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +59 -0
  31. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +65 -11
  32. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +3 -6
  33. package/lib/esm/view/settingsView/epic/fetchNotificationSettingsEpic.js +2 -21
  34. package/lib/esm/view/settingsView/epic/saveNotificationSettingsEpic.js +1 -2
  35. package/lib/esm/view/settingsView/settingsViewHelpers.js +2 -3
  36. package/lib/index.d.ts +8 -12
  37. package/lib/index.js +56 -55
  38. package/lib/reducer.d.ts +0 -6
  39. package/lib/reducer.js +0 -6
  40. package/lib/view/common/recurringViewHelper.d.ts +2 -2
  41. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +14 -1
  42. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  43. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  44. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +45 -0
  45. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +114 -0
  46. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  47. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +57 -0
  48. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  49. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +26 -0
  50. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +43 -0
  51. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +158 -0
  52. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +1 -0
  53. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +36 -8
  54. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +128 -7
  55. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +23 -0
  56. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  57. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +29 -4
  58. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +3 -0
  59. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +63 -0
  60. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +65 -11
  61. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +53 -6
  62. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -8
  63. package/lib/view/settingsView/epic/fetchNotificationSettingsEpic.d.ts +1 -9
  64. package/lib/view/settingsView/epic/fetchNotificationSettingsEpic.js +2 -21
  65. package/lib/view/settingsView/epic/saveNotificationSettingsEpic.js +1 -2
  66. package/lib/view/settingsView/settingsViewHelpers.d.ts +1 -1
  67. package/lib/view/settingsView/settingsViewHelpers.js +2 -3
  68. package/lib/view/settingsView/settingsViewPayload.d.ts +0 -4
  69. package/lib/view/settingsView/settingsViewState.d.ts +1 -1
  70. package/package.json +1 -1
  71. package/lib/entity/notificationRegistry/notificationRegistryPayload.d.ts +0 -18
  72. package/lib/entity/notificationRegistry/notificationRegistryPayload.js +0 -28
  73. package/lib/entity/notificationRegistry/notificationRegistryReducer.d.ts +0 -6
  74. package/lib/entity/notificationRegistry/notificationRegistryReducer.js +0 -26
  75. package/lib/entity/notificationRegistry/notificationRegistrySelector.d.ts +0 -2
  76. package/lib/entity/notificationRegistry/notificationRegistrySelector.js +0 -10
  77. package/lib/entity/notificationRegistry/notificationRegistryState.d.ts +0 -31
  78. package/lib/entity/notificationRegistry/notificationRegistryState.js +0 -10
  79. package/lib/esm/entity/notificationRegistry/notificationRegistryPayload.js +0 -24
  80. package/lib/esm/entity/notificationRegistry/notificationRegistryReducer.js +0 -22
  81. package/lib/esm/entity/notificationRegistry/notificationRegistrySelector.js +0 -6
  82. package/lib/esm/entity/notificationRegistry/notificationRegistryState.js +0 -5
  83. package/lib/esm/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +0 -103
  84. package/lib/esm/view/notificationPreferencesView/notificationPreferencesEndpoint.js +0 -5
  85. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewPayload.js +0 -36
  86. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewReducer.js +0 -222
  87. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewSelector.js +0 -25
  88. package/lib/esm/view/notificationPreferencesView/notificationPreferencesViewState.js +0 -4
  89. package/lib/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.d.ts +0 -34
  90. package/lib/view/notificationPreferencesView/epics/saveNotificationPreferencesEpic.js +0 -107
  91. package/lib/view/notificationPreferencesView/notificationPreferencesEndpoint.d.ts +0 -2
  92. package/lib/view/notificationPreferencesView/notificationPreferencesEndpoint.js +0 -9
  93. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.d.ts +0 -7
  94. package/lib/view/notificationPreferencesView/notificationPreferencesViewPayload.js +0 -41
  95. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.d.ts +0 -30
  96. package/lib/view/notificationPreferencesView/notificationPreferencesViewReducer.js +0 -226
  97. package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.d.ts +0 -7
  98. package/lib/view/notificationPreferencesView/notificationPreferencesViewSelector.js +0 -32
  99. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.d.ts +0 -14
  100. package/lib/view/notificationPreferencesView/notificationPreferencesViewState.js +0 -8
@@ -1,22 +1,29 @@
1
1
  import { NestedAccountHierarchyForReport } from '../../../commonStateTypes/accountView/nestedAccountID';
2
+ import { Amount } from '../../../commonStateTypes/amount';
2
3
  import { FetchStateAndError, FetchedState, ID } from '../../../commonStateTypes/common';
3
4
  import { Recommendation } from '../../../commonStateTypes/recommendationBase';
4
5
  import { SortOrder } from '../../../commonStateTypes/selectorTypes/sortOrderTypes';
5
- import { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
6
+ import { MonthYearPeriodId, ScheduleDaysOfMonth } from '../../../commonStateTypes/timePeriod';
6
7
  import { AccountBase } from '../../../entity/account/accountState';
7
- import { JEScheduleTransactionKey, ScheduleTypes } from '../../../entity/jeSchedules/jeSchedulesTypes';
8
+ import { JEScheduleTransactionKey, ScheduleJournalEntryStatusCodeType, ScheduleTypes } from '../../../entity/jeSchedules/jeSchedulesTypes';
9
+ import { TransactionID } from '../../../entity/transaction/stateTypes/transaction';
8
10
  import { VendorBase } from '../../../entity/vendor/vendorState';
9
- export declare const toJEScheduleSortKey: (v: string) => "vendor" | "type" | "category" | "class" | "memo" | "transactionDate" | "totalAmount" | "runningBalance" | "depCategory" | "scheduleCategory" | "startMonth" | "amortizationPeriod" | "jePostingDate" | "remainingMonths";
11
+ import { ZeniDate } from '../../../zeniDayJS';
12
+ import { JETransactionLink } from '../../scheduleView/scheduleDetailView/scheduleDetailState';
13
+ export declare const toJEScheduleSortKey: (v: string) => "vendor" | "type" | "category" | "class" | "memo" | "transactionDate" | "totalAmount" | "runningBalance" | "jePostingDate" | "depCategory" | "scheduleCategory" | "startMonth" | "amortizationPeriod" | "remainingMonths";
10
14
  export type JEScheduleSortKey = ReturnType<typeof toJEScheduleSortKey>;
11
- export declare const toJEScheduleMainTab: (v: string) => "completed" | "pending_review" | "ongoing";
12
- export type JEScheduleMainTab = ReturnType<typeof toJEScheduleMainTab>;
15
+ export declare const toJEPageTab: (v: string) => "schedules" | "existing_schedules";
16
+ export type JEPageTab = ReturnType<typeof toJEPageTab>;
13
17
  export interface JESchedulesViewUIState {
18
+ createdGroupCollapsed: boolean;
19
+ pendingGroupCollapsed: boolean;
14
20
  scrollPosition: {
15
21
  scrollTop: number;
16
22
  scrollLeft?: number;
17
23
  } | undefined;
18
24
  searchString: string;
19
- selectedMainTab: JEScheduleMainTab;
25
+ selectedJETypeFilter: ScheduleTypes | null;
26
+ selectedPageTab: JEPageTab;
20
27
  sortKey: JEScheduleSortKey;
21
28
  sortOrder: SortOrder;
22
29
  totalCount: number;
@@ -37,10 +44,50 @@ export interface JESchedulesViewState extends FetchedState {
37
44
  ignoreStatusById: Record<JEScheduleTransactionKey, FetchStateAndError>;
38
45
  jeScheduleLocalDataById: Record<ID, JEScheduleLocalData>;
39
46
  jeScheduleTransactionKeysByPeriod: Record<MonthYearPeriodId, JEScheduleTransactionKey[]>;
47
+ newSchedule: NewJeScheduleState;
40
48
  postStatusById: Record<ID, FetchStateAndError>;
41
49
  refreshStatus: FetchStateAndError;
42
50
  uiState: JESchedulesViewUIState;
43
51
  }
52
+ export interface NewJeDetailLocalData {
53
+ amount: Amount;
54
+ jeLink: JETransactionLink;
55
+ memo: string;
56
+ postingDate: ZeniDate;
57
+ postingStatus: ScheduleJournalEntryStatusCodeType;
58
+ runningBalance: Amount;
59
+ }
60
+ export interface NewScheduleLocalData {
61
+ jeScheduleDetails: NewJeDetailLocalData[];
62
+ scheduleType: ScheduleTypes;
63
+ lastDayOfMonth?: boolean;
64
+ selectedAccount?: ID;
65
+ selectedBaseTransactionId?: TransactionID;
66
+ selectedClass?: ID;
67
+ selectedDate?: ZeniDate;
68
+ selectedDayOfMonth?: ScheduleDaysOfMonth;
69
+ selectedJEScheduleKey?: JEScheduleTransactionKey;
70
+ selectedMonths?: number;
71
+ selectedVendor?: VendorBase;
72
+ }
73
+ export interface NewScheduleLocalDataFixedAssets extends NewScheduleLocalData {
74
+ assetId?: string;
75
+ selectedAccumulatedDepreciationCategory?: ID;
76
+ }
77
+ export interface SearchTransactionsState extends FetchStateAndError {
78
+ searchResults: ID[];
79
+ searchString?: string;
80
+ }
81
+ export declare const MIN_NEW_SCHEDULE_SEARCH_LENGTH = 2;
82
+ export interface NewJeScheduleState extends FetchStateAndError {
83
+ newScheduleState: {
84
+ fixed_assets: NewScheduleLocalDataFixedAssets;
85
+ prepaid_expenses: NewScheduleLocalData;
86
+ };
87
+ saveStatus: FetchStateAndError;
88
+ searchTransactions: SearchTransactionsState;
89
+ selectedDetailScheduleType?: ScheduleTypes;
90
+ }
44
91
  export interface AccountSettingsLocalData {
45
92
  previousAccruedExpensesAccount: AccountBase[];
46
93
  previousFixedAssetsAccount: AccountBase[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toJEScheduleMainTab = exports.toJEScheduleSortKey = void 0;
3
+ exports.MIN_NEW_SCHEDULE_SEARCH_LENGTH = exports.toJEPageTab = exports.toJEScheduleSortKey = void 0;
4
4
  const stringToUnion_1 = require("../../../commonStateTypes/stringToUnion");
5
5
  const JE_SCHEDULE_SORT_KEYS = [
6
6
  'vendor',
@@ -20,10 +20,7 @@ const JE_SCHEDULE_SORT_KEYS = [
20
20
  ];
21
21
  const toJEScheduleSortKey = (v) => (0, stringToUnion_1.stringToUnion)(v, JE_SCHEDULE_SORT_KEYS);
22
22
  exports.toJEScheduleSortKey = toJEScheduleSortKey;
23
- const JE_SCHEDULE_MAIN_TABS = [
24
- 'pending_review',
25
- 'ongoing',
26
- 'completed',
27
- ];
28
- const toJEScheduleMainTab = (v) => (0, stringToUnion_1.stringToUnion)(v, JE_SCHEDULE_MAIN_TABS);
29
- exports.toJEScheduleMainTab = toJEScheduleMainTab;
23
+ const JE_PAGE_TABS = ['schedules', 'existing_schedules'];
24
+ const toJEPageTab = (v) => (0, stringToUnion_1.stringToUnion)(v, JE_PAGE_TABS);
25
+ exports.toJEPageTab = toJEPageTab;
26
+ exports.MIN_NEW_SCHEDULE_SEARCH_LENGTH = 2;
@@ -1,10 +1,8 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
- import { updateNotificationRegistry } from '../../../entity/notificationRegistry/notificationRegistryReducer';
3
2
  import { RootState } from '../../../reducer';
4
3
  import { ZeniAPI } from '../../../zeniAPI';
5
- import { fetchNotificationPreferencesSuccess } from '../../notificationPreferencesView/notificationPreferencesViewReducer';
6
4
  import { fetchNotificationSettings, updateNotificationSettingsOnFailure, updateNotificationSettingsOnSuccess } from '../settingsViewReducer';
7
- export type ActionType = ReturnType<typeof fetchNotificationSettings> | ReturnType<typeof updateNotificationSettingsOnSuccess> | ReturnType<typeof updateNotificationSettingsOnFailure> | ReturnType<typeof updateNotificationRegistry> | ReturnType<typeof fetchNotificationPreferencesSuccess>;
5
+ export type ActionType = ReturnType<typeof fetchNotificationSettings> | ReturnType<typeof updateNotificationSettingsOnSuccess> | ReturnType<typeof updateNotificationSettingsOnFailure>;
8
6
  export declare const fetchNotificationSettingsEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
9
7
  payload: undefined;
10
8
  type: "settings/fetchNotificationSettings";
@@ -17,10 +15,4 @@ export declare const fetchNotificationSettingsEpic: (actions$: ActionsObservable
17
15
  } | {
18
16
  payload: import("../../../responsePayload").ZeniAPIStatus<Record<string, unknown>>;
19
17
  type: "settings/updateNotificationSettingsOnFailure";
20
- } | {
21
- payload: import("../../../entity/notificationRegistry/notificationRegistryPayload").NotificationRegistryPayload;
22
- type: "notificationRegistry/updateNotificationRegistry";
23
- } | {
24
- payload: import("../../notificationPreferencesView/notificationPreferencesViewReducer").FetchNotificationPreferencesSuccessPayload;
25
- type: "notificationPreferencesView/fetchNotificationPreferencesSuccess";
26
18
  }>;
@@ -3,39 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchNotificationSettingsEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
- const notificationRegistryReducer_1 = require("../../../entity/notificationRegistry/notificationRegistryReducer");
7
6
  const responsePayload_1 = require("../../../responsePayload");
8
- const notificationPreferencesEndpoint_1 = require("../../notificationPreferencesView/notificationPreferencesEndpoint");
9
- const notificationPreferencesViewReducer_1 = require("../../notificationPreferencesView/notificationPreferencesViewReducer");
10
7
  const settingsViewReducer_1 = require("../settingsViewReducer");
11
8
  const fetchNotificationSettingsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(settingsViewReducer_1.fetchNotificationSettings.match), (0, operators_1.switchMap)(() => {
12
9
  const state = state$.value;
10
+ const URL = `${zeniAPI.apiEndPoints.notificationMicroServiceBaseUrl}/1.0/notification-preferences`;
13
11
  const userEmail = state.tenantState.loggedInUser?.userEmail;
14
12
  if (userEmail == null) {
15
13
  return (0, rxjs_1.from)([]);
16
14
  }
17
- // Snapshot the save epoch at GET-dispatch time. The reducer compares
18
- // the captured value against the current `saveEpoch` on response and
19
- // skips the `preferences` replace when a save has landed in the
20
- // meantime — the GET is carrying the pre-PUT snapshot and would
21
- // otherwise clobber the fresh save. Cursor Bugbot 3632510237.
22
- const saveEpochAtDispatch = state.notificationPreferencesViewState.saveEpoch;
23
- return zeniAPI
24
- .getJSON((0, notificationPreferencesEndpoint_1.notificationPreferencesUrl)(zeniAPI))
25
- .pipe((0, operators_1.mergeMap)((response) => {
15
+ return zeniAPI.getJSON(URL).pipe((0, operators_1.mergeMap)((response) => {
26
16
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
27
17
  const updateActions = [
28
18
  (0, settingsViewReducer_1.updateNotificationSettingsOnSuccess)(response.data, userEmail),
29
19
  ];
30
- if (response.data.task_checklist_registry != null) {
31
- updateActions.push((0, notificationRegistryReducer_1.updateNotificationRegistry)(response.data.task_checklist_registry));
32
- }
33
- if (response.data.task_checklist_preferences != null) {
34
- updateActions.push((0, notificationPreferencesViewReducer_1.fetchNotificationPreferencesSuccess)({
35
- preferences: response.data.task_checklist_preferences,
36
- saveEpochAtDispatch,
37
- }));
38
- }
39
20
  return (0, rxjs_1.of)(...updateActions);
40
21
  }
41
22
  else {
@@ -5,10 +5,9 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
7
7
  const responsePayload_1 = require("../../../responsePayload");
8
- const notificationPreferencesEndpoint_1 = require("../../notificationPreferencesView/notificationPreferencesEndpoint");
9
8
  const settingsViewReducer_1 = require("../settingsViewReducer");
10
9
  const saveNotificationSettingsEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(settingsViewReducer_1.saveNotificationSettings.match), (0, operators_1.switchMap)(() => {
11
- const URL = (0, notificationPreferencesEndpoint_1.notificationPreferencesUrl)(zeniAPI);
10
+ const URL = `${zeniAPI.apiEndPoints.notificationMicroServiceBaseUrl}/1.0/notification-preferences`;
12
11
  const { notificationSettings, notificationSettingsLocalData } = state$.value.settingsViewState.notification;
13
12
  const payload = toSaveNotificationSettingsPayload(notificationSettingsLocalData, notificationSettings);
14
13
  return zeniAPI
@@ -14,4 +14,4 @@ export declare const isMyBankConnectionsTabVisible: (currentTenant: CurrentTenan
14
14
  export declare const isPerformanceTabVisible: (userRole: UserRoleType[], loggedInUser?: LoggedInUser) => boolean;
15
15
  export declare const isRemindersSectionVisibleOnSettingsPage: (reminderNotificationSettings: ReminderNotificationSettingsData) => boolean;
16
16
  export declare const isMonthEndNotificationsSectionVisibleOnSettingsPage: (monthEndInsightsNotificationSettings: MonthEndInsightsNotificationSettingsData, signedInUseEmail: string) => boolean;
17
- export declare const isNotificationsTabVisible: (notificationSettings: NotificationSettingsData, signedInUseEmail: string, isDebitCardFlagEnabled: boolean, currentTenant: CurrentTenant | undefined, hasTaskChecklistAccess: boolean) => boolean;
17
+ export declare const isNotificationsTabVisible: (notificationSettings: NotificationSettingsData, signedInUseEmail: string, isDebitCardFlagEnabled: boolean, currentTenant: CurrentTenant | undefined) => boolean;
@@ -160,14 +160,13 @@ const isMonthEndNotificationsSectionVisibleOnSettingsPage = (monthEndInsightsNot
160
160
  monthEndInsightsNotificationSettings.recipientEmailIds.includes(signedInUseEmail));
161
161
  };
162
162
  exports.isMonthEndNotificationsSectionVisibleOnSettingsPage = isMonthEndNotificationsSectionVisibleOnSettingsPage;
163
- const isNotificationsTabVisible = (notificationSettings, signedInUseEmail, isDebitCardFlagEnabled, currentTenant, hasTaskChecklistAccess) => {
163
+ const isNotificationsTabVisible = (notificationSettings, signedInUseEmail, isDebitCardFlagEnabled, currentTenant) => {
164
164
  if (currentTenant == null) {
165
165
  return false;
166
166
  }
167
167
  const { reminderNotificationSettings, monthEndInsightsNotificationSettings } = notificationSettings;
168
168
  return (((0, exports.isRemindersSectionVisibleOnSettingsPage)(reminderNotificationSettings) ||
169
- (0, exports.isMonthEndNotificationsSectionVisibleOnSettingsPage)(monthEndInsightsNotificationSettings, signedInUseEmail) ||
170
- hasTaskChecklistAccess) &&
169
+ (0, exports.isMonthEndNotificationsSectionVisibleOnSettingsPage)(monthEndInsightsNotificationSettings, signedInUseEmail)) &&
171
170
  ((0, tenantSelector_1.isTenantAccountingServicesEnabled)(currentTenant) ||
172
171
  ((0, tenantSelector_1.isTenantBankingOnly)(isDebitCardFlagEnabled, currentTenant) === false &&
173
172
  (0, tenantSelector_1.isTenantCardsOnly)(currentTenant) === false)));
@@ -1,11 +1,9 @@
1
1
  import { AddressPayload } from '../../entity/address/addressPayload';
2
2
  import { CompanyPayload } from '../../entity/company/companyPayload';
3
- import { NotificationRegistryPayload } from '../../entity/notificationRegistry/notificationRegistryPayload';
4
3
  import { UserPayload } from '../../entity/user/userPayload';
5
4
  import { UserRolePayload } from '../../entity/userRole/userRolePayload';
6
5
  import { ZeniAPIResponse } from '../../responsePayload';
7
6
  import { AddressUpdatableInfoPayload } from '../addressView/addressViewPayload';
8
- import { NotificationPreferencesPayload } from '../notificationPreferencesView/notificationPreferencesViewPayload';
9
7
  interface MyProfilePeoplePayload {
10
8
  user_roles: UserRolePayload[];
11
9
  users: UserPayload[];
@@ -38,8 +36,6 @@ export interface NotificationSettingsPayload {
38
36
  pending_reimbursement_approval_notification: RemindersPayload | null;
39
37
  uncategorized_transaction_notification: RemindersPayload | null;
40
38
  month_end_email_recipient_email_ids?: string[];
41
- task_checklist_preferences?: NotificationPreferencesPayload;
42
- task_checklist_registry?: NotificationRegistryPayload;
43
39
  }
44
40
  export type NotificationSettingsResponse = ZeniAPIResponse<NotificationSettingsPayload>;
45
41
  interface RefreshQBOPayload {
@@ -12,7 +12,7 @@ export interface IntegrationsSettings {
12
12
  export declare const REMINDER_NOTIFICATION_TYPES: readonly ["missingReceiptNotification", "uncategorizedTransactionNotification", "pendingBillApprovalNotification", "pendingReimbursementApprovalNotification"];
13
13
  declare const toReminderTypeKey: (v: string) => "missingReceiptNotification" | "uncategorizedTransactionNotification" | "pendingBillApprovalNotification" | "pendingReimbursementApprovalNotification";
14
14
  export type ReminderTypeKey = ReturnType<typeof toReminderTypeKey>;
15
- export declare const toRemindersFrequencyType: (v: string) => "daily" | "weekly" | "monthly" | "bi-weekly";
15
+ export declare const toRemindersFrequencyType: (v: string) => "weekly" | "monthly" | "daily" | "bi-weekly";
16
16
  export type FrequencyTypeKey = ReturnType<typeof toRemindersFrequencyType>;
17
17
  export declare const NOTIFICATION_MODES: readonly ["email", "dashboard"];
18
18
  export declare const toNotificationMode: (v: string) => "dashboard" | "email";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.1.57-betaDI0",
3
+ "version": "5.1.57-betaRD1",
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",
@@ -1,18 +0,0 @@
1
- import { NotificationRegistry } from './notificationRegistryState';
2
- export interface NotificationEventPayload {
3
- channels: string[];
4
- default_enabled: Record<string, boolean>;
5
- display_name: string;
6
- event_id: string;
7
- suppressible: boolean;
8
- }
9
- export interface NotificationGroupPayload {
10
- display_name: string;
11
- events: NotificationEventPayload[];
12
- group_id: string;
13
- }
14
- export interface NotificationRegistryPayload {
15
- frequency_options: string[];
16
- groups: NotificationGroupPayload[];
17
- }
18
- export declare const mapNotificationRegistryPayloadToRegistry: (payload: NotificationRegistryPayload) => NotificationRegistry;
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapNotificationRegistryPayloadToRegistry = void 0;
4
- const notificationRegistryState_1 = require("./notificationRegistryState");
5
- const mapDefaultEnabled = (raw) => {
6
- const out = {};
7
- Object.entries(raw).forEach(([channel, enabled]) => {
8
- out[(0, notificationRegistryState_1.toNotificationChannel)(channel)] = enabled;
9
- });
10
- return out;
11
- };
12
- const mapEvent = (payload) => ({
13
- channels: payload.channels.map(notificationRegistryState_1.toNotificationChannel),
14
- defaultEnabled: mapDefaultEnabled(payload.default_enabled),
15
- displayName: payload.display_name,
16
- eventId: payload.event_id,
17
- suppressible: payload.suppressible,
18
- });
19
- const mapGroup = (payload) => ({
20
- displayName: payload.display_name,
21
- events: payload.events.map(mapEvent),
22
- groupId: payload.group_id,
23
- });
24
- const mapNotificationRegistryPayloadToRegistry = (payload) => ({
25
- frequencyOptions: payload.frequency_options.map(notificationRegistryState_1.toNotificationFrequency),
26
- groups: payload.groups.map(mapGroup),
27
- });
28
- exports.mapNotificationRegistryPayloadToRegistry = mapNotificationRegistryPayloadToRegistry;
@@ -1,6 +0,0 @@
1
- import { NotificationRegistryPayload } from './notificationRegistryPayload';
2
- import { NotificationRegistryState } from './notificationRegistryState';
3
- export declare const initialState: NotificationRegistryState;
4
- export declare const clearAllNotificationRegistry: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"notificationRegistry/clearAllNotificationRegistry">, updateNotificationRegistry: import("@reduxjs/toolkit").ActionCreatorWithPayload<NotificationRegistryPayload, "notificationRegistry/updateNotificationRegistry">;
5
- declare const _default: import("redux").Reducer<NotificationRegistryState>;
6
- export default _default;
@@ -1,26 +0,0 @@
1
- "use strict";
2
- var _a;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.updateNotificationRegistry = exports.clearAllNotificationRegistry = exports.initialState = void 0;
5
- const toolkit_1 = require("@reduxjs/toolkit");
6
- const notificationRegistryPayload_1 = require("./notificationRegistryPayload");
7
- exports.initialState = {};
8
- const notificationRegistry = (0, toolkit_1.createSlice)({
9
- name: 'notificationRegistry',
10
- initialState: exports.initialState,
11
- reducers: {
12
- clearAllNotificationRegistry() {
13
- return exports.initialState;
14
- },
15
- updateNotificationRegistry(draft, action) {
16
- // Full-replace contract: the registry payload is atomic — every fetch
17
- // returns the complete group/event tree. If the backend ever ships a
18
- // partial registry response, this write MUST switch to a merge (mirror
19
- // the preferences slice's `mergePreferences`). Do not assume the
20
- // current payload is partial without also updating this reducer.
21
- draft.registry = (0, notificationRegistryPayload_1.mapNotificationRegistryPayloadToRegistry)(action.payload);
22
- },
23
- },
24
- });
25
- _a = notificationRegistry.actions, exports.clearAllNotificationRegistry = _a.clearAllNotificationRegistry, exports.updateNotificationRegistry = _a.updateNotificationRegistry;
26
- exports.default = notificationRegistry.reducer;
@@ -1,2 +0,0 @@
1
- import { NotificationRegistry, NotificationRegistryState } from './notificationRegistryState';
2
- export declare const getNotificationRegistry: (slice: NotificationRegistryState) => NotificationRegistry | undefined;
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNotificationRegistry = void 0;
4
- // Current behavior: a null / undefined registry means the whole notification
5
- // section is hidden by consumers. This conflates two distinct states —
6
- // "user has no saved preferences yet" vs "the Task Checklist feature gate is
7
- // off for this tenant". Both currently surface as `undefined`. Distinguishing
8
- // them (e.g. an explicit `gate_off` signal from the server) is a follow-up.
9
- const getNotificationRegistry = (slice) => slice.registry;
10
- exports.getNotificationRegistry = getNotificationRegistry;
@@ -1,31 +0,0 @@
1
- export declare const NOTIFICATION_CHANNELS: readonly ["email", "slack", "in_app"];
2
- export type NotificationChannel = (typeof NOTIFICATION_CHANNELS)[number];
3
- export declare const toNotificationChannel: (raw: string) => NotificationChannel;
4
- export declare const NOTIFICATION_FREQUENCIES: readonly ["instant", "daily"];
5
- export type NotificationFrequency = (typeof NOTIFICATION_FREQUENCIES)[number];
6
- export declare const toNotificationFrequency: (raw: string) => NotificationFrequency;
7
- export interface RegistryNotificationEvent {
8
- channels: NotificationChannel[];
9
- defaultEnabled: Partial<Record<NotificationChannel, boolean>>;
10
- displayName: string;
11
- eventId: string;
12
- suppressible: boolean;
13
- }
14
- export interface RegistryNotificationGroup {
15
- displayName: string;
16
- events: RegistryNotificationEvent[];
17
- groupId: string;
18
- }
19
- export interface NotificationRegistry {
20
- frequencyOptions: NotificationFrequency[];
21
- groups: RegistryNotificationGroup[];
22
- }
23
- /**
24
- * The registry is a singleton (not per-tenant). We keep the wrapper so
25
- * Immer/RTK can safely represent "cleared" as `registry: undefined` — a bare
26
- * top-level `undefined` state is not observable by Immer, which prevents
27
- * `clearAllNotificationRegistry` from taking effect.
28
- */
29
- export interface NotificationRegistryState {
30
- registry?: NotificationRegistry;
31
- }
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toNotificationFrequency = exports.NOTIFICATION_FREQUENCIES = exports.toNotificationChannel = exports.NOTIFICATION_CHANNELS = void 0;
4
- const stringToUnion_1 = require("../../commonStateTypes/stringToUnion");
5
- exports.NOTIFICATION_CHANNELS = ['email', 'slack', 'in_app'];
6
- const toNotificationChannel = (raw) => (0, stringToUnion_1.stringToUnion)(raw, exports.NOTIFICATION_CHANNELS);
7
- exports.toNotificationChannel = toNotificationChannel;
8
- exports.NOTIFICATION_FREQUENCIES = ['instant', 'daily'];
9
- const toNotificationFrequency = (raw) => (0, stringToUnion_1.stringToUnion)(raw, exports.NOTIFICATION_FREQUENCIES);
10
- exports.toNotificationFrequency = toNotificationFrequency;
@@ -1,24 +0,0 @@
1
- import { toNotificationChannel, toNotificationFrequency, } from './notificationRegistryState';
2
- const mapDefaultEnabled = (raw) => {
3
- const out = {};
4
- Object.entries(raw).forEach(([channel, enabled]) => {
5
- out[toNotificationChannel(channel)] = enabled;
6
- });
7
- return out;
8
- };
9
- const mapEvent = (payload) => ({
10
- channels: payload.channels.map(toNotificationChannel),
11
- defaultEnabled: mapDefaultEnabled(payload.default_enabled),
12
- displayName: payload.display_name,
13
- eventId: payload.event_id,
14
- suppressible: payload.suppressible,
15
- });
16
- const mapGroup = (payload) => ({
17
- displayName: payload.display_name,
18
- events: payload.events.map(mapEvent),
19
- groupId: payload.group_id,
20
- });
21
- export const mapNotificationRegistryPayloadToRegistry = (payload) => ({
22
- frequencyOptions: payload.frequency_options.map(toNotificationFrequency),
23
- groups: payload.groups.map(mapGroup),
24
- });
@@ -1,22 +0,0 @@
1
- import { createSlice } from '@reduxjs/toolkit';
2
- import { mapNotificationRegistryPayloadToRegistry, } from './notificationRegistryPayload';
3
- export const initialState = {};
4
- const notificationRegistry = createSlice({
5
- name: 'notificationRegistry',
6
- initialState,
7
- reducers: {
8
- clearAllNotificationRegistry() {
9
- return initialState;
10
- },
11
- updateNotificationRegistry(draft, action) {
12
- // Full-replace contract: the registry payload is atomic — every fetch
13
- // returns the complete group/event tree. If the backend ever ships a
14
- // partial registry response, this write MUST switch to a merge (mirror
15
- // the preferences slice's `mergePreferences`). Do not assume the
16
- // current payload is partial without also updating this reducer.
17
- draft.registry = mapNotificationRegistryPayloadToRegistry(action.payload);
18
- },
19
- },
20
- });
21
- export const { clearAllNotificationRegistry, updateNotificationRegistry } = notificationRegistry.actions;
22
- export default notificationRegistry.reducer;
@@ -1,6 +0,0 @@
1
- // Current behavior: a null / undefined registry means the whole notification
2
- // section is hidden by consumers. This conflates two distinct states —
3
- // "user has no saved preferences yet" vs "the Task Checklist feature gate is
4
- // off for this tenant". Both currently surface as `undefined`. Distinguishing
5
- // them (e.g. an explicit `gate_off` signal from the server) is a follow-up.
6
- export const getNotificationRegistry = (slice) => slice.registry;
@@ -1,5 +0,0 @@
1
- import { stringToUnion } from '../../commonStateTypes/stringToUnion';
2
- export const NOTIFICATION_CHANNELS = ['email', 'slack', 'in_app'];
3
- export const toNotificationChannel = (raw) => stringToUnion(raw, NOTIFICATION_CHANNELS);
4
- export const NOTIFICATION_FREQUENCIES = ['instant', 'daily'];
5
- export const toNotificationFrequency = (raw) => stringToUnion(raw, NOTIFICATION_FREQUENCIES);
@@ -1,103 +0,0 @@
1
- import { EMPTY, concat, of } from 'rxjs';
2
- import { catchError, debounceTime, filter, finalize, mergeMap, switchMap, withLatestFrom, } from 'rxjs/operators';
3
- import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
4
- import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
5
- import { notificationPreferencesUrl } from '../notificationPreferencesEndpoint';
6
- import { mapPreferencesToPayload, } from '../notificationPreferencesViewPayload';
7
- import { saveNotificationPreferences, saveNotificationPreferencesFailure, saveNotificationPreferencesSuccess, setGroupFrequency, toggleEventChannel, } from '../notificationPreferencesViewReducer';
8
- import { getNotificationLocalOverrides } from '../notificationPreferencesViewSelector';
9
- const DEBOUNCE_MS = 300;
10
- export const saveNotificationPreferencesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => toggleEventChannel.match(action) || setGroupFrequency.match(action)),
11
- // Coalesce bursts of toggles into a single PUT. Trade-off: rapid clickers
12
- // defer saves until they pause. Consider a max-wait wrapper if this
13
- // becomes a UX problem.
14
- debounceTime(DEBOUNCE_MS), withLatestFrom(state$),
15
- // `switchMap` unsubscribes from any in-flight PUT observable when a new
16
- // debounced batch fires. The prior HTTP request has already left the
17
- // client — the network call is NOT cancelled — but its response is
18
- // ignored, so stale success/failure actions cannot clobber the newer
19
- // batch's state. Server-side ordering is arrival-order LWW.
20
- switchMap(([, state]) => {
21
- const overrides = getNotificationLocalOverrides(state);
22
- const preferencesPatch = mapPreferencesToPayload(overrides);
23
- if (Object.keys(preferencesPatch).length === 0) {
24
- // No diff → do not dispatch a synthetic success (that would wipe
25
- // stored preferences via the reducer). Simply no-op.
26
- return EMPTY;
27
- }
28
- // Snapshot the Cancel epoch at PUT-dispatch time. Every Cancel bumps
29
- // `cancelEpoch`; the reducer compares the captured value on Success/
30
- // Failure and skips the merge when the value has advanced (user
31
- // pressed Cancel since this save started). See Cursor Bugbot 4aa021f7
32
- // — the earlier counter model failed when `switchMap` abandoned an
33
- // in-flight save's response (Success/Failure never dispatched, so
34
- // the counter never drained and future saves got their merge dropped).
35
- const cancelEpochAtDispatch = state.notificationPreferencesViewState.cancelEpoch;
36
- const body = { task_checklist_preferences: preferencesPatch };
37
- // Suppress the error snackbar when the response lands AFTER the user
38
- // pressed Cancel — the Failure reducer already swallows the state
39
- // update, so the toast would be a stale error for a save the user
40
- // abandoned. `StateObservable#value` reads the current cancelEpoch at
41
- // response time (not at dispatch time — that's what
42
- // `cancelEpochAtDispatch` captures). Cursor Bugbot da2f4fe2 + Nikunj.
43
- const errorSnackbar = openSnackbar({
44
- messageSection: 'notification_settings_saved',
45
- messageText: 'failed',
46
- type: 'error',
47
- });
48
- const isCancelledSince = () => cancelEpochAtDispatch <
49
- state$.value.notificationPreferencesViewState.cancelEpoch;
50
- // Abort the in-flight HTTP request when `switchMap` disposes this
51
- // observable (new debounced batch fires, tenant switch, unmount).
52
- // Without an AbortSignal, `switchMap` would drop the response
53
- // client-side but the older PUT would still land on the server —
54
- // under patch-semantic LWW, a slower older PUT arriving after a
55
- // newer one silently reverts the user's latest choice on the
56
- // server. Cursor Bugbot e3861a76. `AbortController.abort()` is
57
- // idempotent so it's safe if the request already completed.
58
- const controller = new AbortController();
59
- const request$ = zeniAPI
60
- .putAndGetJSON(notificationPreferencesUrl(zeniAPI), body, undefined, controller.signal)
61
- .pipe(mergeMap((response) => {
62
- if (isSuccessResponse(response)) {
63
- return of(saveNotificationPreferencesSuccess({
64
- cancelEpochAtDispatch,
65
- savedOverrides: overrides,
66
- serverEcho: response.data?.task_checklist_preferences,
67
- }));
68
- }
69
- const actions = [
70
- saveNotificationPreferencesFailure({
71
- cancelEpochAtDispatch,
72
- error: response.status,
73
- }),
74
- ];
75
- if (!isCancelledSince()) {
76
- // Surface a user-visible error — without it the UI reverts to
77
- // server truth after debounce and the failed toggle looks like
78
- // a mystery UI bug.
79
- actions.push(errorSnackbar);
80
- }
81
- return of(...actions);
82
- }), catchError((error) => {
83
- const actions = [
84
- saveNotificationPreferencesFailure({
85
- cancelEpochAtDispatch,
86
- error: createZeniAPIStatus('Unexpected Error', 'Save notification preferences failed: ' +
87
- JSON.stringify(error)),
88
- }),
89
- ];
90
- if (!isCancelledSince()) {
91
- actions.push(errorSnackbar);
92
- }
93
- return of(...actions);
94
- }), finalize(() => {
95
- // switchMap disposal (new batch fires, cancel, unmount) → abort
96
- // the still-in-flight HTTP request. No-op if the request has
97
- // already completed successfully or errored.
98
- controller.abort();
99
- }));
100
- // Flip savePreferencesState to In-Progress BEFORE the network call so
101
- // any "saving…" UI can render.
102
- return concat(of(saveNotificationPreferences()), request$);
103
- }));
@@ -1,5 +0,0 @@
1
- // Shared endpoint used by both the GET (envelope refresh in
2
- // `fetchNotificationSettingsEpic`) and the PUT (patch in
3
- // `saveNotificationPreferencesEpic`). Kept as a helper so an endpoint rename
4
- // can't drift between the two callers.
5
- export const notificationPreferencesUrl = (zeniAPI) => `${zeniAPI.apiEndPoints.notificationMicroServiceBaseUrl}/1.0/notification-preferences`;
@@ -1,36 +0,0 @@
1
- import { toNotificationChannel, toNotificationFrequency, } from '../../entity/notificationRegistry/notificationRegistryState';
2
- const mapEventEnabledByChannel = (raw) => {
3
- if (raw == null) {
4
- return {};
5
- }
6
- const out = {};
7
- Object.entries(raw).forEach(([eventId, channelMap]) => {
8
- const mapped = {};
9
- Object.entries(channelMap).forEach(([channel, enabled]) => {
10
- mapped[toNotificationChannel(channel)] = enabled;
11
- });
12
- out[eventId] = mapped;
13
- });
14
- return out;
15
- };
16
- export const mapPayloadToPreferences = (payload) => {
17
- const groupFrequencyRaw = payload?.group_frequency_by_group_id ?? {};
18
- const groupFrequencyByGroupId = Object.fromEntries(Object.entries(groupFrequencyRaw).map(([groupId, frequency]) => [
19
- groupId,
20
- toNotificationFrequency(frequency),
21
- ]));
22
- return {
23
- eventEnabledByChannel: mapEventEnabledByChannel(payload?.event_enabled_by_channel),
24
- groupFrequencyByGroupId,
25
- };
26
- };
27
- export const mapPreferencesToPayload = (preferences) => {
28
- const payload = {};
29
- if (Object.keys(preferences.eventEnabledByChannel).length > 0) {
30
- payload.event_enabled_by_channel = preferences.eventEnabledByChannel;
31
- }
32
- if (Object.keys(preferences.groupFrequencyByGroupId).length > 0) {
33
- payload.group_frequency_by_group_id = preferences.groupFrequencyByGroupId;
34
- }
35
- return payload;
36
- };