@zeniai/client-epic-state 5.1.69 → 5.1.70
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 +7 -7
- package/lib/esm/view/invoicing/couponView/couponViewEpics.js +0 -3
- package/lib/esm/view/invoicing/couponView/couponViewReducer.js +7 -1
- package/lib/esm/view/invoicing/couponView/couponViewSelector.js +27 -14
- package/lib/esm/view/invoicing/invoiceList/fetchInvoiceListEpic.js +7 -5
- package/lib/esm/view/invoicing/invoiceList/fetchInvoiceListPageEpic.js +2 -1
- package/lib/esm/view/invoicing/invoiceList/invoiceListReducer.js +62 -36
- package/lib/esm/view/invoicing/invoiceList/invoiceListSelector.js +19 -15
- package/lib/esm/view/invoicing/invoiceList/invoiceListState.js +10 -0
- package/lib/esm/view/invoicing/invoicingCreditNoteListView/epics/fetchInvoicingCreditNoteListEpic.js +0 -3
- package/lib/esm/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer.js +7 -1
- package/lib/esm/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewSelector.js +23 -13
- package/lib/esm/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js +3 -2
- package/lib/esm/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +1 -1
- package/lib/esm/view/invoicing/invoicingCustomerListView/epics/fetchInvoicingCustomerListEpic.js +0 -3
- package/lib/esm/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.js +7 -1
- package/lib/esm/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewSelector.js +25 -12
- package/lib/esm/view/invoicing/invoicingDunningCaseListView/epics/fetchInvoicingDunningCaseListEpic.js +0 -3
- package/lib/esm/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.js +7 -1
- package/lib/esm/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewSelector.js +23 -13
- package/lib/esm/view/invoicing/invoicingSubscriptionListView/epics/fetchInvoicingSubscriptionListEpic.js +0 -3
- package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.js +7 -1
- package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +22 -12
- package/lib/esm/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListEpic.js +7 -5
- package/lib/esm/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListPageEpic.js +2 -1
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +56 -25
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js +15 -11
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js +10 -0
- package/lib/index.d.ts +7 -7
- package/lib/index.js +15 -8
- package/lib/view/invoicing/couponView/couponViewEpics.js +0 -3
- package/lib/view/invoicing/couponView/couponViewReducer.d.ts +1 -1
- package/lib/view/invoicing/couponView/couponViewReducer.js +8 -2
- package/lib/view/invoicing/couponView/couponViewSelector.d.ts +1 -0
- package/lib/view/invoicing/couponView/couponViewSelector.js +27 -14
- package/lib/view/invoicing/couponView/couponViewState.d.ts +2 -1
- package/lib/view/invoicing/invoiceList/fetchInvoiceListEpic.d.ts +1 -1
- package/lib/view/invoicing/invoiceList/fetchInvoiceListEpic.js +7 -5
- package/lib/view/invoicing/invoiceList/fetchInvoiceListPageEpic.js +2 -1
- package/lib/view/invoicing/invoiceList/invoiceListReducer.d.ts +5 -4
- package/lib/view/invoicing/invoiceList/invoiceListReducer.js +63 -37
- package/lib/view/invoicing/invoiceList/invoiceListSelector.d.ts +1 -0
- package/lib/view/invoicing/invoiceList/invoiceListSelector.js +19 -15
- package/lib/view/invoicing/invoiceList/invoiceListState.d.ts +20 -7
- package/lib/view/invoicing/invoiceList/invoiceListState.js +13 -1
- package/lib/view/invoicing/invoicingCreditNoteListView/epics/fetchInvoicingCreditNoteListEpic.js +0 -3
- package/lib/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer.js +8 -2
- package/lib/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewSelector.d.ts +1 -0
- package/lib/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewSelector.js +23 -13
- package/lib/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewState.d.ts +2 -1
- package/lib/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js +3 -2
- package/lib/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +1 -1
- package/lib/view/invoicing/invoicingCustomerListView/epics/fetchInvoicingCustomerListEpic.js +0 -3
- package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.js +8 -2
- package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewSelector.d.ts +1 -0
- package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewSelector.js +25 -12
- package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewState.d.ts +2 -1
- package/lib/view/invoicing/invoicingDunningCaseListView/epics/fetchInvoicingDunningCaseListEpic.js +0 -3
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer.js +8 -2
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewSelector.d.ts +1 -0
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewSelector.js +23 -13
- package/lib/view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState.d.ts +2 -1
- package/lib/view/invoicing/invoicingSubscriptionListView/epics/fetchInvoicingSubscriptionListEpic.js +0 -3
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.js +8 -2
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.d.ts +1 -0
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +22 -12
- package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +3 -1
- package/lib/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListEpic.d.ts +1 -1
- package/lib/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListEpic.js +7 -5
- package/lib/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListPageEpic.js +2 -1
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.d.ts +1 -1
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +57 -26
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.d.ts +1 -0
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js +15 -11
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.d.ts +18 -4
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js +13 -1
- package/package.json +1 -1
package/lib/esm/index.js
CHANGED
|
@@ -712,7 +712,7 @@ export { INVOICING_DUNNING_ACTIONS, INVOICING_SUBSCRIPTION_LIFECYCLE_ACTIONS, IN
|
|
|
712
712
|
export { mapAuditLogEntry } from './view/invoicing/auditView/auditViewPayload';
|
|
713
713
|
export { clearAllInvoices, removeInvoice, updateInvoices, } from './entity/invoicing/invoice/invoiceReducer';
|
|
714
714
|
export { getInvoiceById, getInvoicesByIds, } from './entity/invoicing/invoice/invoiceSelector';
|
|
715
|
-
export { clearInvoiceList, fetchInvoiceCounts, fetchInvoiceKPIs, fetchInvoiceList, fetchInvoiceListPage, updateInvoiceListFilters, } from './view/invoicing/invoiceList/invoiceListReducer';
|
|
715
|
+
export { clearInvoiceList, fetchInvoiceCounts, fetchInvoiceKPIs, fetchInvoiceList, fetchInvoiceListPage, setInvoiceActiveTab, updateInvoiceListFilters, } from './view/invoicing/invoiceList/invoiceListReducer';
|
|
716
716
|
export { ALL_INVOICING_INVOICE_TAB_IDS, INVOICING_INVOICE_TABS, } from './view/invoicing/invoiceList/invoiceListState';
|
|
717
717
|
export { getInvoiceListView } from './view/invoicing/invoiceList/invoiceListSelector';
|
|
718
718
|
export { clearAllInvoiceDetail, fetchInvoiceDetail, } from './view/invoicing/invoiceDetail/invoiceDetailReducer';
|
|
@@ -768,7 +768,7 @@ export { getInvoicingDataImportActionState } from './view/invoicing/dataImportAc
|
|
|
768
768
|
export { INVOICING_LIST_PAGE_SIZE } from './view/invoicing/invoicingApiHelper';
|
|
769
769
|
// ── Invoicing: customers ──────────────────────────────────────────────────────
|
|
770
770
|
export { clearAllInvoicingCustomers, removeInvoicingCustomer, updateInvoicingCustomers, } from './entity/invoicing/invoicingCustomer/invoicingCustomerReducer';
|
|
771
|
-
export { clearInvoicingCustomerListView, fetchInvoicingCustomerCounts, fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, updateInvoicingCustomerFilters, } from './view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer';
|
|
771
|
+
export { clearInvoicingCustomerListView, fetchInvoicingCustomerCounts, fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, setInvoicingCustomerActiveTab, updateInvoicingCustomerFilters, } from './view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer';
|
|
772
772
|
export { ALL_INVOICING_CUSTOMER_SORT_KEYS, ALL_INVOICING_CUSTOMER_TAB_IDS, INVOICING_CUSTOMER_COLUMNS, INVOICING_CUSTOMER_TABS, } from './view/invoicing/invoicingCustomerListView/invoicingCustomerListViewState';
|
|
773
773
|
export { getInvoicingCustomerListView } from './view/invoicing/invoicingCustomerListView/invoicingCustomerListViewSelector';
|
|
774
774
|
export { clearInvoicingCustomerDetailView, fetchInvoicingCustomerDetail, fetchInvoicingCustomerDetailPage, } from './view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewReducer';
|
|
@@ -780,28 +780,28 @@ export { getInvoicingPaymentLinkSendState, getInvoicingPaymentMethodSaveState, g
|
|
|
780
780
|
export { submitAddPromotionalCredits, resetPromotionalCreditAction, } from './view/invoicing/promotionalCreditAction/promotionalCreditActionReducer';
|
|
781
781
|
// ── Invoicing: subscriptions ──────────────────────────────────────────────────
|
|
782
782
|
export { clearAllInvoicingSubscriptions, removeInvoicingSubscription, updateInvoicingSubscriptions, } from './entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
|
|
783
|
-
export { clearInvoicingSubscriptionListView, fetchInvoicingSubscriptionCounts, fetchInvoicingSubscriptionList, fetchInvoicingSubscriptionListPage, updateInvoicingSubscriptionFilters, } from './view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer';
|
|
783
|
+
export { clearInvoicingSubscriptionListView, fetchInvoicingSubscriptionCounts, fetchInvoicingSubscriptionList, fetchInvoicingSubscriptionListPage, setInvoicingSubscriptionActiveTab, updateInvoicingSubscriptionFilters, } from './view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer';
|
|
784
784
|
export { ALL_INVOICING_SUBSCRIPTION_SORT_KEYS, ALL_INVOICING_SUBSCRIPTION_TAB_IDS, INVOICING_SUBSCRIPTION_COLUMNS, INVOICING_SUBSCRIPTION_TABS, } from './view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState';
|
|
785
785
|
export { getInvoicingSubscriptionListView } from './view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector';
|
|
786
786
|
export { clearInvoicingSubscriptionDetailView, fetchInvoicingSubscriptionDetail, } from './view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewReducer';
|
|
787
787
|
export { getInvoicingSubscriptionById, getInvoicingSubscriptionDetail, } from './view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector';
|
|
788
788
|
// ── Invoicing: payments (transactions) ────────────────────────────────────────
|
|
789
789
|
export { clearAllInvoicingTransactions, removeInvoicingTransaction, updateInvoicingTransactions, } from './entity/invoicing/invoicingTransaction/invoicingTransactionReducer';
|
|
790
|
-
export { clearInvoicingTransactionListView, fetchInvoicingTransactionList, fetchInvoicingTransactionListPage, updateInvoicingTransactionFilters, } from './view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer';
|
|
790
|
+
export { clearInvoicingTransactionListView, fetchInvoicingTransactionList, fetchInvoicingTransactionListPage, setInvoicingTransactionActiveTab, updateInvoicingTransactionFilters, } from './view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer';
|
|
791
791
|
export { ALL_INVOICING_TRANSACTION_SORT_KEYS, ALL_INVOICING_TRANSACTION_TAB_IDS, INVOICING_TRANSACTION_COLUMNS, INVOICING_TRANSACTION_TABS, } from './view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState';
|
|
792
792
|
export { getInvoicingTransactionListView } from './view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector';
|
|
793
793
|
export { clearInvoicingTransactionDetailView, fetchInvoicingTransactionDetail, } from './view/invoicing/invoicingTransactionDetailView/invoicingTransactionDetailViewReducer';
|
|
794
794
|
export { getInvoicingTransactionById, getInvoicingTransactionDetail, } from './view/invoicing/invoicingTransactionDetailView/invoicingTransactionDetailViewSelector';
|
|
795
795
|
// ── Invoicing: credit notes ───────────────────────────────────────────────────
|
|
796
796
|
export { clearAllInvoicingCreditNotes, removeInvoicingCreditNote, updateInvoicingCreditNotes, } from './entity/invoicing/creditNote/creditNoteReducer';
|
|
797
|
-
export { clearInvoicingCreditNoteListView, fetchInvoicingCreditNoteCounts, fetchInvoicingCreditNoteList, fetchInvoicingCreditNoteListPage, updateInvoicingCreditNoteFilters, } from './view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer';
|
|
797
|
+
export { clearInvoicingCreditNoteListView, fetchInvoicingCreditNoteCounts, fetchInvoicingCreditNoteList, fetchInvoicingCreditNoteListPage, setInvoicingCreditNoteActiveTab, updateInvoicingCreditNoteFilters, } from './view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer';
|
|
798
798
|
export { ALL_INVOICING_CREDIT_NOTE_SORT_KEYS, ALL_INVOICING_CREDIT_NOTE_TAB_IDS, INVOICING_CREDIT_NOTE_COLUMNS, INVOICING_CREDIT_NOTE_TABS, } from './view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewState';
|
|
799
799
|
export { getInvoicingCreditNoteListView } from './view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewSelector';
|
|
800
800
|
export { clearInvoicingCreditNoteDetailView, fetchInvoicingCreditNoteDetail, } from './view/invoicing/invoicingCreditNoteDetailView/invoicingCreditNoteDetailViewReducer';
|
|
801
801
|
export { getInvoicingCreditNoteById, getInvoicingCreditNoteDetail, } from './view/invoicing/invoicingCreditNoteDetailView/invoicingCreditNoteDetailViewSelector';
|
|
802
802
|
// ── Invoicing: discounts (coupons) ────────────────────────────────────────────
|
|
803
803
|
export { clearAllInvoicingCoupons, removeInvoicingCoupon, updateInvoicingCoupons, } from './entity/invoicing/coupon/couponReducer';
|
|
804
|
-
export { clearInvoicingCouponView, fetchInvoicingCouponCounts, fetchInvoicingCouponList, fetchInvoicingCouponListPage, updateInvoicingCouponFilters, } from './view/invoicing/couponView/couponViewReducer';
|
|
804
|
+
export { clearInvoicingCouponView, fetchInvoicingCouponCounts, fetchInvoicingCouponList, fetchInvoicingCouponListPage, setInvoicingCouponActiveTab, updateInvoicingCouponFilters, } from './view/invoicing/couponView/couponViewReducer';
|
|
805
805
|
export { ALL_INVOICING_COUPON_SORT_KEYS, ALL_INVOICING_COUPON_TAB_IDS, INVOICING_COUPON_COLUMNS, INVOICING_COUPON_TABS, } from './view/invoicing/couponView/couponViewState';
|
|
806
806
|
export { getInvoicingCouponCounts, getInvoicingCouponListFetchState, getInvoicingCouponListFilters, getInvoicingCouponListHasMore, getInvoicingCouponListItems, getInvoicingCouponListNextCursor, getInvoicingCouponListView, } from './view/invoicing/couponView/couponViewSelector';
|
|
807
807
|
export { getInvoicingCouponById } from './entity/invoicing/coupon/couponSelector';
|
|
@@ -809,7 +809,7 @@ export { clearInvoicingCouponDetailView, fetchInvoicingCouponDetail, } from './v
|
|
|
809
809
|
export { getInvoicingCouponDetail } from './view/invoicing/invoicingCouponDetailView/invoicingCouponDetailViewSelector';
|
|
810
810
|
// ── Invoicing: dunning ────────────────────────────────────────────────────────
|
|
811
811
|
export { clearAllInvoicingDunningCases, removeInvoicingDunningCase, updateInvoicingDunningCases, } from './entity/invoicing/dunningCase/dunningCaseReducer';
|
|
812
|
-
export { clearInvoicingDunningCaseListView, fetchInvoicingDunningCaseCounts, fetchInvoicingDunningCaseList, fetchInvoicingDunningCaseListPage, updateInvoicingDunningCaseFilters, } from './view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer';
|
|
812
|
+
export { clearInvoicingDunningCaseListView, fetchInvoicingDunningCaseCounts, fetchInvoicingDunningCaseList, fetchInvoicingDunningCaseListPage, setInvoicingDunningCaseActiveTab, updateInvoicingDunningCaseFilters, } from './view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewReducer';
|
|
813
813
|
export { ALL_INVOICING_DUNNING_CASE_SORT_KEYS, ALL_INVOICING_DUNNING_CASE_TAB_IDS, INVOICING_DUNNING_CASE_COLUMNS, INVOICING_DUNNING_CASE_TABS, } from './view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewState';
|
|
814
814
|
export { getInvoicingDunningCaseListView } from './view/invoicing/invoicingDunningCaseListView/invoicingDunningCaseListViewSelector';
|
|
815
815
|
export { clearInvoicingDunningCaseDetailView, fetchInvoicingDunningCaseDetail, } from './view/invoicing/invoicingDunningCaseDetailView/invoicingDunningCaseDetailViewReducer';
|
|
@@ -13,9 +13,6 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
13
13
|
fetchStateAndError.fetchState !== 'In-Progress');
|
|
14
14
|
const buildQuery = (filters, cursor, sort) => {
|
|
15
15
|
const params = new URLSearchParams();
|
|
16
|
-
if (filters.status != null && filters.status.length > 0) {
|
|
17
|
-
params.set('status', filters.status);
|
|
18
|
-
}
|
|
19
16
|
if (filters.search != null && filters.search.length > 0) {
|
|
20
17
|
params.set('search', filters.search);
|
|
21
18
|
}
|
|
@@ -9,6 +9,7 @@ function couponStatusToTabCountKey(status) {
|
|
|
9
9
|
export const initialState = {
|
|
10
10
|
fetchState: 'Not-Started',
|
|
11
11
|
error: undefined,
|
|
12
|
+
activeTab: 'all',
|
|
12
13
|
ids: [],
|
|
13
14
|
nextCursor: null,
|
|
14
15
|
filters: {},
|
|
@@ -87,6 +88,11 @@ const couponView = createSlice({
|
|
|
87
88
|
updateInvoicingCouponFilters(draft, action) {
|
|
88
89
|
draft.filters = action.payload;
|
|
89
90
|
},
|
|
91
|
+
// Select a status tab. The list API ignores `status` (returns all statuses),
|
|
92
|
+
// so the selector filters rows to this tab client-side — no refetch needed.
|
|
93
|
+
setInvoicingCouponActiveTab(draft, action) {
|
|
94
|
+
draft.activeTab = action.payload;
|
|
95
|
+
},
|
|
90
96
|
// Reflect a newly created coupon in the cached discounts list + tab counts
|
|
91
97
|
// so the list page shows it without refetching from the server. Edits keep
|
|
92
98
|
// the same id/counts, so only creates dispatch this.
|
|
@@ -105,5 +111,5 @@ const couponView = createSlice({
|
|
|
105
111
|
},
|
|
106
112
|
},
|
|
107
113
|
});
|
|
108
|
-
export const { fetchInvoicingCouponList, fetchInvoicingCouponListPage, updateInvoicingCouponList, updateInvoicingCouponListFailure, fetchInvoicingCouponCounts, updateInvoicingCouponCounts, updateInvoicingCouponCountsFailure, updateInvoicingCouponFilters, addInvoicingCouponToList, clearInvoicingCouponView, } = couponView.actions;
|
|
114
|
+
export const { fetchInvoicingCouponList, fetchInvoicingCouponListPage, updateInvoicingCouponList, updateInvoicingCouponListFailure, fetchInvoicingCouponCounts, updateInvoicingCouponCounts, updateInvoicingCouponCountsFailure, updateInvoicingCouponFilters, setInvoicingCouponActiveTab, addInvoicingCouponToList, clearInvoicingCouponView, } = couponView.actions;
|
|
109
115
|
export default couponView.reducer;
|
|
@@ -17,18 +17,31 @@ export const getInvoicingCouponCounts = (state) => state.invoicingCouponViewStat
|
|
|
17
17
|
* array (and the wrapping view object) keep referential identity until the
|
|
18
18
|
* coupon entity slice or the list-view slice actually change.
|
|
19
19
|
*/
|
|
20
|
-
export const getInvoicingCouponListView = createSelector((state) => state.invoicingCouponState, (state) => state.invoicingCouponViewState, (couponState, listViewState) =>
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export const getInvoicingCouponListView = createSelector((state) => state.invoicingCouponState, (state) => state.invoicingCouponViewState, (couponState, listViewState) => {
|
|
21
|
+
const { activeTab } = listViewState;
|
|
22
|
+
const allCoupons = listViewState.ids
|
|
23
23
|
.map((id) => couponState.couponByID[id])
|
|
24
|
-
.filter((item) => item != null)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
.filter((item) => item != null);
|
|
25
|
+
// The list API ignores `status`, so it returns every status; filter to the
|
|
26
|
+
// active tab client-side. 'all' shows everything, 'active' shows only active
|
|
27
|
+
// coupons, and 'inactive' shows every non-active status (undefined included).
|
|
28
|
+
const coupons = activeTab === 'all'
|
|
29
|
+
? allCoupons
|
|
30
|
+
: allCoupons.filter((coupon) => activeTab === 'active'
|
|
31
|
+
? coupon.status === 'active'
|
|
32
|
+
: coupon.status !== 'active');
|
|
33
|
+
return {
|
|
34
|
+
activeTab,
|
|
35
|
+
columns: INVOICING_COUPON_COLUMNS,
|
|
36
|
+
coupons,
|
|
37
|
+
count: listViewState.counts,
|
|
38
|
+
countsFetchState: listViewState.countsFetchState,
|
|
39
|
+
filters: listViewState.filters,
|
|
40
|
+
nextCursor: listViewState.nextCursor,
|
|
41
|
+
tabIds: INVOICING_COUPON_TABS,
|
|
42
|
+
fetchState: listViewState.fetchState,
|
|
43
|
+
error: listViewState.error,
|
|
44
|
+
sort: listViewState.sort,
|
|
45
|
+
version: 1.0,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
@@ -6,10 +6,10 @@ import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer
|
|
|
6
6
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
7
7
|
import { INVOICING_LIST_PAGE_SIZE, applyListSortParams, withQuery, } from '../invoicingApiHelper';
|
|
8
8
|
import { fetchInvoiceList, updateInvoiceList, updateInvoiceListFailure, } from './invoiceListReducer';
|
|
9
|
-
const buildInvoiceListQuery = (filters, cursor, sort) => {
|
|
9
|
+
const buildInvoiceListQuery = (filters, status, cursor, sort) => {
|
|
10
10
|
const params = new URLSearchParams();
|
|
11
|
-
if (
|
|
12
|
-
params.set('status',
|
|
11
|
+
if (status != null && status.length > 0) {
|
|
12
|
+
params.set('status', status);
|
|
13
13
|
}
|
|
14
14
|
if (filters.customerId != null) {
|
|
15
15
|
params.set('customer_id', filters.customerId);
|
|
@@ -33,9 +33,11 @@ const buildInvoiceListQuery = (filters, cursor, sort) => {
|
|
|
33
33
|
applyListSortParams(params, sort);
|
|
34
34
|
return params;
|
|
35
35
|
};
|
|
36
|
-
export const fetchInvoiceListEpic = (actions$,
|
|
36
|
+
export const fetchInvoiceListEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchInvoiceList.match), switchMap((action) => {
|
|
37
37
|
const { filters, cursor, keepExistingListItems, sort } = action.payload;
|
|
38
|
-
const
|
|
38
|
+
const { activeTab } = state$.value.invoicingInvoiceListState;
|
|
39
|
+
const status = activeTab !== 'all' ? activeTab : undefined;
|
|
40
|
+
const apiUrl = withQuery(`${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices`, buildInvoiceListQuery(filters, status, cursor, sort));
|
|
39
41
|
return zeniAPI.getJSON(apiUrl).pipe(switchMap((response) => {
|
|
40
42
|
if (isSuccessResponse(response)) {
|
|
41
43
|
const items = response.data?.items ?? [];
|
|
@@ -16,8 +16,9 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
16
16
|
export const fetchInvoiceListPageEpic = (actions$, state$) => actions$.pipe(filter(fetchInvoiceListPage.match), mergeMap((action) => {
|
|
17
17
|
const { cacheOverride, filters, sort } = action.payload;
|
|
18
18
|
const state = state$.value.invoicingInvoiceListState;
|
|
19
|
+
const activeTabState = state.invoiceByTab[state.activeTab];
|
|
19
20
|
const pageActions = [];
|
|
20
|
-
if (shouldFetch({ fetchState:
|
|
21
|
+
if (shouldFetch({ fetchState: activeTabState.fetchState, error: activeTabState.error }, cacheOverride)) {
|
|
21
22
|
pageActions.push(fetchInvoiceList({ filters, sort }));
|
|
22
23
|
}
|
|
23
24
|
if (shouldFetch(state.countsFetchState, cacheOverride)) {
|
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import { ALL_INVOICING_INVOICE_TAB_IDS, makeInvoiceByTab, } from './invoiceListState';
|
|
2
3
|
/**
|
|
3
|
-
* Whether two invoice-list queries
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Whether two invoice-list queries share the same base (tab-independent) query.
|
|
5
|
+
* The status tab is server-side per-tab, so it is excluded here — when the base
|
|
6
|
+
* query changes (search / customer / subscription / dates / sort) every per-tab
|
|
7
|
+
* cache is stale and the reducer resets them all.
|
|
6
8
|
*/
|
|
7
9
|
export const sameInvoiceListQuery = (a, b) => a.filters.customerId === b.filters.customerId &&
|
|
8
10
|
a.filters.subscriptionId === b.filters.subscriptionId &&
|
|
9
|
-
a.filters.status === b.filters.status &&
|
|
10
11
|
a.filters.search === b.filters.search &&
|
|
11
12
|
a.filters.dateFrom === b.filters.dateFrom &&
|
|
12
13
|
a.filters.dateTo === b.filters.dateTo &&
|
|
13
14
|
a.sort?.field === b.sort?.field &&
|
|
14
15
|
a.sort?.dir === b.sort?.dir;
|
|
16
|
+
/**
|
|
17
|
+
* Narrow an invoice status to a status tab id when one exists. Statuses like
|
|
18
|
+
* `draft` / `posted` / `pending` have no dedicated tab, so a newly created
|
|
19
|
+
* invoice in one of those states only lands in the `all` tab.
|
|
20
|
+
*/
|
|
21
|
+
const statusToTabId = (status) => ALL_INVOICING_INVOICE_TAB_IDS.includes(status)
|
|
22
|
+
? status
|
|
23
|
+
: undefined;
|
|
15
24
|
export const initialState = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
invoiceIds: [],
|
|
19
|
-
nextCursor: null,
|
|
25
|
+
activeTab: 'all',
|
|
26
|
+
invoiceByTab: makeInvoiceByTab(),
|
|
20
27
|
filters: {},
|
|
21
28
|
counts: { all: 0 },
|
|
22
29
|
countsFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
23
30
|
kpis: undefined,
|
|
24
31
|
kpisFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
25
|
-
hasValidState() {
|
|
26
|
-
return this.fetchState === 'Completed';
|
|
27
|
-
},
|
|
28
32
|
};
|
|
29
33
|
const invoiceList = createSlice({
|
|
30
34
|
name: 'invoicingInvoiceList',
|
|
@@ -32,14 +36,15 @@ const invoiceList = createSlice({
|
|
|
32
36
|
reducers: {
|
|
33
37
|
fetchInvoiceList: {
|
|
34
38
|
reducer(draft, action) {
|
|
39
|
+
const tab = draft.invoiceByTab[draft.activeTab];
|
|
35
40
|
if (!action.payload.keepExistingListItems) {
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
tab.invoiceIds = [];
|
|
42
|
+
tab.nextCursor = null;
|
|
38
43
|
}
|
|
39
44
|
draft.filters = action.payload.filters;
|
|
40
45
|
draft.sort = action.payload.sort;
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
tab.fetchState = 'In-Progress';
|
|
47
|
+
tab.error = undefined;
|
|
43
48
|
},
|
|
44
49
|
prepare(payload) {
|
|
45
50
|
return {
|
|
@@ -54,13 +59,11 @@ const invoiceList = createSlice({
|
|
|
54
59
|
},
|
|
55
60
|
fetchInvoiceListPage: {
|
|
56
61
|
reducer(draft, action) {
|
|
57
|
-
// A different query invalidates
|
|
58
|
-
// epic's shouldFetch refetches instead of showing
|
|
59
|
-
//
|
|
62
|
+
// A different base query invalidates every tab's cache — reset so the
|
|
63
|
+
// page epic's shouldFetch refetches the active tab instead of showing
|
|
64
|
+
// rows fetched under a stale search/customer/subscription/dates/sort.
|
|
60
65
|
if (!sameInvoiceListQuery(draft, action.payload)) {
|
|
61
|
-
draft.
|
|
62
|
-
draft.nextCursor = null;
|
|
63
|
-
draft.fetchState = 'Not-Started';
|
|
66
|
+
draft.invoiceByTab = makeInvoiceByTab();
|
|
64
67
|
}
|
|
65
68
|
draft.filters = action.payload.filters;
|
|
66
69
|
draft.sort = action.payload.sort;
|
|
@@ -76,17 +79,19 @@ const invoiceList = createSlice({
|
|
|
76
79
|
},
|
|
77
80
|
},
|
|
78
81
|
updateInvoiceList(draft, action) {
|
|
82
|
+
const tab = draft.invoiceByTab[draft.activeTab];
|
|
79
83
|
const newIds = action.payload.invoices.map((invoice) => invoice.id);
|
|
80
|
-
|
|
81
|
-
? [...new Set([...
|
|
84
|
+
tab.invoiceIds = action.payload.keepExistingListItems
|
|
85
|
+
? [...new Set([...tab.invoiceIds, ...newIds])]
|
|
82
86
|
: newIds;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
tab.nextCursor = action.payload.nextCursor;
|
|
88
|
+
tab.fetchState = 'Completed';
|
|
89
|
+
tab.error = undefined;
|
|
86
90
|
},
|
|
87
91
|
updateInvoiceListFailure(draft, action) {
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
const tab = draft.invoiceByTab[draft.activeTab];
|
|
93
|
+
tab.fetchState = 'Error';
|
|
94
|
+
tab.error = action.payload;
|
|
90
95
|
},
|
|
91
96
|
fetchInvoiceCounts(draft) {
|
|
92
97
|
draft.countsFetchState.fetchState = 'In-Progress';
|
|
@@ -117,24 +122,45 @@ const invoiceList = createSlice({
|
|
|
117
122
|
updateInvoiceListFilters(draft, action) {
|
|
118
123
|
draft.filters = action.payload;
|
|
119
124
|
},
|
|
125
|
+
// Select a status tab. The view dispatches the follow-up fetchInvoiceListPage
|
|
126
|
+
// so the page epic fetches the tab when its cache is empty and reuses it when
|
|
127
|
+
// already loaded.
|
|
128
|
+
setInvoiceActiveTab(draft, action) {
|
|
129
|
+
draft.activeTab = action.payload;
|
|
130
|
+
},
|
|
120
131
|
// Reflect a newly created invoice in the cached list + tab counts so the
|
|
121
|
-
// invoices page shows it without refetching
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
132
|
+
// invoices page shows it without refetching. Prepends the id to the `all`
|
|
133
|
+
// tab and its status tab (dedup via includes), and bumps the `all` total and
|
|
134
|
+
// the per-status count key the tabs read. KPIs are money aggregates, so they
|
|
135
|
+
// are left untouched and refetched lazily.
|
|
125
136
|
addInvoiceToList(draft, action) {
|
|
126
137
|
const { id, status } = action.payload;
|
|
127
|
-
|
|
138
|
+
const allTab = draft.invoiceByTab['all'];
|
|
139
|
+
if (allTab.invoiceIds.includes(id)) {
|
|
128
140
|
return;
|
|
129
141
|
}
|
|
130
|
-
|
|
142
|
+
allTab.invoiceIds = [id, ...allTab.invoiceIds];
|
|
143
|
+
const statusTab = statusToTabId(status);
|
|
144
|
+
if (statusTab != null) {
|
|
145
|
+
const tab = draft.invoiceByTab[statusTab];
|
|
146
|
+
if (!tab.invoiceIds.includes(id)) {
|
|
147
|
+
tab.invoiceIds = [id, ...tab.invoiceIds];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
131
150
|
draft.counts.all += 1;
|
|
132
151
|
draft.counts[status] = (draft.counts[status] ?? 0) + 1;
|
|
133
152
|
},
|
|
134
153
|
clearInvoiceList(draft) {
|
|
135
|
-
|
|
154
|
+
draft.activeTab = 'all';
|
|
155
|
+
draft.invoiceByTab = makeInvoiceByTab();
|
|
156
|
+
draft.filters = {};
|
|
157
|
+
draft.sort = undefined;
|
|
158
|
+
draft.counts = { all: 0 };
|
|
159
|
+
draft.countsFetchState = { fetchState: 'Not-Started', error: undefined };
|
|
160
|
+
draft.kpis = undefined;
|
|
161
|
+
draft.kpisFetchState = { fetchState: 'Not-Started', error: undefined };
|
|
136
162
|
},
|
|
137
163
|
},
|
|
138
164
|
});
|
|
139
|
-
export const { fetchInvoiceList, fetchInvoiceListPage, updateInvoiceList, updateInvoiceListFailure, fetchInvoiceCounts, updateInvoiceCounts, updateInvoiceCountsFailure, fetchInvoiceKPIs, updateInvoiceKPIs, updateInvoiceKPIsFailure, updateInvoiceListFilters, addInvoiceToList, clearInvoiceList, } = invoiceList.actions;
|
|
165
|
+
export const { fetchInvoiceList, fetchInvoiceListPage, updateInvoiceList, updateInvoiceListFailure, fetchInvoiceCounts, updateInvoiceCounts, updateInvoiceCountsFailure, fetchInvoiceKPIs, updateInvoiceKPIs, updateInvoiceKPIsFailure, updateInvoiceListFilters, setInvoiceActiveTab, addInvoiceToList, clearInvoiceList, } = invoiceList.actions;
|
|
140
166
|
export default invoiceList.reducer;
|
|
@@ -6,18 +6,22 @@ import { INVOICING_INVOICE_TABS, } from './invoiceListState';
|
|
|
6
6
|
* array (and the wrapping view object) keep referential identity until the
|
|
7
7
|
* invoice entity slice or the list-view slice actually change.
|
|
8
8
|
*/
|
|
9
|
-
export const getInvoiceListView = createSelector((state) => state.invoicingInvoiceState, (state) => state.invoicingInvoiceListState, (invoiceState, listViewState) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
export const getInvoiceListView = createSelector((state) => state.invoicingInvoiceState, (state) => state.invoicingInvoiceListState, (invoiceState, listViewState) => {
|
|
10
|
+
const activeTabState = listViewState.invoiceByTab[listViewState.activeTab];
|
|
11
|
+
return {
|
|
12
|
+
activeTab: listViewState.activeTab,
|
|
13
|
+
invoices: activeTabState.invoiceIds
|
|
14
|
+
.map((id) => invoiceState.invoiceByID[id])
|
|
15
|
+
.filter((item) => item != null),
|
|
16
|
+
counts: listViewState.counts,
|
|
17
|
+
countsFetchState: listViewState.countsFetchState,
|
|
18
|
+
filters: listViewState.filters,
|
|
19
|
+
kpis: listViewState.kpis,
|
|
20
|
+
kpisFetchState: listViewState.kpisFetchState,
|
|
21
|
+
nextCursor: activeTabState.nextCursor,
|
|
22
|
+
tabIds: INVOICING_INVOICE_TABS,
|
|
23
|
+
fetchState: activeTabState.fetchState,
|
|
24
|
+
error: activeTabState.error,
|
|
25
|
+
version: 1.0,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
@@ -17,3 +17,13 @@ export const toInvoicingInvoiceTabId = (v) => stringToUnion(v, ALL_INVOICING_INV
|
|
|
17
17
|
export const INVOICING_INVOICE_TABS = [
|
|
18
18
|
...ALL_INVOICING_INVOICE_TAB_IDS,
|
|
19
19
|
];
|
|
20
|
+
export const makeInvoiceTabState = () => ({
|
|
21
|
+
invoiceIds: [],
|
|
22
|
+
nextCursor: null,
|
|
23
|
+
fetchState: 'Not-Started',
|
|
24
|
+
error: undefined,
|
|
25
|
+
});
|
|
26
|
+
export const makeInvoiceByTab = () => ALL_INVOICING_INVOICE_TAB_IDS.reduce((acc, tabId) => {
|
|
27
|
+
acc[tabId] = makeInvoiceTabState();
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
package/lib/esm/view/invoicing/invoicingCreditNoteListView/epics/fetchInvoicingCreditNoteListEpic.js
CHANGED
|
@@ -6,9 +6,6 @@ import { INVOICING_LIST_PAGE_SIZE, applyListSortParams, withQuery, } from '../..
|
|
|
6
6
|
import { fetchInvoicingCreditNoteList, updateInvoicingCreditNoteList, updateInvoicingCreditNoteListFailure, } from '../invoicingCreditNoteListViewReducer';
|
|
7
7
|
const buildQuery = (filters, cursor, sort) => {
|
|
8
8
|
const params = new URLSearchParams();
|
|
9
|
-
if (filters.status != null && filters.status.length > 0) {
|
|
10
|
-
params.set('status', filters.status);
|
|
11
|
-
}
|
|
12
9
|
if (filters.customerId != null) {
|
|
13
10
|
params.set('customer_id', filters.customerId);
|
|
14
11
|
}
|
package/lib/esm/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewReducer.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
|
|
|
2
2
|
export const initialState = {
|
|
3
3
|
fetchState: 'Not-Started',
|
|
4
4
|
error: undefined,
|
|
5
|
+
activeTab: 'all',
|
|
5
6
|
ids: [],
|
|
6
7
|
nextCursor: null,
|
|
7
8
|
filters: {},
|
|
@@ -80,10 +81,15 @@ const invoicingCreditNoteListView = createSlice({
|
|
|
80
81
|
updateInvoicingCreditNoteFilters(draft, action) {
|
|
81
82
|
draft.filters = action.payload;
|
|
82
83
|
},
|
|
84
|
+
// Select a status tab. The list API ignores `status` (returns all statuses),
|
|
85
|
+
// so the selector filters rows to this tab client-side — no refetch needed.
|
|
86
|
+
setInvoicingCreditNoteActiveTab(draft, action) {
|
|
87
|
+
draft.activeTab = action.payload;
|
|
88
|
+
},
|
|
83
89
|
clearInvoicingCreditNoteListView(draft) {
|
|
84
90
|
Object.assign(draft, initialState);
|
|
85
91
|
},
|
|
86
92
|
},
|
|
87
93
|
});
|
|
88
|
-
export const { fetchInvoicingCreditNoteList, fetchInvoicingCreditNoteListPage, updateInvoicingCreditNoteList, updateInvoicingCreditNoteListFailure, fetchInvoicingCreditNoteCounts, updateInvoicingCreditNoteCounts, updateInvoicingCreditNoteCountsFailure, updateInvoicingCreditNoteFilters, clearInvoicingCreditNoteListView, } = invoicingCreditNoteListView.actions;
|
|
94
|
+
export const { fetchInvoicingCreditNoteList, fetchInvoicingCreditNoteListPage, updateInvoicingCreditNoteList, updateInvoicingCreditNoteListFailure, fetchInvoicingCreditNoteCounts, updateInvoicingCreditNoteCounts, updateInvoicingCreditNoteCountsFailure, updateInvoicingCreditNoteFilters, setInvoicingCreditNoteActiveTab, clearInvoicingCreditNoteListView, } = invoicingCreditNoteListView.actions;
|
|
89
95
|
export default invoicingCreditNoteListView.reducer;
|
package/lib/esm/view/invoicing/invoicingCreditNoteListView/invoicingCreditNoteListViewSelector.js
CHANGED
|
@@ -6,16 +6,26 @@ import { INVOICING_CREDIT_NOTE_COLUMNS, INVOICING_CREDIT_NOTE_TABS, } from './in
|
|
|
6
6
|
* object) keep referential identity until the credit-note entity slice or the
|
|
7
7
|
* list-view slice actually change.
|
|
8
8
|
*/
|
|
9
|
-
export const getInvoicingCreditNoteListView = createSelector((state) => state.invoicingCreditNoteState, (state) => state.invoicingCreditNoteListViewState, (creditNoteState, listViewState) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
export const getInvoicingCreditNoteListView = createSelector((state) => state.invoicingCreditNoteState, (state) => state.invoicingCreditNoteListViewState, (creditNoteState, listViewState) => {
|
|
10
|
+
const { activeTab } = listViewState;
|
|
11
|
+
const allCreditNotes = getInvoicingCreditNotesByIds(creditNoteState, listViewState.ids);
|
|
12
|
+
// The list API ignores `status`, so it returns every status; filter to the
|
|
13
|
+
// active tab client-side ('all' shows everything).
|
|
14
|
+
const creditNotes = activeTab === 'all'
|
|
15
|
+
? allCreditNotes
|
|
16
|
+
: allCreditNotes.filter((creditNote) => creditNote.status === activeTab);
|
|
17
|
+
return {
|
|
18
|
+
activeTab,
|
|
19
|
+
columns: INVOICING_CREDIT_NOTE_COLUMNS,
|
|
20
|
+
creditNotes,
|
|
21
|
+
count: listViewState.counts,
|
|
22
|
+
countsFetchState: listViewState.countsFetchState,
|
|
23
|
+
filters: listViewState.filters,
|
|
24
|
+
nextCursor: listViewState.nextCursor,
|
|
25
|
+
tabIds: INVOICING_CREDIT_NOTE_TABS,
|
|
26
|
+
fetchState: listViewState.fetchState,
|
|
27
|
+
error: listViewState.error,
|
|
28
|
+
sort: listViewState.sort,
|
|
29
|
+
version: 1.0,
|
|
30
|
+
};
|
|
31
|
+
});
|
package/lib/esm/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js
CHANGED
|
@@ -20,6 +20,7 @@ export const fetchInvoicingCustomerDetailPageEpic = (actions$, state$) => action
|
|
|
20
20
|
const { cacheOverride, id } = action.payload;
|
|
21
21
|
const customerDetail = state$.value.invoicingCustomerDetailViewState.detailById[id];
|
|
22
22
|
const invoiceListState = state$.value.invoicingInvoiceListState;
|
|
23
|
+
const invoiceListTabState = invoiceListState.invoiceByTab[invoiceListState.activeTab];
|
|
23
24
|
const settingsState = state$.value.invoicingSettingsViewState;
|
|
24
25
|
const pageActions = [];
|
|
25
26
|
if (shouldFetch({
|
|
@@ -33,8 +34,8 @@ export const fetchInvoicingCustomerDetailPageEpic = (actions$, state$) => action
|
|
|
33
34
|
const invoiceListIsForCustomer = invoiceListState.filters.customerId === id;
|
|
34
35
|
if (!invoiceListIsForCustomer ||
|
|
35
36
|
shouldFetch({
|
|
36
|
-
fetchState:
|
|
37
|
-
error:
|
|
37
|
+
fetchState: invoiceListTabState.fetchState,
|
|
38
|
+
error: invoiceListTabState.error,
|
|
38
39
|
}, cacheOverride)) {
|
|
39
40
|
pageActions.push(fetchInvoiceList({ filters: { customerId: id } }));
|
|
40
41
|
}
|
package/lib/esm/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js
CHANGED
|
@@ -10,7 +10,7 @@ export const getInvoicingCustomerDetail = (state, invoicingCustomerID) => {
|
|
|
10
10
|
const settings = getInvoicingSettings(state);
|
|
11
11
|
return {
|
|
12
12
|
invoicingCustomer: getInvoicingCustomerById(invoicingCustomerState, invoicingCustomerID),
|
|
13
|
-
invoices: getInvoicesByIds(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceIds),
|
|
13
|
+
invoices: getInvoicesByIds(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceByTab[state.invoicingInvoiceListState.activeTab].invoiceIds),
|
|
14
14
|
setupIntent: getInvoicingSetupIntent(state),
|
|
15
15
|
setupIntentFetchState: getInvoicingSetupIntentFetchState(state),
|
|
16
16
|
plaidLinkToken: getInvoicingPlaidLinkToken(state),
|
package/lib/esm/view/invoicing/invoicingCustomerListView/epics/fetchInvoicingCustomerListEpic.js
CHANGED
|
@@ -11,9 +11,6 @@ const buildQuery = (filters, cursor, sort) => {
|
|
|
11
11
|
if (filters.search != null && filters.search.length > 0) {
|
|
12
12
|
params.set('search', filters.search);
|
|
13
13
|
}
|
|
14
|
-
if (filters.status != null && filters.status.length > 0) {
|
|
15
|
-
params.set('status', filters.status);
|
|
16
|
-
}
|
|
17
14
|
params.set('limit', String(INVOICING_LIST_PAGE_SIZE));
|
|
18
15
|
if (cursor != null) {
|
|
19
16
|
params.set('cursor', cursor);
|
package/lib/esm/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
|
|
|
2
2
|
export const initialState = {
|
|
3
3
|
fetchState: 'Not-Started',
|
|
4
4
|
error: undefined,
|
|
5
|
+
activeTab: 'all',
|
|
5
6
|
ids: [],
|
|
6
7
|
nextCursor: null,
|
|
7
8
|
filters: {},
|
|
@@ -80,6 +81,11 @@ const invoicingCustomerListView = createSlice({
|
|
|
80
81
|
updateInvoicingCustomerFilters(draft, action) {
|
|
81
82
|
draft.filters = action.payload;
|
|
82
83
|
},
|
|
84
|
+
// Select a status tab. The list API ignores `status` (returns all statuses),
|
|
85
|
+
// so the selector filters rows to this tab client-side — no refetch needed.
|
|
86
|
+
setInvoicingCustomerActiveTab(draft, action) {
|
|
87
|
+
draft.activeTab = action.payload;
|
|
88
|
+
},
|
|
83
89
|
// Reflect a newly created customer in the cached list + tab counts so the
|
|
84
90
|
// customer page shows the new row without refetching from the server. The
|
|
85
91
|
// per-status count key mirrors the customer `status` value the counts map
|
|
@@ -101,5 +107,5 @@ const invoicingCustomerListView = createSlice({
|
|
|
101
107
|
},
|
|
102
108
|
},
|
|
103
109
|
});
|
|
104
|
-
export const { fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, updateInvoicingCustomerList, updateInvoicingCustomerListFailure, fetchInvoicingCustomerCounts, updateInvoicingCustomerCounts, updateInvoicingCustomerCountsFailure, updateInvoicingCustomerFilters, addInvoicingCustomerToList, clearInvoicingCustomerListView, } = invoicingCustomerListView.actions;
|
|
110
|
+
export const { fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, updateInvoicingCustomerList, updateInvoicingCustomerListFailure, fetchInvoicingCustomerCounts, updateInvoicingCustomerCounts, updateInvoicingCustomerCountsFailure, updateInvoicingCustomerFilters, setInvoicingCustomerActiveTab, addInvoicingCustomerToList, clearInvoicingCustomerListView, } = invoicingCustomerListView.actions;
|
|
105
111
|
export default invoicingCustomerListView.reducer;
|
package/lib/esm/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewSelector.js
CHANGED
|
@@ -7,15 +7,28 @@ import { INVOICING_CUSTOMER_COLUMNS, INVOICING_CUSTOMER_TABS, } from './invoicin
|
|
|
7
7
|
* slice actually change. Without this, the connected list page re-rendered on
|
|
8
8
|
* every unrelated redux action because a fresh array was built each call.
|
|
9
9
|
*/
|
|
10
|
-
export const getInvoicingCustomerListView = createSelector((state) => state.invoicingCustomerState, (state) => state.invoicingCustomerListViewState, (customerState, listViewState) =>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
export const getInvoicingCustomerListView = createSelector((state) => state.invoicingCustomerState, (state) => state.invoicingCustomerListViewState, (customerState, listViewState) => {
|
|
11
|
+
const { activeTab } = listViewState;
|
|
12
|
+
const allCustomers = getInvoicingCustomersByIds(customerState, listViewState.ids);
|
|
13
|
+
// The list API ignores `status`, so it returns every status; filter to the
|
|
14
|
+
// active tab client-side ('all' shows everything, 'at_risk' keys off the
|
|
15
|
+
// `isAtRisk` flag, the rest match the customer `status`).
|
|
16
|
+
const customers = activeTab === 'all'
|
|
17
|
+
? allCustomers
|
|
18
|
+
: activeTab === 'at_risk'
|
|
19
|
+
? allCustomers.filter((customer) => customer.isAtRisk === true)
|
|
20
|
+
: allCustomers.filter((customer) => customer.status === activeTab);
|
|
21
|
+
return {
|
|
22
|
+
activeTab,
|
|
23
|
+
columns: INVOICING_CUSTOMER_COLUMNS,
|
|
24
|
+
customers,
|
|
25
|
+
fetchState: listViewState.fetchState,
|
|
26
|
+
error: listViewState.error,
|
|
27
|
+
nextCursor: listViewState.nextCursor,
|
|
28
|
+
filters: listViewState.filters,
|
|
29
|
+
count: listViewState.counts,
|
|
30
|
+
countsFetchState: listViewState.countsFetchState,
|
|
31
|
+
tabIds: INVOICING_CUSTOMER_TABS,
|
|
32
|
+
sort: listViewState.sort,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
@@ -6,9 +6,6 @@ import { INVOICING_LIST_PAGE_SIZE, applyListSortParams, withQuery, } from '../..
|
|
|
6
6
|
import { fetchInvoicingDunningCaseList, updateInvoicingDunningCaseList, updateInvoicingDunningCaseListFailure, } from '../invoicingDunningCaseListViewReducer';
|
|
7
7
|
const buildQuery = (filters, cursor, sort) => {
|
|
8
8
|
const params = new URLSearchParams();
|
|
9
|
-
if (filters.status != null && filters.status.length > 0) {
|
|
10
|
-
params.set('status', filters.status);
|
|
11
|
-
}
|
|
12
9
|
if (filters.search != null && filters.search.length > 0) {
|
|
13
10
|
params.set('search', filters.search);
|
|
14
11
|
}
|