@zeniai/client-epic-state 5.2.81 → 5.2.83-beta0UT
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.
- package/lib/esm/index.js +2 -0
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +5 -1
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +50 -0
- package/lib/esm/view/settingsView/epic/saveNotificationSettingsEpic.js +7 -0
- package/lib/esm/view/settingsView/settingsViewHelpers.js +1 -0
- package/lib/esm/view/settingsView/settingsViewReducer.js +5 -1
- package/lib/esm/view/settingsView/settingsViewState.js +1 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +2 -1
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +6 -4
- package/lib/esm/view/userGroupListView/userGroupListViewSelector.js +5 -0
- package/lib/esm/view/userListView/fetchUserListByTypeEpic.js +14 -5
- package/lib/esm/view/userListView/userListViewReducer.js +7 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +42 -39
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +5 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.d.ts +10 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +50 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState.d.ts +13 -0
- package/lib/view/settingsView/epic/saveNotificationSettingsEpic.js +7 -0
- package/lib/view/settingsView/settingsViewHelpers.js +1 -0
- package/lib/view/settingsView/settingsViewPayload.d.ts +2 -0
- package/lib/view/settingsView/settingsViewReducer.js +5 -1
- package/lib/view/settingsView/settingsViewState.d.ts +2 -2
- package/lib/view/settingsView/settingsViewState.js +1 -0
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +2 -1
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +6 -4
- package/lib/view/userGroupListView/userGroupListViewSelector.d.ts +2 -0
- package/lib/view/userGroupListView/userGroupListViewSelector.js +6 -1
- package/lib/view/userListView/fetchUserListByTypeEpic.d.ts +2 -2
- package/lib/view/userListView/fetchUserListByTypeEpic.js +13 -4
- package/lib/view/userListView/userListViewReducer.d.ts +3 -1
- package/lib/view/userListView/userListViewReducer.js +8 -2
- package/package.json +1 -1
package/lib/esm/index.js
CHANGED
|
@@ -446,6 +446,7 @@ import { resendOtp, sendOtp, verifyOtp, } from './view/twoFactorAuthentication/t
|
|
|
446
446
|
import { getTwoFactorAuthenticationView, getTwoFactorAuthenticationViewForCardUserOnboarding, getTwoFactorAuthenticationViewForChargeCardHolder, } from './view/twoFactorAuthentication/twoFactorAuthenticationSelector';
|
|
447
447
|
import { fetchUserFinancialAccount } from './view/userFinancialAccount/userFinancialAccountReducer';
|
|
448
448
|
import { getUserFinancialAccount, } from './view/userFinancialAccount/userFinancialAccountSelector';
|
|
449
|
+
import { getTaskManagerCandidateUserGroups } from './view/userGroupListView/userGroupListViewSelector';
|
|
449
450
|
import { fetchUserListByType } from './view/userListView/userListViewReducer';
|
|
450
451
|
import { getUserList, } from './view/userListView/userListViewSelector';
|
|
451
452
|
import { fetchUserRoleConfig } from './view/userRoleConfigView/userRoleConfigReducer';
|
|
@@ -533,6 +534,7 @@ export { fetchProfitAndLossClassesView, updateProfitAndLossClassesToFilterOut, r
|
|
|
533
534
|
export { fetchProfitAndLossForTimeframeProjectView, fetchProfitAndLossProjectView, resetProfitAndLossProjectNodeCollapseState, updateProjectViewAccountViewMode, updateProjectsToFilterOut, updateProfitAndLossProjectViewUIState, getProfitAndLossProjectView, };
|
|
534
535
|
export { getAccountingProviderAttachment };
|
|
535
536
|
export { fetchUserListByType, getUserList };
|
|
537
|
+
export { getTaskManagerCandidateUserGroups };
|
|
536
538
|
export { fetchAllPeopleRequiredViews, fetchPeoplePage, fetchPeople, deletePerson, resendInvite, changeZeniPersonRoles, invitePeople, inviteZeniPeople, updatePeopleUIState, peopleSaveUpdates, resetUpdateErrorMessage, peopleSaveDataInLocalStore, peopleClearDataInLocalStore, getPeople, getPeopleLocalData, initializeEditPerson, };
|
|
537
539
|
export { REMINDER_NOTIFICATION_TYPES, NOTIFICATION_MODES, clearSettingsView, fetchMyProfileView, fetchMyProfile, fetchBankConnectionsView, fetchBillingAccountsView, fetchCompanyBillingAddress, saveCompanyBillingAddress, fetchNotificationSettings, saveNotificationSettings, updateNotificationSettingsLocalData, fetchNotificationSettingsView, resetNotificationSettingsLocalData, resetNotificationSettingsUpdateStatus, refreshQBOData, updateSettingsViewUIState, isMonthEndNotificationsSectionVisibleOnSettingsPage, getNotificationSettingsView, getNotificationSettings, getBillingAccountsViewDetails, getMyProfileView, getMyBankConnectionsDetails, isAccountingTabVisible, isApprovalRulesTabVisible, isBankConnectionsTabVisible, isBillingTabVisible, isBusinessVerificationTabVisible, isCompanyDetailsTabVisible, isIntegrationsTabVisible, isSettingsVisible, isMyBankConnectionsTabVisible, isNotificationsTabVisible, isPerformanceTabVisible, isRemindersSectionVisibleOnSettingsPage, updateMyProfile, updateMyProfileLocalData, initializeMyProfileLocalData, };
|
|
538
540
|
export { fetchBalanceSheet, getBalanceSheet, getBalanceSheetFetchState, getBalanceSheetForFullDataAvailableRange, resetBalanceSheetNodeCollapseState, updateBalanceSheetUIState, typeOfBalanceSheetRootSection, isBalanceSheetReportViewSectionID, isBalanceSheetReportViewCalculatedSectionID, fetchBalanceSheetForTimeframe, };
|
package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isCustomerTransaction, } from '../../../entity/transaction/stateTypes/customerTransaction';
|
|
1
2
|
import { isVendorTransaction } from '../../../entity/transaction/stateTypes/vendorTransaction';
|
|
2
3
|
import { isEntityMatching, mergeTransactionAndEntityRecommendationsWithCOT, toLineEntity, } from '../../transactionDetail/transactionDetailLocalDataHelper';
|
|
3
4
|
import { isAccountUncategorized } from '../../transactionDetail/transactionDetailLocalDataHelper';
|
|
@@ -208,7 +209,10 @@ const buildLineItemById = (transaction, recommendations) => {
|
|
|
208
209
|
logo: accountLine.vendor.logo,
|
|
209
210
|
}
|
|
210
211
|
: undefined;
|
|
211
|
-
const customer = accountLine.customer
|
|
212
|
+
const customer = accountLine.customer ??
|
|
213
|
+
(isCustomerTransaction(transaction) === true
|
|
214
|
+
? transaction.customer
|
|
215
|
+
: undefined);
|
|
212
216
|
record.customer =
|
|
213
217
|
customer != null && Boolean(customer.id) && Boolean(customer.name)
|
|
214
218
|
? {
|
|
@@ -59,11 +59,59 @@ export const localDataToSaveInvoicingSubscriptionPayload = (localData, shippingA
|
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
61
|
const toEstimateDate = (value) => value != null && value !== '' ? date(value) : undefined;
|
|
62
|
+
const isItemLevelCoupon = (discount) => discount.entity_type === 'item_level_coupon';
|
|
63
|
+
const isCoupon = (discount) => discount.entity_type === 'document_level_coupon' ||
|
|
64
|
+
discount.entity_type === 'item_level_coupon';
|
|
65
|
+
/**
|
|
66
|
+
* Name the coupon behind a line's discount. Exact when the API links a coupon
|
|
67
|
+
* row to its line (`line_item_id`); otherwise only when a single item-level
|
|
68
|
+
* coupon applies, since then every discounted line got that one.
|
|
69
|
+
*/
|
|
70
|
+
const lineDiscountLabel = (lineItem, discounts) => {
|
|
71
|
+
if (lineItem.discount_amount <= 0) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const itemCoupons = discounts.filter(isItemLevelCoupon);
|
|
75
|
+
const linked = lineItem.id != null
|
|
76
|
+
? itemCoupons.filter((coupon) => coupon.line_item_id === lineItem.id)
|
|
77
|
+
: [];
|
|
78
|
+
if (linked.length > 0) {
|
|
79
|
+
return [...new Set(linked.map((coupon) => coupon.description))].join(', ');
|
|
80
|
+
}
|
|
81
|
+
const names = [...new Set(itemCoupons.map((coupon) => coupon.description))];
|
|
82
|
+
return names.length === 1 ? names[0] : undefined;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* One row per coupon. An item-level coupon comes back once per line it
|
|
86
|
+
* discounted, so its rows are summed; listing each would read as the same
|
|
87
|
+
* discount taken several times.
|
|
88
|
+
*/
|
|
89
|
+
const mergeCouponRows = (discounts) => {
|
|
90
|
+
const rowsByCoupon = new Map();
|
|
91
|
+
discounts.filter(isCoupon).forEach((coupon) => {
|
|
92
|
+
// The API sends `entity_id: ""` when it has none; key those by name so
|
|
93
|
+
// two unrelated coupons are not merged into one row.
|
|
94
|
+
const couponKey = coupon.entity_id != null && coupon.entity_id !== ''
|
|
95
|
+
? coupon.entity_id
|
|
96
|
+
: coupon.description;
|
|
97
|
+
const key = `${coupon.entity_type}:${couponKey}`;
|
|
98
|
+
const row = rowsByCoupon.get(key);
|
|
99
|
+
rowsByCoupon.set(key, {
|
|
100
|
+
amount: Math.round(((row?.amount ?? 0) + coupon.amount) * 100) / 100,
|
|
101
|
+
description: coupon.description,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
return [...rowsByCoupon.values()];
|
|
105
|
+
};
|
|
62
106
|
const mapInvoiceEstimate = (payload, money) => payload == null
|
|
63
107
|
? undefined
|
|
64
108
|
: {
|
|
65
109
|
amountDue: money(payload.amount_due),
|
|
66
110
|
couponDiscountTotal: money(payload.coupon_discount_total),
|
|
111
|
+
coupons: mergeCouponRows(payload.discounts ?? []).map((coupon) => ({
|
|
112
|
+
amount: money(coupon.amount),
|
|
113
|
+
description: coupon.description,
|
|
114
|
+
})),
|
|
67
115
|
creditsApplied: money(payload.credits_applied),
|
|
68
116
|
dueDate: toEstimateDate(payload.due_date),
|
|
69
117
|
grossSubTotal: money(payload.gross_sub_total),
|
|
@@ -74,6 +122,8 @@ const mapInvoiceEstimate = (payload, money) => payload == null
|
|
|
74
122
|
dateTo: toEstimateDate(lineItem.date_to),
|
|
75
123
|
description: lineItem.description,
|
|
76
124
|
discountAmount: money(lineItem.discount_amount),
|
|
125
|
+
discountLabel: lineDiscountLabel(lineItem, payload.discounts ?? []),
|
|
126
|
+
grossAmount: money(lineItem.gross_amount ?? lineItem.amount),
|
|
77
127
|
quantity: lineItem.quantity,
|
|
78
128
|
taxAmount: lineItem.tax_amount != null
|
|
79
129
|
? money(lineItem.tax_amount)
|
|
@@ -50,6 +50,8 @@ function toSaveNotificationSettingsPayload(localData, notificationSettingsData)
|
|
|
50
50
|
pending_bill_approval_notification: null,
|
|
51
51
|
pending_reimbursement_approval_notification: null,
|
|
52
52
|
is_pending_reimbursement_approval_notification_active: null,
|
|
53
|
+
is_pending_task_notification_active: null,
|
|
54
|
+
pending_task_notification: null,
|
|
53
55
|
is_month_end_insights_active: monthEndInsightsNotificationSettings.enabled != null
|
|
54
56
|
? monthEndInsights.notify
|
|
55
57
|
: null,
|
|
@@ -77,5 +79,10 @@ function toSaveNotificationSettingsPayload(localData, notificationSettingsData)
|
|
|
77
79
|
0;
|
|
78
80
|
payload.pending_reimbursement_approval_notification = toRemindersPayload(reminders.pendingReimbursementApprovalNotification);
|
|
79
81
|
}
|
|
82
|
+
if (reminderNotificationSettings.pendingTaskNotification != null) {
|
|
83
|
+
payload.is_pending_task_notification_active =
|
|
84
|
+
reminders.pendingTaskNotification.preferredMode.length > 0;
|
|
85
|
+
payload.pending_task_notification = toRemindersPayload(reminders.pendingTaskNotification);
|
|
86
|
+
}
|
|
80
87
|
return payload;
|
|
81
88
|
}
|
|
@@ -140,6 +140,7 @@ export const isRemindersSectionVisibleOnSettingsPage = (reminderNotificationSett
|
|
|
140
140
|
reminderNotificationSettings.pendingBillApprovalNotification != null ||
|
|
141
141
|
reminderNotificationSettings.pendingReimbursementApprovalNotification !=
|
|
142
142
|
null ||
|
|
143
|
+
reminderNotificationSettings.pendingTaskNotification != null ||
|
|
143
144
|
reminderNotificationSettings.uncategorizedTransactionNotification != null);
|
|
144
145
|
};
|
|
145
146
|
export const isMonthEndNotificationsSectionVisibleOnSettingsPage = (monthEndInsightsNotificationSettings, signedInUseEmail) => {
|
|
@@ -4,6 +4,7 @@ import { toNotificationMode, toRemindersFrequencyType, } from './settingsViewSta
|
|
|
4
4
|
const initialNotificationSettingsData = {
|
|
5
5
|
reminderNotificationSettings: {
|
|
6
6
|
missingReceiptNotification: null,
|
|
7
|
+
pendingTaskNotification: null,
|
|
7
8
|
uncategorizedTransactionNotification: null,
|
|
8
9
|
pendingBillApprovalNotification: null,
|
|
9
10
|
pendingReimbursementApprovalNotification: null,
|
|
@@ -44,6 +45,7 @@ const initialNotificationSettingsLocalData = {
|
|
|
44
45
|
missingReceiptNotification: initialRemindersLocalData,
|
|
45
46
|
pendingBillApprovalNotification: initialRemindersLocalData,
|
|
46
47
|
pendingReimbursementApprovalNotification: initialRemindersLocalData,
|
|
48
|
+
pendingTaskNotification: initialRemindersLocalData,
|
|
47
49
|
uncategorizedTransactionNotification: initialRemindersLocalData,
|
|
48
50
|
},
|
|
49
51
|
};
|
|
@@ -373,7 +375,7 @@ function toRemindersLocalData(reminderNotificationSettingDetails) {
|
|
|
373
375
|
}
|
|
374
376
|
const toNotificationSettingsLocalData = (data, loggedInUserEmail) => {
|
|
375
377
|
const { monthEndInsightsNotificationSettings, reminderNotificationSettings } = data;
|
|
376
|
-
const { missingReceiptNotification, pendingBillApprovalNotification, pendingReimbursementApprovalNotification, uncategorizedTransactionNotification, } = reminderNotificationSettings;
|
|
378
|
+
const { missingReceiptNotification, pendingBillApprovalNotification, pendingReimbursementApprovalNotification, pendingTaskNotification, uncategorizedTransactionNotification, } = reminderNotificationSettings;
|
|
377
379
|
return {
|
|
378
380
|
monthEndInsights: {
|
|
379
381
|
notify: monthEndInsightsNotificationSettings.enabled ??
|
|
@@ -384,6 +386,7 @@ const toNotificationSettingsLocalData = (data, loggedInUserEmail) => {
|
|
|
384
386
|
missingReceiptNotification: toRemindersLocalData(missingReceiptNotification),
|
|
385
387
|
pendingBillApprovalNotification: toRemindersLocalData(pendingBillApprovalNotification),
|
|
386
388
|
pendingReimbursementApprovalNotification: toRemindersLocalData(pendingReimbursementApprovalNotification),
|
|
389
|
+
pendingTaskNotification: toRemindersLocalData(pendingTaskNotification),
|
|
387
390
|
uncategorizedTransactionNotification: toRemindersLocalData(uncategorizedTransactionNotification),
|
|
388
391
|
},
|
|
389
392
|
};
|
|
@@ -408,6 +411,7 @@ const toNotificationSettings = (data) => {
|
|
|
408
411
|
missingReceiptNotification: toReminderNotificationSettingsDetails(data.is_missing_receipt_notification_active, data.missing_receipt_notification),
|
|
409
412
|
pendingBillApprovalNotification: toReminderNotificationSettingsDetails(data.is_pending_bill_approval_notification_active, data.pending_bill_approval_notification),
|
|
410
413
|
pendingReimbursementApprovalNotification: toReminderNotificationSettingsDetails(data.is_pending_reimbursement_approval_notification_active, data.pending_reimbursement_approval_notification),
|
|
414
|
+
pendingTaskNotification: toReminderNotificationSettingsDetails(data.is_pending_task_notification_active, data.pending_task_notification),
|
|
411
415
|
uncategorizedTransactionNotification: toReminderNotificationSettingsDetails(data.is_uncategorized_transaction_notification_active, data.uncategorized_transaction_notification),
|
|
412
416
|
},
|
|
413
417
|
monthEndInsightsNotificationSettings: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { stringToUnion } from '../../commonStateTypes/stringToUnion';
|
|
2
2
|
export const REMINDER_NOTIFICATION_TYPES = [
|
|
3
3
|
'missingReceiptNotification',
|
|
4
|
+
'pendingTaskNotification',
|
|
4
5
|
'uncategorizedTransactionNotification',
|
|
5
6
|
'pendingBillApprovalNotification',
|
|
6
7
|
'pendingReimbursementApprovalNotification',
|
|
@@ -6,6 +6,7 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
|
6
6
|
import { updateTasks } from '../../../../entity/task/taskReducer';
|
|
7
7
|
import { getTaskById } from '../../../../entity/task/taskSelector';
|
|
8
8
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
9
|
+
import { dateNow } from '../../../../zeniDayJS';
|
|
9
10
|
import { removeTaskFromGroupBucket, updateTaskListOnNewTaskCreationSuccess, } from '../../taskListView/taskListReducer';
|
|
10
11
|
import { saveTaskDetail, saveTaskSuccessOrFailure } from '../taskDetailReducer';
|
|
11
12
|
export const saveTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveTaskDetail.match), mergeMap((action) => {
|
|
@@ -150,7 +151,7 @@ const prepareTaskPayload = (state, taskId, taskGroupIds) => {
|
|
|
150
151
|
: null,
|
|
151
152
|
recurring_frequency: localData.type.code === 'recurring' ? localData.recurringFrequency : null,
|
|
152
153
|
recurring_start_date: localData.type.code === 'recurring'
|
|
153
|
-
? (localData.recurringStartDate
|
|
154
|
+
? (localData.recurringStartDate ?? dateNow()).format(DEFAULT_DATE_FORMAT)
|
|
154
155
|
: null,
|
|
155
156
|
recurring_days_of_week: localData.type.code === 'recurring' &&
|
|
156
157
|
localData.recurringFrequency === 'semi_weekly'
|
|
@@ -170,10 +170,12 @@ const showFormFooter = (taskDetailLocalData, taskDetailInStore) => {
|
|
|
170
170
|
!isEqual(taskDetailLocalData.fileIds, taskDetailInStore.fileIds ?? []) ||
|
|
171
171
|
!isEqual(taskDetailLocalData.dueDate, taskDetailInStore.dueDate) ||
|
|
172
172
|
!isEqual(taskDetailLocalData.type, taskDetailInStore.type) ||
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
// Only a recurring task saves these, so on any other type they are not an edit.
|
|
174
|
+
(taskDetailLocalData.type.code === 'recurring' &&
|
|
175
|
+
(!isEqual(taskDetailLocalData.savedRecurringEndDate, taskDetailInStore.recurringEndDate) ||
|
|
176
|
+
!isEqual(taskDetailLocalData.recurringFrequency, taskDetailInStore.recurringFrequency) ||
|
|
177
|
+
!isEqual(taskDetailLocalData.recurringDaysOfWeek, taskDetailInStore.recurringDaysOfWeek) ||
|
|
178
|
+
!isEqual(taskDetailLocalData.recurringStartDate, taskDetailInStore.recurringStartDate))) ||
|
|
177
179
|
!isEqual(taskDetailLocalData.timeSpent, taskDetailInStore.timeSpent) ||
|
|
178
180
|
!isEqual(taskDetailLocalData.taskGroupId, taskDetailInStore.taskGroupIds.length > 0
|
|
179
181
|
? taskDetailInStore.taskGroupIds[0]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
1
2
|
import { getUserGroupByUserGroupId } from '../../entity/userGroups/userGroupsSelector';
|
|
2
3
|
export const getUserGroupList = (userGroupsState, userGroupListViewState, userGroupType) => {
|
|
3
4
|
const listState = userGroupListViewState.userGroupListByType[userGroupType];
|
|
@@ -14,3 +15,7 @@ function getUserGroupListByIds(userGroupsState, userGroupListViewState, type) {
|
|
|
14
15
|
.map((id) => getUserGroupByUserGroupId(userGroupsState, id))
|
|
15
16
|
.filter((value) => value != null);
|
|
16
17
|
}
|
|
18
|
+
export const getTaskManagerCandidateUserGroups = createSelector([
|
|
19
|
+
(state) => state.userGroupsState,
|
|
20
|
+
(state) => state.userGroupListViewState,
|
|
21
|
+
], (userGroupsState, userGroupListViewState) => getUserGroupListByIds(userGroupsState, userGroupListViewState, 'taskManagerCandidate'));
|
|
@@ -8,7 +8,7 @@ import { updateUserRoles } from '../../entity/userRole/userRoleReducer';
|
|
|
8
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
9
9
|
import { updateChargeCardCount, updateDebitCardCount, } from '../spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer';
|
|
10
10
|
import { updateUserGroupIds } from '../userGroupListView/userGroupListViewReducer';
|
|
11
|
-
import { fetchUserListByType, updateUserIds, updateUserListFetchFailure, } from './userListViewReducer';
|
|
11
|
+
import { fetchUserListByType, resetUserListFetchState, updateUserIds, updateUserListFetchFailure, } from './userListViewReducer';
|
|
12
12
|
export const fetchUserListByTypeEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchUserListByType.match), mergeMap((action) => {
|
|
13
13
|
const { userType, cacheOverride } = action.payload;
|
|
14
14
|
const state = state$.value;
|
|
@@ -21,7 +21,14 @@ export const fetchUserListByTypeEpic = (actions$, state$, zeniAPI) => actions$.p
|
|
|
21
21
|
const queryParam = getQueryParam(userType, isZeniTenant);
|
|
22
22
|
apiUrl =
|
|
23
23
|
apiUrl + `?query=${encodeURIComponent(JSON.stringify(queryParam))}`;
|
|
24
|
+
// The tenant the request is sent for. A reply after a tenant switch must
|
|
25
|
+
// not land in the new tenant's state, so the fetch is reset instead.
|
|
26
|
+
const requestTenantId = zeniAPI.tenantId;
|
|
27
|
+
const isForPreviousTenant = () => requestTenantId != null && zeniAPI.tenantId !== requestTenantId;
|
|
24
28
|
return zeniAPI.getJSON(apiUrl).pipe(mergeMap((response) => {
|
|
29
|
+
if (isForPreviousTenant()) {
|
|
30
|
+
return of(resetUserListFetchState({ userType }));
|
|
31
|
+
}
|
|
25
32
|
if (isSuccessResponse(response)) {
|
|
26
33
|
const userListAction = [
|
|
27
34
|
updateAllUsers({ users: response.data?.users ?? [] }),
|
|
@@ -50,10 +57,12 @@ export const fetchUserListByTypeEpic = (actions$, state$, zeniAPI) => actions$.p
|
|
|
50
57
|
else {
|
|
51
58
|
return of(updateUserListFetchFailure({ userType, status: response.status }));
|
|
52
59
|
}
|
|
53
|
-
}), catchError((error) => of(
|
|
54
|
-
userType
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
}), catchError((error) => of(isForPreviousTenant()
|
|
61
|
+
? resetUserListFetchState({ userType })
|
|
62
|
+
: updateUserListFetchFailure({
|
|
63
|
+
userType,
|
|
64
|
+
status: createZeniAPIStatus('Unexpected error', 'User REST API call errored out' + JSON.stringify(error)),
|
|
65
|
+
}))));
|
|
57
66
|
}
|
|
58
67
|
else {
|
|
59
68
|
return from([]);
|
|
@@ -59,6 +59,12 @@ const userListView = createSlice({
|
|
|
59
59
|
draft.userListByType[userType].ids.splice(userIndex, 1);
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
|
+
resetUserListFetchState(draft, action) {
|
|
63
|
+
const list = draft.userListByType[action.payload.userType];
|
|
64
|
+
if (list.fetchState === 'In-Progress') {
|
|
65
|
+
list.fetchState = 'Not-Started';
|
|
66
|
+
}
|
|
67
|
+
},
|
|
62
68
|
updateUserListFetchFailure(draft, action) {
|
|
63
69
|
const { userType, status } = action.payload;
|
|
64
70
|
draft.userListByType[userType].fetchState = 'Error';
|
|
@@ -71,5 +77,5 @@ const userListView = createSlice({
|
|
|
71
77
|
});
|
|
72
78
|
},
|
|
73
79
|
});
|
|
74
|
-
export const { fetchUserListByType, updateUserIds, addUserId, removeUserId, updateUserListFetchFailure, } = userListView.actions;
|
|
80
|
+
export const { fetchUserListByType, updateUserIds, addUserId, removeUserId, updateUserListFetchFailure, resetUserListFetchState, } = userListView.actions;
|
|
75
81
|
export default userListView.reducer;
|
package/lib/index.d.ts
CHANGED
|
@@ -664,6 +664,7 @@ import { resendOtp, sendOtp, verifyOtp } from './view/twoFactorAuthentication/tw
|
|
|
664
664
|
import { TwoFactorAuthenticationView, getTwoFactorAuthenticationView, getTwoFactorAuthenticationViewForCardUserOnboarding, getTwoFactorAuthenticationViewForChargeCardHolder } from './view/twoFactorAuthentication/twoFactorAuthenticationSelector';
|
|
665
665
|
import { fetchUserFinancialAccount } from './view/userFinancialAccount/userFinancialAccountReducer';
|
|
666
666
|
import { UserFinancialAccountSelectorView, getUserFinancialAccount } from './view/userFinancialAccount/userFinancialAccountSelector';
|
|
667
|
+
import { getTaskManagerCandidateUserGroups } from './view/userGroupListView/userGroupListViewSelector';
|
|
667
668
|
import { fetchUserListByType } from './view/userListView/userListViewReducer';
|
|
668
669
|
import { UserListSelectorView, getUserList } from './view/userListView/userListViewSelector';
|
|
669
670
|
import { fetchUserRoleConfig } from './view/userRoleConfigView/userRoleConfigReducer';
|
|
@@ -785,6 +786,7 @@ export { fetchProfitAndLossClassesView, updateProfitAndLossClassesToFilterOut, r
|
|
|
785
786
|
export { fetchProfitAndLossForTimeframeProjectView, fetchProfitAndLossProjectView, resetProfitAndLossProjectNodeCollapseState, updateProjectViewAccountViewMode, updateProjectsToFilterOut, updateProfitAndLossProjectViewUIState, ProfitAndLossProjectViewUIState, getProfitAndLossProjectView, ProfitAndLossProjectViewReport, Project, ProjectBase, ProjectReportWithBalances, SectionProjectViewReport, };
|
|
786
787
|
export { AccountingProviderAttachmentSelector, getAccountingProviderAttachment };
|
|
787
788
|
export { fetchUserListByType, getUserList, UserListSelectorView };
|
|
789
|
+
export { getTaskManagerCandidateUserGroups };
|
|
788
790
|
export { fetchAllPeopleRequiredViews, fetchPeoplePage, fetchPeople, deletePerson, resendInvite, changeZeniPersonRoles, invitePeople, inviteZeniPeople, updatePeopleUIState, peopleSaveUpdates, resetUpdateErrorMessage, peopleSaveDataInLocalStore, peopleClearDataInLocalStore, PeopleSelectorView, PeopleLocalDataView, Person, getPeople, getPeopleLocalData, PeopleState, PersonUpdateType, PeoplePageMode, ZeniPersonUserRoleType, PeopleUIState, PeopleLocalData, initializeEditPerson, };
|
|
789
791
|
export { REMINDER_NOTIFICATION_TYPES, NOTIFICATION_MODES, clearSettingsView, fetchMyProfileView, fetchMyProfile, fetchBankConnectionsView, fetchBillingAccountsView, fetchCompanyBillingAddress, saveCompanyBillingAddress, fetchNotificationSettings, saveNotificationSettings, updateNotificationSettingsLocalData, fetchNotificationSettingsView, resetNotificationSettingsLocalData, resetNotificationSettingsUpdateStatus, refreshQBOData, updateSettingsViewUIState, isMonthEndNotificationsSectionVisibleOnSettingsPage, getNotificationSettingsView, getNotificationSettings, getBillingAccountsViewDetails, getMyProfileView, getMyBankConnectionsDetails, isAccountingTabVisible, isApprovalRulesTabVisible, isBankConnectionsTabVisible, isBillingTabVisible, isBusinessVerificationTabVisible, isCompanyDetailsTabVisible, isIntegrationsTabVisible, isSettingsVisible, isMyBankConnectionsTabVisible, isNotificationsTabVisible, isPerformanceTabVisible, isRemindersSectionVisibleOnSettingsPage, MyProfileSelectorView, MyBankConnectionsView, BillingView, MyProfile, SettingsViewState, SettingsViewUIState, NotificationSettings, NotificationSettingsLocalData, ReminderNotificationSettingsLocalData, NotificationSettingsSelectorView, ReminderNotificationSettingsData, MonthEndInsightsNotificationSettingsData, MonthEndInsightsNotificationSettingsLocalData, ReminderTypeKey, NotificationModeKey, FrequencyTypeKey, RemindersLocalData, IntegrationsSettings, ProductWisePrimaryAccount, OtherPaymentAccountWithSetup, updateMyProfile, updateMyProfileLocalData, MyProfileSettingsLocalData, initializeMyProfileLocalData, };
|
|
790
792
|
export { PeopleViewSortKey };
|
|
@@ -1128,7 +1130,7 @@ export { getInvoicingCustomerFormView } from './view/invoicing/editInvoicingCust
|
|
|
1128
1130
|
export type { InvoicingCustomerFormView } from './view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector';
|
|
1129
1131
|
export { clearInvoicingSubscriptionEstimate, fetchInvoicingSubscriptionEstimate, fetchInvoicingSubscriptionFormPage, initializeInvoicingSubscriptionAddress, resetEditInvoicingSubscriptionDetailView, submitInvoicingSubscriptionForm, updateInvoicingSubscriptionFormDraft, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer';
|
|
1130
1132
|
export type { SubmitInvoicingSubscriptionFormPayload, UpdateInvoicingSubscriptionFormDraftPayload, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer';
|
|
1131
|
-
export type { InvoicingSubscriptionEstimateLineItem, InvoicingSubscriptionFormLocalData, InvoicingSubscriptionInvoiceEstimate, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState';
|
|
1133
|
+
export type { InvoicingSubscriptionEstimateCoupon, InvoicingSubscriptionEstimateLineItem, InvoicingSubscriptionFormLocalData, InvoicingSubscriptionInvoiceEstimate, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState';
|
|
1132
1134
|
export { INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE, entityToInvoicingSubscriptionFormLocalData, initialInvoicingSubscriptionFormLocalData, invoicingSubscriptionTodayIso, toInvoicingSubscriptionQuantity, } from './view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig';
|
|
1133
1135
|
export { getEditInvoicingSubscriptionDetailViewState, getInvoicingSubscriptionFormView, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector';
|
|
1134
1136
|
export type { EditInvoicingSubscriptionDetailView, InvoicingSubscriptionEstimateKind, InvoicingSubscriptionEstimateView, InvoicingSubscriptionFormView, InvoicingSubscriptionOption, } from './view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector';
|