@mx-cartographer/experiences 9.4.58 → 9.4.60

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 (117) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/dist/core/api/BeatApi.d.ts +6 -0
  3. package/dist/core/api/BeatApi.es.js +1 -1
  4. package/dist/core/api/BeatApi.es.js.map +1 -1
  5. package/dist/core/api/UserApi.d.ts +2 -1
  6. package/dist/core/api/UserApi.es.js +6 -5
  7. package/dist/core/api/UserApi.es.js.map +1 -1
  8. package/dist/core/constants/ApiEndpoints.d.ts +1 -0
  9. package/dist/core/constants/ApiEndpoints.es.js +1 -0
  10. package/dist/core/constants/ApiEndpoints.es.js.map +1 -1
  11. package/dist/core/stores/AccountStore.d.ts +2 -1
  12. package/dist/core/stores/AccountStore.es.js +16 -16
  13. package/dist/core/stores/AccountStore.es.js.map +1 -1
  14. package/dist/core/stores/BeatStore.d.ts +6 -0
  15. package/dist/core/stores/BeatStore.es.js +30 -17
  16. package/dist/core/stores/BeatStore.es.js.map +1 -1
  17. package/dist/core/stores/BudgetsStore.d.ts +2 -1
  18. package/dist/core/stores/BudgetsStore.es.js +8 -8
  19. package/dist/core/stores/BudgetsStore.es.js.map +1 -1
  20. package/dist/core/stores/CategoryStore.d.ts +7 -0
  21. package/dist/core/stores/CategoryStore.es.js +18 -7
  22. package/dist/core/stores/CategoryStore.es.js.map +1 -1
  23. package/dist/core/stores/InsightsV2Store.es.js.map +1 -1
  24. package/dist/core/stores/SettingsStore.d.ts +2 -1
  25. package/dist/core/stores/SettingsStore.es.js +11 -11
  26. package/dist/core/stores/SettingsStore.es.js.map +1 -1
  27. package/dist/core/stores/TransactionStore.d.ts +4 -2
  28. package/dist/core/stores/TransactionStore.es.js +6 -6
  29. package/dist/core/stores/TransactionStore.es.js.map +1 -1
  30. package/dist/core/stores/UserStore.d.ts +15 -1
  31. package/dist/core/stores/UserStore.es.js +21 -3
  32. package/dist/core/stores/UserStore.es.js.map +1 -1
  33. package/dist/core/types/Beat.d.ts +6 -0
  34. package/dist/core/types/Beat.es.js.map +1 -1
  35. package/dist/core/types/Insights.d.ts +127 -5
  36. package/dist/core/types/InsightsInstanceSlotData.d.ts +1 -13
  37. package/dist/core/types/InsightsInstanceSlotData.es.js.map +1 -1
  38. package/dist/core/types/RepeatingTransaction.d.ts +2 -0
  39. package/dist/core/types/RepeatingTransaction.es.js.map +1 -1
  40. package/dist/core/types/User.d.ts +11 -0
  41. package/dist/core/types/index.d.ts +2 -3
  42. package/dist/insights-v2/actionBlocks/ContactSupportActionBlock.d.ts +31 -0
  43. package/dist/insights-v2/actionBlocks/ContactSupportActionBlock.es.js +22 -0
  44. package/dist/insights-v2/actionBlocks/ContactSupportActionBlock.es.js.map +1 -0
  45. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.d.ts +10 -9
  46. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js +7 -7
  47. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js.map +1 -1
  48. package/dist/insights-v2/beatActions.d.ts +7 -0
  49. package/dist/insights-v2/beatActions.es.js.map +1 -1
  50. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js +8 -8
  51. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.d.ts +30 -3
  52. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js +67 -24
  53. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js.map +1 -1
  54. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/index.d.ts +1 -1
  55. package/dist/insights-v2/components/BadgedTile.d.ts +22 -0
  56. package/dist/insights-v2/components/BadgedTile.es.js +46 -0
  57. package/dist/insights-v2/components/BadgedTile.es.js.map +1 -0
  58. package/dist/insights-v2/components/BaseLayout.es.js +113 -92
  59. package/dist/insights-v2/components/BaseLayout.es.js.map +1 -1
  60. package/dist/insights-v2/components/CompactInsightCard.d.ts +31 -0
  61. package/dist/insights-v2/components/CompactInsightCard.es.js +129 -0
  62. package/dist/insights-v2/components/CompactInsightCard.es.js.map +1 -0
  63. package/dist/insights-v2/components/Footer.d.ts +1 -4
  64. package/dist/insights-v2/components/Footer.es.js +30 -21
  65. package/dist/insights-v2/components/Footer.es.js.map +1 -1
  66. package/dist/insights-v2/components/Header.es.js +10 -10
  67. package/dist/insights-v2/components/Header.es.js.map +1 -1
  68. package/dist/insights-v2/components/InsightErrorCard.d.ts +19 -0
  69. package/dist/insights-v2/components/InsightErrorCard.es.js +45 -0
  70. package/dist/insights-v2/components/InsightErrorCard.es.js.map +1 -0
  71. package/dist/insights-v2/components/InsightTransactionRow.es.js +19 -15
  72. package/dist/insights-v2/components/InsightTransactionRow.es.js.map +1 -1
  73. package/dist/insights-v2/components/LogoFromGuid.d.ts +26 -0
  74. package/dist/insights-v2/components/LogoFromGuid.es.js +48 -0
  75. package/dist/insights-v2/components/LogoFromGuid.es.js.map +1 -0
  76. package/dist/insights-v2/components/StatusBadge.d.ts +16 -0
  77. package/dist/insights-v2/components/StatusBadge.es.js +29 -0
  78. package/dist/insights-v2/components/StatusBadge.es.js.map +1 -0
  79. package/dist/insights-v2/components/StatusPill.d.ts +11 -2
  80. package/dist/insights-v2/components/StatusPill.es.js +25 -13
  81. package/dist/insights-v2/components/StatusPill.es.js.map +1 -1
  82. package/dist/insights-v2/components/SubHeader.es.js +7 -5
  83. package/dist/insights-v2/components/SubHeader.es.js.map +1 -1
  84. package/dist/insights-v2/components/TransactionListCard.es.js +11 -11
  85. package/dist/insights-v2/components/TransactionListCard.es.js.map +1 -1
  86. package/dist/insights-v2/components/shared/EntityLogo.d.ts +26 -0
  87. package/dist/insights-v2/components/shared/EntityLogo.es.js +33 -0
  88. package/dist/insights-v2/components/shared/EntityLogo.es.js.map +1 -0
  89. package/dist/insights-v2/index.d.ts +6 -0
  90. package/dist/insights-v2/index.es.js +95 -81
  91. package/dist/insights-v2/mappings/actionBlocksKey.d.ts +1 -0
  92. package/dist/insights-v2/mappings/actionBlocksKey.es.js +2 -1
  93. package/dist/insights-v2/mappings/actionBlocksKey.es.js.map +1 -1
  94. package/dist/insights-v2/mappings/blocks.es.js +50 -44
  95. package/dist/insights-v2/mappings/blocks.es.js.map +1 -1
  96. package/dist/insights-v2/resolveInsightRender.d.ts +30 -0
  97. package/dist/insights-v2/resolveInsightRender.es.js +10 -0
  98. package/dist/insights-v2/resolveInsightRender.es.js.map +1 -0
  99. package/dist/microinsights/cards/InsightCard.es.js +83 -39
  100. package/dist/microinsights/cards/InsightCard.es.js.map +1 -1
  101. package/dist/microinsights/carousel/BeatList.es.js +24 -24
  102. package/dist/microinsights/carousel/BeatList.es.js.map +1 -1
  103. package/dist/notifications/components/NotificationBadge.es.js +12 -10
  104. package/dist/notifications/components/NotificationBadge.es.js.map +1 -1
  105. package/dist/notifications/components/NotificationCard.es.js +27 -18
  106. package/dist/notifications/components/NotificationCard.es.js.map +1 -1
  107. package/dist/transactions/components/shared/TransactionDetails.d.ts +7 -0
  108. package/dist/transactions/components/shared/TransactionDetails.es.js +159 -143
  109. package/dist/transactions/components/shared/TransactionDetails.es.js.map +1 -1
  110. package/dist/transactions/components/shared/TransactionInsightTag.d.ts +26 -0
  111. package/dist/transactions/components/shared/TransactionInsightTag.es.js +53 -0
  112. package/dist/transactions/components/shared/TransactionInsightTag.es.js.map +1 -0
  113. package/dist/transactions/components/shared/transactionlist/TransactionRow.es.js +30 -39
  114. package/dist/transactions/components/shared/transactionlist/TransactionRow.es.js.map +1 -1
  115. package/dist/transactions/components/shared/transactiontable/cells/AmountCell.es.js +15 -15
  116. package/dist/transactions/components/shared/transactiontable/cells/AmountCell.es.js.map +1 -1
  117. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ ## [9.4.60] - 10-07-2026
2
+
3
+ - **ADDED** - Insights 2.0 render gate: `Beat.is_insights_v2` (written by firefly) and `resolveInsightRender(beat)` → `legacy` | `v2` | `error`. An absent flag renders the legacy path unchanged; a flagged beat with no envelope is an `error`, never a legacy card. (WEC-1823)
4
+ - **CHANGED** - `resolveInsightRender` treats an envelope with no `description` as missing, so it resolves to `error` instead of throwing: `BaseLayout`, `CompactInsightCard` and the micro `InsightCard` all paint `description.html_text` unguarded. (WEC-1823)
5
+ - **FIXED** - Large Transaction full card now matches Figma 1941:111919: the subheader is uppercased with 0.52px tracking (`typography/body2 (upper)`), the slot's date strip is `text.primary` at 36px with an 8px radius, the row's category is `text.primary`, the amount uses tabular figures with -0.15px tracking, the title row top-aligns so a wrapping title keeps the overflow menu on the first line, the description pads 16px each side, and the footer uses `text.secondary` rather than the secondary palette colour. (WEC-1823)
6
+ - **FIXED** - Embedded insight card: the CTA label now lines up with the description's left edge (Figma 1941:111897). The column's padding and the button's own were stacking, so the label sat 8px to the right. (WEC-1823)
7
+ - **ADDED** - `InsightErrorCard`: the `error` branch — the copy store's generic error, no CTA, reported once per beat (guid + template) through the host error handler. (WEC-1823)
8
+ - **ADDED** - `LogoFromGuid` (+ `isLogoGuid`): one component for every V2 logo object (`{ guid, fallback_guid?, alt? }`), dispatching on the guid prefix and rendering nothing for `PARENT-ENTITY`, account or budget guids. Built on `logoFromRef` so the prefix mapping lives in one place. (WEC-1823)
9
+ - **ADDED** - `CompactInsightCard`: the one renderer the `micro` and `embedded` envelopes share — title row with the overflow slot, HTML description, primary CTA, first-row logo beside the `header_text` date tile. It never opens anything itself (`onTap` / `onCtaClick` go to the host); `isCtaDisabled` renders the CTA `aria-disabled`. (WEC-1823)
10
+ - **CHANGED** - `InsightsPayload.widget_type` widened to `WidgetType` (`full` | `mini` | `micro` | `embedded` | `notification`); `InsightsPayload` gains `pill?: { text }` (embedded envelope only) and `drilldown_data?` (flat facts hash). (WEC-1823)
11
+ - **CHANGED** - `BeatApi.getBeatsWithAssociatedTransaction` adds `widget_type=embedded` to the existing `has_associated_transaction_guid` fetch. No new endpoint; the transaction row and the details drawer both render from what it returns, and nothing is fetched on drawer open. (WEC-1823)
12
+ - **CHANGED** - Transaction list row and table amount cell render the insight tag through new `TransactionInsightTag`: a V2 beat shows `insights_payload.pill.text` as a `StatusPill` (lightbulb, `primary.lighter` surface), a legacy beat shows `short_title` as before, and a flagged beat with no envelope or no `pill` shows nothing. Tap still posts `insightOnTransaction`; `showInsights` still gates. `StatusPill` gains `onClick`, `data-testid`, `labelVariant`; with an `onClick` it is keyboard-accessible (`role="button"`, focusable, Enter and Space activate it, focus ring like the theme's Button). (WEC-1823)
13
+ - **CHANGED** - Transaction details drawer branches on the beat it already matched: `v2` renders `CompactInsightCard` from the embedded envelope above the account block, `error` renders `InsightErrorCard` in that slot, `legacy` runs `getEmbeddedInstanceSlotByBeatTemplates` as before. `shouldShowEmbeddedCard={false}` suppresses all three. (WEC-1823)
14
+ - **ADDED** - `contact_support_block` CTA support, registered under its ditto name. insights-v2 and transactions deliberately do **not** import the help module (hosts that don't ship the Help widget stub that import — pulse's webpack `IgnorePlugin` — and would crash at import time), so the flow is injected by the host: `beatActions.onContactSupport` for feed/mini cards (`BaseLayout` calls it directly, never a drawer) and a new `TransactionDetails.onContactSupport` prop for the details-drawer card. The CTA renders disabled (label shown, `aria-disabled`, nothing opens or posts) when the client's `enable_support_requests` is off **or** the host wired no handler (`isContactSupportCtaDisabled`). The registry entry is a safety net only. (WEC-1823)
15
+ - **CHANGED** - `NotificationCard` draws `LogoFromGuid` when `entity_guid` is a `MCH-` / `CAT-` / `INS-` guid (Newman writes it at send time) and today's `NotificationBadge` otherwise. Text stays `content`; no beat is fetched. Inert until the newman recorder change ships. (WEC-1823)
16
+ - **CHANGED** - insights-v2 transaction block renamed to match the ditto LargeTransactionV2 contract (`lib/ditto/beats/large_transaction_v2.yml`): block `category_transactions_block` → `transaction_block` (`TransactionBlock`), variant `SameHeaderDesign` → `with_header` / `no_header`, primary CTA `transaction_details` → `transaction_details_block`. The old names are no longer registered. (WEC-1823)
17
+ - **CHANGED** - `TransactionBlock` now renders pre-localized rows carried inline on `instance_slot.data_series` (`logo`, `primary_text`, `secondary_text`, `amount`) instead of `instance_slot_data.primary_transaction`. `CategoryTransactionsBlockData` / `InsightTransaction` types removed. (WEC-1823)
18
+ - **FIXED** - insights-v2 `TransactionBlock` rendered the wrong `with_header` header: it used the first row's `secondary_text`, which on a `with_merchant` card is the *category*, so the category appeared twice and the transaction date never appeared. The header now comes from `instance_slot.header_text` (new optional field), which is where tupac sends the date. The `with_header` mock fixtures were also carrying the `no_merchant` row shape and are corrected. (WEC-1823)
19
+ - **FIXED** - insights-v2 `TransactionBlock` row category icon: mxui `CategoryIcon` only knows top-level category guids and fell back to the Uncategorized icon for a sub-category guid. The row guid is now walked up to its top-level parent via new `CategoryStore.getTopLevelCategoryGuid`, matching what the transaction-details drawer shows. (WEC-1823)
20
+ - **CHANGED** - insights-v2 `BaseLayout` renders the sub-header from the flat `subtitle` string plus payload-level `logo` (resolved via new `logoFromRef`); `sub_title` continues to work and wins when both are present. (WEC-1823)
21
+ - **ADDED** - `LogoRef` type, shared by the V2 header `logo` and every `instance_slot.data_series` row `logo`. A logo is either an entity (`guid`, resolved by its `INS-` / `MCH-` / `CAT-` prefix, plus an optional `fallback_guid`) or a status icon (`icon` + `color`, the V2 counterpart of V1's `logo_name` / `logo_color`), rendered in both the sub-header and `TransactionBlock` rows. `icon` wins when a logo sends both. (WEC-1823)
22
+ - **FIXED** - insights-v2 `TransactionBlock` merchant rows passed `MerchantLogo` an empty `categoryGuid`, so a merchant with no logo asset fell back to the Uncategorized tile. The row's `logo.fallback_guid` (the transaction's category) is now passed through, resolved to its top-level category. (WEC-1823)
23
+ - **CHANGED** - insights-v2 `Footer` accepts `timestamp` (unix seconds, formatted as e.g. "September 27, 2026") alongside the V1 `date`. (WEC-1823)
24
+ - **CHANGED** - insights-v2 footer standardizes on a single `account` key; the separate `accounts` key is removed from `Footer` and the V2 fixtures. The backend resolves plurality into that one field (one account sends its name, several send a localized `N Accounts`), matching tupac's `footer_account_label`, so the frontend never counts accounts itself. (WEC-1823)
25
+ - **CHANGED** - `InsightsPayload` / `InstanceSlot` / `Footer` types gain optional fields (`subtitle`, `logo`, `variant`, `instance_slot.data_series`, `footer.timestamp`). (WEC-1823)
26
+ - **CHANGED** - `InsightsPayload` gains the remaining optional fields on the V2 envelope contract (`client_guid`, `template`, `revision`, `created_at`, `updated_at`, `active_at`, `displayed_at`, `cta_clicked_at`, `has_been_displayed`, `is_deleted`, `is_hidden_by_system`, `is_obsolete`, `is_refreshable`, `is_sampled`, `is_zero_state`, `status`, `primary_account_guid`, `primary_transaction_guid`, `primary_category_guid`, `primary_merchant_guid`). (WEC-1823)
27
+ - **CHANGED** - insights-v2 transaction-details drawer resolves its transaction solely from `insights_payload.primary_transaction_guid` (the ditto contract) or a nested-drawer `actionContext.transaction_guid`. The speculative `instance_slot_data.transaction_guid`, beat-envelope `primary_transaction_guid` / `transaction_guids[0]`, and `beat.primary_transaction` snapshot fallbacks are removed; `TransactionDetailsBlockData.transaction_guid` is dropped. (WEC-1823)
28
+ - **CHANGED** - insights-v2 transaction-details drawer no longer reads `instance_slot_data` at all: the key is not part of the V2 contract (the LargeTransactionV2 payload omits it), so the `top_actions` read is dead. Top actions are always the defaults; bottom actions continue to derive from the triggering CTA's `variant`. (WEC-1823)
29
+ - **CHANGED** - `InsightsPayload.instance_slot_data` is now optional, matching the V2 contract. Blocks that genuinely require it still receive it as a required field via `BlockProps`, which re-declares it. (WEC-1823)
30
+ - **CHANGED** - insights-v2 `BaseLayout` shows the primary CTA on the mini card as a label, not a button, so a tap on it reaches the host's card handler (pulse posts `carousel/cta`, as a V1 mini card does) instead of opening the action drawer the full card's CTA opens. The label keeps the Button look (semi-bold, not uppercased, 44px). Full cards are unchanged. (WEC-1823)
31
+ - **ADDED** - `BadgedTile` and `StatusBadge`: the embedded card's right-hand cluster. The first slot row's logo fills a 44px tile badged on its top-right by the insight's status tone (`warning` for Large Transaction), with a bottom-left slot for a second badge. The card's right-hand visual dispatches on ditto's layout variant through `createVariantBlock`: `embedded` draws the badged tile, anything else (micro, an unregistered variant) draws the logo alone. A variant names a rendering shape, not an insight, so a new visual registers one entry and leaves the others untouched. (WEC-1823)
32
+ - **REMOVED** - the embedded card's `instance_slot.header_text` date tile, per design. `header_text` stays on the envelope and is still rendered by `transaction_block`'s `with_header` variant. (WEC-1823)
33
+
34
+ ## [9.4.59] - 10-07-2026
35
+
36
+ - **ADDED** - `UserInsightProfile` type, `ApiEndpoints.USER_INSIGHT_PROFILE`, `UserApi.updateUserInsightProfile` (`PUT user_insight_profile`) and `UserStore.userInsightProfile` with `setUserInsightProfile` (the host seeds the profile it loaded) and `updateUserInsightProfile`, which merges the changed fields over the seeded profile and PUTs the whole profile (the endpoint upserts every field, so a partial body would null the rest), refuses to PUT before the profile is seeded, and rethrows so a caller can surface a failed save (WEC-1852)
37
+ - **ADDED** - `BeatStore.updateOffer` (`PUT offers/:guid`) to flag a marketing offer as clicked; rethrows on failure (WEC-1852)
38
+ - **ADDED** - `RepeatingTransaction.user_response` field (WEC-1852)
39
+ - **CHANGED** - `AccountStore.updateAccount`, `SettingsStore.updateNotificationProfile`, `TransactionStore.updateTransaction`, `TransactionStore.addOrUpdateTransactionRule` and `BudgetsStore.addBudget` now resolve `true` on success and `false` when the API call fails, instead of resolving `undefined` either way. They still catch and report their own errors and never throw, so existing callers are unaffected; the flag lets a caller distinguish a failed write (WEC-1852)
40
+ - **ADDED** - MSW handlers and mock data for `PUT user_insight_profile` and `PUT offers/:guid` (WEC-1852)
41
+
1
42
  ## [9.4.58] - 10-07-2026
2
43
 
3
44
  - **ADDED** - Insights V2 `ErrorCard` and `LoadingCard` components, plus `isError`/`isLoading` props on `BaseLayout`: `isError` replaces the entire card with the `ErrorCard` (heading, message, and a "Try Again" retry button that reloads by default), while `isLoading` swaps only the block slot for the `LoadingCard`. `ErrorCard` derives the CIBC illustration variant from the app's `custom_copy_namespace`. Added `error_heading`, `error_message`, `loading`, and `try_again` copy keys under `insights_feed.general`, with stories for all three states (WEC-1854)
@@ -201,7 +242,6 @@
201
242
  - **FIXED** - `FeedbackDialog` props made non-optional: `primaryText`, `secondaryText`, and `closeAriaLabel` are now required (previously optional), and `multiline={true}` is now explicit on the TextField. All callers (BaseLayout, stories, tests) updated to provide required props (WEC-1766)
202
243
  - **FIXED** - `DismissInsightDialog` spacing restored: `sx` overrides for content padding and header alignment re-added after being accidentally removed during refactor (WEC-1766)
203
244
 
204
-
205
245
  ## [9.4.17] - 09-04-2026
206
246
 
207
247
  - **ADDED** - insights-v2 feedback UI screens (WEC-1781): `FeedbackDialog` (generic feedback survey with radio options + optional detail field), `DismissInsightDialog` (dismiss beat with Once/Always choices + confirmation), `FeedbackBar` (compact inline helpful/not-helpful reactions), `HiddenConfirmationCard` (visual confirmation of hidden insight). All presentational, data-agnostic; parent owns copy, options, and callback logic. Wired to `beatActions` context for parent handler dispatch (WEC-1781)
@@ -273,6 +313,7 @@
273
313
  - **CHANGED** - Moved ActionBlock from `blocks/ComponentBlocks/ActionBlock` to `src/insights-v2/actionBlocks`; drilldown figures/copy now sourced from `insights_payload.instance_slot_data` (WEC-1705)
274
314
  - **CHANGED** - `InsightsV2Store.closeActionDrawer` preserves `trigger` so the drawer keeps its title/content through the slide-out animation (WEC-1705)
275
315
  - **FIXED** - Action drawer first-open animation: `ActionBlockLayer` stays mounted for null-block CTAs so the slide-in transition plays on the first open (WEC-1705)
316
+
276
317
  ## [9.4.7] - 08-27-2026
277
318
 
278
319
  - **ADDED** - `CategoryTransactionsBlock` component block supporting `SameHeaderDesign` variant for single fee and large transactions in Insights v2 (MEW2-3237)
@@ -4,6 +4,12 @@ export declare class BeatApi {
4
4
  fetchInstance: Fetch;
5
5
  constructor(endpoint: string, token: string, onError?: GlobalErrorHandler);
6
6
  getBeats: (pageNum?: number, perPage?: number) => Promise<any>;
7
+ /**
8
+ * The transactions widget's one beat fetch: the row pill and the details-drawer card both render
9
+ * from what it returns, so it asks for the `embedded` envelope (Insights 2.0). A flagged beat
10
+ * arrives with `is_insights_v2: true` and its `insights_payload` (`pill`, compact slot); a legacy
11
+ * beat is unchanged. There is deliberately no per-drawer fetch and no pills endpoint.
12
+ */
7
13
  getBeatsWithAssociatedTransaction: (fromDate?: string) => Promise<any>;
8
14
  getOffers: () => Promise<any>;
9
15
  updateBeat: (beat: Beat) => Promise<any>;
@@ -10,7 +10,7 @@ var h = class {
10
10
  return this.fetchInstance.get(`${n.BEATS}?${s}`).then((a) => a.beats);
11
11
  };
12
12
  getBeatsWithAssociatedTransaction = async (t) => {
13
- let e = "has_associated_transaction_guid=true";
13
+ let e = "has_associated_transaction_guid=true&widget_type=embedded";
14
14
  return e += t ? `&from_date=${t}` : "", this.fetchInstance.get(`${n.BEATS}?${e}`).then((s) => s.beats);
15
15
  };
16
16
  getOffers = async () => this.fetchInstance.get(`${n.OFFERS}/${n.PULSE_COMMUNICATIONS}`).then((t) => t.pulse_communications);
@@ -1 +1 @@
1
- {"version":3,"file":"BeatApi.es.js","names":[],"sources":["../../../src/core/api/BeatApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\nimport { ApiEndpoints } from '../constants'\nimport type { Beat, GlobalErrorHandler } from '..'\n\nexport class BeatApi {\n fetchInstance: Fetch\n\n constructor(endpoint: string, token: string, onError?: GlobalErrorHandler) {\n this.fetchInstance = new Fetch(endpoint, token, undefined, onError)\n }\n\n getBeats = async (pageNum?: number, perPage?: number) => {\n const beatParams = `page=${pageNum ? pageNum : 1}&per_page=${perPage ? perPage : 5}`\n\n return this.fetchInstance.get(`${ApiEndpoints.BEATS}?${beatParams}`).then((data) => data.beats)\n }\n\n getBeatsWithAssociatedTransaction = async (fromDate?: string) => {\n let beatParams = 'has_associated_transaction_guid=true'\n beatParams += fromDate ? `&from_date=${fromDate}` : ''\n\n return this.fetchInstance.get(`${ApiEndpoints.BEATS}?${beatParams}`).then((data) => data.beats)\n }\n\n getOffers = async () => {\n return this.fetchInstance\n .get(`${ApiEndpoints.OFFERS}/${ApiEndpoints.PULSE_COMMUNICATIONS}`)\n .then((data) => data.pulse_communications)\n }\n\n updateBeat = async (beat: Beat) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.BEATS}/${beat.guid}`, beat)\n .then((data) => data.beat)\n }\n\n updateOffer = async (beat: Beat) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.OFFERS}/${beat.guid}`, beat)\n .then((data) => data.beat)\n }\n}\n"],"mappings":";;AAIA,IAAa,IAAb,MAAqB;AAAA,EACnB;AAAA,EAEA,YAAY,GAAkB,GAAe,GAA8B;AACzE,SAAK,gBAAgB,IAAI,EAAM,GAAU,GAAO,QAAW,CAAO;AAAA,EACpE;AAAA,EAEA,WAAW,OAAO,GAAkB,MAAqB;AACvD,UAAM,IAAa,QAAQ,KAAoB,CAAA,aAAc,KAAoB,CAAA;AAEjF,WAAO,KAAK,cAAc,IAAI,GAAG,EAAa,KAAA,IAAS,CAAA,EAAY,EAAE,KAAA,CAAM,MAAS,EAAK,KAAK;AAAA,EAChG;AAAA,EAEA,oCAAoC,OAAO,MAAsB;AAC/D,QAAI,IAAa;AACjB,WAAA,KAAc,IAAW,cAAc,CAAA,KAAa,IAE7C,KAAK,cAAc,IAAI,GAAG,EAAa,KAAA,IAAS,CAAA,EAAY,EAAE,KAAA,CAAM,MAAS,EAAK,KAAK;AAAA,EAChG;AAAA,EAEA,YAAY,YACH,KAAK,cACT,IAAI,GAAG,EAAa,MAAA,IAAU,EAAa,oBAAA,EAAsB,EACjE,KAAA,CAAM,MAAS,EAAK,oBAAoB;AAAA,EAG7C,aAAa,OAAO,MACX,KAAK,cACT,IAAI,GAAG,EAAa,KAAA,IAAS,EAAK,IAAA,IAAQ,CAAI,EAC9C,KAAA,CAAM,MAAS,EAAK,IAAI;AAAA,EAG7B,cAAc,OAAO,MACZ,KAAK,cACT,IAAI,GAAG,EAAa,MAAA,IAAU,EAAK,IAAA,IAAQ,CAAI,EAC/C,KAAA,CAAM,MAAS,EAAK,IAAI;AAE/B"}
1
+ {"version":3,"file":"BeatApi.es.js","names":[],"sources":["../../../src/core/api/BeatApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\nimport { ApiEndpoints } from '../constants'\nimport type { Beat, GlobalErrorHandler } from '..'\n\nexport class BeatApi {\n fetchInstance: Fetch\n\n constructor(endpoint: string, token: string, onError?: GlobalErrorHandler) {\n this.fetchInstance = new Fetch(endpoint, token, undefined, onError)\n }\n\n getBeats = async (pageNum?: number, perPage?: number) => {\n const beatParams = `page=${pageNum ? pageNum : 1}&per_page=${perPage ? perPage : 5}`\n\n return this.fetchInstance.get(`${ApiEndpoints.BEATS}?${beatParams}`).then((data) => data.beats)\n }\n\n /**\n * The transactions widget's one beat fetch: the row pill and the details-drawer card both render\n * from what it returns, so it asks for the `embedded` envelope (Insights 2.0). A flagged beat\n * arrives with `is_insights_v2: true` and its `insights_payload` (`pill`, compact slot); a legacy\n * beat is unchanged. There is deliberately no per-drawer fetch and no pills endpoint.\n */\n getBeatsWithAssociatedTransaction = async (fromDate?: string) => {\n let beatParams = 'has_associated_transaction_guid=true&widget_type=embedded'\n beatParams += fromDate ? `&from_date=${fromDate}` : ''\n\n return this.fetchInstance.get(`${ApiEndpoints.BEATS}?${beatParams}`).then((data) => data.beats)\n }\n\n getOffers = async () => {\n return this.fetchInstance\n .get(`${ApiEndpoints.OFFERS}/${ApiEndpoints.PULSE_COMMUNICATIONS}`)\n .then((data) => data.pulse_communications)\n }\n\n updateBeat = async (beat: Beat) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.BEATS}/${beat.guid}`, beat)\n .then((data) => data.beat)\n }\n\n updateOffer = async (beat: Beat) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.OFFERS}/${beat.guid}`, beat)\n .then((data) => data.beat)\n }\n}\n"],"mappings":";;AAIA,IAAa,IAAb,MAAqB;AAAA,EACnB;AAAA,EAEA,YAAY,GAAkB,GAAe,GAA8B;AACzE,SAAK,gBAAgB,IAAI,EAAM,GAAU,GAAO,QAAW,CAAO;AAAA,EACpE;AAAA,EAEA,WAAW,OAAO,GAAkB,MAAqB;AACvD,UAAM,IAAa,QAAQ,KAAoB,CAAA,aAAc,KAAoB,CAAA;AAEjF,WAAO,KAAK,cAAc,IAAI,GAAG,EAAa,KAAA,IAAS,CAAA,EAAY,EAAE,KAAA,CAAM,MAAS,EAAK,KAAK;AAAA,EAChG;AAAA,EAQA,oCAAoC,OAAO,MAAsB;AAC/D,QAAI,IAAa;AACjB,WAAA,KAAc,IAAW,cAAc,CAAA,KAAa,IAE7C,KAAK,cAAc,IAAI,GAAG,EAAa,KAAA,IAAS,CAAA,EAAY,EAAE,KAAA,CAAM,MAAS,EAAK,KAAK;AAAA,EAChG;AAAA,EAEA,YAAY,YACH,KAAK,cACT,IAAI,GAAG,EAAa,MAAA,IAAU,EAAa,oBAAA,EAAsB,EACjE,KAAA,CAAM,MAAS,EAAK,oBAAoB;AAAA,EAG7C,aAAa,OAAO,MACX,KAAK,cACT,IAAI,GAAG,EAAa,KAAA,IAAS,EAAK,IAAA,IAAQ,CAAI,EAC9C,KAAA,CAAM,MAAS,EAAK,IAAI;AAAA,EAG7B,cAAc,OAAO,MACZ,KAAK,cACT,IAAI,GAAG,EAAa,MAAA,IAAU,EAAK,IAAA,IAAQ,CAAI,EAC/C,KAAA,CAAM,MAAS,EAAK,IAAI;AAE/B"}
@@ -1,9 +1,10 @@
1
1
  import { Fetch } from '../utils';
2
- import { GlobalErrorHandler, User, UserProfile } from '..';
2
+ import { GlobalErrorHandler, User, UserInsightProfile, UserProfile } from '..';
3
3
  export declare class UserApi {
4
4
  fetchInstance: Fetch;
5
5
  constructor(endpoint: string, token: string, onError?: GlobalErrorHandler);
6
6
  getUserFeatures: () => Promise<any>;
7
7
  updateUser: (user: User) => Promise<any>;
8
8
  updateUserProfile: (userProfile: UserProfile) => Promise<any>;
9
+ updateUserInsightProfile: (profile: Partial<UserInsightProfile>) => Promise<UserInsightProfile>;
9
10
  }
@@ -2,12 +2,13 @@ import { ApiEndpoints as s } from "../constants/ApiEndpoints.es.js";
2
2
  import { Fetch as r } from "../utils/Fetch.es.js";
3
3
  var h = class {
4
4
  fetchInstance;
5
- constructor(t, e, n) {
6
- this.fetchInstance = new r(t, e, void 0, n);
5
+ constructor(e, t, n) {
6
+ this.fetchInstance = new r(e, t, void 0, n);
7
7
  }
8
- getUserFeatures = async () => this.fetchInstance.get(s.USER_FEATURES).then((t) => t.user_features);
9
- updateUser = async (t) => this.fetchInstance.put(s.USER, t).then((e) => e.user);
10
- updateUserProfile = async (t) => this.fetchInstance.put(`${s.USER_PROFILES}/${t.guid}`, t).then((e) => e.user_profile);
8
+ getUserFeatures = async () => this.fetchInstance.get(s.USER_FEATURES).then((e) => e.user_features);
9
+ updateUser = async (e) => this.fetchInstance.put(s.USER, e).then((t) => t.user);
10
+ updateUserProfile = async (e) => this.fetchInstance.put(`${s.USER_PROFILES}/${e.guid}`, e).then((t) => t.user_profile);
11
+ updateUserInsightProfile = async (e) => this.fetchInstance.put(s.USER_INSIGHT_PROFILE, { user_insight_profile: e }).then((t) => t.user_insight_profile);
11
12
  };
12
13
  export {
13
14
  h as UserApi
@@ -1 +1 @@
1
- {"version":3,"file":"UserApi.es.js","names":[],"sources":["../../../src/core/api/UserApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\nimport { ApiEndpoints } from '../constants'\nimport type { GlobalErrorHandler, User, UserProfile } from '..'\n\nexport class UserApi {\n fetchInstance: Fetch\n\n constructor(endpoint: string, token: string, onError?: GlobalErrorHandler) {\n this.fetchInstance = new Fetch(endpoint, token, undefined, onError)\n }\n\n getUserFeatures = async () => {\n return this.fetchInstance.get(ApiEndpoints.USER_FEATURES).then((data) => data.user_features)\n }\n\n updateUser = async (user: User) => {\n return this.fetchInstance.put(ApiEndpoints.USER, user).then((data) => data.user)\n }\n\n updateUserProfile = async (userProfile: UserProfile) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.USER_PROFILES}/${userProfile.guid}`, userProfile)\n .then((data) => data.user_profile)\n }\n}\n"],"mappings":";;AAIA,IAAa,IAAb,MAAqB;AAAA,EACnB;AAAA,EAEA,YAAY,GAAkB,GAAe,GAA8B;AACzE,SAAK,gBAAgB,IAAI,EAAM,GAAU,GAAO,QAAW,CAAO;AAAA,EACpE;AAAA,EAEA,kBAAkB,YACT,KAAK,cAAc,IAAI,EAAa,aAAa,EAAE,KAAA,CAAM,MAAS,EAAK,aAAa;AAAA,EAG7F,aAAa,OAAO,MACX,KAAK,cAAc,IAAI,EAAa,MAAM,CAAI,EAAE,KAAA,CAAM,MAAS,EAAK,IAAI;AAAA,EAGjF,oBAAoB,OAAO,MAClB,KAAK,cACT,IAAI,GAAG,EAAa,aAAA,IAAiB,EAAY,IAAA,IAAQ,CAAW,EACpE,KAAA,CAAM,MAAS,EAAK,YAAY;AAEvC"}
1
+ {"version":3,"file":"UserApi.es.js","names":[],"sources":["../../../src/core/api/UserApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\nimport { ApiEndpoints } from '../constants'\nimport type { GlobalErrorHandler, User, UserInsightProfile, UserProfile } from '..'\n\nexport class UserApi {\n fetchInstance: Fetch\n\n constructor(endpoint: string, token: string, onError?: GlobalErrorHandler) {\n this.fetchInstance = new Fetch(endpoint, token, undefined, onError)\n }\n\n getUserFeatures = async () => {\n return this.fetchInstance.get(ApiEndpoints.USER_FEATURES).then((data) => data.user_features)\n }\n\n updateUser = async (user: User) => {\n return this.fetchInstance.put(ApiEndpoints.USER, user).then((data) => data.user)\n }\n\n updateUserProfile = async (userProfile: UserProfile) => {\n return this.fetchInstance\n .put(`${ApiEndpoints.USER_PROFILES}/${userProfile.guid}`, userProfile)\n .then((data) => data.user_profile)\n }\n\n // The endpoint is singular per user, so no guid in the path (mirrors pulse FireflyAPI).\n updateUserInsightProfile = async (\n profile: Partial<UserInsightProfile>,\n ): Promise<UserInsightProfile> => {\n return this.fetchInstance\n .put(ApiEndpoints.USER_INSIGHT_PROFILE, { user_insight_profile: profile })\n .then((data) => data.user_insight_profile)\n }\n}\n"],"mappings":";;AAIA,IAAa,IAAb,MAAqB;AAAA,EACnB;AAAA,EAEA,YAAY,GAAkB,GAAe,GAA8B;AACzE,SAAK,gBAAgB,IAAI,EAAM,GAAU,GAAO,QAAW,CAAO;AAAA,EACpE;AAAA,EAEA,kBAAkB,YACT,KAAK,cAAc,IAAI,EAAa,aAAa,EAAE,KAAA,CAAM,MAAS,EAAK,aAAa;AAAA,EAG7F,aAAa,OAAO,MACX,KAAK,cAAc,IAAI,EAAa,MAAM,CAAI,EAAE,KAAA,CAAM,MAAS,EAAK,IAAI;AAAA,EAGjF,oBAAoB,OAAO,MAClB,KAAK,cACT,IAAI,GAAG,EAAa,aAAA,IAAiB,EAAY,IAAA,IAAQ,CAAW,EACpE,KAAA,CAAM,MAAS,EAAK,YAAY;AAAA,EAIrC,2BAA2B,OACzB,MAEO,KAAK,cACT,IAAI,EAAa,sBAAsB,EAAE,sBAAsB,EAAQ,CAAC,EACxE,KAAA,CAAM,MAAS,EAAK,oBAAoB;AAE/C"}
@@ -42,6 +42,7 @@ export declare const ApiEndpoints: {
42
42
  USER: string;
43
43
  USER_COMMUNICATION_PROFILE: string;
44
44
  USER_FEATURES: string;
45
+ USER_INSIGHT_PROFILE: string;
45
46
  USER_PROFILES: string;
46
47
  WIDGET_URLS: string;
47
48
  };
@@ -42,6 +42,7 @@ var _ = {
42
42
  USER: "user",
43
43
  USER_COMMUNICATION_PROFILE: "user_communication_profile",
44
44
  USER_FEATURES: "user_features",
45
+ USER_INSIGHT_PROFILE: "user_insight_profile",
45
46
  USER_PROFILES: "user_profiles",
46
47
  WIDGET_URLS: "widget_urls"
47
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ApiEndpoints.es.js","names":[],"sources":["../../../src/core/constants/ApiEndpoints.ts"],"sourcesContent":["export const ApiEndpoints = {\n ACCOUNTS: 'accounts',\n ANALYTICS_EVENTS: 'analytics_events',\n ANALYTICS_FEATURE_VISITS: 'feature_visits',\n ANALYTICS_PAGEVIEWS: 'analytics_pageviews',\n ANALYTICS_SESSION: 'analytics_sessions',\n APP_DATA: 'raja/data?type=master',\n BEATS: 'beats',\n BUDGETS: 'budgets',\n CATEGORIES: 'categories',\n CHANGE_PASSWORD: 'user/change_password',\n DATE_RANGE_CATEGORY_TOTALS: 'date_range_category_totals',\n DEVICES: 'devices',\n EMAIL_VERIFICATIONS: 'email_verifications',\n GOALS: 'goals',\n HEALTH_SCORES: 'health_scores',\n HOLDINGS: 'holdings',\n INSTITUTIONS: 'institutions',\n INSIGHTS_NOTIFICATION_PROFILES: 'insight_notification_profiles',\n LOCALIZED_COPY: 'localized_copies',\n LOCALIZED_CONTENT: 'localized_content',\n MEMBERS: 'members',\n MERCHANTS: 'merchants',\n MERCHANT_BUDGETS: 'merchant_budgets',\n MONTHLY_CASH_FLOW_PROFILE: 'monthly_cash_flow_profile',\n MONTHLY_CATEGORY_TOTALS: 'monthly_category_totals',\n OFFERS: 'offers',\n NOTIFICATION_PROFILES: 'notification_profiles',\n NOTIFICATIONS: 'notifications',\n PHONE_VERIFICATIONS: 'sms_verification',\n PULSE_COMMUNICATIONS: 'pulse_communications',\n REPEATING_TRANSACTIONS: 'repeating_transactions',\n RETIREMENT_GOALS: 'retirement_goals',\n RETIREMENT_GOAL_ACCOUNTS: 'retirement_goal_accounts',\n SCHEDULED_PAYMENTS: 'scheduled_payments',\n SPENDING_PLANS: 'spending_plans',\n SUPPORT_TICKETS: 'support_tickets',\n TAGGINGS: 'taggings',\n TAGS: 'tags',\n TRANSACTION_RULES: 'transaction_rules',\n TRANSACTIONS: 'transactions',\n USER: 'user',\n USER_COMMUNICATION_PROFILE: 'user_communication_profile',\n USER_FEATURES: 'user_features',\n USER_PROFILES: 'user_profiles',\n WIDGET_URLS: 'widget_urls',\n}\n"],"mappings":"AAAA,IAAa,IAAe;AAAA,EAC1B,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,OAAO;AAAA,EACP,eAAe;AAAA,EACf,UAAU;AAAA,EACV,cAAc;AAAA,EACd,gCAAgC;AAAA,EAChC,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,QAAQ;AAAA,EACR,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,MAAM;AAAA,EACN,4BAA4B;AAAA,EAC5B,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AACf"}
1
+ {"version":3,"file":"ApiEndpoints.es.js","names":[],"sources":["../../../src/core/constants/ApiEndpoints.ts"],"sourcesContent":["export const ApiEndpoints = {\n ACCOUNTS: 'accounts',\n ANALYTICS_EVENTS: 'analytics_events',\n ANALYTICS_FEATURE_VISITS: 'feature_visits',\n ANALYTICS_PAGEVIEWS: 'analytics_pageviews',\n ANALYTICS_SESSION: 'analytics_sessions',\n APP_DATA: 'raja/data?type=master',\n BEATS: 'beats',\n BUDGETS: 'budgets',\n CATEGORIES: 'categories',\n CHANGE_PASSWORD: 'user/change_password',\n DATE_RANGE_CATEGORY_TOTALS: 'date_range_category_totals',\n DEVICES: 'devices',\n EMAIL_VERIFICATIONS: 'email_verifications',\n GOALS: 'goals',\n HEALTH_SCORES: 'health_scores',\n HOLDINGS: 'holdings',\n INSTITUTIONS: 'institutions',\n INSIGHTS_NOTIFICATION_PROFILES: 'insight_notification_profiles',\n LOCALIZED_COPY: 'localized_copies',\n LOCALIZED_CONTENT: 'localized_content',\n MEMBERS: 'members',\n MERCHANTS: 'merchants',\n MERCHANT_BUDGETS: 'merchant_budgets',\n MONTHLY_CASH_FLOW_PROFILE: 'monthly_cash_flow_profile',\n MONTHLY_CATEGORY_TOTALS: 'monthly_category_totals',\n OFFERS: 'offers',\n NOTIFICATION_PROFILES: 'notification_profiles',\n NOTIFICATIONS: 'notifications',\n PHONE_VERIFICATIONS: 'sms_verification',\n PULSE_COMMUNICATIONS: 'pulse_communications',\n REPEATING_TRANSACTIONS: 'repeating_transactions',\n RETIREMENT_GOALS: 'retirement_goals',\n RETIREMENT_GOAL_ACCOUNTS: 'retirement_goal_accounts',\n SCHEDULED_PAYMENTS: 'scheduled_payments',\n SPENDING_PLANS: 'spending_plans',\n SUPPORT_TICKETS: 'support_tickets',\n TAGGINGS: 'taggings',\n TAGS: 'tags',\n TRANSACTION_RULES: 'transaction_rules',\n TRANSACTIONS: 'transactions',\n USER: 'user',\n USER_COMMUNICATION_PROFILE: 'user_communication_profile',\n USER_FEATURES: 'user_features',\n USER_INSIGHT_PROFILE: 'user_insight_profile',\n USER_PROFILES: 'user_profiles',\n WIDGET_URLS: 'widget_urls',\n}\n"],"mappings":"AAAA,IAAa,IAAe;AAAA,EAC1B,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,OAAO;AAAA,EACP,eAAe;AAAA,EACf,UAAU;AAAA,EACV,cAAc;AAAA,EACd,gCAAgC;AAAA,EAChC,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,QAAQ;AAAA,EACR,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,MAAM;AAAA,EACN,4BAA4B;AAAA,EAC5B,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,aAAa;AACf"}
@@ -53,7 +53,8 @@ export declare class AccountStore {
53
53
  refreshAccounts: () => Promise<void>;
54
54
  refreshMembers: () => Promise<void>;
55
55
  removeAccount: (accountGuid: string) => Promise<void>;
56
- updateAccount: (account: Account) => Promise<void>;
56
+ /** Resolves `true` when the account was saved, `false` when the API call failed. */
57
+ updateAccount: (account: Account) => Promise<boolean>;
57
58
  updateAccountBalance: (accountGuid: string, balanceChange: number) => void;
58
59
  updateAccountFilter: (accountMap: Map<string, boolean>) => Promise<void>;
59
60
  }
@@ -37,8 +37,8 @@ var C = class {
37
37
  get accountsByTypeMap() {
38
38
  return this.detailedAccounts.reduce((t, e) => {
39
39
  const s = e.account_type;
40
- let o = t.get(s);
41
- return o || (o = []), o.push(e), t.set(s, o), t;
40
+ let n = t.get(s);
41
+ return n || (n = []), n.push(e), t.set(s, n), t;
42
42
  }, /* @__PURE__ */ new Map());
43
43
  }
44
44
  get cashAccounts() {
@@ -163,9 +163,9 @@ var C = class {
163
163
  try {
164
164
  const e = await this.api.mergeAccounts(t), s = e[Object.keys(e)[0]];
165
165
  d(() => {
166
- const o = this.accounts.findIndex((n) => n.guid === t[1]);
167
- this.accounts.splice(o, 1);
168
- const i = this.accounts.findIndex((n) => n.guid === t[0]);
166
+ const n = this.accounts.findIndex((o) => o.guid === t[1]);
167
+ this.accounts.splice(n, 1);
168
+ const i = this.accounts.findIndex((o) => o.guid === t[0]);
169
169
  this.accounts.splice(i, 1, s);
170
170
  });
171
171
  } catch (e) {
@@ -197,14 +197,14 @@ var C = class {
197
197
  };
198
198
  updateAccount = async (t) => {
199
199
  try {
200
- const e = await this.api.updateAccount(t), s = this.accounts.findIndex((o) => o.guid === e.guid);
201
- this.accounts.splice(s, 1, e);
200
+ const e = await this.api.updateAccount(t), s = this.accounts.findIndex((n) => n.guid === e.guid);
201
+ return this.accounts.splice(s, 1, e), !0;
202
202
  } catch (e) {
203
- console.error("Error occurred while updating account:", e), this.globalStore.captureException(e, { store: "AccountStore" });
203
+ return console.error("Error occurred while updating account:", e), this.globalStore.captureException(e, { store: "AccountStore" }), !1;
204
204
  }
205
205
  };
206
206
  updateAccountBalance = (t, e) => {
207
- const s = this.accounts.find((o) => o.guid === t);
207
+ const s = this.accounts.find((n) => n.guid === t);
208
208
  s && d(() => {
209
209
  s.balance = (s.balance || 0) + e;
210
210
  });
@@ -212,22 +212,22 @@ var C = class {
212
212
  updateAccountFilter = async (t) => {
213
213
  try {
214
214
  const e = [];
215
- for (const [i, n] of t.entries()) {
215
+ for (const [i, o] of t.entries()) {
216
216
  const r = this.accounts.find((u) => u.guid === i);
217
- if (r && r.is_excluded_from_accounts === n) {
217
+ if (r && r.is_excluded_from_accounts === o) {
218
218
  const u = {
219
219
  ...r,
220
- is_excluded_from_accounts: !n
220
+ is_excluded_from_accounts: !o
221
221
  };
222
222
  e.push(this.api.updateAccount(u).catch((l) => (console.error("Error occurred while updating account filter:", l), this.globalStore.captureException(l, { store: "AccountStore" }), null)));
223
223
  }
224
224
  }
225
- const s = (await Promise.all(e)).filter((i) => i !== null), o = [...this.accounts];
225
+ const s = (await Promise.all(e)).filter((i) => i !== null), n = [...this.accounts];
226
226
  for (const i of s) {
227
- const n = o.findIndex((r) => r.guid === i.guid);
228
- n !== -1 && o.splice(n, 1, i);
227
+ const o = n.findIndex((r) => r.guid === i.guid);
228
+ o !== -1 && n.splice(o, 1, i);
229
229
  }
230
- this.setAccounts(o);
230
+ this.setAccounts(n);
231
231
  } catch (e) {
232
232
  console.error("Error occurred while updating account filter:", e), this.globalStore.captureException(e, { store: "AccountStore" });
233
233
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AccountStore.es.js","names":[],"sources":["../../../src/core/stores/AccountStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AccountApi } from '../api'\nimport { upsertByGuid } from '../utils/upsertByGuid'\nimport {\n type Account,\n type DetailedAccount,\n type Institution,\n type Member,\n AccountType,\n AccountSubType,\n} from '../types'\nimport { augmentAccounts } from '../utils/AccountUtils'\nimport { isFeatureEnabled } from '../utils/UserUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AccountStore {\n globalStore: GlobalStore\n api: AccountApi = new AccountApi('/', '')\n\n accounts: Account[] = []\n accountsLoaded: boolean = false\n accountsLoading: boolean = false\n institutions: Institution[] = []\n institutionsLoaded: boolean = false\n institutionsLoading: boolean = false\n members: Member[] = []\n membersLoaded: boolean = false\n membersLoading: boolean = false\n uiStore: UiStore\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new AccountApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadAccountData = async () => {\n await Promise.all([this.loadAccounts(), this.loadMembers(), this.loadInstitutions()])\n }\n\n get isAccountDataLoaded(): boolean {\n return this.accountsLoaded && this.membersLoaded && this.institutionsLoaded\n }\n\n get detailedAccounts(): DetailedAccount[] {\n const userFeatures = this.globalStore.userStore.userFeatures\n const excludeExternal = isFeatureEnabled(userFeatures, 'MD_EXCLUDE_EXTERNAL_ACCOUNTS')\n\n // Hide held account when this flag is toggled and this is the individual accounts widget\n const excludeHeld =\n this.globalStore.appConfig.config.display_only_external_accounts_in_accounts &&\n this.globalStore.appConfig.options.subtype === 'accounts' // Indicates this is an individual widget\n\n return augmentAccounts(\n this.accounts,\n this.institutions,\n this.members,\n excludeExternal,\n excludeHeld,\n )\n }\n\n get accountsByTypeMap(): Map<AccountType, DetailedAccount[]> {\n return this.detailedAccounts.reduce((typeMap: Map<AccountType, DetailedAccount[]>, account) => {\n const accountType = account.account_type\n\n let accounts = typeMap.get(accountType)\n if (!accounts) {\n accounts = []\n }\n accounts.push(account)\n typeMap.set(accountType, accounts)\n\n return typeMap\n }, new Map<AccountType, DetailedAccount[]>())\n }\n\n get cashAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.PREPAID ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get cashBalance(): number {\n return this.cashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get checkingAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.CHECKING)\n }\n\n get debtAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CREDIT_CARD ||\n account.account_type === AccountType.LOAN ||\n account.account_type === AccountType.MORTGAGE ||\n account.account_type === AccountType.LINE_OF_CREDIT ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get finstrongAccounts(): DetailedAccount[] {\n const eligibleTypes = new Set([\n AccountType.CHECKING,\n AccountType.SAVINGS,\n AccountType.CREDIT_CARD,\n AccountType.INVESTMENT,\n ])\n\n return this.detailedAccounts.filter((account) => eligibleTypes.has(account.account_type))\n }\n\n get investmentAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) => account.account_type === AccountType.INVESTMENT,\n )\n }\n\n get manualAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((account) => account.is_manual)\n }\n\n get savingsAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.SAVINGS)\n }\n\n get retirementAccounts(): Account[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.INVESTMENT ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.PROPERTY ||\n (account.account_type === AccountType.INSURANCE &&\n (account.account_subtype === AccountSubType.WHOLE_LIFE ||\n account.account_subtype === AccountSubType.UNIVERSAL_LIFE ||\n account.account_subtype === AccountSubType.VARIABLE_UNIVERSAL_LIFE)),\n )\n }\n\n get visibleAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => !a.is_hidden && !a.is_closed)\n }\n\n get visibleCashAccounts(): DetailedAccount[] {\n return this.cashAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleCashBalance(): number {\n return this.visibleCashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get visibleCheckingAccounts(): DetailedAccount[] {\n return this.checkingAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleDebtAccounts(): DetailedAccount[] {\n return this.debtAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleFinstrongAccounts(): DetailedAccount[] {\n return this.finstrongAccounts.filter(\n (account: Account) => !(account.is_closed || account.is_deleted || account.is_hidden),\n )\n }\n\n get visibleRetirementAccounts(): Account[] {\n return this.retirementAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleInvestmentAccounts(): DetailedAccount[] {\n return this.investmentAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleSavingsAccounts(): DetailedAccount[] {\n return this.savingsAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get savingsAndCheckingAccountsBalance(): number {\n const savingsAndCheckingAccountsList = this.savingsAndCheckingAccounts\n\n return savingsAndCheckingAccountsList.reduce(\n (total, account) => total + (account?.balance || 0),\n 0,\n )\n }\n\n get savingsAndCheckingAccounts(): Account[] {\n const savingsAndCheckingAccounts = this.accounts.filter(\n (account: Account) =>\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING,\n )\n\n return savingsAndCheckingAccounts\n }\n\n setAccounts = (accounts: Account[]) => {\n this.accounts = accounts\n this.accountsLoading = false\n this.accountsLoaded = true\n }\n\n setMembers = (members: Member[]) => {\n this.members = members\n this.membersLoading = false\n this.membersLoaded = true\n }\n\n setInstitutions = (institutions: Institution[]) => {\n this.institutions = institutions\n this.institutionsLoading = false\n this.institutionsLoaded = true\n }\n\n addAccount = async (account: Account) => {\n try {\n const newAccount = await this.api.createAccount(account)\n\n runInAction(() => {\n this.accounts = upsertByGuid(this.accounts, newAccount)\n })\n } catch (error) {\n console.error('Error occurred while adding an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n loadAccounts = async () => {\n if (this.accountsLoading) return\n\n this.accountsLoading = true\n try {\n const accounts = await this.api.getAccounts()\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while loading accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setAccounts([])\n }\n }\n\n loadInstitutions = async () => {\n if (this.institutionsLoading) return\n\n this.institutionsLoading = true\n try {\n const institutions = await this.api.getInstitutions()\n this.setInstitutions(institutions)\n } catch (error) {\n console.error('Error occurred while loading institutions:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setInstitutions([])\n }\n }\n\n loadMembers = async () => {\n if (this.membersLoading) return\n\n this.membersLoading = true\n try {\n const members = await this.api.getMembers()\n this.setMembers(members)\n } catch (error) {\n console.error('Error occurred while loading members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setMembers([])\n }\n }\n\n mergeAccounts = async (accountGuids: string[]) => {\n try {\n const response = await this.api.mergeAccounts(accountGuids)\n // the response from the api is a funky database key here, so this is essentially just getting the first item in the returned object\n // to prevent making multiple api calls here\n const mergedAccount = response[Object.keys(response)[0]]\n\n runInAction(() => {\n const account2Index = this.accounts.findIndex((account) => account.guid === accountGuids[1])\n this.accounts.splice(account2Index, 1)\n\n const account1Index = this.accounts.findIndex((account) => account.guid === accountGuids[0])\n this.accounts.splice(account1Index, 1, mergedAccount)\n })\n } catch (error) {\n console.error('Error occurred while merging accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n /**\n * DEPRECATED: Use loadAccountData instead\n */\n refreshAccounts = async () => {\n await Promise.all([this.loadAccounts(), this.loadInstitutions(), this.loadMembers()])\n }\n\n refreshMembers = async () => {\n try {\n await this.api.refreshAllMembers()\n } catch (error) {\n console.error('Error occurred while refreshing members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n removeAccount = async (accountGuid: string) => {\n try {\n await this.api.deleteAccount(accountGuid)\n\n const deletedIndex = this.accounts.findIndex((account) => account.guid === accountGuid)\n this.accounts.splice(deletedIndex, 1)\n } catch (error) {\n console.error('Error occurred while removing an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccount = async (account: Account) => {\n try {\n const updatedAccount = await this.api.updateAccount(account)\n\n const updatedAccountIndex = this.accounts.findIndex(\n (account) => account.guid === updatedAccount.guid,\n )\n\n this.accounts.splice(updatedAccountIndex, 1, updatedAccount)\n } catch (error) {\n console.error('Error occurred while updating account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n updateAccountBalance = (accountGuid: string, balanceChange: number) => {\n const account = this.accounts.find((a) => a.guid === accountGuid)\n\n if (account) {\n runInAction(() => {\n account.balance = (account.balance || 0) + balanceChange\n })\n }\n }\n\n updateAccountFilter = async (accountMap: Map<string, boolean>) => {\n try {\n const accountUpdates: Promise<Account | null>[] = []\n for (const [guid, isSelected] of accountMap.entries()) {\n const account = this.accounts.find((acc) => acc.guid === guid)\n\n if (account && account.is_excluded_from_accounts === isSelected) {\n const updatedPayload = { ...account, is_excluded_from_accounts: !isSelected }\n accountUpdates.push(\n this.api.updateAccount(updatedPayload).catch((error) => {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n return null\n }),\n )\n }\n }\n\n const results = await Promise.all(accountUpdates)\n const updatedAccounts: Account[] = results.filter((acc): acc is Account => acc !== null)\n\n const accounts = [...this.accounts]\n for (const updatedAccount of updatedAccounts) {\n const index = accounts.findIndex((acc) => acc.guid === updatedAccount.guid)\n if (index !== -1) {\n accounts.splice(index, 1, updatedAccount)\n }\n }\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n}\n\n// TODO: Move into AccountStore\nclass UiStore {\n selectedAccount: Account = {} as Account\n selectedMember: Member = {} as Member\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setSelectedAccount = (account: Account) => (this.selectedAccount = account)\n setSelectedMember = (member: Member) => (this.selectedMember = member)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AccountStore.es.js","names":[],"sources":["../../../src/core/stores/AccountStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AccountApi } from '../api'\nimport { upsertByGuid } from '../utils/upsertByGuid'\nimport {\n type Account,\n type DetailedAccount,\n type Institution,\n type Member,\n AccountType,\n AccountSubType,\n} from '../types'\nimport { augmentAccounts } from '../utils/AccountUtils'\nimport { isFeatureEnabled } from '../utils/UserUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AccountStore {\n globalStore: GlobalStore\n api: AccountApi = new AccountApi('/', '')\n\n accounts: Account[] = []\n accountsLoaded: boolean = false\n accountsLoading: boolean = false\n institutions: Institution[] = []\n institutionsLoaded: boolean = false\n institutionsLoading: boolean = false\n members: Member[] = []\n membersLoaded: boolean = false\n membersLoading: boolean = false\n uiStore: UiStore\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new AccountApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadAccountData = async () => {\n await Promise.all([this.loadAccounts(), this.loadMembers(), this.loadInstitutions()])\n }\n\n get isAccountDataLoaded(): boolean {\n return this.accountsLoaded && this.membersLoaded && this.institutionsLoaded\n }\n\n get detailedAccounts(): DetailedAccount[] {\n const userFeatures = this.globalStore.userStore.userFeatures\n const excludeExternal = isFeatureEnabled(userFeatures, 'MD_EXCLUDE_EXTERNAL_ACCOUNTS')\n\n // Hide held account when this flag is toggled and this is the individual accounts widget\n const excludeHeld =\n this.globalStore.appConfig.config.display_only_external_accounts_in_accounts &&\n this.globalStore.appConfig.options.subtype === 'accounts' // Indicates this is an individual widget\n\n return augmentAccounts(\n this.accounts,\n this.institutions,\n this.members,\n excludeExternal,\n excludeHeld,\n )\n }\n\n get accountsByTypeMap(): Map<AccountType, DetailedAccount[]> {\n return this.detailedAccounts.reduce((typeMap: Map<AccountType, DetailedAccount[]>, account) => {\n const accountType = account.account_type\n\n let accounts = typeMap.get(accountType)\n if (!accounts) {\n accounts = []\n }\n accounts.push(account)\n typeMap.set(accountType, accounts)\n\n return typeMap\n }, new Map<AccountType, DetailedAccount[]>())\n }\n\n get cashAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.PREPAID ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get cashBalance(): number {\n return this.cashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get checkingAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.CHECKING)\n }\n\n get debtAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.CREDIT_CARD ||\n account.account_type === AccountType.LOAN ||\n account.account_type === AccountType.MORTGAGE ||\n account.account_type === AccountType.LINE_OF_CREDIT ||\n account.account_type === AccountType.CHECKING_LINE_OF_CREDIT,\n )\n }\n\n get finstrongAccounts(): DetailedAccount[] {\n const eligibleTypes = new Set([\n AccountType.CHECKING,\n AccountType.SAVINGS,\n AccountType.CREDIT_CARD,\n AccountType.INVESTMENT,\n ])\n\n return this.detailedAccounts.filter((account) => eligibleTypes.has(account.account_type))\n }\n\n get investmentAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter(\n (account: Account) => account.account_type === AccountType.INVESTMENT,\n )\n }\n\n get manualAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((account) => account.is_manual)\n }\n\n get savingsAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => a.account_type === AccountType.SAVINGS)\n }\n\n get retirementAccounts(): Account[] {\n return this.detailedAccounts.filter(\n (account: Account) =>\n account.account_type === AccountType.INVESTMENT ||\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING ||\n account.account_type === AccountType.CASH ||\n account.account_type === AccountType.PROPERTY ||\n (account.account_type === AccountType.INSURANCE &&\n (account.account_subtype === AccountSubType.WHOLE_LIFE ||\n account.account_subtype === AccountSubType.UNIVERSAL_LIFE ||\n account.account_subtype === AccountSubType.VARIABLE_UNIVERSAL_LIFE)),\n )\n }\n\n get visibleAccounts(): DetailedAccount[] {\n return this.detailedAccounts.filter((a: Account) => !a.is_hidden && !a.is_closed)\n }\n\n get visibleCashAccounts(): DetailedAccount[] {\n return this.cashAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleCashBalance(): number {\n return this.visibleCashAccounts.reduce((total, account) => total + (account?.balance || 0), 0)\n }\n\n get visibleCheckingAccounts(): DetailedAccount[] {\n return this.checkingAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleDebtAccounts(): DetailedAccount[] {\n return this.debtAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleFinstrongAccounts(): DetailedAccount[] {\n return this.finstrongAccounts.filter(\n (account: Account) => !(account.is_closed || account.is_deleted || account.is_hidden),\n )\n }\n\n get visibleRetirementAccounts(): Account[] {\n return this.retirementAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleInvestmentAccounts(): DetailedAccount[] {\n return this.investmentAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get visibleSavingsAccounts(): DetailedAccount[] {\n return this.savingsAccounts.filter((account: Account) => !account.is_hidden)\n }\n\n get savingsAndCheckingAccountsBalance(): number {\n const savingsAndCheckingAccountsList = this.savingsAndCheckingAccounts\n\n return savingsAndCheckingAccountsList.reduce(\n (total, account) => total + (account?.balance || 0),\n 0,\n )\n }\n\n get savingsAndCheckingAccounts(): Account[] {\n const savingsAndCheckingAccounts = this.accounts.filter(\n (account: Account) =>\n account.account_type === AccountType.SAVINGS ||\n account.account_type === AccountType.CHECKING,\n )\n\n return savingsAndCheckingAccounts\n }\n\n setAccounts = (accounts: Account[]) => {\n this.accounts = accounts\n this.accountsLoading = false\n this.accountsLoaded = true\n }\n\n setMembers = (members: Member[]) => {\n this.members = members\n this.membersLoading = false\n this.membersLoaded = true\n }\n\n setInstitutions = (institutions: Institution[]) => {\n this.institutions = institutions\n this.institutionsLoading = false\n this.institutionsLoaded = true\n }\n\n addAccount = async (account: Account) => {\n try {\n const newAccount = await this.api.createAccount(account)\n\n runInAction(() => {\n this.accounts = upsertByGuid(this.accounts, newAccount)\n })\n } catch (error) {\n console.error('Error occurred while adding an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n loadAccounts = async () => {\n if (this.accountsLoading) return\n\n this.accountsLoading = true\n try {\n const accounts = await this.api.getAccounts()\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while loading accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setAccounts([])\n }\n }\n\n loadInstitutions = async () => {\n if (this.institutionsLoading) return\n\n this.institutionsLoading = true\n try {\n const institutions = await this.api.getInstitutions()\n this.setInstitutions(institutions)\n } catch (error) {\n console.error('Error occurred while loading institutions:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setInstitutions([])\n }\n }\n\n loadMembers = async () => {\n if (this.membersLoading) return\n\n this.membersLoading = true\n try {\n const members = await this.api.getMembers()\n this.setMembers(members)\n } catch (error) {\n console.error('Error occurred while loading members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n this.setMembers([])\n }\n }\n\n mergeAccounts = async (accountGuids: string[]) => {\n try {\n const response = await this.api.mergeAccounts(accountGuids)\n // the response from the api is a funky database key here, so this is essentially just getting the first item in the returned object\n // to prevent making multiple api calls here\n const mergedAccount = response[Object.keys(response)[0]]\n\n runInAction(() => {\n const account2Index = this.accounts.findIndex((account) => account.guid === accountGuids[1])\n this.accounts.splice(account2Index, 1)\n\n const account1Index = this.accounts.findIndex((account) => account.guid === accountGuids[0])\n this.accounts.splice(account1Index, 1, mergedAccount)\n })\n } catch (error) {\n console.error('Error occurred while merging accounts:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n /**\n * DEPRECATED: Use loadAccountData instead\n */\n refreshAccounts = async () => {\n await Promise.all([this.loadAccounts(), this.loadInstitutions(), this.loadMembers()])\n }\n\n refreshMembers = async () => {\n try {\n await this.api.refreshAllMembers()\n } catch (error) {\n console.error('Error occurred while refreshing members:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n removeAccount = async (accountGuid: string) => {\n try {\n await this.api.deleteAccount(accountGuid)\n\n const deletedIndex = this.accounts.findIndex((account) => account.guid === accountGuid)\n this.accounts.splice(deletedIndex, 1)\n } catch (error) {\n console.error('Error occurred while removing an account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n\n /** Resolves `true` when the account was saved, `false` when the API call failed. */\n updateAccount = async (account: Account): Promise<boolean> => {\n try {\n const updatedAccount = await this.api.updateAccount(account)\n\n const updatedAccountIndex = this.accounts.findIndex(\n (account) => account.guid === updatedAccount.guid,\n )\n\n this.accounts.splice(updatedAccountIndex, 1, updatedAccount)\n return true\n } catch (error) {\n console.error('Error occurred while updating account:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n return false\n }\n }\n\n updateAccountBalance = (accountGuid: string, balanceChange: number) => {\n const account = this.accounts.find((a) => a.guid === accountGuid)\n\n if (account) {\n runInAction(() => {\n account.balance = (account.balance || 0) + balanceChange\n })\n }\n }\n\n updateAccountFilter = async (accountMap: Map<string, boolean>) => {\n try {\n const accountUpdates: Promise<Account | null>[] = []\n for (const [guid, isSelected] of accountMap.entries()) {\n const account = this.accounts.find((acc) => acc.guid === guid)\n\n if (account && account.is_excluded_from_accounts === isSelected) {\n const updatedPayload = { ...account, is_excluded_from_accounts: !isSelected }\n accountUpdates.push(\n this.api.updateAccount(updatedPayload).catch((error) => {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n return null\n }),\n )\n }\n }\n\n const results = await Promise.all(accountUpdates)\n const updatedAccounts: Account[] = results.filter((acc): acc is Account => acc !== null)\n\n const accounts = [...this.accounts]\n for (const updatedAccount of updatedAccounts) {\n const index = accounts.findIndex((acc) => acc.guid === updatedAccount.guid)\n if (index !== -1) {\n accounts.splice(index, 1, updatedAccount)\n }\n }\n this.setAccounts(accounts)\n } catch (error) {\n console.error('Error occurred while updating account filter:', error)\n this.globalStore.captureException(error, { store: 'AccountStore' })\n }\n }\n}\n\n// TODO: Move into AccountStore\nclass UiStore {\n selectedAccount: Account = {} as Account\n selectedMember: Member = {} as Member\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setSelectedAccount = (account: Account) => (this.selectedAccount = account)\n setSelectedMember = (member: Member) => (this.selectedMember = member)\n}\n"],"mappings":"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"}
@@ -8,6 +8,12 @@ export declare class BeatStore {
8
8
  isLoading: boolean;
9
9
  constructor(globalStore: GlobalStore);
10
10
  loadBeats: () => Promise<void>;
11
+ /**
12
+ * Persists changes to an offer-backed beat (pulse marketing offers, `PUT offers/:guid`),
13
+ * e.g. flagging `has_been_clicked` when its CTA is pressed. Rethrows so callers driving
14
+ * UI state can surface the failure.
15
+ */
16
+ updateOffer: (beat: Beat) => Promise<any>;
11
17
  getFilteredBeats(filter: {
12
18
  categoryGuids?: string[];
13
19
  templates?: string[];
@@ -1,43 +1,56 @@
1
- import { BeatApi as s } from "../api/BeatApi.es.js";
1
+ import { BeatApi as i } from "../api/BeatApi.es.js";
2
2
  import { orderArray as o, transformOfferIntoBeatLikeObject as n } from "../utils/BeatUtils.es.js";
3
- import { makeAutoObservable as l, runInAction as i } from "mobx";
4
- var B = class {
3
+ import { makeAutoObservable as c, runInAction as s } from "mobx";
4
+ var u = class {
5
5
  globalStore;
6
- api = new s("/", "");
6
+ api = new i("/", "");
7
7
  beats = [];
8
8
  isLoading = !1;
9
9
  constructor(t) {
10
- this.globalStore = t, this.api = new s(t.endpoint, t.sessionToken, t.onError), l(this);
10
+ this.globalStore = t, this.api = new i(t.endpoint, t.sessionToken, t.onError), c(this);
11
11
  }
12
12
  loadBeats = async () => {
13
13
  this.isLoading = !0;
14
14
  try {
15
- const t = await this.api.getBeats(), r = (await this.api.getOffers()).map((a) => n(a));
16
- i(() => {
17
- this.beats = o(t, r, "active_at", "desc");
15
+ const t = await this.api.getBeats(), e = (await this.api.getOffers()).map((r) => n(r));
16
+ s(() => {
17
+ this.beats = o(t, e, "active_at", "desc");
18
18
  });
19
19
  } catch (t) {
20
20
  console.error("Error occurred while loading beats:", t), this.globalStore.captureException(t, { store: "BeatStore" });
21
21
  } finally {
22
- i(() => {
22
+ s(() => {
23
23
  this.isLoading = !1;
24
24
  });
25
25
  }
26
26
  };
27
+ updateOffer = async (t) => {
28
+ try {
29
+ const e = await this.api.updateOffer(t);
30
+ return s(() => {
31
+ this.beats = this.beats.map((r) => r.guid === t.guid ? {
32
+ ...r,
33
+ ...e
34
+ } : r);
35
+ }), e;
36
+ } catch (e) {
37
+ throw console.error("Error occurred while updating offer:", e), this.globalStore.captureException(e, { store: "BeatStore" }), e;
38
+ }
39
+ };
27
40
  getFilteredBeats(t) {
28
- const { categoryGuids: r, templates: a } = t;
29
- let e = this.beats;
30
- return r && (e = this.filterBeatsByCategory(e, r)), a && (e = this.filterBeatsByTemplate(e, a)), e;
41
+ const { categoryGuids: e, templates: r } = t;
42
+ let a = this.beats;
43
+ return e && (a = this.filterBeatsByCategory(a, e)), r && (a = this.filterBeatsByTemplate(a, r)), a;
31
44
  }
32
- filterBeatsByCategory(t, r) {
33
- return t.filter((a) => a.category_guids?.some((e) => r.includes(e)));
45
+ filterBeatsByCategory(t, e) {
46
+ return t.filter((r) => r.category_guids?.some((a) => e.includes(a)));
34
47
  }
35
- filterBeatsByTemplate(t, r) {
36
- return t.filter((a) => r.some((e) => a.template === e));
48
+ filterBeatsByTemplate(t, e) {
49
+ return t.filter((r) => e.some((a) => r.template === a));
37
50
  }
38
51
  };
39
52
  export {
40
- B as BeatStore
53
+ u as BeatStore
41
54
  };
42
55
 
43
56
  //# sourceMappingURL=BeatStore.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BeatStore.es.js","names":[],"sources":["../../../src/core/stores/BeatStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { BeatApi } from '../api'\nimport type { Beat, Offer } from '../types'\nimport { orderArray, transformOfferIntoBeatLikeObject } from '../utils/BeatUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class BeatStore {\n globalStore: GlobalStore\n api: BeatApi = new BeatApi('/', '')\n beats: Beat[] = []\n isLoading = false\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadBeats = async () => {\n this.isLoading = true\n try {\n const beats = await this.api.getBeats()\n const offers = await this.api.getOffers()\n const beatLikeOffers = offers.map((o: Offer) => transformOfferIntoBeatLikeObject(o))\n\n runInAction(() => {\n this.beats = orderArray(beats, beatLikeOffers, 'active_at', 'desc')\n })\n } catch (error) {\n console.error('Error occurred while loading beats:', error)\n this.globalStore.captureException(error, { store: 'BeatStore' })\n } finally {\n runInAction(() => {\n this.isLoading = false\n })\n }\n }\n\n getFilteredBeats(filter: { categoryGuids?: string[]; templates?: string[] }): Beat[] {\n const { categoryGuids, templates } = filter\n let filteredBeats = this.beats\n if (categoryGuids) filteredBeats = this.filterBeatsByCategory(filteredBeats, categoryGuids)\n if (templates) filteredBeats = this.filterBeatsByTemplate(filteredBeats, templates)\n return filteredBeats\n }\n\n // Return beats with any beat.category_guids that are in categoryGuids\n filterBeatsByCategory(beats: Beat[], categoryGuids: string[]): Beat[] {\n return beats.filter((beat) => {\n return beat.category_guids?.some((guid) => categoryGuids.includes(guid))\n })\n }\n\n // Return beats with a beat.template that is in templates\n filterBeatsByTemplate(beats: Beat[], templates: string[]): Beat[] {\n return beats.filter((beat) => {\n return templates.some((template) => beat.template === template)\n })\n }\n}\n"],"mappings":";;;AAQA,IAAa,IAAb,MAAuB;AAAA,EACrB;AAAA,EACA,MAAe,IAAI,EAAQ,KAAK,EAAE;AAAA,EAClC,QAAgB,CAAC;AAAA,EACjB,YAAY;AAAA,EAEZ,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAQ,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE1F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,YAAY,YAAY;AACtB,SAAK,YAAY;AACjB,QAAI;AACF,YAAM,IAAQ,MAAM,KAAK,IAAI,SAAS,GAEhC,KAAiB,MADF,KAAK,IAAI,UAAU,GACV,IAAA,CAAK,MAAa,EAAiC,CAAC,CAAC;AAEnF,MAAA,EAAA,MAAkB;AAChB,aAAK,QAAQ,EAAW,GAAO,GAAgB,aAAa,MAAM;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,uCAAuC,CAAK,GAC1D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,YAAY,CAAC;AAAA,IACjE,UAAA;AACE,MAAA,EAAA,MAAkB;AAChB,aAAK,YAAY;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,iBAAiB,GAAoE;AACnF,UAAM,EAAE,eAAA,GAAe,WAAA,EAAA,IAAc;AACrC,QAAI,IAAgB,KAAK;AACzB,WAAI,MAAe,IAAgB,KAAK,sBAAsB,GAAe,CAAa,IACtF,MAAW,IAAgB,KAAK,sBAAsB,GAAe,CAAS,IAC3E;AAAA,EACT;AAAA,EAGA,sBAAsB,GAAe,GAAiC;AACpE,WAAO,EAAM,OAAA,CAAQ,MACZ,EAAK,gBAAgB,KAAA,CAAM,MAAS,EAAc,SAAS,CAAI,CAAC,CACxE;AAAA,EACH;AAAA,EAGA,sBAAsB,GAAe,GAA6B;AAChE,WAAO,EAAM,OAAA,CAAQ,MACZ,EAAU,KAAA,CAAM,MAAa,EAAK,aAAa,CAAQ,CAC/D;AAAA,EACH;AACF"}
1
+ {"version":3,"file":"BeatStore.es.js","names":[],"sources":["../../../src/core/stores/BeatStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { BeatApi } from '../api'\nimport type { Beat, Offer } from '../types'\nimport { orderArray, transformOfferIntoBeatLikeObject } from '../utils/BeatUtils'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class BeatStore {\n globalStore: GlobalStore\n api: BeatApi = new BeatApi('/', '')\n beats: Beat[] = []\n isLoading = false\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadBeats = async () => {\n this.isLoading = true\n try {\n const beats = await this.api.getBeats()\n const offers = await this.api.getOffers()\n const beatLikeOffers = offers.map((o: Offer) => transformOfferIntoBeatLikeObject(o))\n\n runInAction(() => {\n this.beats = orderArray(beats, beatLikeOffers, 'active_at', 'desc')\n })\n } catch (error) {\n console.error('Error occurred while loading beats:', error)\n this.globalStore.captureException(error, { store: 'BeatStore' })\n } finally {\n runInAction(() => {\n this.isLoading = false\n })\n }\n }\n\n /**\n * Persists changes to an offer-backed beat (pulse marketing offers, `PUT offers/:guid`),\n * e.g. flagging `has_been_clicked` when its CTA is pressed. Rethrows so callers driving\n * UI state can surface the failure.\n */\n updateOffer = async (beat: Beat) => {\n try {\n const updated = await this.api.updateOffer(beat)\n\n runInAction(() => {\n this.beats = this.beats.map((b) => (b.guid === beat.guid ? { ...b, ...updated } : b))\n })\n\n return updated\n } catch (error) {\n console.error('Error occurred while updating offer:', error)\n this.globalStore.captureException(error, { store: 'BeatStore' })\n throw error\n }\n }\n\n getFilteredBeats(filter: { categoryGuids?: string[]; templates?: string[] }): Beat[] {\n const { categoryGuids, templates } = filter\n let filteredBeats = this.beats\n if (categoryGuids) filteredBeats = this.filterBeatsByCategory(filteredBeats, categoryGuids)\n if (templates) filteredBeats = this.filterBeatsByTemplate(filteredBeats, templates)\n return filteredBeats\n }\n\n // Return beats with any beat.category_guids that are in categoryGuids\n filterBeatsByCategory(beats: Beat[], categoryGuids: string[]): Beat[] {\n return beats.filter((beat) => {\n return beat.category_guids?.some((guid) => categoryGuids.includes(guid))\n })\n }\n\n // Return beats with a beat.template that is in templates\n filterBeatsByTemplate(beats: Beat[], templates: string[]): Beat[] {\n return beats.filter((beat) => {\n return templates.some((template) => beat.template === template)\n })\n }\n}\n"],"mappings":";;;AAQA,IAAa,IAAb,MAAuB;AAAA,EACrB;AAAA,EACA,MAAe,IAAI,EAAQ,KAAK,EAAE;AAAA,EAClC,QAAgB,CAAC;AAAA,EACjB,YAAY;AAAA,EAEZ,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAQ,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE1F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,YAAY,YAAY;AACtB,SAAK,YAAY;AACjB,QAAI;AACF,YAAM,IAAQ,MAAM,KAAK,IAAI,SAAS,GAEhC,KAAiB,MADF,KAAK,IAAI,UAAU,GACV,IAAA,CAAK,MAAa,EAAiC,CAAC,CAAC;AAEnF,MAAA,EAAA,MAAkB;AAChB,aAAK,QAAQ,EAAW,GAAO,GAAgB,aAAa,MAAM;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,uCAAuC,CAAK,GAC1D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,YAAY,CAAC;AAAA,IACjE,UAAA;AACE,MAAA,EAAA,MAAkB;AAChB,aAAK,YAAY;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAOA,cAAc,OAAO,MAAe;AAClC,QAAI;AACF,YAAM,IAAU,MAAM,KAAK,IAAI,YAAY,CAAI;AAE/C,aAAA,EAAA,MAAkB;AAChB,aAAK,QAAQ,KAAK,MAAM,IAAA,CAAK,MAAO,EAAE,SAAS,EAAK,OAAO;AAAA,UAAE,GAAG;AAAA,UAAG,GAAG;AAAA,QAAQ,IAAI,CAAE;AAAA,MACtF,CAAC,GAEM;AAAA,IACT,SAAS,GAAO;AACd,oBAAQ,MAAM,wCAAwC,CAAK,GAC3D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,YAAY,CAAC,GACzD;AAAA,IACR;AAAA,EACF;AAAA,EAEA,iBAAiB,GAAoE;AACnF,UAAM,EAAE,eAAA,GAAe,WAAA,EAAA,IAAc;AACrC,QAAI,IAAgB,KAAK;AACzB,WAAI,MAAe,IAAgB,KAAK,sBAAsB,GAAe,CAAa,IACtF,MAAW,IAAgB,KAAK,sBAAsB,GAAe,CAAS,IAC3E;AAAA,EACT;AAAA,EAGA,sBAAsB,GAAe,GAAiC;AACpE,WAAO,EAAM,OAAA,CAAQ,MACZ,EAAK,gBAAgB,KAAA,CAAM,MAAS,EAAc,SAAS,CAAI,CAAC,CACxE;AAAA,EACH;AAAA,EAGA,sBAAsB,GAAe,GAA6B;AAChE,WAAO,EAAM,OAAA,CAAQ,MACZ,EAAU,KAAA,CAAM,MAAa,EAAK,aAAa,CAAQ,CAC/D;AAAA,EACH;AACF"}
@@ -22,7 +22,8 @@ export declare class BudgetsStore {
22
22
  get incomeBudget(): number | undefined;
23
23
  get unbudgetedCategories(): DetailedCategory[];
24
24
  get totalBudgeted(): number;
25
- addBudget: (category: Category, amount: number, parentGuid?: string | null) => Promise<void>;
25
+ /** Resolves `true` when the budget was created, `false` when the API call failed. */
26
+ addBudget: (category: Category, amount: number, parentGuid?: string | null) => Promise<boolean>;
26
27
  deleteBudget: (guid: string) => Promise<boolean>;
27
28
  loadBudgets: () => Promise<void>;
28
29
  setAlert: (alert: {
@@ -1,18 +1,18 @@
1
1
  import { CategoryGuids as o } from "../constants/Category.es.js";
2
2
  import { BudgetsApi as g } from "../api/BudgetsApi.es.js";
3
3
  import { upsertByGuid as n } from "../utils/upsertByGuid.es.js";
4
- import { augmentBudgets as c, findBudget as l, findSubBudget as p } from "../utils/BudgetUtil.es.js";
4
+ import { augmentBudgets as c, findBudget as h, findSubBudget as p } from "../utils/BudgetUtil.es.js";
5
5
  import { endOfMonth as B } from "date-fns/endOfMonth";
6
6
  import { startOfMonth as f } from "date-fns/startOfMonth";
7
- import { startOfToday as h } from "date-fns/startOfToday";
7
+ import { startOfToday as l } from "date-fns/startOfToday";
8
8
  import { makeAutoObservable as S, reaction as b, runInAction as i } from "mobx";
9
9
  var A = class {
10
10
  api = new g("/", "");
11
11
  globalStore;
12
12
  alert = null;
13
13
  dateRange = {
14
- start: f(h()),
15
- end: B(h())
14
+ start: f(l()),
15
+ end: B(l())
16
16
  };
17
17
  budgets = [];
18
18
  selectedBudget;
@@ -27,7 +27,7 @@ var A = class {
27
27
  this.globalStore.recurringTransactionsStore.isDataLoaded || await this.globalStore.recurringTransactionsStore.loadRepeatingTransactionData(), await this.loadBudgets(), b(() => this.detailedBudgets, (t) => {
28
28
  if (t) {
29
29
  const e = this.selectedBudget;
30
- e && (this.selectedBudget = l(t, e.guid));
30
+ e && (this.selectedBudget = h(t, e.guid));
31
31
  const r = this.selectedSubBudget;
32
32
  r && r.parent_guid && (this.selectedSubBudget = p(t, r.guid, r.parent_guid));
33
33
  }
@@ -48,11 +48,11 @@ var A = class {
48
48
  addBudget = async (t, e, r = null) => {
49
49
  try {
50
50
  const s = await this.api.addBudget(t, e, r);
51
- i(() => {
51
+ return i(() => {
52
52
  this.budgets = n(this.budgets, s);
53
- });
53
+ }), !0;
54
54
  } catch (s) {
55
- console.error("Error adding budget:", s), this.globalStore.captureException(s, { store: "BudgetsStore" });
55
+ return console.error("Error adding budget:", s), this.globalStore.captureException(s, { store: "BudgetsStore" }), !1;
56
56
  }
57
57
  };
58
58
  deleteBudget = async (t) => {