@zeniai/client-epic-state 5.2.50-betaRD1 → 5.2.50

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 (85) hide show
  1. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +1 -4
  2. package/lib/entity/jeSchedules/jeSchedulesReducer.js +5 -47
  3. package/lib/epic.d.ts +1 -2
  4. package/lib/epic.js +4 -6
  5. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +4 -46
  6. package/lib/esm/epic.js +4 -6
  7. package/lib/esm/index.js +3 -3
  8. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +1 -9
  9. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +13 -10
  10. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/initializeJeScheduleLocalDataEpic.js +15 -29
  11. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.js +1 -12
  12. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +1 -60
  13. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +11 -11
  14. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +19 -11
  15. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +4 -1
  16. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -2
  17. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +26 -7
  18. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.js +19 -11
  19. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.js +3 -1
  20. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +1 -1
  21. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.js +25 -6
  22. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +19 -11
  23. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +4 -2
  24. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +1 -1
  25. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.js +25 -6
  26. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.js +21 -13
  27. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +3 -2
  28. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +4 -1
  29. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -1
  30. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.js +29 -8
  31. package/lib/esm/view/invoicing/invoicingFormDraft.js +65 -0
  32. package/lib/index.d.ts +3 -3
  33. package/lib/index.js +49 -50
  34. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.d.ts +2 -2
  35. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +0 -8
  36. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +11 -8
  37. package/lib/view/expenseAutomationView/epics/jeSchedule/initializeJeScheduleLocalDataEpic.js +15 -29
  38. package/lib/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.d.ts +2 -2
  39. package/lib/view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic.js +1 -12
  40. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +0 -18
  41. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -8
  42. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +3 -62
  43. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +0 -2
  44. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +11 -11
  45. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +0 -15
  46. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.d.ts +3 -1
  47. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +19 -11
  48. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +10 -0
  49. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +4 -1
  50. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewState.d.ts +2 -1
  51. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -2
  52. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.d.ts +10 -6
  53. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/seedInvoicingCatalogItemFormDraftEpic.js +25 -6
  54. package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.d.ts +3 -1
  55. package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewReducer.js +19 -11
  56. package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.d.ts +13 -0
  57. package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewSelector.js +3 -1
  58. package/lib/view/invoicing/editInvoicingCouponDetailView/editInvoicingCouponDetailViewState.d.ts +2 -1
  59. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +1 -1
  60. package/lib/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.d.ts +10 -6
  61. package/lib/view/invoicing/editInvoicingCouponDetailView/seedInvoicingCouponFormDraftEpic.js +24 -5
  62. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.d.ts +3 -1
  63. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer.js +19 -11
  64. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.d.ts +9 -0
  65. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewSelector.js +4 -2
  66. package/lib/view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewState.d.ts +2 -1
  67. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +1 -1
  68. package/lib/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.d.ts +10 -6
  69. package/lib/view/invoicing/editInvoicingCustomerDetailView/seedInvoicingCustomerFormDraftEpic.js +24 -5
  70. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.d.ts +3 -1
  71. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewReducer.js +21 -13
  72. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.d.ts +9 -0
  73. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +3 -2
  74. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewState.d.ts +2 -1
  75. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +4 -1
  76. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +1 -1
  77. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.d.ts +10 -6
  78. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/seedInvoicingSubscriptionFormDraftEpic.js +28 -7
  79. package/lib/view/invoicing/invoicingFormDraft.d.ts +54 -0
  80. package/lib/view/invoicing/invoicingFormDraft.js +72 -0
  81. package/package.json +1 -1
  82. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.js +0 -40
  83. package/lib/tsconfig.mocks.tsbuildinfo +0 -1
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.d.ts +0 -20
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchFailedJePostingsEpic.js +0 -44
@@ -8,6 +8,7 @@ const couponViewSelector_1 = require("../couponView/couponViewSelector");
8
8
  const invoicingCatalogListViewSelector_1 = require("../invoicingCatalogListView/invoicingCatalogListViewSelector");
9
9
  const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
10
10
  const invoicingCustomerListViewSelector_1 = require("../invoicingCustomerListView/invoicingCustomerListViewSelector");
11
+ const invoicingFormDraft_1 = require("../invoicingFormDraft");
11
12
  const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
12
13
  const invoicingSubscriptionFormConfig_2 = require("./invoicingSubscriptionFormConfig");
13
14
  const getEditInvoicingSubscriptionDetailViewState = (state, invoicingSubscriptionID) => {
@@ -37,8 +38,7 @@ const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
37
38
  // `seedInvoicingSubscriptionFormDraftEpic` when the detail load lands. Until
38
39
  // then the page is showing its skeleton.
39
40
  const localData = invoicingSubscriptionID != null
40
- ? (editDraftById[invoicingSubscriptionID] ??
41
- invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData)
41
+ ? (0, invoicingFormDraft_1.getInvoicingFormDraftLocalData)(editDraftById, invoicingSubscriptionID, invoicingSubscriptionFormConfig_1.initialInvoicingSubscriptionFormLocalData)
42
42
  : newSubscriptionDraft;
43
43
  // Shipping address is captured via the shared Address screen and seeded there
44
44
  // (looked up in the shared address store by `shippingAddressId`) on detail
@@ -69,6 +69,7 @@ const getInvoicingSubscriptionFormView = (state, invoicingSubscriptionID) => {
69
69
  subscriptionLifecycleActionOptions: configState.subscriptionLifecycleActionOptions,
70
70
  subscriptionMetadataEditAllowedFromStatuses: configState.subscriptionMetadataEditAllowedFromStatuses,
71
71
  recordState,
72
+ isFormLoading: (0, invoicingFormDraft_1.isInvoicingFormDraftPending)(editDraftById, invoicingSubscriptionID),
72
73
  fieldHelp: (0, invoicingConfigViewSelector_1.invoicingFieldHelpForGroup)(state, 'subscription'),
73
74
  coupons: (0, couponViewSelector_1.getInvoicingCouponListItems)(state),
74
75
  customers: (0, invoicingCustomerListViewSelector_1.getInvoicingCustomerListView)(state).customers,
@@ -1,5 +1,6 @@
1
1
  import { Amount } from '../../../commonStateTypes/amount';
2
2
  import { FetchStateAndError, FetchedState, ID } from '../../../commonStateTypes/common';
3
+ import { InvoicingFormDraftById } from '../invoicingFormDraft';
3
4
  /**
4
5
  * Draft form state for the create/edit subscription form. Held in CES so the
5
6
  * form flows its data from here (mirrors the customer form / bill-pay pattern).
@@ -41,7 +42,7 @@ export interface InvoicingSubscriptionFormLocalData {
41
42
  export interface EditInvoicingSubscriptionDetailViewState extends FetchedState {
42
43
  /** Lifecycle action fetch state per subscription id. */
43
44
  actionStateById: Record<ID, FetchStateAndError>;
44
- editDraftById: Record<ID, InvoicingSubscriptionFormLocalData>;
45
+ editDraftById: InvoicingFormDraftById<InvoicingSubscriptionFormLocalData>;
45
46
  newSubscriptionDraft: InvoicingSubscriptionFormLocalData;
46
47
  /** Detail-load state per subscription id. */
47
48
  recordStateById: Record<ID, FetchStateAndError>;
@@ -19,8 +19,11 @@ const fetchInvoicingSubscriptionFormPageEpic = (actions$) => actions$.pipe((0, o
19
19
  const { subscriptionId } = action.payload;
20
20
  const pageActions = [
21
21
  (0, invoicingCustomerListViewReducer_1.fetchInvoicingCustomerList)({ filters: {}, keepExistingListItems: false }),
22
+ // Plans only: the form's plan picker is the one consumer, and an
23
+ // unfiltered list would replace the store's plans with every catalog
24
+ // item.
22
25
  (0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
23
- filters: {},
26
+ filters: { type: 'plan' },
24
27
  keepExistingListItems: false,
25
28
  }),
26
29
  (0, couponViewReducer_1.fetchInvoicingCouponList)({ filters: {}, keepExistingListItems: false }),
@@ -20,7 +20,7 @@ const saveInvoicingSubscriptionEpic = (actions$, state$, zeniAPI) => actions$.pi
20
20
  const rootState = state$.value;
21
21
  const viewState = rootState.editInvoicingSubscriptionDetailViewState;
22
22
  const localData = (id != null
23
- ? viewState.editDraftById[id]
23
+ ? viewState.editDraftById[id]?.localData
24
24
  : viewState.newSubscriptionDraft) ?? viewState.newSubscriptionDraft;
25
25
  // Shipping address captured via the shared Address screen is sent as an
26
26
  // object in the payload (same pattern as the customer save flow).
@@ -1,12 +1,16 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { Observable } from 'rxjs';
3
3
  import { RootState } from '../../../rootStateTypes';
4
- import { seedInvoicingSubscriptionFormDraft, updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
5
- export type ActionType = ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof seedInvoicingSubscriptionFormDraft>;
4
+ import { fetchInvoicingSubscriptionFormPage, seedInvoicingSubscriptionFormDraft, updateInvoicingSubscriptionDetail } from './editInvoicingSubscriptionDetailViewReducer';
5
+ export type ActionType = ReturnType<typeof fetchInvoicingSubscriptionFormPage> | ReturnType<typeof updateInvoicingSubscriptionDetail> | ReturnType<typeof seedInvoicingSubscriptionFormDraft>;
6
6
  /**
7
- * Seeds the edit draft from the record the moment the detail fetch lands, so
8
- * the form has its values before it mounts. The reducer ignores the seed when a
9
- * draft already exists, which is what stops a background refetch from
10
- * overwriting edits in progress.
7
+ * Seeds the edit draft from the record, so the form has its values before it
8
+ * mounts. The reducer ignores a seed once the draft holds the record, which is
9
+ * what stops a background refetch from overwriting edits in progress.
10
+ *
11
+ * Opening the page counts as a trigger, not just the detail response: the page
12
+ * fetch is cache-guarded, so re-opening a form for a record already loaded this
13
+ * session issues no request at all — and a draft cleared in between (by a save
14
+ * or a cancel) would have nothing left to seed it.
11
15
  */
12
16
  export declare const seedInvoicingSubscriptionFormDraftEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
@@ -7,14 +7,35 @@ const editInvoicingSubscriptionDetailViewReducer_1 = require("./editInvoicingSub
7
7
  const invoicingSubscriptionDetailHelper_1 = require("./invoicingSubscriptionDetailHelper");
8
8
  const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormConfig");
9
9
  /**
10
- * Seeds the edit draft from the record the moment the detail fetch lands, so
11
- * the form has its values before it mounts. The reducer ignores the seed when a
12
- * draft already exists, which is what stops a background refetch from
13
- * overwriting edits in progress.
10
+ * Seeds the edit draft from the record, so the form has its values before it
11
+ * mounts. The reducer ignores a seed once the draft holds the record, which is
12
+ * what stops a background refetch from overwriting edits in progress.
13
+ *
14
+ * Opening the page counts as a trigger, not just the detail response: the page
15
+ * fetch is cache-guarded, so re-opening a form for a record already loaded this
16
+ * session issues no request at all — and a draft cleared in between (by a save
17
+ * or a cancel) would have nothing left to seed it.
14
18
  */
15
- const seedInvoicingSubscriptionFormDraftEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match), (0, operators_1.withLatestFrom)(state$), (0, operators_1.mergeMap)(([action, state]) => {
16
- const { id } = action.payload;
17
- const subscription = (0, invoicingSubscriptionDetailHelper_1.getInvoicingSubscriptionById)(state, id);
19
+ const seedInvoicingSubscriptionFormDraftEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match(action) ||
20
+ editInvoicingSubscriptionDetailViewReducer_1.fetchInvoicingSubscriptionFormPage.match(action)), (0, operators_1.withLatestFrom)(state$), (0, operators_1.mergeMap)(([action, state]) => {
21
+ const id = editInvoicingSubscriptionDetailViewReducer_1.updateInvoicingSubscriptionDetail.match(action)
22
+ ? action.payload.id
23
+ : action.payload.subscriptionId;
24
+ if (id == null) {
25
+ return rxjs_1.EMPTY;
26
+ }
27
+ // The entity alone does not say the whole record is loaded — the list
28
+ // endpoints merge their own list-shaped rows into the same store. Only a
29
+ // completed detail load does, which is also exactly when the page's
30
+ // cache-guarded fetch issues no request and this is the sole seed.
31
+ if (editInvoicingSubscriptionDetailViewReducer_1.fetchInvoicingSubscriptionFormPage.match(action) &&
32
+ state.editInvoicingSubscriptionDetailViewState.recordStateById[id]
33
+ ?.fetchState !== 'Completed') {
34
+ return rxjs_1.EMPTY;
35
+ }
36
+ // Nothing to seed from on a cold open; the detail response triggers this
37
+ // again once it lands.
38
+ const subscription = id != null ? (0, invoicingSubscriptionDetailHelper_1.getInvoicingSubscriptionById)(state, id) : undefined;
18
39
  if (subscription == null) {
19
40
  return rxjs_1.EMPTY;
20
41
  }
@@ -0,0 +1,54 @@
1
+ import { FetchState, ID } from '../../commonStateTypes/common';
2
+ /**
3
+ * A create/edit form's draft, plus where its values came from.
4
+ *
5
+ * The status is what lets an edit form tell "these are the record's values"
6
+ * from "these are whatever the form had at first render". It cannot be read off
7
+ * the presence of a draft, because the form writes drafts too: it pushes its
8
+ * whole state back on every change, so a change made before the record landed
9
+ * leaves a draft that looks seeded but holds nothing.
10
+ *
11
+ * `Not-Started` — written by the form, never filled from a record.
12
+ * `Completed` — filled from the loaded record; the form may have edited it since.
13
+ * `Error` — the record's fetch failed, so the form starts blank and a
14
+ * later successful fetch is still allowed to seed it.
15
+ */
16
+ export interface InvoicingFormDraft<TLocalData> {
17
+ fetchState: FetchState;
18
+ localData: TLocalData;
19
+ }
20
+ export type InvoicingFormDraftById<TLocalData> = Record<ID, InvoicingFormDraft<TLocalData>>;
21
+ /**
22
+ * The form's own write. Keeps the status: an edit on top of a seeded draft is
23
+ * still the record's draft, and an edit made before the record arrived must not
24
+ * pass for one.
25
+ */
26
+ export declare function applyInvoicingFormDraftEdit<TLocalData>(draftById: InvoicingFormDraftById<TLocalData>, id: ID, localData: TLocalData): void;
27
+ /**
28
+ * Fill the draft from the loaded record, once. A second seed is ignored so a
29
+ * late refetch cannot overwrite edits in progress — but a draft the form wrote
30
+ * before the record landed is replaced, since it was never the record's.
31
+ */
32
+ export declare function applyInvoicingFormDraftSeed<TLocalData>(draftById: InvoicingFormDraftById<TLocalData>, id: ID, localData: TLocalData): void;
33
+ /**
34
+ * Record that the fetch failed, so the form renders instead of waiting behind a
35
+ * skeleton that will never resolve.
36
+ *
37
+ * Mirrors the seed: a draft holding the record is left alone, since a
38
+ * background refetch failing is no reason to discard it, and anything else is
39
+ * marked failed. A draft the form wrote before the record landed keeps its
40
+ * values — there is no reason to throw away what the user typed — but stops
41
+ * counting as still loading, and a later successful fetch can still seed it.
42
+ */
43
+ export declare function applyInvoicingFormDraftFailure<TLocalData>(draftById: InvoicingFormDraftById<TLocalData>, id: ID, blankLocalData: TLocalData): void;
44
+ /** The draft's values, or the blank form when nothing is drafted yet. */
45
+ export declare function getInvoicingFormDraftLocalData<TLocalData>(draftById: InvoicingFormDraftById<TLocalData>, id: ID | undefined, blankLocalData: TLocalData): TLocalData;
46
+ /**
47
+ * Whether the form should still be showing its skeleton — the record has
48
+ * neither reached the draft nor failed trying.
49
+ *
50
+ * Settles once and stays settled, which is what keeps a later refetch from
51
+ * swapping a form the user is typing into back for a skeleton. Create mode
52
+ * (no id) has no record to wait for.
53
+ */
54
+ export declare function isInvoicingFormDraftPending<TLocalData>(draftById: InvoicingFormDraftById<TLocalData>, id: ID | undefined): boolean;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyInvoicingFormDraftEdit = applyInvoicingFormDraftEdit;
4
+ exports.applyInvoicingFormDraftSeed = applyInvoicingFormDraftSeed;
5
+ exports.applyInvoicingFormDraftFailure = applyInvoicingFormDraftFailure;
6
+ exports.getInvoicingFormDraftLocalData = getInvoicingFormDraftLocalData;
7
+ exports.isInvoicingFormDraftPending = isInvoicingFormDraftPending;
8
+ /**
9
+ * The form's own write. Keeps the status: an edit on top of a seeded draft is
10
+ * still the record's draft, and an edit made before the record arrived must not
11
+ * pass for one.
12
+ */
13
+ function applyInvoicingFormDraftEdit(draftById, id, localData) {
14
+ draftById[id] = {
15
+ fetchState: draftById[id]?.fetchState ?? 'Not-Started',
16
+ localData,
17
+ };
18
+ }
19
+ /**
20
+ * Fill the draft from the loaded record, once. A second seed is ignored so a
21
+ * late refetch cannot overwrite edits in progress — but a draft the form wrote
22
+ * before the record landed is replaced, since it was never the record's.
23
+ */
24
+ function applyInvoicingFormDraftSeed(draftById, id, localData) {
25
+ if (draftById[id]?.fetchState === 'Completed') {
26
+ return;
27
+ }
28
+ draftById[id] = { fetchState: 'Completed', localData };
29
+ }
30
+ /**
31
+ * Record that the fetch failed, so the form renders instead of waiting behind a
32
+ * skeleton that will never resolve.
33
+ *
34
+ * Mirrors the seed: a draft holding the record is left alone, since a
35
+ * background refetch failing is no reason to discard it, and anything else is
36
+ * marked failed. A draft the form wrote before the record landed keeps its
37
+ * values — there is no reason to throw away what the user typed — but stops
38
+ * counting as still loading, and a later successful fetch can still seed it.
39
+ */
40
+ function applyInvoicingFormDraftFailure(draftById, id, blankLocalData) {
41
+ const existing = draftById[id];
42
+ if (existing == null) {
43
+ draftById[id] = { fetchState: 'Error', localData: blankLocalData };
44
+ return;
45
+ }
46
+ if (existing.fetchState === 'Completed') {
47
+ return;
48
+ }
49
+ existing.fetchState = 'Error';
50
+ }
51
+ /** The draft's values, or the blank form when nothing is drafted yet. */
52
+ function getInvoicingFormDraftLocalData(draftById, id, blankLocalData) {
53
+ if (id == null) {
54
+ return blankLocalData;
55
+ }
56
+ return draftById[id]?.localData ?? blankLocalData;
57
+ }
58
+ /**
59
+ * Whether the form should still be showing its skeleton — the record has
60
+ * neither reached the draft nor failed trying.
61
+ *
62
+ * Settles once and stays settled, which is what keeps a later refetch from
63
+ * swapping a form the user is typing into back for a skeleton. Create mode
64
+ * (no id) has no record to wait for.
65
+ */
66
+ function isInvoicingFormDraftPending(draftById, id) {
67
+ if (id == null) {
68
+ return false;
69
+ }
70
+ const fetchState = draftById[id]?.fetchState;
71
+ return fetchState !== 'Completed' && fetchState !== 'Error';
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.2.50-betaRD1",
3
+ "version": "5.2.50",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -1,40 +0,0 @@
1
- import { from, of } from 'rxjs';
2
- import { catchError, filter, switchMap, takeUntil } from 'rxjs/operators';
3
- import { updateJESchedules, updateJESchedulesDetails, } from '../../../../entity/jeSchedules/jeSchedulesReducer';
4
- import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
5
- import { clearAll } from '../../../../rootActions';
6
- import { fetchFailedJePostings, fetchFailedJePostingsFailure, fetchFailedJePostingsSuccess, initializeJeScheduleLocalData, } from '../../reducers/jeSchedulesViewReducer';
7
- /**
8
- * Fetches every currently-failing posting for the tenant, on its own endpoint and with no window.
9
- *
10
- * Sends no query at all. The endpoint takes an optional `expected_post_start_date` floor and the
11
- * client deliberately omits it: a failure is outstanding work until someone resolves it, whatever
12
- * month it belongs to, and windowing this list is exactly what kept older failures off the only
13
- * screen that can resolve them.
14
- *
15
- * `switchMap`, not `mergeMap`: there is one list per tenant, so a second trigger supersedes the
16
- * first rather than racing it.
17
- */
18
- export const fetchFailedJePostingsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchFailedJePostings.match), switchMap(() => zeniAPI
19
- .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/expenses_automation/failed_je_postings`)
20
- .pipe(switchMap((response) => {
21
- if (!isSuccessResponse(response) || response.data == null) {
22
- return of(fetchFailedJePostingsFailure(response.status));
23
- }
24
- const failedJeSchedules = response.data.failed_je_postings?.je_schedules ?? [];
25
- const failedScheduledJournalEntries = response.data.failed_je_postings?.scheduled_journal_entries ?? [];
26
- // Order matters and matches fetchJeSchedulesEpic: updateJESchedules fans out to the
27
- // vendor / account / class / user entities, updateJESchedulesDetails then attaches the
28
- // journal entries, and only then can initializeJeScheduleLocalData read them back.
29
- return from([
30
- updateJESchedules(failedJeSchedules),
31
- updateJESchedulesDetails(failedJeSchedules, failedScheduledJournalEntries),
32
- initializeJeScheduleLocalData(failedJeSchedules),
33
- fetchFailedJePostingsSuccess(failedJeSchedules),
34
- ]);
35
- }), catchError((error) => of(fetchFailedJePostingsFailure(createZeniAPIStatus('Unexpected Error', 'fetch failed JE postings REST API call errored out' +
36
- JSON.stringify(error))))),
37
- // A tenant switch clears the store while this request is still in flight. Without this
38
- // the old tenant's rows are written back into the freshly cleared store and stay on
39
- // screen under the new tenant until a manual refresh.
40
- takeUntil(actions$.pipe(filter(clearAll.match))))));