@zeniai/client-epic-state 5.1.97-betaAK3 → 5.1.97-betaAK4
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/view/invoicing/invoiceList/fetchInvoiceListPageEpic.js +2 -1
- package/lib/esm/view/invoicing/invoiceList/invoiceListReducer.js +6 -6
- package/lib/esm/view/invoicing/invoiceList/invoiceListSelector.js +5 -2
- package/lib/esm/view/invoicing/invoiceList/invoiceListState.js +13 -0
- package/lib/esm/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js +2 -2
- package/lib/esm/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +1 -1
- package/lib/esm/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListPageEpic.js +2 -1
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +5 -5
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js +2 -2
- package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js +10 -0
- package/lib/view/invoicing/invoiceList/fetchInvoiceListPageEpic.js +2 -1
- package/lib/view/invoicing/invoiceList/invoiceListReducer.js +5 -5
- package/lib/view/invoicing/invoiceList/invoiceListSelector.js +4 -1
- package/lib/view/invoicing/invoiceList/invoiceListState.d.ts +13 -2
- package/lib/view/invoicing/invoiceList/invoiceListState.js +15 -1
- package/lib/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js +2 -2
- package/lib/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +1 -1
- package/lib/view/invoicing/invoicingTransactionListView/epics/fetchInvoicingTransactionListPageEpic.js +2 -1
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +4 -4
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js +1 -1
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.d.ts +8 -1
- package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js +12 -1
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { concat, from } from 'rxjs';
|
|
2
2
|
import { filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { makeInvoiceTabState } from './invoiceListState';
|
|
3
4
|
import { fetchInvoiceCounts, fetchInvoiceKPIs, fetchInvoiceList, fetchInvoiceListPage, } from './invoiceListReducer';
|
|
4
5
|
/**
|
|
5
6
|
* Fetch unless the endpoint is already loaded or in flight — or always when the
|
|
@@ -16,7 +17,7 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
16
17
|
export const fetchInvoiceListPageEpic = (actions$, state$) => actions$.pipe(filter(fetchInvoiceListPage.match), mergeMap((action) => {
|
|
17
18
|
const { cacheOverride, filters, sort } = action.payload;
|
|
18
19
|
const state = state$.value.invoicingInvoiceListState;
|
|
19
|
-
const activeTabState = state.invoiceByTab[state.activeTab];
|
|
20
|
+
const activeTabState = state.invoiceByTab[state.activeTab] ?? makeInvoiceTabState();
|
|
20
21
|
const pageActions = [];
|
|
21
22
|
if (shouldFetch({ fetchState: activeTabState.fetchState, error: activeTabState.error }, cacheOverride)) {
|
|
22
23
|
pageActions.push(fetchInvoiceList({ filters, sort }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { clearAll } from '../../../rootActions';
|
|
3
|
-
import { ALL_INVOICING_INVOICE_TAB_IDS, makeInvoiceByTab, } from './invoiceListState';
|
|
3
|
+
import { ALL_INVOICING_INVOICE_TAB_IDS, invoiceTabStateFor, makeInvoiceByTab, } from './invoiceListState';
|
|
4
4
|
/**
|
|
5
5
|
* Whether two invoice-list queries share the same base (tab-independent) query.
|
|
6
6
|
* The status tab is server-side per-tab, so it is excluded here — when the base
|
|
@@ -37,7 +37,7 @@ const invoiceList = createSlice({
|
|
|
37
37
|
reducers: {
|
|
38
38
|
fetchInvoiceList: {
|
|
39
39
|
reducer(draft, action) {
|
|
40
|
-
const tab = draft.invoiceByTab
|
|
40
|
+
const tab = invoiceTabStateFor(draft.invoiceByTab, draft.activeTab);
|
|
41
41
|
if (!action.payload.keepExistingListItems) {
|
|
42
42
|
tab.invoiceIds = [];
|
|
43
43
|
tab.nextCursor = null;
|
|
@@ -80,7 +80,7 @@ const invoiceList = createSlice({
|
|
|
80
80
|
},
|
|
81
81
|
},
|
|
82
82
|
updateInvoiceList(draft, action) {
|
|
83
|
-
const tab = draft.invoiceByTab
|
|
83
|
+
const tab = invoiceTabStateFor(draft.invoiceByTab, draft.activeTab);
|
|
84
84
|
const newIds = action.payload.invoices.map((invoice) => invoice.id);
|
|
85
85
|
tab.invoiceIds = action.payload.keepExistingListItems
|
|
86
86
|
? [...new Set([...tab.invoiceIds, ...newIds])]
|
|
@@ -90,7 +90,7 @@ const invoiceList = createSlice({
|
|
|
90
90
|
tab.error = undefined;
|
|
91
91
|
},
|
|
92
92
|
updateInvoiceListFailure(draft, action) {
|
|
93
|
-
const tab = draft.invoiceByTab
|
|
93
|
+
const tab = invoiceTabStateFor(draft.invoiceByTab, draft.activeTab);
|
|
94
94
|
tab.fetchState = 'Error';
|
|
95
95
|
tab.error = action.payload;
|
|
96
96
|
},
|
|
@@ -136,14 +136,14 @@ const invoiceList = createSlice({
|
|
|
136
136
|
// are left untouched and refetched lazily.
|
|
137
137
|
addInvoiceToList(draft, action) {
|
|
138
138
|
const { id, status } = action.payload;
|
|
139
|
-
const allTab = draft.invoiceByTab
|
|
139
|
+
const allTab = invoiceTabStateFor(draft.invoiceByTab, 'all');
|
|
140
140
|
if (allTab.invoiceIds.includes(id)) {
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
143
|
allTab.invoiceIds = [id, ...allTab.invoiceIds];
|
|
144
144
|
const statusTab = statusToTabId(status);
|
|
145
145
|
if (statusTab != null) {
|
|
146
|
-
const tab = draft.invoiceByTab
|
|
146
|
+
const tab = invoiceTabStateFor(draft.invoiceByTab, statusTab);
|
|
147
147
|
if (!tab.invoiceIds.includes(id)) {
|
|
148
148
|
tab.invoiceIds = [id, ...tab.invoiceIds];
|
|
149
149
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
2
|
import { invoicingTabIdsFromConfig } from '../invoicingTabHelper';
|
|
3
|
-
import { ALL_INVOICING_INVOICE_TAB_IDS, } from './invoiceListState';
|
|
3
|
+
import { ALL_INVOICING_INVOICE_TAB_IDS, makeInvoiceTabState, } from './invoiceListState';
|
|
4
4
|
/**
|
|
5
5
|
* Bundled read view for the invoices list page: the denormalized invoice rows
|
|
6
6
|
* plus list counts, KPIs and their fetch states. Memoized so the `invoices`
|
|
@@ -8,7 +8,10 @@ import { ALL_INVOICING_INVOICE_TAB_IDS, } from './invoiceListState';
|
|
|
8
8
|
* invoice entity slice or the list-view slice actually change.
|
|
9
9
|
*/
|
|
10
10
|
export const getInvoiceListView = createSelector((state) => state.invoicingInvoiceState, (state) => state.invoicingInvoiceListState, (state) => state.invoicingConfigViewState.invoiceStatusOptions, (invoiceState, listViewState, statusOptions) => {
|
|
11
|
-
|
|
11
|
+
// Config-driven tabs: a status this build's union does not know has no
|
|
12
|
+
// cache entry until it is fetched, so default rather than crash.
|
|
13
|
+
const activeTabState = listViewState.invoiceByTab[listViewState.activeTab] ??
|
|
14
|
+
makeInvoiceTabState();
|
|
12
15
|
return {
|
|
13
16
|
activeTab: listViewState.activeTab,
|
|
14
17
|
invoices: activeTabState.invoiceIds
|
|
@@ -14,6 +14,19 @@ export const makeInvoiceTabState = () => ({
|
|
|
14
14
|
fetchState: 'Not-Started',
|
|
15
15
|
error: undefined,
|
|
16
16
|
});
|
|
17
|
+
/**
|
|
18
|
+
* The cache entry for a tab, created on first use. The tab set is config-driven,
|
|
19
|
+
* so a status this build's union does not know still needs somewhere to cache.
|
|
20
|
+
*/
|
|
21
|
+
export const invoiceTabStateFor = (invoiceByTab, tabId) => {
|
|
22
|
+
const existing = invoiceByTab[tabId];
|
|
23
|
+
if (existing != null) {
|
|
24
|
+
return existing;
|
|
25
|
+
}
|
|
26
|
+
const created = makeInvoiceTabState();
|
|
27
|
+
invoiceByTab[tabId] = created;
|
|
28
|
+
return created;
|
|
29
|
+
};
|
|
17
30
|
export const makeInvoiceByTab = () => ALL_INVOICING_INVOICE_TAB_IDS.reduce((acc, tabId) => {
|
|
18
31
|
acc[tabId] = makeInvoiceTabState();
|
|
19
32
|
return acc;
|
package/lib/esm/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js
CHANGED
|
@@ -34,8 +34,8 @@ export const fetchInvoicingCustomerDetailPageEpic = (actions$, state$) => action
|
|
|
34
34
|
const invoiceListIsForCustomer = invoiceListState.filters.customerId === id;
|
|
35
35
|
if (!invoiceListIsForCustomer ||
|
|
36
36
|
shouldFetch({
|
|
37
|
-
fetchState: invoiceListTabState
|
|
38
|
-
error: invoiceListTabState
|
|
37
|
+
fetchState: invoiceListTabState?.fetchState ?? 'Not-Started',
|
|
38
|
+
error: invoiceListTabState?.error,
|
|
39
39
|
}, cacheOverride)) {
|
|
40
40
|
pageActions.push(fetchInvoiceList({ filters: { customerId: id } }));
|
|
41
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.invoiceByTab[state.invoicingInvoiceListState.activeTab]
|
|
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),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { concat, from } from 'rxjs';
|
|
2
2
|
import { filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { makeInvoicingTransactionTabState } from '../invoicingTransactionListViewState';
|
|
3
4
|
import { fetchInvoicingTransactionList, fetchInvoicingTransactionListPage, } from '../invoicingTransactionListViewReducer';
|
|
4
5
|
/**
|
|
5
6
|
* Fetch unless the endpoint is already loaded or in flight — or always when the
|
|
@@ -16,7 +17,7 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
16
17
|
export const fetchInvoicingTransactionListPageEpic = (actions$, state$) => actions$.pipe(filter(fetchInvoicingTransactionListPage.match), mergeMap((action) => {
|
|
17
18
|
const { cacheOverride, filters, sort } = action.payload;
|
|
18
19
|
const state = state$.value.invoicingTransactionListViewState;
|
|
19
|
-
const activeTabState = state.byTab[state.activeTab];
|
|
20
|
+
const activeTabState = state.byTab[state.activeTab] ?? makeInvoicingTransactionTabState();
|
|
20
21
|
const pageActions = [];
|
|
21
22
|
if (shouldFetch({ fetchState: activeTabState.fetchState, error: activeTabState.error }, cacheOverride)) {
|
|
22
23
|
pageActions.push(fetchInvoicingTransactionList({ filters, sort }));
|
package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { clearAll } from '../../../rootActions';
|
|
3
|
-
import { makeInvoicingTransactionIdsByTab, } from './invoicingTransactionListViewState';
|
|
3
|
+
import { invoicingTransactionTabStateFor, makeInvoicingTransactionIdsByTab, } from './invoicingTransactionListViewState';
|
|
4
4
|
/**
|
|
5
5
|
* Whether two transaction-list queries share the same base (tab-independent)
|
|
6
6
|
* query. When the base query changes (search / customer / status / sort) every
|
|
@@ -22,7 +22,7 @@ const invoicingTransactionListView = createSlice({
|
|
|
22
22
|
reducers: {
|
|
23
23
|
fetchInvoicingTransactionList: {
|
|
24
24
|
reducer(draft, action) {
|
|
25
|
-
const tab = draft.byTab
|
|
25
|
+
const tab = invoicingTransactionTabStateFor(draft.byTab, draft.activeTab);
|
|
26
26
|
if (!action.payload.keepExistingListItems) {
|
|
27
27
|
tab.ids = [];
|
|
28
28
|
tab.nextCursor = null;
|
|
@@ -65,7 +65,7 @@ const invoicingTransactionListView = createSlice({
|
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
67
|
updateInvoicingTransactionList(draft, action) {
|
|
68
|
-
const tab = draft.byTab
|
|
68
|
+
const tab = invoicingTransactionTabStateFor(draft.byTab, draft.activeTab);
|
|
69
69
|
tab.ids = action.payload.keepExistingListItems
|
|
70
70
|
? [...new Set([...tab.ids, ...action.payload.ids])]
|
|
71
71
|
: action.payload.ids;
|
|
@@ -74,7 +74,7 @@ const invoicingTransactionListView = createSlice({
|
|
|
74
74
|
tab.error = undefined;
|
|
75
75
|
},
|
|
76
76
|
updateInvoicingTransactionListFailure(draft, action) {
|
|
77
|
-
const tab = draft.byTab
|
|
77
|
+
const tab = invoicingTransactionTabStateFor(draft.byTab, draft.activeTab);
|
|
78
78
|
tab.fetchState = 'Error';
|
|
79
79
|
tab.error = action.payload;
|
|
80
80
|
},
|
|
@@ -94,7 +94,7 @@ const invoicingTransactionListView = createSlice({
|
|
|
94
94
|
addInvoicingTransactionToList(draft, action) {
|
|
95
95
|
const id = action.payload;
|
|
96
96
|
const prependTo = (tabId) => {
|
|
97
|
-
const tab = draft.byTab
|
|
97
|
+
const tab = invoicingTransactionTabStateFor(draft.byTab, tabId);
|
|
98
98
|
if (!tab.ids.includes(id)) {
|
|
99
99
|
tab.ids = [id, ...tab.ids];
|
|
100
100
|
}
|
package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
2
|
import { getInvoicingTransactionsByIds } from '../../../entity/invoicing/invoicingTransaction/invoicingTransactionSelector';
|
|
3
3
|
import { invoicingTabIdsFromConfig } from '../invoicingTabHelper';
|
|
4
|
-
import { INVOICING_TRANSACTION_COLUMNS, ALL_INVOICING_TRANSACTION_TAB_IDS, } from './invoicingTransactionListViewState';
|
|
4
|
+
import { INVOICING_TRANSACTION_COLUMNS, ALL_INVOICING_TRANSACTION_TAB_IDS, makeInvoicingTransactionTabState, } from './invoicingTransactionListViewState';
|
|
5
5
|
/**
|
|
6
6
|
* Memoized so the denormalized `transactions` array (and the wrapping view
|
|
7
7
|
* object) keep referential identity until the transaction entity slice or the
|
|
8
8
|
* list-view slice actually change.
|
|
9
9
|
*/
|
|
10
10
|
export const getInvoicingTransactionListView = createSelector((state) => state.invoicingTransactionState, (state) => state.invoicingTransactionListViewState, (state) => state.invoicingConfigViewState.transactionTypeOptions, (transactionState, listViewState, statusOptions) => {
|
|
11
|
-
const activeTabState = listViewState.byTab[listViewState.activeTab];
|
|
11
|
+
const activeTabState = listViewState.byTab[listViewState.activeTab] ?? makeInvoicingTransactionTabState();
|
|
12
12
|
return {
|
|
13
13
|
activeTab: listViewState.activeTab,
|
|
14
14
|
columns: INVOICING_TRANSACTION_COLUMNS,
|
package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js
CHANGED
|
@@ -35,6 +35,16 @@ export const makeInvoicingTransactionTabState = () => ({
|
|
|
35
35
|
fetchState: 'Not-Started',
|
|
36
36
|
error: undefined,
|
|
37
37
|
});
|
|
38
|
+
/** The cache entry for a tab, created on first use. */
|
|
39
|
+
export const invoicingTransactionTabStateFor = (byTab, tabId) => {
|
|
40
|
+
const existing = byTab[tabId];
|
|
41
|
+
if (existing != null) {
|
|
42
|
+
return existing;
|
|
43
|
+
}
|
|
44
|
+
const created = makeInvoicingTransactionTabState();
|
|
45
|
+
byTab[tabId] = created;
|
|
46
|
+
return created;
|
|
47
|
+
};
|
|
38
48
|
export const makeInvoicingTransactionIdsByTab = () => ALL_INVOICING_TRANSACTION_TAB_IDS.reduce((acc, tabId) => {
|
|
39
49
|
acc[tabId] = makeInvoicingTransactionTabState();
|
|
40
50
|
return acc;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.fetchInvoiceListPageEpic = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const invoiceListState_1 = require("./invoiceListState");
|
|
6
7
|
const invoiceListReducer_1 = require("./invoiceListReducer");
|
|
7
8
|
/**
|
|
8
9
|
* Fetch unless the endpoint is already loaded or in flight — or always when the
|
|
@@ -19,7 +20,7 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
19
20
|
const fetchInvoiceListPageEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(invoiceListReducer_1.fetchInvoiceListPage.match), (0, operators_1.mergeMap)((action) => {
|
|
20
21
|
const { cacheOverride, filters, sort } = action.payload;
|
|
21
22
|
const state = state$.value.invoicingInvoiceListState;
|
|
22
|
-
const activeTabState = state.invoiceByTab[state.activeTab];
|
|
23
|
+
const activeTabState = state.invoiceByTab[state.activeTab] ?? (0, invoiceListState_1.makeInvoiceTabState)();
|
|
23
24
|
const pageActions = [];
|
|
24
25
|
if (shouldFetch({ fetchState: activeTabState.fetchState, error: activeTabState.error }, cacheOverride)) {
|
|
25
26
|
pageActions.push((0, invoiceListReducer_1.fetchInvoiceList)({ filters, sort }));
|
|
@@ -42,7 +42,7 @@ const invoiceList = (0, toolkit_1.createSlice)({
|
|
|
42
42
|
reducers: {
|
|
43
43
|
fetchInvoiceList: {
|
|
44
44
|
reducer(draft, action) {
|
|
45
|
-
const tab = draft.invoiceByTab
|
|
45
|
+
const tab = (0, invoiceListState_1.invoiceTabStateFor)(draft.invoiceByTab, draft.activeTab);
|
|
46
46
|
if (!action.payload.keepExistingListItems) {
|
|
47
47
|
tab.invoiceIds = [];
|
|
48
48
|
tab.nextCursor = null;
|
|
@@ -85,7 +85,7 @@ const invoiceList = (0, toolkit_1.createSlice)({
|
|
|
85
85
|
},
|
|
86
86
|
},
|
|
87
87
|
updateInvoiceList(draft, action) {
|
|
88
|
-
const tab = draft.invoiceByTab
|
|
88
|
+
const tab = (0, invoiceListState_1.invoiceTabStateFor)(draft.invoiceByTab, draft.activeTab);
|
|
89
89
|
const newIds = action.payload.invoices.map((invoice) => invoice.id);
|
|
90
90
|
tab.invoiceIds = action.payload.keepExistingListItems
|
|
91
91
|
? [...new Set([...tab.invoiceIds, ...newIds])]
|
|
@@ -95,7 +95,7 @@ const invoiceList = (0, toolkit_1.createSlice)({
|
|
|
95
95
|
tab.error = undefined;
|
|
96
96
|
},
|
|
97
97
|
updateInvoiceListFailure(draft, action) {
|
|
98
|
-
const tab = draft.invoiceByTab
|
|
98
|
+
const tab = (0, invoiceListState_1.invoiceTabStateFor)(draft.invoiceByTab, draft.activeTab);
|
|
99
99
|
tab.fetchState = 'Error';
|
|
100
100
|
tab.error = action.payload;
|
|
101
101
|
},
|
|
@@ -141,14 +141,14 @@ const invoiceList = (0, toolkit_1.createSlice)({
|
|
|
141
141
|
// are left untouched and refetched lazily.
|
|
142
142
|
addInvoiceToList(draft, action) {
|
|
143
143
|
const { id, status } = action.payload;
|
|
144
|
-
const allTab = draft.invoiceByTab
|
|
144
|
+
const allTab = (0, invoiceListState_1.invoiceTabStateFor)(draft.invoiceByTab, 'all');
|
|
145
145
|
if (allTab.invoiceIds.includes(id)) {
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
allTab.invoiceIds = [id, ...allTab.invoiceIds];
|
|
149
149
|
const statusTab = statusToTabId(status);
|
|
150
150
|
if (statusTab != null) {
|
|
151
|
-
const tab = draft.invoiceByTab
|
|
151
|
+
const tab = (0, invoiceListState_1.invoiceTabStateFor)(draft.invoiceByTab, statusTab);
|
|
152
152
|
if (!tab.invoiceIds.includes(id)) {
|
|
153
153
|
tab.invoiceIds = [id, ...tab.invoiceIds];
|
|
154
154
|
}
|
|
@@ -11,7 +11,10 @@ const invoiceListState_1 = require("./invoiceListState");
|
|
|
11
11
|
* invoice entity slice or the list-view slice actually change.
|
|
12
12
|
*/
|
|
13
13
|
exports.getInvoiceListView = (0, toolkit_1.createSelector)((state) => state.invoicingInvoiceState, (state) => state.invoicingInvoiceListState, (state) => state.invoicingConfigViewState.invoiceStatusOptions, (invoiceState, listViewState, statusOptions) => {
|
|
14
|
-
|
|
14
|
+
// Config-driven tabs: a status this build's union does not know has no
|
|
15
|
+
// cache entry until it is fetched, so default rather than crash.
|
|
16
|
+
const activeTabState = listViewState.invoiceByTab[listViewState.activeTab] ??
|
|
17
|
+
(0, invoiceListState_1.makeInvoiceTabState)();
|
|
15
18
|
return {
|
|
16
19
|
activeTab: listViewState.activeTab,
|
|
17
20
|
invoices: activeTabState.invoiceIds
|
|
@@ -31,7 +31,13 @@ export interface InvoiceListState {
|
|
|
31
31
|
/** Base query shared across tabs (search / customer / subscription / dates). */
|
|
32
32
|
filters: InvoiceListFilters;
|
|
33
33
|
/** Per-tab cached invoice ids + cursor + fetch state. */
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Per-tab cache. `Partial` because the tab set comes from `/1.0/config`: a
|
|
36
|
+
* status the backend added that this build's tab-id union does not know still
|
|
37
|
+
* renders a tab, and its cache entry is created on first use rather than
|
|
38
|
+
* pre-seeded. Readers must default a missing entry.
|
|
39
|
+
*/
|
|
40
|
+
invoiceByTab: Partial<Record<InvoicingInvoiceTabId, InvoiceTabState>>;
|
|
35
41
|
kpisFetchState: FetchStateAndError;
|
|
36
42
|
/** Tab-independent money KPIs. */
|
|
37
43
|
kpis?: InvoicingInvoiceKPIs;
|
|
@@ -39,4 +45,9 @@ export interface InvoiceListState {
|
|
|
39
45
|
sort?: InvoicingListSort;
|
|
40
46
|
}
|
|
41
47
|
export declare const makeInvoiceTabState: () => InvoiceTabState;
|
|
42
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The cache entry for a tab, created on first use. The tab set is config-driven,
|
|
50
|
+
* so a status this build's union does not know still needs somewhere to cache.
|
|
51
|
+
*/
|
|
52
|
+
export declare const invoiceTabStateFor: (invoiceByTab: Partial<Record<InvoicingInvoiceTabId, InvoiceTabState>>, tabId: InvoicingInvoiceTabId) => InvoiceTabState;
|
|
53
|
+
export declare const makeInvoiceByTab: () => Partial<Record<InvoicingInvoiceTabId, InvoiceTabState>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeInvoiceByTab = exports.makeInvoiceTabState = exports.toInvoicingInvoiceTabId = exports.ALL_INVOICING_INVOICE_TAB_IDS = void 0;
|
|
3
|
+
exports.makeInvoiceByTab = exports.invoiceTabStateFor = exports.makeInvoiceTabState = exports.toInvoicingInvoiceTabId = exports.ALL_INVOICING_INVOICE_TAB_IDS = void 0;
|
|
4
4
|
const stringToUnion_1 = require("../../../commonStateTypes/stringToUnion");
|
|
5
5
|
exports.ALL_INVOICING_INVOICE_TAB_IDS = [
|
|
6
6
|
'all',
|
|
@@ -19,6 +19,20 @@ const makeInvoiceTabState = () => ({
|
|
|
19
19
|
error: undefined,
|
|
20
20
|
});
|
|
21
21
|
exports.makeInvoiceTabState = makeInvoiceTabState;
|
|
22
|
+
/**
|
|
23
|
+
* The cache entry for a tab, created on first use. The tab set is config-driven,
|
|
24
|
+
* so a status this build's union does not know still needs somewhere to cache.
|
|
25
|
+
*/
|
|
26
|
+
const invoiceTabStateFor = (invoiceByTab, tabId) => {
|
|
27
|
+
const existing = invoiceByTab[tabId];
|
|
28
|
+
if (existing != null) {
|
|
29
|
+
return existing;
|
|
30
|
+
}
|
|
31
|
+
const created = (0, exports.makeInvoiceTabState)();
|
|
32
|
+
invoiceByTab[tabId] = created;
|
|
33
|
+
return created;
|
|
34
|
+
};
|
|
35
|
+
exports.invoiceTabStateFor = invoiceTabStateFor;
|
|
22
36
|
const makeInvoiceByTab = () => exports.ALL_INVOICING_INVOICE_TAB_IDS.reduce((acc, tabId) => {
|
|
23
37
|
acc[tabId] = (0, exports.makeInvoiceTabState)();
|
|
24
38
|
return acc;
|
package/lib/view/invoicing/invoicingCustomerDetailView/fetchInvoicingCustomerDetailPageEpic.js
CHANGED
|
@@ -37,8 +37,8 @@ const fetchInvoicingCustomerDetailPageEpic = (actions$, state$) => actions$.pipe
|
|
|
37
37
|
const invoiceListIsForCustomer = invoiceListState.filters.customerId === id;
|
|
38
38
|
if (!invoiceListIsForCustomer ||
|
|
39
39
|
shouldFetch({
|
|
40
|
-
fetchState: invoiceListTabState
|
|
41
|
-
error: invoiceListTabState
|
|
40
|
+
fetchState: invoiceListTabState?.fetchState ?? 'Not-Started',
|
|
41
|
+
error: invoiceListTabState?.error,
|
|
42
42
|
}, cacheOverride)) {
|
|
43
43
|
pageActions.push((0, invoiceListReducer_1.fetchInvoiceList)({ filters: { customerId: id } }));
|
|
44
44
|
}
|
package/lib/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js
CHANGED
|
@@ -16,7 +16,7 @@ const getInvoicingCustomerDetail = (state, invoicingCustomerID) => {
|
|
|
16
16
|
const settings = (0, settingsViewSelector_1.getInvoicingSettings)(state);
|
|
17
17
|
return {
|
|
18
18
|
invoicingCustomer: (0, invoicingCustomerSelector_1.getInvoicingCustomerById)(invoicingCustomerState, invoicingCustomerID),
|
|
19
|
-
invoices: (0, invoiceSelector_1.getInvoicesByIds)(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceByTab[state.invoicingInvoiceListState.activeTab]
|
|
19
|
+
invoices: (0, invoiceSelector_1.getInvoicesByIds)(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceByTab[state.invoicingInvoiceListState.activeTab]?.invoiceIds ?? []),
|
|
20
20
|
setupIntent: (0, customerPaymentMethodSelector_1.getInvoicingSetupIntent)(state),
|
|
21
21
|
setupIntentFetchState: (0, customerPaymentMethodSelector_1.getInvoicingSetupIntentFetchState)(state),
|
|
22
22
|
plaidLinkToken: (0, customerPaymentMethodSelector_1.getInvoicingPlaidLinkToken)(state),
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.fetchInvoicingTransactionListPageEpic = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const invoicingTransactionListViewState_1 = require("../invoicingTransactionListViewState");
|
|
6
7
|
const invoicingTransactionListViewReducer_1 = require("../invoicingTransactionListViewReducer");
|
|
7
8
|
/**
|
|
8
9
|
* Fetch unless the endpoint is already loaded or in flight — or always when the
|
|
@@ -19,7 +20,7 @@ const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
|
19
20
|
const fetchInvoicingTransactionListPageEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(invoicingTransactionListViewReducer_1.fetchInvoicingTransactionListPage.match), (0, operators_1.mergeMap)((action) => {
|
|
20
21
|
const { cacheOverride, filters, sort } = action.payload;
|
|
21
22
|
const state = state$.value.invoicingTransactionListViewState;
|
|
22
|
-
const activeTabState = state.byTab[state.activeTab];
|
|
23
|
+
const activeTabState = state.byTab[state.activeTab] ?? (0, invoicingTransactionListViewState_1.makeInvoicingTransactionTabState)();
|
|
23
24
|
const pageActions = [];
|
|
24
25
|
if (shouldFetch({ fetchState: activeTabState.fetchState, error: activeTabState.error }, cacheOverride)) {
|
|
25
26
|
pageActions.push((0, invoicingTransactionListViewReducer_1.fetchInvoicingTransactionList)({ filters, sort }));
|
package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js
CHANGED
|
@@ -26,7 +26,7 @@ const invoicingTransactionListView = (0, toolkit_1.createSlice)({
|
|
|
26
26
|
reducers: {
|
|
27
27
|
fetchInvoicingTransactionList: {
|
|
28
28
|
reducer(draft, action) {
|
|
29
|
-
const tab = draft.byTab
|
|
29
|
+
const tab = (0, invoicingTransactionListViewState_1.invoicingTransactionTabStateFor)(draft.byTab, draft.activeTab);
|
|
30
30
|
if (!action.payload.keepExistingListItems) {
|
|
31
31
|
tab.ids = [];
|
|
32
32
|
tab.nextCursor = null;
|
|
@@ -69,7 +69,7 @@ const invoicingTransactionListView = (0, toolkit_1.createSlice)({
|
|
|
69
69
|
},
|
|
70
70
|
},
|
|
71
71
|
updateInvoicingTransactionList(draft, action) {
|
|
72
|
-
const tab = draft.byTab
|
|
72
|
+
const tab = (0, invoicingTransactionListViewState_1.invoicingTransactionTabStateFor)(draft.byTab, draft.activeTab);
|
|
73
73
|
tab.ids = action.payload.keepExistingListItems
|
|
74
74
|
? [...new Set([...tab.ids, ...action.payload.ids])]
|
|
75
75
|
: action.payload.ids;
|
|
@@ -78,7 +78,7 @@ const invoicingTransactionListView = (0, toolkit_1.createSlice)({
|
|
|
78
78
|
tab.error = undefined;
|
|
79
79
|
},
|
|
80
80
|
updateInvoicingTransactionListFailure(draft, action) {
|
|
81
|
-
const tab = draft.byTab
|
|
81
|
+
const tab = (0, invoicingTransactionListViewState_1.invoicingTransactionTabStateFor)(draft.byTab, draft.activeTab);
|
|
82
82
|
tab.fetchState = 'Error';
|
|
83
83
|
tab.error = action.payload;
|
|
84
84
|
},
|
|
@@ -98,7 +98,7 @@ const invoicingTransactionListView = (0, toolkit_1.createSlice)({
|
|
|
98
98
|
addInvoicingTransactionToList(draft, action) {
|
|
99
99
|
const id = action.payload;
|
|
100
100
|
const prependTo = (tabId) => {
|
|
101
|
-
const tab = draft.byTab
|
|
101
|
+
const tab = (0, invoicingTransactionListViewState_1.invoicingTransactionTabStateFor)(draft.byTab, tabId);
|
|
102
102
|
if (!tab.ids.includes(id)) {
|
|
103
103
|
tab.ids = [id, ...tab.ids];
|
|
104
104
|
}
|
package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewSelector.js
CHANGED
|
@@ -11,7 +11,7 @@ const invoicingTransactionListViewState_1 = require("./invoicingTransactionListV
|
|
|
11
11
|
* list-view slice actually change.
|
|
12
12
|
*/
|
|
13
13
|
exports.getInvoicingTransactionListView = (0, toolkit_1.createSelector)((state) => state.invoicingTransactionState, (state) => state.invoicingTransactionListViewState, (state) => state.invoicingConfigViewState.transactionTypeOptions, (transactionState, listViewState, statusOptions) => {
|
|
14
|
-
const activeTabState = listViewState.byTab[listViewState.activeTab];
|
|
14
|
+
const activeTabState = listViewState.byTab[listViewState.activeTab] ?? (0, invoicingTransactionListViewState_1.makeInvoicingTransactionTabState)();
|
|
15
15
|
return {
|
|
16
16
|
activeTab: listViewState.activeTab,
|
|
17
17
|
columns: invoicingTransactionListViewState_1.INVOICING_TRANSACTION_COLUMNS,
|
package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.d.ts
CHANGED
|
@@ -32,7 +32,12 @@ export interface InvoicingTransactionTabState extends FetchStateAndError {
|
|
|
32
32
|
ids: ID[];
|
|
33
33
|
nextCursor: string | null;
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Per-tab cache. `Partial` because the tab set comes from `/1.0/config`: a type
|
|
37
|
+
* the backend added that this build's tab-id union does not know still renders a
|
|
38
|
+
* tab, and its entry is created on first use rather than pre-seeded.
|
|
39
|
+
*/
|
|
40
|
+
export type InvoicingTransactionIdsByTab = Partial<Record<InvoicingTransactionTabId, InvoicingTransactionTabState>>;
|
|
36
41
|
export interface InvoicingTransactionListViewState {
|
|
37
42
|
/** Selected type tab (CES-owned so it persists across page revisits). */
|
|
38
43
|
activeTab: InvoicingTransactionTabId;
|
|
@@ -44,4 +49,6 @@ export interface InvoicingTransactionListViewState {
|
|
|
44
49
|
sort?: InvoicingListSort;
|
|
45
50
|
}
|
|
46
51
|
export declare const makeInvoicingTransactionTabState: () => InvoicingTransactionTabState;
|
|
52
|
+
/** The cache entry for a tab, created on first use. */
|
|
53
|
+
export declare const invoicingTransactionTabStateFor: (byTab: InvoicingTransactionIdsByTab, tabId: InvoicingTransactionTabId) => InvoicingTransactionTabState;
|
|
47
54
|
export declare const makeInvoicingTransactionIdsByTab: () => InvoicingTransactionIdsByTab;
|
package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewState.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeInvoicingTransactionIdsByTab = exports.makeInvoicingTransactionTabState = exports.toInvoicingTransactionTabId = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.INVOICING_TRANSACTION_COLUMNS = exports.toInvoicingTransactionSortKey = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = void 0;
|
|
3
|
+
exports.makeInvoicingTransactionIdsByTab = exports.invoicingTransactionTabStateFor = exports.makeInvoicingTransactionTabState = exports.toInvoicingTransactionTabId = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.INVOICING_TRANSACTION_COLUMNS = exports.toInvoicingTransactionSortKey = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = void 0;
|
|
4
4
|
const stringToUnion_1 = require("../../../commonStateTypes/stringToUnion");
|
|
5
5
|
exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = [
|
|
6
6
|
'transaction',
|
|
@@ -41,6 +41,17 @@ const makeInvoicingTransactionTabState = () => ({
|
|
|
41
41
|
error: undefined,
|
|
42
42
|
});
|
|
43
43
|
exports.makeInvoicingTransactionTabState = makeInvoicingTransactionTabState;
|
|
44
|
+
/** The cache entry for a tab, created on first use. */
|
|
45
|
+
const invoicingTransactionTabStateFor = (byTab, tabId) => {
|
|
46
|
+
const existing = byTab[tabId];
|
|
47
|
+
if (existing != null) {
|
|
48
|
+
return existing;
|
|
49
|
+
}
|
|
50
|
+
const created = (0, exports.makeInvoicingTransactionTabState)();
|
|
51
|
+
byTab[tabId] = created;
|
|
52
|
+
return created;
|
|
53
|
+
};
|
|
54
|
+
exports.invoicingTransactionTabStateFor = invoicingTransactionTabStateFor;
|
|
44
55
|
const makeInvoicingTransactionIdsByTab = () => exports.ALL_INVOICING_TRANSACTION_TAB_IDS.reduce((acc, tabId) => {
|
|
45
56
|
acc[tabId] = (0, exports.makeInvoicingTransactionTabState)();
|
|
46
57
|
return acc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.1.97-
|
|
3
|
+
"version": "5.1.97-betaAK4",
|
|
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",
|