@zeniai/client-epic-state 5.1.51-betaAK3 → 5.1.51-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.
Files changed (40) hide show
  1. package/lib/esm/view/invoicing/couponView/couponViewReducer.js +21 -1
  2. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +5 -0
  3. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +15 -1
  4. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +15 -3
  5. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +12 -1
  6. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +12 -1
  7. package/lib/esm/view/invoicing/invoiceList/invoiceListReducer.js +15 -1
  8. package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogListPageEpic.js +5 -3
  9. package/lib/esm/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.js +21 -1
  10. package/lib/esm/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.js +17 -1
  11. package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.js +15 -1
  12. package/lib/esm/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +11 -1
  13. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +2 -0
  14. package/lib/view/invoicing/couponView/couponViewReducer.d.ts +5 -1
  15. package/lib/view/invoicing/couponView/couponViewReducer.js +22 -2
  16. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -1
  17. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +5 -0
  18. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +2 -1
  19. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +15 -1
  20. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.d.ts +2 -1
  21. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +15 -3
  22. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.d.ts +2 -1
  23. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +12 -1
  24. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +2 -1
  25. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +12 -1
  26. package/lib/view/invoicing/invoiceList/invoiceListReducer.d.ts +6 -2
  27. package/lib/view/invoicing/invoiceList/invoiceListReducer.js +16 -2
  28. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogListPageEpic.d.ts +2 -2
  29. package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogListPageEpic.js +5 -3
  30. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.d.ts +4 -1
  31. package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.js +22 -2
  32. package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.d.ts +4 -1
  33. package/lib/view/invoicing/invoicingCustomerListView/invoicingCustomerListViewReducer.js +18 -2
  34. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +5 -1
  35. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.js +16 -2
  36. package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.d.ts +1 -1
  37. package/lib/view/invoicing/invoicingTransactionListView/invoicingTransactionListViewReducer.js +12 -2
  38. package/lib/view/invoicing/recordPayment/recordPaymentEpic.d.ts +2 -1
  39. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +2 -0
  40. package/package.json +1 -1
@@ -1,4 +1,11 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
+ // The discounts-list tabs look up counts by tab id ('active' / 'inactive'),
3
+ // while a coupon's status is 'active' | 'expired' | 'archived'. Collapse the
4
+ // non-active statuses onto the 'inactive' tab; a newly created coupon with no
5
+ // status defaults to 'active'.
6
+ function couponStatusToTabCountKey(status) {
7
+ return status == null || status === 'active' ? 'active' : 'inactive';
8
+ }
2
9
  export const initialState = {
3
10
  fetchState: 'Not-Started',
4
11
  error: undefined,
@@ -80,10 +87,23 @@ const couponView = createSlice({
80
87
  updateInvoicingCouponFilters(draft, action) {
81
88
  draft.filters = action.payload;
82
89
  },
90
+ // Reflect a newly created coupon in the cached discounts list + tab counts
91
+ // so the list page shows it without refetching from the server. Edits keep
92
+ // the same id/counts, so only creates dispatch this.
93
+ addInvoicingCouponToList(draft, action) {
94
+ const { id, status } = action.payload;
95
+ if (draft.ids.includes(id)) {
96
+ return;
97
+ }
98
+ draft.ids = [id, ...draft.ids];
99
+ draft.counts.all += 1;
100
+ const tabCountKey = couponStatusToTabCountKey(status);
101
+ draft.counts[tabCountKey] = (draft.counts[tabCountKey] ?? 0) + 1;
102
+ },
83
103
  clearInvoicingCouponView(draft) {
84
104
  Object.assign(draft, initialState);
85
105
  },
86
106
  },
87
107
  });
88
- export const { fetchInvoicingCouponList, fetchInvoicingCouponListPage, updateInvoicingCouponList, updateInvoicingCouponListFailure, fetchInvoicingCouponCounts, updateInvoicingCouponCounts, updateInvoicingCouponCountsFailure, updateInvoicingCouponFilters, clearInvoicingCouponView, } = couponView.actions;
108
+ export const { fetchInvoicingCouponList, fetchInvoicingCouponListPage, updateInvoicingCouponList, updateInvoicingCouponListFailure, fetchInvoicingCouponCounts, updateInvoicingCouponCounts, updateInvoicingCouponCountsFailure, updateInvoicingCouponFilters, addInvoicingCouponToList, clearInvoicingCouponView, } = couponView.actions;
89
109
  export default couponView.reducer;
@@ -4,6 +4,7 @@ import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { extractInvoicingInvoiceAddresses } from '../../../entity/invoicing/invoice/invoicePayload';
5
5
  import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
+ import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
7
8
  import { createInvoice, createInvoiceFailure, createInvoiceSuccess, } from './createInvoiceReducer';
8
9
  export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(createInvoice.match), mergeMap((action) => {
9
10
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices`;
@@ -16,6 +17,10 @@ export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
16
17
  return [
17
18
  updateInvoices([response.data], 'merge'),
18
19
  updateAddresses(extractInvoicingInvoiceAddresses([response.data])),
20
+ addInvoiceToList({
21
+ id: response.data.id,
22
+ status: response.data.status,
23
+ }),
19
24
  createInvoiceSuccess({ invoiceId: response.data.id }),
20
25
  ];
21
26
  }
@@ -3,6 +3,7 @@ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingPlans } from '../../../entity/invoicing/plan/planReducer';
4
4
  import { updateInvoicingProducts } from '../../../entity/invoicing/product/productReducer';
5
5
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
6
+ import { addInvoicingCatalogItem } from '../invoicingCatalogListView/invoicingCatalogListViewReducer';
6
7
  import { localDataToSaveInvoicingCatalogItemPayload, } from './editInvoicingCatalogItemDetailViewPayload';
7
8
  import { saveInvoicingCatalogItem, submitInvoicingCatalogItemForm, submitInvoicingCatalogItemFormFailure, submitInvoicingCatalogItemFormSuccess, } from './editInvoicingCatalogItemDetailViewReducer';
8
9
  export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => submitInvoicingCatalogItemForm.match(action) ||
@@ -39,13 +40,26 @@ export const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actio
39
40
  const entityAction = kind === 'plan'
40
41
  ? updateInvoicingPlans([response.data], 'merge')
41
42
  : updateInvoicingProducts([response.data], 'merge');
42
- return [
43
+ const resultActions = [
43
44
  entityAction,
44
45
  submitInvoicingCatalogItemFormSuccess({
45
46
  itemId: response.data.id,
46
47
  kind,
47
48
  }),
48
49
  ];
50
+ // Create (no id): reflect the new row + tab counts in the cached
51
+ // catalog lists so the list page shows it without a refetch. Edits
52
+ // keep the same id/counts, so the entity merge above is enough.
53
+ if (id == null) {
54
+ const itemType = kind === 'plan'
55
+ ? 'plan'
56
+ : response.data.item_type ===
57
+ 'charge'
58
+ ? 'charge'
59
+ : 'addon';
60
+ resultActions.push(addInvoicingCatalogItem({ id: response.data.id, type: itemType }));
61
+ }
62
+ return resultActions;
49
63
  }
50
64
  return of(submitInvoicingCatalogItemFormFailure(response.status));
51
65
  }), catchError((error) => of(submitInvoicingCatalogItemFormFailure(createZeniAPIStatus('Unexpected Error', 'Save catalog item REST API call errored out ' +
@@ -2,6 +2,7 @@ import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingCoupons } from '../../../entity/invoicing/coupon/couponReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
+ import { addInvoicingCouponToList } from '../couponView/couponViewReducer';
5
6
  import { localDataToSaveInvoicingCouponPayload, } from './editInvoicingCouponDetailViewPayload';
6
7
  import { saveInvoicingCoupon, submitInvoicingCouponForm, submitInvoicingCouponFormFailure, submitInvoicingCouponFormSuccess, } from './editInvoicingCouponDetailViewReducer';
7
8
  export const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter((action) => submitInvoicingCouponForm.match(action) ||
@@ -26,10 +27,21 @@ export const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.p
26
27
  : zeniAPI.postAndGetJSON(path, { ...data });
27
28
  return request$.pipe(mergeMap((response) => {
28
29
  if (isSuccessResponse(response) && response.data != null) {
29
- return [
30
- updateInvoicingCoupons([response.data], 'merge'),
31
- submitInvoicingCouponFormSuccess({ couponId: response.data.id }),
30
+ const couponPayload = response.data;
31
+ const resultActions = [
32
+ updateInvoicingCoupons([couponPayload], 'merge'),
33
+ submitInvoicingCouponFormSuccess({ couponId: couponPayload.id }),
32
34
  ];
35
+ // Create (no id): reflect the new row + tab counts in the cached
36
+ // discounts list so it shows without a refetch. Edits keep the same
37
+ // id/counts, so the entity merge above is enough.
38
+ if (id == null) {
39
+ resultActions.push(addInvoicingCouponToList({
40
+ id: couponPayload.id,
41
+ status: couponPayload.status,
42
+ }));
43
+ }
44
+ return resultActions;
33
45
  }
34
46
  return of(submitInvoicingCouponFormFailure(response.status));
35
47
  }), catchError((error) => of(submitInvoicingCouponFormFailure(createZeniAPIStatus('Unexpected Error', 'Save coupon REST API call errored out ' + JSON.stringify(error))))));
@@ -5,6 +5,7 @@ import { extractInvoicingCustomerAddresses } from '../../../entity/invoicing/inv
5
5
  import { updateInvoicingCustomers } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
7
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
+ import { addInvoicingCustomerToList } from '../invoicingCustomerListView/invoicingCustomerListViewReducer';
8
9
  import { localDataToSaveInvoicingCustomerPayload, } from './editInvoicingCustomerDetailViewPayload';
9
10
  import { INVOICING_CUSTOMER_BILLING_ADDRESS_TYPE } from './invoicingCustomerFormConfig';
10
11
  import { submitInvoicingCustomerForm, submitInvoicingCustomerFormFailure, submitInvoicingCustomerFormSuccess, } from './editInvoicingCustomerDetailViewReducer';
@@ -25,7 +26,7 @@ export const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$
25
26
  : zeniAPI.postAndGetJSON(`${baseUrl}/customers`, { ...data });
26
27
  return request$.pipe(mergeMap((response) => {
27
28
  if (isSuccessResponse(response) && response.data != null) {
28
- return [
29
+ const resultActions = [
29
30
  updateInvoicingCustomers([response.data], 'merge'),
30
31
  updateAddresses(extractInvoicingCustomerAddresses([response.data])),
31
32
  submitInvoicingCustomerFormSuccess({
@@ -34,6 +35,16 @@ export const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$
34
35
  // Clear the stashed address so the next customer starts fresh.
35
36
  resetNewAddressDataInLocalStore(INVOICING_CUSTOMER_BILLING_ADDRESS_TYPE),
36
37
  ];
38
+ // Create (no id): reflect the new row + tab counts in the cached
39
+ // customer list so the list page shows it without a refetch. Edits
40
+ // keep the same id/counts, so the entity merge above is enough.
41
+ if (id == null) {
42
+ resultActions.push(addInvoicingCustomerToList({
43
+ id: response.data.id,
44
+ status: response.data.status,
45
+ }));
46
+ }
47
+ return resultActions;
37
48
  }
38
49
  return of(submitInvoicingCustomerFormFailure(response.status));
39
50
  }), catchError((error) => of(submitInvoicingCustomerFormFailure(createZeniAPIStatus('Unexpected Error', 'Save customer REST API call errored out ' +
@@ -5,6 +5,7 @@ import { extractInvoicingSubscriptionAddresses } from '../../../entity/invoicing
5
5
  import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
7
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
+ import { addInvoicingSubscriptionToList } from '../invoicingSubscriptionListView/invoicingSubscriptionListViewReducer';
8
9
  import { localDataToSaveInvoicingSubscriptionPayload, } from './editInvoicingSubscriptionDetailViewPayload';
9
10
  import { INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE } from './invoicingSubscriptionFormConfig';
10
11
  import { submitInvoicingSubscriptionForm, submitInvoicingSubscriptionFormFailure, submitInvoicingSubscriptionFormSuccess, } from './editInvoicingSubscriptionDetailViewReducer';
@@ -25,7 +26,7 @@ export const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => acti
25
26
  : zeniAPI.postAndGetJSON(`${baseUrl}/subscriptions`, { ...data });
26
27
  return request$.pipe(mergeMap((response) => {
27
28
  if (isSuccessResponse(response) && response.data != null) {
28
- return [
29
+ const resultActions = [
29
30
  updateInvoicingSubscriptions([response.data], 'merge'),
30
31
  updateAddresses(extractInvoicingSubscriptionAddresses([response.data])),
31
32
  submitInvoicingSubscriptionFormSuccess({
@@ -34,6 +35,16 @@ export const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => acti
34
35
  // Clear the stashed address so the next subscription starts fresh.
35
36
  resetNewAddressDataInLocalStore(INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE),
36
37
  ];
38
+ // Create (no id): reflect the new row + tab counts in the cached list
39
+ // so the list page shows it without a refetch. Edits keep the same
40
+ // id/counts, so the entity merge above is enough.
41
+ if (id == null) {
42
+ resultActions.push(addInvoicingSubscriptionToList({
43
+ id: response.data.id,
44
+ status: response.data.status,
45
+ }));
46
+ }
47
+ return resultActions;
37
48
  }
38
49
  return of(submitInvoicingSubscriptionFormFailure(response.status));
39
50
  }), catchError((error) => of(submitInvoicingSubscriptionFormFailure(createZeniAPIStatus('Unexpected Error', 'Save subscription REST API call errored out ' +
@@ -117,10 +117,24 @@ const invoiceList = createSlice({
117
117
  updateInvoiceListFilters(draft, action) {
118
118
  draft.filters = action.payload;
119
119
  },
120
+ // Reflect a newly created invoice in the cached list + tab counts so the
121
+ // invoices page shows it without refetching from the server. Bumps the
122
+ // `all` total and the per-status count key the tabs read (a create is
123
+ // typically `draft`). KPIs are money aggregates (Amount, not a plain
124
+ // increment), so they are left untouched and refetched lazily.
125
+ addInvoiceToList(draft, action) {
126
+ const { id, status } = action.payload;
127
+ if (draft.invoiceIds.includes(id)) {
128
+ return;
129
+ }
130
+ draft.invoiceIds = [id, ...draft.invoiceIds];
131
+ draft.counts.all += 1;
132
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
133
+ },
120
134
  clearInvoiceList(draft) {
121
135
  Object.assign(draft, initialState);
122
136
  },
123
137
  },
124
138
  });
125
- export const { fetchInvoiceList, fetchInvoiceListPage, updateInvoiceList, updateInvoiceListFailure, fetchInvoiceCounts, updateInvoiceCounts, updateInvoiceCountsFailure, fetchInvoiceKPIs, updateInvoiceKPIs, updateInvoiceKPIsFailure, updateInvoiceListFilters, clearInvoiceList, } = invoiceList.actions;
139
+ export const { fetchInvoiceList, fetchInvoiceListPage, updateInvoiceList, updateInvoiceListFailure, fetchInvoiceCounts, updateInvoiceCounts, updateInvoiceCountsFailure, fetchInvoiceKPIs, updateInvoiceKPIs, updateInvoiceKPIsFailure, updateInvoiceListFilters, addInvoiceToList, clearInvoiceList, } = invoiceList.actions;
126
140
  export default invoiceList.reducer;
@@ -3,15 +3,17 @@ import { filter, mergeMap } from 'rxjs/operators';
3
3
  import { fetchInvoicingCatalogCounts, fetchInvoicingCatalogListPage, fetchInvoicingCatalogPlanList, fetchInvoicingCatalogProductList, } from '../invoicingCatalogListViewReducer';
4
4
  /**
5
5
  * Fetch unless the endpoint is already loaded or in flight — or always when the
6
- * caller forces a refresh via `cacheOverride` (e.g. on a filter/sort change).
6
+ * caller forces a refresh via `cacheOverride`. The web layer sets
7
+ * `cacheOverride` per use case: false to reuse cached data (page revisit, tab
8
+ * switch), true to force a reload (search/sort change).
7
9
  */
8
10
  const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
9
11
  (fetchStateAndError.fetchState !== 'Completed' &&
10
12
  fetchStateAndError.fetchState !== 'In-Progress');
11
13
  /**
12
14
  * Orchestrates the catalog page: on `fetchInvoicingCatalogListPage`, fans out to
13
- * the plan-list, product-list, counts fetches, skipping any whose data
14
- * is already cached unless `cacheOverride` is set (e.g. on a filter/sort change).
15
+ * the plan-list, product-list and counts fetches, skipping any whose data is
16
+ * already cached unless `cacheOverride` is set.
15
17
  */
16
18
  export const fetchInvoicingCatalogListPageEpic = (actions$, state$) => actions$.pipe(filter(fetchInvoicingCatalogListPage.match), mergeMap((action) => {
17
19
  const { cacheOverride, planFilters, productFilters, planSort, productSort, } = action.payload;
@@ -106,6 +106,26 @@ const invoicingCatalogListView = createSlice({
106
106
  updateInvoicingCatalogProductFilters(draft, action) {
107
107
  draft.productFilters = action.payload;
108
108
  },
109
+ // Reflect a newly created catalog item in the cached lists + tab counts so
110
+ // the catalog page shows it without refetching all lists from the server.
111
+ // Plans land in the plan list; add-ons/one-time-charges in the (single)
112
+ // product list, split back into tabs client-side by the catalog page.
113
+ addInvoicingCatalogItem(draft, action) {
114
+ const { id, type } = action.payload;
115
+ const isPlan = type === 'plan';
116
+ const alreadyPresent = (isPlan ? draft.planIds : draft.productIds).includes(id);
117
+ if (alreadyPresent) {
118
+ return;
119
+ }
120
+ if (isPlan) {
121
+ draft.planIds = [id, ...draft.planIds];
122
+ }
123
+ else {
124
+ draft.productIds = [id, ...draft.productIds];
125
+ }
126
+ draft.counts.all += 1;
127
+ draft.counts[type] = (draft.counts[type] ?? 0) + 1;
128
+ },
109
129
  fetchInvoicingCatalogListPage: {
110
130
  reducer() {
111
131
  // No state mutation; the aggregator epic fans out the plan-list,
@@ -128,5 +148,5 @@ const invoicingCatalogListView = createSlice({
128
148
  },
129
149
  },
130
150
  });
131
- export const { fetchInvoicingCatalogPlanList, updateInvoicingCatalogPlanList, updateInvoicingCatalogPlanListFailure, fetchInvoicingCatalogProductList, updateInvoicingCatalogProductList, updateInvoicingCatalogProductListFailure, fetchInvoicingCatalogCounts, updateInvoicingCatalogCounts, updateInvoicingCatalogCountsFailure, updateInvoicingCatalogPlanFilters, updateInvoicingCatalogProductFilters, fetchInvoicingCatalogListPage, clearInvoicingCatalogListView, } = invoicingCatalogListView.actions;
151
+ export const { fetchInvoicingCatalogPlanList, updateInvoicingCatalogPlanList, updateInvoicingCatalogPlanListFailure, fetchInvoicingCatalogProductList, updateInvoicingCatalogProductList, updateInvoicingCatalogProductListFailure, fetchInvoicingCatalogCounts, updateInvoicingCatalogCounts, updateInvoicingCatalogCountsFailure, updateInvoicingCatalogPlanFilters, updateInvoicingCatalogProductFilters, addInvoicingCatalogItem, fetchInvoicingCatalogListPage, clearInvoicingCatalogListView, } = invoicingCatalogListView.actions;
132
152
  export default invoicingCatalogListView.reducer;
@@ -80,10 +80,26 @@ const invoicingCustomerListView = createSlice({
80
80
  updateInvoicingCustomerFilters(draft, action) {
81
81
  draft.filters = action.payload;
82
82
  },
83
+ // Reflect a newly created customer in the cached list + tab counts so the
84
+ // customer page shows the new row without refetching from the server. The
85
+ // per-status count key mirrors the customer `status` value the counts map
86
+ // and filter tabs key off (e.g. 'active', 'trial'); it may be unknown at
87
+ // dispatch time, so bump only `counts.all` when `status` is absent.
88
+ addInvoicingCustomerToList(draft, action) {
89
+ const { id, status } = action.payload;
90
+ if (draft.ids.includes(id)) {
91
+ return;
92
+ }
93
+ draft.ids = [id, ...draft.ids];
94
+ draft.counts.all += 1;
95
+ if (status != null) {
96
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
97
+ }
98
+ },
83
99
  clearInvoicingCustomerListView(draft) {
84
100
  Object.assign(draft, initialState);
85
101
  },
86
102
  },
87
103
  });
88
- export const { fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, updateInvoicingCustomerList, updateInvoicingCustomerListFailure, fetchInvoicingCustomerCounts, updateInvoicingCustomerCounts, updateInvoicingCustomerCountsFailure, updateInvoicingCustomerFilters, clearInvoicingCustomerListView, } = invoicingCustomerListView.actions;
104
+ export const { fetchInvoicingCustomerList, fetchInvoicingCustomerListPage, updateInvoicingCustomerList, updateInvoicingCustomerListFailure, fetchInvoicingCustomerCounts, updateInvoicingCustomerCounts, updateInvoicingCustomerCountsFailure, updateInvoicingCustomerFilters, addInvoicingCustomerToList, clearInvoicingCustomerListView, } = invoicingCustomerListView.actions;
89
105
  export default invoicingCustomerListView.reducer;
@@ -80,10 +80,24 @@ const invoicingSubscriptionListView = createSlice({
80
80
  updateInvoicingSubscriptionFilters(draft, action) {
81
81
  draft.filters = action.payload;
82
82
  },
83
+ // Reflect a newly created subscription in the cached list + tab counts so the
84
+ // subscription page shows it without refetching from the server. The status
85
+ // doubles as the per-tab count key (tab ids mirror InvoicingSubscriptionStatus).
86
+ addInvoicingSubscriptionToList(draft, action) {
87
+ const { id, status } = action.payload;
88
+ if (draft.ids.includes(id)) {
89
+ return;
90
+ }
91
+ draft.ids = [id, ...draft.ids];
92
+ draft.counts.all += 1;
93
+ if (status != null) {
94
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
95
+ }
96
+ },
83
97
  clearInvoicingSubscriptionListView(draft) {
84
98
  Object.assign(draft, initialState);
85
99
  },
86
100
  },
87
101
  });
88
- export const { fetchInvoicingSubscriptionList, fetchInvoicingSubscriptionListPage, updateInvoicingSubscriptionList, updateInvoicingSubscriptionListFailure, fetchInvoicingSubscriptionCounts, updateInvoicingSubscriptionCounts, updateInvoicingSubscriptionCountsFailure, updateInvoicingSubscriptionFilters, clearInvoicingSubscriptionListView, } = invoicingSubscriptionListView.actions;
102
+ export const { fetchInvoicingSubscriptionList, fetchInvoicingSubscriptionListPage, updateInvoicingSubscriptionList, updateInvoicingSubscriptionListFailure, fetchInvoicingSubscriptionCounts, updateInvoicingSubscriptionCounts, updateInvoicingSubscriptionCountsFailure, updateInvoicingSubscriptionFilters, addInvoicingSubscriptionToList, clearInvoicingSubscriptionListView, } = invoicingSubscriptionListView.actions;
89
103
  export default invoicingSubscriptionListView.reducer;
@@ -65,10 +65,20 @@ const invoicingTransactionListView = createSlice({
65
65
  updateInvoicingTransactionFilters(draft, action) {
66
66
  draft.filters = action.payload;
67
67
  },
68
+ // Reflect a newly recorded payment's transaction in the cached list so the
69
+ // payments page shows it without refetching. The list view has no counts
70
+ // slice, so we only prepend the id (dedup/no-op if already present).
71
+ addInvoicingTransactionToList(draft, action) {
72
+ const id = action.payload;
73
+ if (draft.ids.includes(id)) {
74
+ return;
75
+ }
76
+ draft.ids = [id, ...draft.ids];
77
+ },
68
78
  clearInvoicingTransactionListView(draft) {
69
79
  Object.assign(draft, initialState);
70
80
  },
71
81
  },
72
82
  });
73
- export const { fetchInvoicingTransactionList, fetchInvoicingTransactionListPage, updateInvoicingTransactionList, updateInvoicingTransactionListFailure, updateInvoicingTransactionFilters, clearInvoicingTransactionListView, } = invoicingTransactionListView.actions;
83
+ export const { fetchInvoicingTransactionList, fetchInvoicingTransactionListPage, updateInvoicingTransactionList, updateInvoicingTransactionListFailure, updateInvoicingTransactionFilters, addInvoicingTransactionToList, clearInvoicingTransactionListView, } = invoicingTransactionListView.actions;
74
84
  export default invoicingTransactionListView.reducer;
@@ -2,6 +2,7 @@ import { of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { updateInvoicingTransactions } from '../../../entity/invoicing/invoicingTransaction/invoicingTransactionReducer';
4
4
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
5
+ import { addInvoicingTransactionToList } from '../invoicingTransactionListView/invoicingTransactionListViewReducer';
5
6
  import { localDataToRecordPaymentPayload, } from './recordPaymentPayload';
6
7
  import { recordPaymentFailure, recordPaymentSuccess, submitRecordPayment, } from './recordPaymentReducer';
7
8
  export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(submitRecordPayment.match), mergeMap(() => {
@@ -15,6 +16,7 @@ export const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe(fi
15
16
  if (isSuccessResponse(response) && response.data != null) {
16
17
  return [
17
18
  updateInvoicingTransactions([response.data], 'merge'),
19
+ addInvoicingTransactionToList(response.data.id),
18
20
  recordPaymentSuccess({ transactionId: response.data.id }),
19
21
  ];
20
22
  }
@@ -1,4 +1,5 @@
1
1
  import { ID } from '../../../commonStateTypes/common';
2
+ import { InvoicingCouponStatus } from '../../../entity/invoicing/coupon/couponPayload';
2
3
  import { InvoicingListCounts } from '../../../entity/invoicing/invoicingCommonPayload';
3
4
  import { ZeniAPIStatus } from '../../../responsePayload';
4
5
  import { InvoicingListSort } from '../invoicingApiHelper';
@@ -26,6 +27,9 @@ export declare const fetchInvoicingCouponList: import("@reduxjs/toolkit").Action
26
27
  ids: ID[];
27
28
  keepExistingListItems: boolean;
28
29
  nextCursor: string | null;
29
- }, "invoicingCouponView/updateInvoicingCouponList">, updateInvoicingCouponListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCouponView/updateInvoicingCouponListFailure">, fetchInvoicingCouponCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCouponView/fetchInvoicingCouponCounts">, updateInvoicingCouponCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCouponView/updateInvoicingCouponCounts">, updateInvoicingCouponCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCouponView/updateInvoicingCouponCountsFailure">, updateInvoicingCouponFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCouponFilters, "invoicingCouponView/updateInvoicingCouponFilters">, clearInvoicingCouponView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCouponView/clearInvoicingCouponView">;
30
+ }, "invoicingCouponView/updateInvoicingCouponList">, updateInvoicingCouponListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCouponView/updateInvoicingCouponListFailure">, fetchInvoicingCouponCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCouponView/fetchInvoicingCouponCounts">, updateInvoicingCouponCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCouponView/updateInvoicingCouponCounts">, updateInvoicingCouponCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCouponView/updateInvoicingCouponCountsFailure">, updateInvoicingCouponFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCouponFilters, "invoicingCouponView/updateInvoicingCouponFilters">, addInvoicingCouponToList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
31
+ id: ID;
32
+ status?: InvoicingCouponStatus;
33
+ }, "invoicingCouponView/addInvoicingCouponToList">, clearInvoicingCouponView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCouponView/clearInvoicingCouponView">;
30
34
  declare const _default: import("redux").Reducer<InvoicingCouponViewState>;
31
35
  export default _default;
@@ -1,8 +1,15 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoicingCouponView = exports.updateInvoicingCouponFilters = exports.updateInvoicingCouponCountsFailure = exports.updateInvoicingCouponCounts = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCouponListFailure = exports.updateInvoicingCouponList = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.initialState = void 0;
4
+ exports.clearInvoicingCouponView = exports.addInvoicingCouponToList = exports.updateInvoicingCouponFilters = exports.updateInvoicingCouponCountsFailure = exports.updateInvoicingCouponCounts = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCouponListFailure = exports.updateInvoicingCouponList = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
+ // The discounts-list tabs look up counts by tab id ('active' / 'inactive'),
7
+ // while a coupon's status is 'active' | 'expired' | 'archived'. Collapse the
8
+ // non-active statuses onto the 'inactive' tab; a newly created coupon with no
9
+ // status defaults to 'active'.
10
+ function couponStatusToTabCountKey(status) {
11
+ return status == null || status === 'active' ? 'active' : 'inactive';
12
+ }
6
13
  exports.initialState = {
7
14
  fetchState: 'Not-Started',
8
15
  error: undefined,
@@ -84,10 +91,23 @@ const couponView = (0, toolkit_1.createSlice)({
84
91
  updateInvoicingCouponFilters(draft, action) {
85
92
  draft.filters = action.payload;
86
93
  },
94
+ // Reflect a newly created coupon in the cached discounts list + tab counts
95
+ // so the list page shows it without refetching from the server. Edits keep
96
+ // the same id/counts, so only creates dispatch this.
97
+ addInvoicingCouponToList(draft, action) {
98
+ const { id, status } = action.payload;
99
+ if (draft.ids.includes(id)) {
100
+ return;
101
+ }
102
+ draft.ids = [id, ...draft.ids];
103
+ draft.counts.all += 1;
104
+ const tabCountKey = couponStatusToTabCountKey(status);
105
+ draft.counts[tabCountKey] = (draft.counts[tabCountKey] ?? 0) + 1;
106
+ },
87
107
  clearInvoicingCouponView(draft) {
88
108
  Object.assign(draft, exports.initialState);
89
109
  },
90
110
  },
91
111
  });
92
- _a = couponView.actions, exports.fetchInvoicingCouponList = _a.fetchInvoicingCouponList, exports.fetchInvoicingCouponListPage = _a.fetchInvoicingCouponListPage, exports.updateInvoicingCouponList = _a.updateInvoicingCouponList, exports.updateInvoicingCouponListFailure = _a.updateInvoicingCouponListFailure, exports.fetchInvoicingCouponCounts = _a.fetchInvoicingCouponCounts, exports.updateInvoicingCouponCounts = _a.updateInvoicingCouponCounts, exports.updateInvoicingCouponCountsFailure = _a.updateInvoicingCouponCountsFailure, exports.updateInvoicingCouponFilters = _a.updateInvoicingCouponFilters, exports.clearInvoicingCouponView = _a.clearInvoicingCouponView;
112
+ _a = couponView.actions, exports.fetchInvoicingCouponList = _a.fetchInvoicingCouponList, exports.fetchInvoicingCouponListPage = _a.fetchInvoicingCouponListPage, exports.updateInvoicingCouponList = _a.updateInvoicingCouponList, exports.updateInvoicingCouponListFailure = _a.updateInvoicingCouponListFailure, exports.fetchInvoicingCouponCounts = _a.fetchInvoicingCouponCounts, exports.updateInvoicingCouponCounts = _a.updateInvoicingCouponCounts, exports.updateInvoicingCouponCountsFailure = _a.updateInvoicingCouponCountsFailure, exports.updateInvoicingCouponFilters = _a.updateInvoicingCouponFilters, exports.addInvoicingCouponToList = _a.addInvoicingCouponToList, exports.clearInvoicingCouponView = _a.clearInvoicingCouponView;
93
113
  exports.default = couponView.reducer;
@@ -4,6 +4,7 @@ import { updateAddresses } from '../../../entity/address/addressReducer';
4
4
  import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
5
5
  import { RootState } from '../../../reducer';
6
6
  import { ZeniAPI } from '../../../zeniAPI';
7
+ import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
7
8
  import { createInvoice, createInvoiceFailure, createInvoiceSuccess } from './createInvoiceReducer';
8
- export type ActionType = ReturnType<typeof createInvoice> | ReturnType<typeof createInvoiceSuccess> | ReturnType<typeof createInvoiceFailure> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoices>;
9
+ export type ActionType = ReturnType<typeof createInvoice> | ReturnType<typeof createInvoiceSuccess> | ReturnType<typeof createInvoiceFailure> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoices> | ReturnType<typeof addInvoiceToList>;
9
10
  export declare const createInvoiceEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -7,6 +7,7 @@ const addressReducer_1 = require("../../../entity/address/addressReducer");
7
7
  const invoicePayload_1 = require("../../../entity/invoicing/invoice/invoicePayload");
8
8
  const invoiceReducer_1 = require("../../../entity/invoicing/invoice/invoiceReducer");
9
9
  const responsePayload_1 = require("../../../responsePayload");
10
+ const invoiceListReducer_1 = require("../invoiceList/invoiceListReducer");
10
11
  const createInvoiceReducer_1 = require("./createInvoiceReducer");
11
12
  const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(createInvoiceReducer_1.createInvoice.match), (0, operators_1.mergeMap)((action) => {
12
13
  const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/invoices`;
@@ -19,6 +20,10 @@ const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, oper
19
20
  return [
20
21
  (0, invoiceReducer_1.updateInvoices)([response.data], 'merge'),
21
22
  (0, addressReducer_1.updateAddresses)((0, invoicePayload_1.extractInvoicingInvoiceAddresses)([response.data])),
23
+ (0, invoiceListReducer_1.addInvoiceToList)({
24
+ id: response.data.id,
25
+ status: response.data.status,
26
+ }),
22
27
  (0, createInvoiceReducer_1.createInvoiceSuccess)({ invoiceId: response.data.id }),
23
28
  ];
24
29
  }
@@ -3,7 +3,8 @@ import { Observable } from 'rxjs';
3
3
  import { updateInvoicingPlans } from '../../../entity/invoicing/plan/planReducer';
4
4
  import { updateInvoicingProducts } from '../../../entity/invoicing/product/productReducer';
5
5
  import { RootState } from '../../../reducer';
6
+ import { addInvoicingCatalogItem } from '../invoicingCatalogListView/invoicingCatalogListViewReducer';
6
7
  import { ZeniAPI } from '../../../zeniAPI';
7
8
  import { saveInvoicingCatalogItem, submitInvoicingCatalogItemForm, submitInvoicingCatalogItemFormFailure, submitInvoicingCatalogItemFormSuccess } from './editInvoicingCatalogItemDetailViewReducer';
8
- export type ActionType = ReturnType<typeof submitInvoicingCatalogItemForm> | ReturnType<typeof saveInvoicingCatalogItem> | ReturnType<typeof submitInvoicingCatalogItemFormSuccess> | ReturnType<typeof submitInvoicingCatalogItemFormFailure> | ReturnType<typeof updateInvoicingPlans> | ReturnType<typeof updateInvoicingProducts>;
9
+ export type ActionType = ReturnType<typeof submitInvoicingCatalogItemForm> | ReturnType<typeof saveInvoicingCatalogItem> | ReturnType<typeof submitInvoicingCatalogItemFormSuccess> | ReturnType<typeof submitInvoicingCatalogItemFormFailure> | ReturnType<typeof updateInvoicingPlans> | ReturnType<typeof updateInvoicingProducts> | ReturnType<typeof addInvoicingCatalogItem>;
9
10
  export declare const saveInvoicingCatalogItemEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
6
6
  const planReducer_1 = require("../../../entity/invoicing/plan/planReducer");
7
7
  const productReducer_1 = require("../../../entity/invoicing/product/productReducer");
8
8
  const responsePayload_1 = require("../../../responsePayload");
9
+ const invoicingCatalogListViewReducer_1 = require("../invoicingCatalogListView/invoicingCatalogListViewReducer");
9
10
  const editInvoicingCatalogItemDetailViewPayload_1 = require("./editInvoicingCatalogItemDetailViewPayload");
10
11
  const editInvoicingCatalogItemDetailViewReducer_1 = require("./editInvoicingCatalogItemDetailViewReducer");
11
12
  const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemForm.match(action) ||
@@ -42,13 +43,26 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
42
43
  const entityAction = kind === 'plan'
43
44
  ? (0, planReducer_1.updateInvoicingPlans)([response.data], 'merge')
44
45
  : (0, productReducer_1.updateInvoicingProducts)([response.data], 'merge');
45
- return [
46
+ const resultActions = [
46
47
  entityAction,
47
48
  (0, editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemFormSuccess)({
48
49
  itemId: response.data.id,
49
50
  kind,
50
51
  }),
51
52
  ];
53
+ // Create (no id): reflect the new row + tab counts in the cached
54
+ // catalog lists so the list page shows it without a refetch. Edits
55
+ // keep the same id/counts, so the entity merge above is enough.
56
+ if (id == null) {
57
+ const itemType = kind === 'plan'
58
+ ? 'plan'
59
+ : response.data.item_type ===
60
+ 'charge'
61
+ ? 'charge'
62
+ : 'addon';
63
+ resultActions.push((0, invoicingCatalogListViewReducer_1.addInvoicingCatalogItem)({ id: response.data.id, type: itemType }));
64
+ }
65
+ return resultActions;
52
66
  }
53
67
  return (0, rxjs_1.of)((0, editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemFormFailure)(response.status));
54
68
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemFormFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Save catalog item REST API call errored out ' +
@@ -2,7 +2,8 @@ import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
3
  import { updateInvoicingCoupons } from '../../../entity/invoicing/coupon/couponReducer';
4
4
  import { RootState } from '../../../reducer';
5
+ import { addInvoicingCouponToList } from '../couponView/couponViewReducer';
5
6
  import { ZeniAPI } from '../../../zeniAPI';
6
7
  import { saveInvoicingCoupon, submitInvoicingCouponForm, submitInvoicingCouponFormFailure, submitInvoicingCouponFormSuccess } from './editInvoicingCouponDetailViewReducer';
7
- export type ActionType = ReturnType<typeof submitInvoicingCouponForm> | ReturnType<typeof saveInvoicingCoupon> | ReturnType<typeof submitInvoicingCouponFormSuccess> | ReturnType<typeof submitInvoicingCouponFormFailure> | ReturnType<typeof updateInvoicingCoupons>;
8
+ export type ActionType = ReturnType<typeof submitInvoicingCouponForm> | ReturnType<typeof saveInvoicingCoupon> | ReturnType<typeof submitInvoicingCouponFormSuccess> | ReturnType<typeof submitInvoicingCouponFormFailure> | ReturnType<typeof updateInvoicingCoupons> | ReturnType<typeof addInvoicingCouponToList>;
8
9
  export declare const saveInvoicingCouponEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const couponReducer_1 = require("../../../entity/invoicing/coupon/couponReducer");
7
7
  const responsePayload_1 = require("../../../responsePayload");
8
+ const couponViewReducer_1 = require("../couponView/couponViewReducer");
8
9
  const editInvoicingCouponDetailViewPayload_1 = require("./editInvoicingCouponDetailViewPayload");
9
10
  const editInvoicingCouponDetailViewReducer_1 = require("./editInvoicingCouponDetailViewReducer");
10
11
  const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingCouponDetailViewReducer_1.submitInvoicingCouponForm.match(action) ||
@@ -29,10 +30,21 @@ const saveInvoicingCouponEpic = (actions$, state$, zeniAPI) => actions$.pipe((0,
29
30
  : zeniAPI.postAndGetJSON(path, { ...data });
30
31
  return request$.pipe((0, operators_1.mergeMap)((response) => {
31
32
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
32
- return [
33
- (0, couponReducer_1.updateInvoicingCoupons)([response.data], 'merge'),
34
- (0, editInvoicingCouponDetailViewReducer_1.submitInvoicingCouponFormSuccess)({ couponId: response.data.id }),
33
+ const couponPayload = response.data;
34
+ const resultActions = [
35
+ (0, couponReducer_1.updateInvoicingCoupons)([couponPayload], 'merge'),
36
+ (0, editInvoicingCouponDetailViewReducer_1.submitInvoicingCouponFormSuccess)({ couponId: couponPayload.id }),
35
37
  ];
38
+ // Create (no id): reflect the new row + tab counts in the cached
39
+ // discounts list so it shows without a refetch. Edits keep the same
40
+ // id/counts, so the entity merge above is enough.
41
+ if (id == null) {
42
+ resultActions.push((0, couponViewReducer_1.addInvoicingCouponToList)({
43
+ id: couponPayload.id,
44
+ status: couponPayload.status,
45
+ }));
46
+ }
47
+ return resultActions;
36
48
  }
37
49
  return (0, rxjs_1.of)((0, editInvoicingCouponDetailViewReducer_1.submitInvoicingCouponFormFailure)(response.status));
38
50
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, editInvoicingCouponDetailViewReducer_1.submitInvoicingCouponFormFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Save coupon REST API call errored out ' + JSON.stringify(error))))));
@@ -5,6 +5,7 @@ import { updateInvoicingCustomers } from '../../../entity/invoicing/invoicingCus
5
5
  import { RootState } from '../../../reducer';
6
6
  import { ZeniAPI } from '../../../zeniAPI';
7
7
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
+ import { addInvoicingCustomerToList } from '../invoicingCustomerListView/invoicingCustomerListViewReducer';
8
9
  import { submitInvoicingCustomerForm, submitInvoicingCustomerFormFailure, submitInvoicingCustomerFormSuccess } from './editInvoicingCustomerDetailViewReducer';
9
- export type ActionType = ReturnType<typeof submitInvoicingCustomerForm> | ReturnType<typeof submitInvoicingCustomerFormSuccess> | ReturnType<typeof submitInvoicingCustomerFormFailure> | ReturnType<typeof resetNewAddressDataInLocalStore> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingCustomers>;
10
+ export type ActionType = ReturnType<typeof submitInvoicingCustomerForm> | ReturnType<typeof submitInvoicingCustomerFormSuccess> | ReturnType<typeof submitInvoicingCustomerFormFailure> | ReturnType<typeof resetNewAddressDataInLocalStore> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingCustomers> | ReturnType<typeof addInvoicingCustomerToList>;
10
11
  export declare const saveInvoicingCustomerEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -8,6 +8,7 @@ const invoicingCustomerPayload_1 = require("../../../entity/invoicing/invoicingC
8
8
  const invoicingCustomerReducer_1 = require("../../../entity/invoicing/invoicingCustomer/invoicingCustomerReducer");
9
9
  const responsePayload_1 = require("../../../responsePayload");
10
10
  const addressViewReducer_1 = require("../../addressView/addressViewReducer");
11
+ const invoicingCustomerListViewReducer_1 = require("../invoicingCustomerListView/invoicingCustomerListViewReducer");
11
12
  const editInvoicingCustomerDetailViewPayload_1 = require("./editInvoicingCustomerDetailViewPayload");
12
13
  const invoicingCustomerFormConfig_1 = require("./invoicingCustomerFormConfig");
13
14
  const editInvoicingCustomerDetailViewReducer_1 = require("./editInvoicingCustomerDetailViewReducer");
@@ -28,7 +29,7 @@ const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$.pipe((
28
29
  : zeniAPI.postAndGetJSON(`${baseUrl}/customers`, { ...data });
29
30
  return request$.pipe((0, operators_1.mergeMap)((response) => {
30
31
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
31
- return [
32
+ const resultActions = [
32
33
  (0, invoicingCustomerReducer_1.updateInvoicingCustomers)([response.data], 'merge'),
33
34
  (0, addressReducer_1.updateAddresses)((0, invoicingCustomerPayload_1.extractInvoicingCustomerAddresses)([response.data])),
34
35
  (0, editInvoicingCustomerDetailViewReducer_1.submitInvoicingCustomerFormSuccess)({
@@ -37,6 +38,16 @@ const saveInvoicingCustomerEpic = (actions$, state$, zeniAPI) => actions$.pipe((
37
38
  // Clear the stashed address so the next customer starts fresh.
38
39
  (0, addressViewReducer_1.resetNewAddressDataInLocalStore)(invoicingCustomerFormConfig_1.INVOICING_CUSTOMER_BILLING_ADDRESS_TYPE),
39
40
  ];
41
+ // Create (no id): reflect the new row + tab counts in the cached
42
+ // customer list so the list page shows it without a refetch. Edits
43
+ // keep the same id/counts, so the entity merge above is enough.
44
+ if (id == null) {
45
+ resultActions.push((0, invoicingCustomerListViewReducer_1.addInvoicingCustomerToList)({
46
+ id: response.data.id,
47
+ status: response.data.status,
48
+ }));
49
+ }
50
+ return resultActions;
40
51
  }
41
52
  return (0, rxjs_1.of)((0, editInvoicingCustomerDetailViewReducer_1.submitInvoicingCustomerFormFailure)(response.status));
42
53
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, editInvoicingCustomerDetailViewReducer_1.submitInvoicingCustomerFormFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Save customer REST API call errored out ' +
@@ -5,6 +5,7 @@ import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicin
5
5
  import { RootState } from '../../../reducer';
6
6
  import { ZeniAPI } from '../../../zeniAPI';
7
7
  import { resetNewAddressDataInLocalStore } from '../../addressView/addressViewReducer';
8
+ import { addInvoicingSubscriptionToList } from '../invoicingSubscriptionListView/invoicingSubscriptionListViewReducer';
8
9
  import { submitInvoicingSubscriptionForm, submitInvoicingSubscriptionFormFailure, submitInvoicingSubscriptionFormSuccess } from './editInvoicingSubscriptionDetailViewReducer';
9
- export type ActionType = ReturnType<typeof submitInvoicingSubscriptionForm> | ReturnType<typeof submitInvoicingSubscriptionFormSuccess> | ReturnType<typeof submitInvoicingSubscriptionFormFailure> | ReturnType<typeof resetNewAddressDataInLocalStore> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingSubscriptions>;
10
+ export type ActionType = ReturnType<typeof submitInvoicingSubscriptionForm> | ReturnType<typeof submitInvoicingSubscriptionFormSuccess> | ReturnType<typeof submitInvoicingSubscriptionFormFailure> | ReturnType<typeof resetNewAddressDataInLocalStore> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingSubscriptions> | ReturnType<typeof addInvoicingSubscriptionToList>;
10
11
  export declare const saveInvoicingSubscriptionEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -8,6 +8,7 @@ const invoicingSubscriptionPayload_1 = require("../../../entity/invoicing/invoic
8
8
  const invoicingSubscriptionReducer_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer");
9
9
  const responsePayload_1 = require("../../../responsePayload");
10
10
  const addressViewReducer_1 = require("../../addressView/addressViewReducer");
11
+ const invoicingSubscriptionListViewReducer_1 = require("../invoicingSubscriptionListView/invoicingSubscriptionListViewReducer");
11
12
  const editInvoicingSubscriptionDetailViewPayload_1 = require("./editInvoicingSubscriptionDetailViewPayload");
12
13
  const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
13
14
  const editInvoicingSubscriptionDetailViewReducer_1 = require("./editInvoicingSubscriptionDetailViewReducer");
@@ -28,7 +29,7 @@ const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => actions$.pi
28
29
  : zeniAPI.postAndGetJSON(`${baseUrl}/subscriptions`, { ...data });
29
30
  return request$.pipe((0, operators_1.mergeMap)((response) => {
30
31
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
31
- return [
32
+ const resultActions = [
32
33
  (0, invoicingSubscriptionReducer_1.updateInvoicingSubscriptions)([response.data], 'merge'),
33
34
  (0, addressReducer_1.updateAddresses)((0, invoicingSubscriptionPayload_1.extractInvoicingSubscriptionAddresses)([response.data])),
34
35
  (0, editInvoicingSubscriptionDetailViewReducer_1.submitInvoicingSubscriptionFormSuccess)({
@@ -37,6 +38,16 @@ const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => actions$.pi
37
38
  // Clear the stashed address so the next subscription starts fresh.
38
39
  (0, addressViewReducer_1.resetNewAddressDataInLocalStore)(invoicingSubscriptionFormConfig_1.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE),
39
40
  ];
41
+ // Create (no id): reflect the new row + tab counts in the cached list
42
+ // so the list page shows it without a refetch. Edits keep the same
43
+ // id/counts, so the entity merge above is enough.
44
+ if (id == null) {
45
+ resultActions.push((0, invoicingSubscriptionListViewReducer_1.addInvoicingSubscriptionToList)({
46
+ id: response.data.id,
47
+ status: response.data.status,
48
+ }));
49
+ }
50
+ return resultActions;
40
51
  }
41
52
  return (0, rxjs_1.of)((0, editInvoicingSubscriptionDetailViewReducer_1.submitInvoicingSubscriptionFormFailure)(response.status));
42
53
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, editInvoicingSubscriptionDetailViewReducer_1.submitInvoicingSubscriptionFormFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Save subscription REST API call errored out ' +
@@ -1,4 +1,5 @@
1
- import { InvoicingInvoicePayload } from '../../../entity/invoicing/invoice/invoicePayload';
1
+ import { ID } from '../../../commonStateTypes/common';
2
+ import { InvoicingInvoicePayload, InvoicingInvoiceStatus } from '../../../entity/invoicing/invoice/invoicePayload';
2
3
  import { InvoicingInvoiceKPIs } from '../../../entity/invoicing/invoice/invoiceState';
3
4
  import { InvoicingListCounts } from '../../../entity/invoicing/invoicingCommonPayload';
4
5
  import { ZeniAPIStatus } from '../../../responsePayload';
@@ -39,6 +40,9 @@ export declare const fetchInvoiceList: import("@reduxjs/toolkit").ActionCreatorW
39
40
  invoices: InvoicingInvoicePayload[];
40
41
  keepExistingListItems: boolean;
41
42
  nextCursor: string | null;
42
- }, "invoicingInvoiceList/updateInvoiceList">, updateInvoiceListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceListFailure">, fetchInvoiceCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/fetchInvoiceCounts">, updateInvoiceCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingInvoiceList/updateInvoiceCounts">, updateInvoiceCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceCountsFailure">, fetchInvoiceKPIs: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/fetchInvoiceKPIs">, updateInvoiceKPIs: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingInvoiceKPIs, "invoicingInvoiceList/updateInvoiceKPIs">, updateInvoiceKPIsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceKPIsFailure">, updateInvoiceListFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoiceListFilters, "invoicingInvoiceList/updateInvoiceListFilters">, clearInvoiceList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/clearInvoiceList">;
43
+ }, "invoicingInvoiceList/updateInvoiceList">, updateInvoiceListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceListFailure">, fetchInvoiceCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/fetchInvoiceCounts">, updateInvoiceCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingInvoiceList/updateInvoiceCounts">, updateInvoiceCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceCountsFailure">, fetchInvoiceKPIs: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/fetchInvoiceKPIs">, updateInvoiceKPIs: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingInvoiceKPIs, "invoicingInvoiceList/updateInvoiceKPIs">, updateInvoiceKPIsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingInvoiceList/updateInvoiceKPIsFailure">, updateInvoiceListFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoiceListFilters, "invoicingInvoiceList/updateInvoiceListFilters">, addInvoiceToList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
44
+ id: ID;
45
+ status: InvoicingInvoiceStatus;
46
+ }, "invoicingInvoiceList/addInvoiceToList">, clearInvoiceList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingInvoiceList/clearInvoiceList">;
43
47
  declare const _default: import("redux").Reducer<InvoiceListState>;
44
48
  export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoiceList = exports.updateInvoiceListFilters = exports.updateInvoiceKPIsFailure = exports.updateInvoiceKPIs = exports.fetchInvoiceKPIs = exports.updateInvoiceCountsFailure = exports.updateInvoiceCounts = exports.fetchInvoiceCounts = exports.updateInvoiceListFailure = exports.updateInvoiceList = exports.fetchInvoiceListPage = exports.fetchInvoiceList = exports.initialState = exports.sameInvoiceListQuery = void 0;
4
+ exports.clearInvoiceList = exports.addInvoiceToList = exports.updateInvoiceListFilters = exports.updateInvoiceKPIsFailure = exports.updateInvoiceKPIs = exports.fetchInvoiceKPIs = exports.updateInvoiceCountsFailure = exports.updateInvoiceCounts = exports.fetchInvoiceCounts = exports.updateInvoiceListFailure = exports.updateInvoiceList = exports.fetchInvoiceListPage = exports.fetchInvoiceList = exports.initialState = exports.sameInvoiceListQuery = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  /**
7
7
  * Whether two invoice-list queries (filters + sort) would return the same list.
@@ -122,10 +122,24 @@ const invoiceList = (0, toolkit_1.createSlice)({
122
122
  updateInvoiceListFilters(draft, action) {
123
123
  draft.filters = action.payload;
124
124
  },
125
+ // Reflect a newly created invoice in the cached list + tab counts so the
126
+ // invoices page shows it without refetching from the server. Bumps the
127
+ // `all` total and the per-status count key the tabs read (a create is
128
+ // typically `draft`). KPIs are money aggregates (Amount, not a plain
129
+ // increment), so they are left untouched and refetched lazily.
130
+ addInvoiceToList(draft, action) {
131
+ const { id, status } = action.payload;
132
+ if (draft.invoiceIds.includes(id)) {
133
+ return;
134
+ }
135
+ draft.invoiceIds = [id, ...draft.invoiceIds];
136
+ draft.counts.all += 1;
137
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
138
+ },
125
139
  clearInvoiceList(draft) {
126
140
  Object.assign(draft, exports.initialState);
127
141
  },
128
142
  },
129
143
  });
130
- _a = invoiceList.actions, exports.fetchInvoiceList = _a.fetchInvoiceList, exports.fetchInvoiceListPage = _a.fetchInvoiceListPage, exports.updateInvoiceList = _a.updateInvoiceList, exports.updateInvoiceListFailure = _a.updateInvoiceListFailure, exports.fetchInvoiceCounts = _a.fetchInvoiceCounts, exports.updateInvoiceCounts = _a.updateInvoiceCounts, exports.updateInvoiceCountsFailure = _a.updateInvoiceCountsFailure, exports.fetchInvoiceKPIs = _a.fetchInvoiceKPIs, exports.updateInvoiceKPIs = _a.updateInvoiceKPIs, exports.updateInvoiceKPIsFailure = _a.updateInvoiceKPIsFailure, exports.updateInvoiceListFilters = _a.updateInvoiceListFilters, exports.clearInvoiceList = _a.clearInvoiceList;
144
+ _a = invoiceList.actions, exports.fetchInvoiceList = _a.fetchInvoiceList, exports.fetchInvoiceListPage = _a.fetchInvoiceListPage, exports.updateInvoiceList = _a.updateInvoiceList, exports.updateInvoiceListFailure = _a.updateInvoiceListFailure, exports.fetchInvoiceCounts = _a.fetchInvoiceCounts, exports.updateInvoiceCounts = _a.updateInvoiceCounts, exports.updateInvoiceCountsFailure = _a.updateInvoiceCountsFailure, exports.fetchInvoiceKPIs = _a.fetchInvoiceKPIs, exports.updateInvoiceKPIs = _a.updateInvoiceKPIs, exports.updateInvoiceKPIsFailure = _a.updateInvoiceKPIsFailure, exports.updateInvoiceListFilters = _a.updateInvoiceListFilters, exports.addInvoiceToList = _a.addInvoiceToList, exports.clearInvoiceList = _a.clearInvoiceList;
131
145
  exports.default = invoiceList.reducer;
@@ -11,7 +11,7 @@ import { fetchInvoicingCatalogCounts, fetchInvoicingCatalogListPage, fetchInvoic
11
11
  export type ActionType = ReturnType<typeof fetchInvoicingCatalogPlanList> | ReturnType<typeof fetchInvoicingCatalogProductList> | ReturnType<typeof fetchInvoicingCatalogListPage> | ReturnType<typeof fetchInvoicingCatalogCounts> | ReturnType<typeof updateInvoicingCatalogPlanList> | ReturnType<typeof updateInvoicingCatalogPlanListFailure> | ReturnType<typeof updateInvoicingCatalogProductList> | ReturnType<typeof updateInvoicingCatalogProductListFailure> | ReturnType<typeof updateInvoicingCatalogCounts> | ReturnType<typeof updateInvoicingCatalogCountsFailure> | ReturnType<typeof updateInvoicingPlans> | ReturnType<typeof updateInvoicingProducts>;
12
12
  /**
13
13
  * Orchestrates the catalog page: on `fetchInvoicingCatalogListPage`, fans out to
14
- * the plan-list, product-list, counts fetches, skipping any whose data
15
- * is already cached unless `cacheOverride` is set (e.g. on a filter/sort change).
14
+ * the plan-list, product-list and counts fetches, skipping any whose data is
15
+ * already cached unless `cacheOverride` is set.
16
16
  */
17
17
  export declare const fetchInvoicingCatalogListPageEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
@@ -6,15 +6,17 @@ const operators_1 = require("rxjs/operators");
6
6
  const invoicingCatalogListViewReducer_1 = require("../invoicingCatalogListViewReducer");
7
7
  /**
8
8
  * Fetch unless the endpoint is already loaded or in flight — or always when the
9
- * caller forces a refresh via `cacheOverride` (e.g. on a filter/sort change).
9
+ * caller forces a refresh via `cacheOverride`. The web layer sets
10
+ * `cacheOverride` per use case: false to reuse cached data (page revisit, tab
11
+ * switch), true to force a reload (search/sort change).
10
12
  */
11
13
  const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
12
14
  (fetchStateAndError.fetchState !== 'Completed' &&
13
15
  fetchStateAndError.fetchState !== 'In-Progress');
14
16
  /**
15
17
  * Orchestrates the catalog page: on `fetchInvoicingCatalogListPage`, fans out to
16
- * the plan-list, product-list, counts fetches, skipping any whose data
17
- * is already cached unless `cacheOverride` is set (e.g. on a filter/sort change).
18
+ * the plan-list, product-list and counts fetches, skipping any whose data is
19
+ * already cached unless `cacheOverride` is set.
18
20
  */
19
21
  const fetchInvoicingCatalogListPageEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(invoicingCatalogListViewReducer_1.fetchInvoicingCatalogListPage.match), (0, operators_1.mergeMap)((action) => {
20
22
  const { cacheOverride, planFilters, productFilters, planSort, productSort, } = action.payload;
@@ -32,7 +32,10 @@ export declare const fetchInvoicingCatalogPlanList: import("@reduxjs/toolkit").A
32
32
  ids: ID[];
33
33
  keepExistingListItems: boolean;
34
34
  nextCursor: string | null;
35
- }, "invoicingCatalogListView/updateInvoicingCatalogProductList">, updateInvoicingCatalogProductListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCatalogListView/updateInvoicingCatalogProductListFailure">, fetchInvoicingCatalogCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCatalogListView/fetchInvoicingCatalogCounts">, updateInvoicingCatalogCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCatalogListView/updateInvoicingCatalogCounts">, updateInvoicingCatalogCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCatalogListView/updateInvoicingCatalogCountsFailure">, updateInvoicingCatalogPlanFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCatalogPlanFilters, "invoicingCatalogListView/updateInvoicingCatalogPlanFilters">, updateInvoicingCatalogProductFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCatalogProductFilters, "invoicingCatalogListView/updateInvoicingCatalogProductFilters">, fetchInvoicingCatalogListPage: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
35
+ }, "invoicingCatalogListView/updateInvoicingCatalogProductList">, updateInvoicingCatalogProductListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCatalogListView/updateInvoicingCatalogProductListFailure">, fetchInvoicingCatalogCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCatalogListView/fetchInvoicingCatalogCounts">, updateInvoicingCatalogCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCatalogListView/updateInvoicingCatalogCounts">, updateInvoicingCatalogCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCatalogListView/updateInvoicingCatalogCountsFailure">, updateInvoicingCatalogPlanFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCatalogPlanFilters, "invoicingCatalogListView/updateInvoicingCatalogPlanFilters">, updateInvoicingCatalogProductFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCatalogProductFilters, "invoicingCatalogListView/updateInvoicingCatalogProductFilters">, addInvoicingCatalogItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
36
+ id: ID;
37
+ type: "addon" | "charge" | "plan";
38
+ }, "invoicingCatalogListView/addInvoicingCatalogItem">, fetchInvoicingCatalogListPage: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
36
39
  cacheOverride?: boolean;
37
40
  planFilters?: InvoicingCatalogPlanFilters;
38
41
  planSort?: InvoicingListSort;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoicingCatalogListView = exports.fetchInvoicingCatalogListPage = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.updateInvoicingCatalogCountsFailure = exports.updateInvoicingCatalogCounts = exports.fetchInvoicingCatalogCounts = exports.updateInvoicingCatalogProductListFailure = exports.updateInvoicingCatalogProductList = exports.fetchInvoicingCatalogProductList = exports.updateInvoicingCatalogPlanListFailure = exports.updateInvoicingCatalogPlanList = exports.fetchInvoicingCatalogPlanList = exports.initialState = void 0;
4
+ exports.clearInvoicingCatalogListView = exports.fetchInvoicingCatalogListPage = exports.addInvoicingCatalogItem = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.updateInvoicingCatalogCountsFailure = exports.updateInvoicingCatalogCounts = exports.fetchInvoicingCatalogCounts = exports.updateInvoicingCatalogProductListFailure = exports.updateInvoicingCatalogProductList = exports.fetchInvoicingCatalogProductList = exports.updateInvoicingCatalogPlanListFailure = exports.updateInvoicingCatalogPlanList = exports.fetchInvoicingCatalogPlanList = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  exports.initialState = {
7
7
  fetchState: 'Not-Started',
@@ -110,6 +110,26 @@ const invoicingCatalogListView = (0, toolkit_1.createSlice)({
110
110
  updateInvoicingCatalogProductFilters(draft, action) {
111
111
  draft.productFilters = action.payload;
112
112
  },
113
+ // Reflect a newly created catalog item in the cached lists + tab counts so
114
+ // the catalog page shows it without refetching all lists from the server.
115
+ // Plans land in the plan list; add-ons/one-time-charges in the (single)
116
+ // product list, split back into tabs client-side by the catalog page.
117
+ addInvoicingCatalogItem(draft, action) {
118
+ const { id, type } = action.payload;
119
+ const isPlan = type === 'plan';
120
+ const alreadyPresent = (isPlan ? draft.planIds : draft.productIds).includes(id);
121
+ if (alreadyPresent) {
122
+ return;
123
+ }
124
+ if (isPlan) {
125
+ draft.planIds = [id, ...draft.planIds];
126
+ }
127
+ else {
128
+ draft.productIds = [id, ...draft.productIds];
129
+ }
130
+ draft.counts.all += 1;
131
+ draft.counts[type] = (draft.counts[type] ?? 0) + 1;
132
+ },
113
133
  fetchInvoicingCatalogListPage: {
114
134
  reducer() {
115
135
  // No state mutation; the aggregator epic fans out the plan-list,
@@ -132,5 +152,5 @@ const invoicingCatalogListView = (0, toolkit_1.createSlice)({
132
152
  },
133
153
  },
134
154
  });
135
- _a = invoicingCatalogListView.actions, exports.fetchInvoicingCatalogPlanList = _a.fetchInvoicingCatalogPlanList, exports.updateInvoicingCatalogPlanList = _a.updateInvoicingCatalogPlanList, exports.updateInvoicingCatalogPlanListFailure = _a.updateInvoicingCatalogPlanListFailure, exports.fetchInvoicingCatalogProductList = _a.fetchInvoicingCatalogProductList, exports.updateInvoicingCatalogProductList = _a.updateInvoicingCatalogProductList, exports.updateInvoicingCatalogProductListFailure = _a.updateInvoicingCatalogProductListFailure, exports.fetchInvoicingCatalogCounts = _a.fetchInvoicingCatalogCounts, exports.updateInvoicingCatalogCounts = _a.updateInvoicingCatalogCounts, exports.updateInvoicingCatalogCountsFailure = _a.updateInvoicingCatalogCountsFailure, exports.updateInvoicingCatalogPlanFilters = _a.updateInvoicingCatalogPlanFilters, exports.updateInvoicingCatalogProductFilters = _a.updateInvoicingCatalogProductFilters, exports.fetchInvoicingCatalogListPage = _a.fetchInvoicingCatalogListPage, exports.clearInvoicingCatalogListView = _a.clearInvoicingCatalogListView;
155
+ _a = invoicingCatalogListView.actions, exports.fetchInvoicingCatalogPlanList = _a.fetchInvoicingCatalogPlanList, exports.updateInvoicingCatalogPlanList = _a.updateInvoicingCatalogPlanList, exports.updateInvoicingCatalogPlanListFailure = _a.updateInvoicingCatalogPlanListFailure, exports.fetchInvoicingCatalogProductList = _a.fetchInvoicingCatalogProductList, exports.updateInvoicingCatalogProductList = _a.updateInvoicingCatalogProductList, exports.updateInvoicingCatalogProductListFailure = _a.updateInvoicingCatalogProductListFailure, exports.fetchInvoicingCatalogCounts = _a.fetchInvoicingCatalogCounts, exports.updateInvoicingCatalogCounts = _a.updateInvoicingCatalogCounts, exports.updateInvoicingCatalogCountsFailure = _a.updateInvoicingCatalogCountsFailure, exports.updateInvoicingCatalogPlanFilters = _a.updateInvoicingCatalogPlanFilters, exports.updateInvoicingCatalogProductFilters = _a.updateInvoicingCatalogProductFilters, exports.addInvoicingCatalogItem = _a.addInvoicingCatalogItem, exports.fetchInvoicingCatalogListPage = _a.fetchInvoicingCatalogListPage, exports.clearInvoicingCatalogListView = _a.clearInvoicingCatalogListView;
136
156
  exports.default = invoicingCatalogListView.reducer;
@@ -26,6 +26,9 @@ export declare const fetchInvoicingCustomerList: import("@reduxjs/toolkit").Acti
26
26
  ids: ID[];
27
27
  keepExistingListItems: boolean;
28
28
  nextCursor: string | null;
29
- }, "invoicingCustomerListView/updateInvoicingCustomerList">, updateInvoicingCustomerListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCustomerListView/updateInvoicingCustomerListFailure">, fetchInvoicingCustomerCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCustomerListView/fetchInvoicingCustomerCounts">, updateInvoicingCustomerCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCustomerListView/updateInvoicingCustomerCounts">, updateInvoicingCustomerCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCustomerListView/updateInvoicingCustomerCountsFailure">, updateInvoicingCustomerFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCustomerFilters, "invoicingCustomerListView/updateInvoicingCustomerFilters">, clearInvoicingCustomerListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCustomerListView/clearInvoicingCustomerListView">;
29
+ }, "invoicingCustomerListView/updateInvoicingCustomerList">, updateInvoicingCustomerListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCustomerListView/updateInvoicingCustomerListFailure">, fetchInvoicingCustomerCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCustomerListView/fetchInvoicingCustomerCounts">, updateInvoicingCustomerCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingCustomerListView/updateInvoicingCustomerCounts">, updateInvoicingCustomerCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCustomerListView/updateInvoicingCustomerCountsFailure">, updateInvoicingCustomerFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingCustomerFilters, "invoicingCustomerListView/updateInvoicingCustomerFilters">, addInvoicingCustomerToList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
30
+ id: ID;
31
+ status?: string;
32
+ }, "invoicingCustomerListView/addInvoicingCustomerToList">, clearInvoicingCustomerListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingCustomerListView/clearInvoicingCustomerListView">;
30
33
  declare const _default: import("redux").Reducer<InvoicingCustomerListViewState>;
31
34
  export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoicingCustomerListView = exports.updateInvoicingCustomerFilters = exports.updateInvoicingCustomerCountsFailure = exports.updateInvoicingCustomerCounts = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomerListFailure = exports.updateInvoicingCustomerList = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.initialState = void 0;
4
+ exports.clearInvoicingCustomerListView = exports.addInvoicingCustomerToList = exports.updateInvoicingCustomerFilters = exports.updateInvoicingCustomerCountsFailure = exports.updateInvoicingCustomerCounts = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomerListFailure = exports.updateInvoicingCustomerList = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  exports.initialState = {
7
7
  fetchState: 'Not-Started',
@@ -84,10 +84,26 @@ const invoicingCustomerListView = (0, toolkit_1.createSlice)({
84
84
  updateInvoicingCustomerFilters(draft, action) {
85
85
  draft.filters = action.payload;
86
86
  },
87
+ // Reflect a newly created customer in the cached list + tab counts so the
88
+ // customer page shows the new row without refetching from the server. The
89
+ // per-status count key mirrors the customer `status` value the counts map
90
+ // and filter tabs key off (e.g. 'active', 'trial'); it may be unknown at
91
+ // dispatch time, so bump only `counts.all` when `status` is absent.
92
+ addInvoicingCustomerToList(draft, action) {
93
+ const { id, status } = action.payload;
94
+ if (draft.ids.includes(id)) {
95
+ return;
96
+ }
97
+ draft.ids = [id, ...draft.ids];
98
+ draft.counts.all += 1;
99
+ if (status != null) {
100
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
101
+ }
102
+ },
87
103
  clearInvoicingCustomerListView(draft) {
88
104
  Object.assign(draft, exports.initialState);
89
105
  },
90
106
  },
91
107
  });
92
- _a = invoicingCustomerListView.actions, exports.fetchInvoicingCustomerList = _a.fetchInvoicingCustomerList, exports.fetchInvoicingCustomerListPage = _a.fetchInvoicingCustomerListPage, exports.updateInvoicingCustomerList = _a.updateInvoicingCustomerList, exports.updateInvoicingCustomerListFailure = _a.updateInvoicingCustomerListFailure, exports.fetchInvoicingCustomerCounts = _a.fetchInvoicingCustomerCounts, exports.updateInvoicingCustomerCounts = _a.updateInvoicingCustomerCounts, exports.updateInvoicingCustomerCountsFailure = _a.updateInvoicingCustomerCountsFailure, exports.updateInvoicingCustomerFilters = _a.updateInvoicingCustomerFilters, exports.clearInvoicingCustomerListView = _a.clearInvoicingCustomerListView;
108
+ _a = invoicingCustomerListView.actions, exports.fetchInvoicingCustomerList = _a.fetchInvoicingCustomerList, exports.fetchInvoicingCustomerListPage = _a.fetchInvoicingCustomerListPage, exports.updateInvoicingCustomerList = _a.updateInvoicingCustomerList, exports.updateInvoicingCustomerListFailure = _a.updateInvoicingCustomerListFailure, exports.fetchInvoicingCustomerCounts = _a.fetchInvoicingCustomerCounts, exports.updateInvoicingCustomerCounts = _a.updateInvoicingCustomerCounts, exports.updateInvoicingCustomerCountsFailure = _a.updateInvoicingCustomerCountsFailure, exports.updateInvoicingCustomerFilters = _a.updateInvoicingCustomerFilters, exports.addInvoicingCustomerToList = _a.addInvoicingCustomerToList, exports.clearInvoicingCustomerListView = _a.clearInvoicingCustomerListView;
93
109
  exports.default = invoicingCustomerListView.reducer;
@@ -1,5 +1,6 @@
1
1
  import { ID } from '../../../commonStateTypes/common';
2
2
  import { InvoicingListCounts } from '../../../entity/invoicing/invoicingCommonPayload';
3
+ import { InvoicingSubscriptionStatus } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload';
3
4
  import { ZeniAPIStatus } from '../../../responsePayload';
4
5
  import { InvoicingListSort } from '../invoicingApiHelper';
5
6
  import { InvoicingSubscriptionFilters, InvoicingSubscriptionListViewState } from './invoicingSubscriptionListViewState';
@@ -26,6 +27,9 @@ export declare const fetchInvoicingSubscriptionList: import("@reduxjs/toolkit").
26
27
  ids: ID[];
27
28
  keepExistingListItems: boolean;
28
29
  nextCursor: string | null;
29
- }, "invoicingSubscriptionListView/updateInvoicingSubscriptionList">, updateInvoicingSubscriptionListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingSubscriptionListView/updateInvoicingSubscriptionListFailure">, fetchInvoicingSubscriptionCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingSubscriptionListView/fetchInvoicingSubscriptionCounts">, updateInvoicingSubscriptionCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingSubscriptionListView/updateInvoicingSubscriptionCounts">, updateInvoicingSubscriptionCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingSubscriptionListView/updateInvoicingSubscriptionCountsFailure">, updateInvoicingSubscriptionFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingSubscriptionFilters, "invoicingSubscriptionListView/updateInvoicingSubscriptionFilters">, clearInvoicingSubscriptionListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingSubscriptionListView/clearInvoicingSubscriptionListView">;
30
+ }, "invoicingSubscriptionListView/updateInvoicingSubscriptionList">, updateInvoicingSubscriptionListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingSubscriptionListView/updateInvoicingSubscriptionListFailure">, fetchInvoicingSubscriptionCounts: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingSubscriptionListView/fetchInvoicingSubscriptionCounts">, updateInvoicingSubscriptionCounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingListCounts, "invoicingSubscriptionListView/updateInvoicingSubscriptionCounts">, updateInvoicingSubscriptionCountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingSubscriptionListView/updateInvoicingSubscriptionCountsFailure">, updateInvoicingSubscriptionFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingSubscriptionFilters, "invoicingSubscriptionListView/updateInvoicingSubscriptionFilters">, addInvoicingSubscriptionToList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
31
+ id: ID;
32
+ status?: InvoicingSubscriptionStatus;
33
+ }, "invoicingSubscriptionListView/addInvoicingSubscriptionToList">, clearInvoicingSubscriptionListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingSubscriptionListView/clearInvoicingSubscriptionListView">;
30
34
  declare const _default: import("redux").Reducer<InvoicingSubscriptionListViewState>;
31
35
  export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoicingSubscriptionListView = exports.updateInvoicingSubscriptionFilters = exports.updateInvoicingSubscriptionCountsFailure = exports.updateInvoicingSubscriptionCounts = exports.fetchInvoicingSubscriptionCounts = exports.updateInvoicingSubscriptionListFailure = exports.updateInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.initialState = void 0;
4
+ exports.clearInvoicingSubscriptionListView = exports.addInvoicingSubscriptionToList = exports.updateInvoicingSubscriptionFilters = exports.updateInvoicingSubscriptionCountsFailure = exports.updateInvoicingSubscriptionCounts = exports.fetchInvoicingSubscriptionCounts = exports.updateInvoicingSubscriptionListFailure = exports.updateInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  exports.initialState = {
7
7
  fetchState: 'Not-Started',
@@ -84,10 +84,24 @@ const invoicingSubscriptionListView = (0, toolkit_1.createSlice)({
84
84
  updateInvoicingSubscriptionFilters(draft, action) {
85
85
  draft.filters = action.payload;
86
86
  },
87
+ // Reflect a newly created subscription in the cached list + tab counts so the
88
+ // subscription page shows it without refetching from the server. The status
89
+ // doubles as the per-tab count key (tab ids mirror InvoicingSubscriptionStatus).
90
+ addInvoicingSubscriptionToList(draft, action) {
91
+ const { id, status } = action.payload;
92
+ if (draft.ids.includes(id)) {
93
+ return;
94
+ }
95
+ draft.ids = [id, ...draft.ids];
96
+ draft.counts.all += 1;
97
+ if (status != null) {
98
+ draft.counts[status] = (draft.counts[status] ?? 0) + 1;
99
+ }
100
+ },
87
101
  clearInvoicingSubscriptionListView(draft) {
88
102
  Object.assign(draft, exports.initialState);
89
103
  },
90
104
  },
91
105
  });
92
- _a = invoicingSubscriptionListView.actions, exports.fetchInvoicingSubscriptionList = _a.fetchInvoicingSubscriptionList, exports.fetchInvoicingSubscriptionListPage = _a.fetchInvoicingSubscriptionListPage, exports.updateInvoicingSubscriptionList = _a.updateInvoicingSubscriptionList, exports.updateInvoicingSubscriptionListFailure = _a.updateInvoicingSubscriptionListFailure, exports.fetchInvoicingSubscriptionCounts = _a.fetchInvoicingSubscriptionCounts, exports.updateInvoicingSubscriptionCounts = _a.updateInvoicingSubscriptionCounts, exports.updateInvoicingSubscriptionCountsFailure = _a.updateInvoicingSubscriptionCountsFailure, exports.updateInvoicingSubscriptionFilters = _a.updateInvoicingSubscriptionFilters, exports.clearInvoicingSubscriptionListView = _a.clearInvoicingSubscriptionListView;
106
+ _a = invoicingSubscriptionListView.actions, exports.fetchInvoicingSubscriptionList = _a.fetchInvoicingSubscriptionList, exports.fetchInvoicingSubscriptionListPage = _a.fetchInvoicingSubscriptionListPage, exports.updateInvoicingSubscriptionList = _a.updateInvoicingSubscriptionList, exports.updateInvoicingSubscriptionListFailure = _a.updateInvoicingSubscriptionListFailure, exports.fetchInvoicingSubscriptionCounts = _a.fetchInvoicingSubscriptionCounts, exports.updateInvoicingSubscriptionCounts = _a.updateInvoicingSubscriptionCounts, exports.updateInvoicingSubscriptionCountsFailure = _a.updateInvoicingSubscriptionCountsFailure, exports.updateInvoicingSubscriptionFilters = _a.updateInvoicingSubscriptionFilters, exports.addInvoicingSubscriptionToList = _a.addInvoicingSubscriptionToList, exports.clearInvoicingSubscriptionListView = _a.clearInvoicingSubscriptionListView;
93
107
  exports.default = invoicingSubscriptionListView.reducer;
@@ -25,6 +25,6 @@ export declare const fetchInvoicingTransactionList: import("@reduxjs/toolkit").A
25
25
  ids: ID[];
26
26
  keepExistingListItems: boolean;
27
27
  nextCursor: string | null;
28
- }, "invoicingTransactionListView/updateInvoicingTransactionList">, updateInvoicingTransactionListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingTransactionListView/updateInvoicingTransactionListFailure">, updateInvoicingTransactionFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingTransactionFilters, "invoicingTransactionListView/updateInvoicingTransactionFilters">, clearInvoicingTransactionListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingTransactionListView/clearInvoicingTransactionListView">;
28
+ }, "invoicingTransactionListView/updateInvoicingTransactionList">, updateInvoicingTransactionListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingTransactionListView/updateInvoicingTransactionListFailure">, updateInvoicingTransactionFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingTransactionFilters, "invoicingTransactionListView/updateInvoicingTransactionFilters">, addInvoicingTransactionToList: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "invoicingTransactionListView/addInvoicingTransactionToList">, clearInvoicingTransactionListView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingTransactionListView/clearInvoicingTransactionListView">;
29
29
  declare const _default: import("redux").Reducer<InvoicingTransactionListViewState>;
30
30
  export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearInvoicingTransactionListView = exports.updateInvoicingTransactionFilters = exports.updateInvoicingTransactionListFailure = exports.updateInvoicingTransactionList = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.initialState = void 0;
4
+ exports.clearInvoicingTransactionListView = exports.addInvoicingTransactionToList = exports.updateInvoicingTransactionFilters = exports.updateInvoicingTransactionListFailure = exports.updateInvoicingTransactionList = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  exports.initialState = {
7
7
  fetchState: 'Not-Started',
@@ -69,10 +69,20 @@ const invoicingTransactionListView = (0, toolkit_1.createSlice)({
69
69
  updateInvoicingTransactionFilters(draft, action) {
70
70
  draft.filters = action.payload;
71
71
  },
72
+ // Reflect a newly recorded payment's transaction in the cached list so the
73
+ // payments page shows it without refetching. The list view has no counts
74
+ // slice, so we only prepend the id (dedup/no-op if already present).
75
+ addInvoicingTransactionToList(draft, action) {
76
+ const id = action.payload;
77
+ if (draft.ids.includes(id)) {
78
+ return;
79
+ }
80
+ draft.ids = [id, ...draft.ids];
81
+ },
72
82
  clearInvoicingTransactionListView(draft) {
73
83
  Object.assign(draft, exports.initialState);
74
84
  },
75
85
  },
76
86
  });
77
- _a = invoicingTransactionListView.actions, exports.fetchInvoicingTransactionList = _a.fetchInvoicingTransactionList, exports.fetchInvoicingTransactionListPage = _a.fetchInvoicingTransactionListPage, exports.updateInvoicingTransactionList = _a.updateInvoicingTransactionList, exports.updateInvoicingTransactionListFailure = _a.updateInvoicingTransactionListFailure, exports.updateInvoicingTransactionFilters = _a.updateInvoicingTransactionFilters, exports.clearInvoicingTransactionListView = _a.clearInvoicingTransactionListView;
87
+ _a = invoicingTransactionListView.actions, exports.fetchInvoicingTransactionList = _a.fetchInvoicingTransactionList, exports.fetchInvoicingTransactionListPage = _a.fetchInvoicingTransactionListPage, exports.updateInvoicingTransactionList = _a.updateInvoicingTransactionList, exports.updateInvoicingTransactionListFailure = _a.updateInvoicingTransactionListFailure, exports.updateInvoicingTransactionFilters = _a.updateInvoicingTransactionFilters, exports.addInvoicingTransactionToList = _a.addInvoicingTransactionToList, exports.clearInvoicingTransactionListView = _a.clearInvoicingTransactionListView;
78
88
  exports.default = invoicingTransactionListView.reducer;
@@ -2,7 +2,8 @@ import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
3
  import { updateInvoicingTransactions } from '../../../entity/invoicing/invoicingTransaction/invoicingTransactionReducer';
4
4
  import { RootState } from '../../../reducer';
5
+ import { addInvoicingTransactionToList } from '../invoicingTransactionListView/invoicingTransactionListViewReducer';
5
6
  import { ZeniAPI } from '../../../zeniAPI';
6
7
  import { recordPaymentFailure, recordPaymentSuccess, submitRecordPayment } from './recordPaymentReducer';
7
- export type ActionType = ReturnType<typeof submitRecordPayment> | ReturnType<typeof recordPaymentSuccess> | ReturnType<typeof recordPaymentFailure> | ReturnType<typeof updateInvoicingTransactions>;
8
+ export type ActionType = ReturnType<typeof submitRecordPayment> | ReturnType<typeof recordPaymentSuccess> | ReturnType<typeof recordPaymentFailure> | ReturnType<typeof updateInvoicingTransactions> | ReturnType<typeof addInvoicingTransactionToList>;
8
9
  export declare const recordPaymentEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const invoicingTransactionReducer_1 = require("../../../entity/invoicing/invoicingTransaction/invoicingTransactionReducer");
7
7
  const responsePayload_1 = require("../../../responsePayload");
8
+ const invoicingTransactionListViewReducer_1 = require("../invoicingTransactionListView/invoicingTransactionListViewReducer");
8
9
  const recordPaymentPayload_1 = require("./recordPaymentPayload");
9
10
  const recordPaymentReducer_1 = require("./recordPaymentReducer");
10
11
  const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(recordPaymentReducer_1.submitRecordPayment.match), (0, operators_1.mergeMap)(() => {
@@ -18,6 +19,7 @@ const recordPaymentEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, opera
18
19
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
19
20
  return [
20
21
  (0, invoicingTransactionReducer_1.updateInvoicingTransactions)([response.data], 'merge'),
22
+ (0, invoicingTransactionListViewReducer_1.addInvoicingTransactionToList)(response.data.id),
21
23
  (0, recordPaymentReducer_1.recordPaymentSuccess)({ transactionId: response.data.id }),
22
24
  ];
23
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.1.51-betaAK3",
3
+ "version": "5.1.51-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",