@mx-cartographer/experiences 9.6.7 → 9.6.9

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 (50) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/common/components/Banner.es.js +66 -26
  3. package/dist/common/components/Banner.es.js.map +1 -1
  4. package/dist/common/components/ConnectDrawer.d.ts +2 -0
  5. package/dist/common/components/ConnectDrawer.es.js +15 -14
  6. package/dist/common/components/ConnectDrawer.es.js.map +1 -1
  7. package/dist/common/components/ConnectWidgetPanel.d.ts +2 -0
  8. package/dist/common/components/ConnectWidgetPanel.es.js +48 -39
  9. package/dist/common/components/ConnectWidgetPanel.es.js.map +1 -1
  10. package/dist/common/constants/Analytics.d.ts +6 -0
  11. package/dist/common/constants/Analytics.es.js +7 -1
  12. package/dist/common/constants/Analytics.es.js.map +1 -1
  13. package/dist/common/constants/Connect.d.ts +7 -0
  14. package/dist/common/constants/Connect.es.js +6 -4
  15. package/dist/common/constants/Connect.es.js.map +1 -1
  16. package/dist/common/constants/index.d.ts +2 -1
  17. package/dist/common/index.es.js +95 -93
  18. package/dist/core/api/BannerApi.d.ts +1 -0
  19. package/dist/core/api/BannerApi.es.js +4 -2
  20. package/dist/core/api/BannerApi.es.js.map +1 -1
  21. package/dist/core/stores/AppDataStore.d.ts +1 -0
  22. package/dist/core/stores/AppDataStore.es.js +9 -2
  23. package/dist/core/stores/AppDataStore.es.js.map +1 -1
  24. package/dist/core/types/AppData.d.ts +2 -0
  25. package/dist/core/types/localization/InsightsFeedCopy.d.ts +1 -1
  26. package/dist/insights-v2/actionBlocks/MakeTransferActionBlock/layout.es.js +6 -6
  27. package/dist/insights-v2/actionBlocks/MakeTransferActionBlock/layout.es.js.map +1 -1
  28. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/layout.d.ts +2 -2
  29. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/layout.es.js +15 -15
  30. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/layout.es.js.map +1 -1
  31. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/layout.d.ts +1 -1
  32. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/layout.es.js +1 -1
  33. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/layout.es.js.map +1 -1
  34. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.d.ts +1 -1
  35. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.es.js +16 -16
  36. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.es.js.map +1 -1
  37. package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/AccountBlock.es.js +6 -7
  38. package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/AccountBlock.es.js.map +1 -1
  39. package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/layout.d.ts +1 -1
  40. package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/layout.es.js +14 -30
  41. package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/layout.es.js.map +1 -1
  42. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.d.ts +8 -8
  43. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js +14 -14
  44. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js.map +1 -1
  45. package/dist/insights-v2/blocks/ComponentBlocks/UpcomingSubscriptionBlock/UpcomingSubscriptionBlock.es.js +1 -1
  46. package/dist/insights-v2/blocks/ComponentBlocks/UpcomingSubscriptionBlock/UpcomingSubscriptionBlock.es.js.map +1 -1
  47. package/dist/insights-v2/blocks/ComponentBlocks/UpcomingSubscriptionBlock/layout.d.ts +4 -3
  48. package/dist/insights-v2/blocks/ComponentBlocks/UpcomingSubscriptionBlock/layout.es.js +2 -2
  49. package/dist/insights-v2/blocks/ComponentBlocks/UpcomingSubscriptionBlock/layout.es.js.map +1 -1
  50. package/package.json +1 -1
@@ -4,9 +4,9 @@ import a from "./components/charts/StatusBar.es.js";
4
4
  import p from "./components/charts/Donut.es.js";
5
5
  import u from "./hooks/useAccountDisplayName.es.js";
6
6
  import { useCombineEvents as C, useCombinePageviews as S } from "./hooks/useCombineEvents.es.js";
7
- import { GlobalDataContext as c, GlobalDataProvider as d } from "./context/GlobalDataProvider.es.js";
8
- import { WidgetContainerContext as E, WidgetContainerProvider as D } from "./context/WidgetContainerProvider.es.js";
9
- import { useAccountStore as I, useActionContext as N, useAppConfig as P, useBudgetsStore as y, useCashflowStore as A, useCategoryStore as b, useDebtStore as O, useError as W, useEvent as G, useFinstrongStore as L, useGlobalCopyStore as R, useGlobalStore as U, useGlobalUiStore as v, useGoalStore as B, useHelpStore as h, useHoldingStore as w, useInsightsV2Store as x, useLoad as M, useMerchantStore as Y, useNetWorthStore as H, useNotificationStore as F, usePageView as z, useRecurringTransactionsStore as V, useSettingsStore as Z, useTransactionStore as k, useTrendsStore as q, useUserStore as K, useWidgetContainerProvider as j } from "./context/hooks.es.js";
7
+ import { GlobalDataContext as c, GlobalDataProvider as T } from "./context/GlobalDataProvider.es.js";
8
+ import { WidgetContainerContext as d, WidgetContainerProvider as D } from "./context/WidgetContainerProvider.es.js";
9
+ import { useAccountStore as I, useActionContext as N, useAppConfig as P, useBudgetsStore as y, useCashflowStore as A, useCategoryStore as O, useDebtStore as b, useError as W, useEvent as G, useFinstrongStore as L, useGlobalCopyStore as R, useGlobalStore as U, useGlobalUiStore as v, useGoalStore as B, useHelpStore as h, useHoldingStore as w, useInsightsV2Store as x, useLoad as M, useMerchantStore as Y, useNetWorthStore as H, useNotificationStore as F, usePageView as z, useRecurringTransactionsStore as V, useSettingsStore as Z, useTransactionStore as K, useTrendsStore as k, useUserStore as q, useWidgetContainerProvider as j } from "./context/hooks.es.js";
10
10
  import { useInsightsEnabled as Q } from "./hooks/useInsightsEnabled.es.js";
11
11
  import { useScreenSize as $ } from "./hooks/useScreenSize.es.js";
12
12
  import ro from "./hooks/usePrevious.es.js";
@@ -18,112 +18,114 @@ import co from "./components/dialog/Dialog.es.js";
18
18
  import Eo from "./components/drawer/Drawer.es.js";
19
19
  import _o from "./components/daterangeselector/DateRangeSelector.es.js";
20
20
  import { ANALYTICS_EVENTS as No } from "./constants/Analytics.es.js";
21
- import { CONNECTIONS_WIDGET_ID as yo, CONNECT_WIDGET_ID as Ao, MemberConnectionStatus as bo } from "./constants/Connect.es.js";
22
- import { GlobalStore as Wo } from "../core/stores/GlobalStore.es.js";
23
- import { INCOME_ACCOUNT_TYPES as Lo, PAYMENT_ACCOUNT_TYPES as Ro, SPENDING_ACCOUNT_TYPES as Uo } from "./constants/Account.es.js";
24
- import { RECURRENCE_COPY as Bo } from "./constants/ScheduledPayment.es.js";
25
- import { LOADING_STATUS as wo } from "./constants/SpendingPlan.es.js";
26
- import { DEFAULT_DONUT_SIZE as Mo, DEFAULT_STROKE_WIDTH as Yo } from "./constants/Donut.es.js";
27
- import { Sizes as Fo, TOUCH_TARGET as zo } from "./constants/Sizes.es.js";
28
- import Zo from "./components/donuts/MultiSegmentDonut.es.js";
29
- import qo from "./components/donuts/SingleSegmentDonut.es.js";
30
- import jo from "./components/ErrorBoundary.es.js";
31
- import Qo from "./components/Error.es.js";
32
- import $o from "./components/MicroWidgetContainer.es.js";
33
- import rr from "./components/MiniWidgetContainer.es.js";
34
- import { GlobalAccountFilter as er } from "./components/GlobalAccountFilter.es.js";
35
- import mr from "./components/Loader.es.js";
36
- import { WidgetContainer as ar } from "./components/WidgetContainer.es.js";
37
- import pr from "./components/ConnectWidgetPanel.es.js";
38
- import ur from "./components/ConnectDrawer.es.js";
39
- import Cr from "./components/CurrencyDialog.es.js";
40
- import gr from "./components/CurrencyInput.es.js";
21
+ import { CONNECTIONS_WIDGET_ID as yo, CONNECT_WIDGET_ID as Ao, CONNECT_WIDGET_SOURCES as Oo, DEEP_LINK_TYPE as bo, MemberConnectionStatus as Wo } from "./constants/Connect.es.js";
22
+ import { GlobalStore as Lo } from "../core/stores/GlobalStore.es.js";
23
+ import { INCOME_ACCOUNT_TYPES as Uo, PAYMENT_ACCOUNT_TYPES as vo, SPENDING_ACCOUNT_TYPES as Bo } from "./constants/Account.es.js";
24
+ import { RECURRENCE_COPY as wo } from "./constants/ScheduledPayment.es.js";
25
+ import { LOADING_STATUS as Mo } from "./constants/SpendingPlan.es.js";
26
+ import { DEFAULT_DONUT_SIZE as Ho, DEFAULT_STROKE_WIDTH as Fo } from "./constants/Donut.es.js";
27
+ import { Sizes as Vo, TOUCH_TARGET as Zo } from "./constants/Sizes.es.js";
28
+ import ko from "./components/donuts/MultiSegmentDonut.es.js";
29
+ import jo from "./components/donuts/SingleSegmentDonut.es.js";
30
+ import Qo from "./components/ErrorBoundary.es.js";
31
+ import $o from "./components/Error.es.js";
32
+ import rr from "./components/MicroWidgetContainer.es.js";
33
+ import er from "./components/MiniWidgetContainer.es.js";
34
+ import { GlobalAccountFilter as mr } from "./components/GlobalAccountFilter.es.js";
35
+ import ar from "./components/Loader.es.js";
36
+ import { WidgetContainer as pr } from "./components/WidgetContainer.es.js";
37
+ import ur from "./components/ConnectWidgetPanel.es.js";
38
+ import Cr from "./components/ConnectDrawer.es.js";
39
+ import gr from "./components/CurrencyDialog.es.js";
40
+ import Tr from "./components/CurrencyInput.es.js";
41
41
  import dr from "./components/ResponsiveButton.es.js";
42
- import Er from "./components/SearchBox.es.js";
43
- import _r from "./components/SelectionBox.es.js";
44
- import Nr from "./components/TabContentContainer.es.js";
45
- import yr from "./components/IconBacking.es.js";
46
- import br from "./components/DataRow.es.js";
47
- import Wr from "./components/ZeroState.es.js";
48
- import Lr from "./components/InformationTooltip.es.js";
49
- import { ConnectCard as Ur } from "./components/ConnectCard.es.js";
50
- import { CurrencyText as Br } from "./components/CurrencyText.es.js";
51
- import { EmptyState as wr } from "./components/EmptyState.es.js";
52
- import { ListItemAction as Mr } from "./components/ListItemAction.es.js";
53
- import { ListItemRow as Hr } from "./components/ListItemRow.es.js";
54
- import { ListItemWrapper as zr } from "./components/ListItemWrapper.es.js";
55
- import { Select as Zr } from "./components/Select.es.js";
56
- import { ToggleButtonListItem as qr } from "./components/listitems/ToggleButtonListItem.es.js";
57
- import { ToggleListItem as jr } from "./components/listitems/ToggleListItem.es.js";
58
- import { analyticsSession as Qr } from "./utils/Analytics.es.js";
59
- import { getClientComponentOverrides as $r, getClientCustomizations as ot, getClientPaletteOptions as rt, getClientTheme as tt } from "./utils/Theme.es.js";
42
+ import _r from "./components/SearchBox.es.js";
43
+ import Nr from "./components/SelectionBox.es.js";
44
+ import yr from "./components/TabContentContainer.es.js";
45
+ import Or from "./components/IconBacking.es.js";
46
+ import Wr from "./components/DataRow.es.js";
47
+ import Lr from "./components/ZeroState.es.js";
48
+ import Ur from "./components/InformationTooltip.es.js";
49
+ import { ConnectCard as Br } from "./components/ConnectCard.es.js";
50
+ import { CurrencyText as wr } from "./components/CurrencyText.es.js";
51
+ import { EmptyState as Mr } from "./components/EmptyState.es.js";
52
+ import { ListItemAction as Hr } from "./components/ListItemAction.es.js";
53
+ import { ListItemRow as zr } from "./components/ListItemRow.es.js";
54
+ import { ListItemWrapper as Zr } from "./components/ListItemWrapper.es.js";
55
+ import { Select as kr } from "./components/Select.es.js";
56
+ import { ToggleButtonListItem as jr } from "./components/listitems/ToggleButtonListItem.es.js";
57
+ import { ToggleListItem as Qr } from "./components/listitems/ToggleListItem.es.js";
58
+ import { analyticsSession as $r } from "./utils/Analytics.es.js";
59
+ import { getClientComponentOverrides as rt, getClientCustomizations as tt, getClientPaletteOptions as et, getClientTheme as it } from "./utils/Theme.es.js";
60
60
  export {
61
61
  No as ANALYTICS_EVENTS,
62
62
  yo as CONNECTIONS_WIDGET_ID,
63
63
  Ao as CONNECT_WIDGET_ID,
64
+ Oo as CONNECT_WIDGET_SOURCES,
64
65
  i as Calendar,
65
66
  m as CalendarSelectionTypes,
66
- Ur as ConnectCard,
67
- ur as ConnectDrawer,
68
- pr as ConnectWidgetPanel,
69
- Cr as CurrencyDialog,
70
- gr as CurrencyInput,
71
- Br as CurrencyText,
72
- Mo as DEFAULT_DONUT_SIZE,
73
- Yo as DEFAULT_STROKE_WIDTH,
74
- br as DataRow,
67
+ Br as ConnectCard,
68
+ Cr as ConnectDrawer,
69
+ ur as ConnectWidgetPanel,
70
+ gr as CurrencyDialog,
71
+ Tr as CurrencyInput,
72
+ wr as CurrencyText,
73
+ bo as DEEP_LINK_TYPE,
74
+ Ho as DEFAULT_DONUT_SIZE,
75
+ Fo as DEFAULT_STROKE_WIDTH,
76
+ Wr as DataRow,
75
77
  _o as DateRangeSelector,
76
78
  co as Dialog,
77
79
  p as Donut,
78
80
  Eo as Drawer,
79
- wr as EmptyState,
80
- Qo as Error,
81
- jo as ErrorBoundary,
82
- er as GlobalAccountFilter,
81
+ Mr as EmptyState,
82
+ $o as Error,
83
+ Qo as ErrorBoundary,
84
+ mr as GlobalAccountFilter,
83
85
  c as GlobalDataContext,
84
- d as GlobalDataProvider,
85
- Wo as GlobalStore,
86
- Lo as INCOME_ACCOUNT_TYPES,
87
- yr as IconBacking,
88
- Lr as InformationTooltip,
89
- wo as LOADING_STATUS,
90
- Mr as ListItemAction,
91
- Hr as ListItemRow,
92
- zr as ListItemWrapper,
93
- mr as Loader,
94
- bo as MemberConnectionStatus,
95
- $o as MicroWidgetContainer,
96
- rr as MiniWidgetContainer,
97
- Zo as MultiSegmentDonut,
98
- Ro as PAYMENT_ACCOUNT_TYPES,
99
- Bo as RECURRENCE_COPY,
86
+ T as GlobalDataProvider,
87
+ Lo as GlobalStore,
88
+ Uo as INCOME_ACCOUNT_TYPES,
89
+ Or as IconBacking,
90
+ Ur as InformationTooltip,
91
+ Mo as LOADING_STATUS,
92
+ Hr as ListItemAction,
93
+ zr as ListItemRow,
94
+ Zr as ListItemWrapper,
95
+ ar as Loader,
96
+ Wo as MemberConnectionStatus,
97
+ rr as MicroWidgetContainer,
98
+ er as MiniWidgetContainer,
99
+ ko as MultiSegmentDonut,
100
+ vo as PAYMENT_ACCOUNT_TYPES,
101
+ wo as RECURRENCE_COPY,
100
102
  dr as ResponsiveButton,
101
- Uo as SPENDING_ACCOUNT_TYPES,
102
- Er as SearchBox,
103
- Zr as Select,
104
- _r as SelectionBox,
105
- qo as SingleSegmentDonut,
106
- Fo as Sizes,
103
+ Bo as SPENDING_ACCOUNT_TYPES,
104
+ _r as SearchBox,
105
+ kr as Select,
106
+ Nr as SelectionBox,
107
+ jo as SingleSegmentDonut,
108
+ Vo as Sizes,
107
109
  a as StatusBar,
108
- zo as TOUCH_TARGET,
109
- Nr as TabContentContainer,
110
- qr as ToggleButtonListItem,
111
- jr as ToggleListItem,
112
- ar as WidgetContainer,
113
- E as WidgetContainerContext,
110
+ Zo as TOUCH_TARGET,
111
+ yr as TabContentContainer,
112
+ jr as ToggleButtonListItem,
113
+ Qr as ToggleListItem,
114
+ pr as WidgetContainer,
115
+ d as WidgetContainerContext,
114
116
  D as WidgetContainerProvider,
115
- Wr as ZeroState,
116
- Qr as analyticsSession,
117
+ Lr as ZeroState,
118
+ $r as analyticsSession,
117
119
  r as buildDynamicCopy,
118
120
  t as buildPluralCopy,
119
121
  eo as formatCurrency,
120
122
  io as formatOrdinal,
121
123
  mo as formatPercentage,
122
124
  no as generateEqualIntervals,
123
- $r as getClientComponentOverrides,
124
- ot as getClientCustomizations,
125
- rt as getClientPaletteOptions,
126
- tt as getClientTheme,
125
+ rt as getClientComponentOverrides,
126
+ tt as getClientCustomizations,
127
+ et as getClientPaletteOptions,
128
+ it as getClientTheme,
127
129
  ao as getCurrencyCodes,
128
130
  so as getPluralRules,
129
131
  u as useAccountDisplayName,
@@ -132,10 +134,10 @@ export {
132
134
  P as useAppConfig,
133
135
  y as useBudgetsStore,
134
136
  A as useCashflowStore,
135
- b as useCategoryStore,
137
+ O as useCategoryStore,
136
138
  C as useCombineEvents,
137
139
  S as useCombinePageviews,
138
- O as useDebtStore,
140
+ b as useDebtStore,
139
141
  W as useError,
140
142
  G as useEvent,
141
143
  L as useFinstrongStore,
@@ -157,9 +159,9 @@ export {
157
159
  fo as useRepeatingTransactionEligibility,
158
160
  $ as useScreenSize,
159
161
  Z as useSettingsStore,
160
- k as useTransactionStore,
161
- q as useTrendsStore,
162
- K as useUserStore,
162
+ K as useTransactionStore,
163
+ k as useTrendsStore,
164
+ q as useUserStore,
163
165
  j as useWidgetContainerProvider,
164
166
  lo as useWidgetHeaderStyles,
165
167
  So as useWidgetLoadTimer
@@ -3,4 +3,5 @@ export declare class BannerApi {
3
3
  fetchInstance: Fetch | null;
4
4
  constructor(bullseyeEndpoint: string);
5
5
  getBanner: (userGuid: string) => Promise<any>;
6
+ markClicked: (guid: string) => Promise<any>;
6
7
  }
@@ -1,5 +1,6 @@
1
+ import { ApiEndpoints as c } from "../constants/ApiEndpoints.es.js";
1
2
  import { Fetch as r } from "../utils/Fetch.es.js";
2
- var a = class {
3
+ var s = class {
3
4
  fetchInstance;
4
5
  constructor(n) {
5
6
  this.fetchInstance = new r(n, "", {
@@ -15,9 +16,10 @@ var a = class {
15
16
  return console.error("Error fetching banner:", t), null;
16
17
  }
17
18
  };
19
+ markClicked = async (n) => this.fetchInstance?.put(`/${c.OFFERS}/${encodeURIComponent(n)}/clicked`, {});
18
20
  };
19
21
  export {
20
- a as BannerApi
22
+ s as BannerApi
21
23
  };
22
24
 
23
25
  //# sourceMappingURL=BannerApi.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BannerApi.es.js","names":[],"sources":["../../../src/core/api/BannerApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\n\nexport class BannerApi {\n fetchInstance: Fetch | null\n\n constructor(bullseyeEndpoint: string) {\n // Override headers without MD-Session-Token to avoid CORS error in bullseye\n this.fetchInstance = new Fetch(bullseyeEndpoint, '', {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n })\n }\n\n getBanner = async (userGuid: string) => {\n try {\n const path = `/banner/${userGuid}/account_widget_banner`\n return this.fetchInstance?.get(path).then((data) => data.banner) ?? {}\n } catch (error) {\n console.error('Error fetching banner:', error)\n return null\n }\n }\n}\n"],"mappings":";AAEA,IAAa,IAAb,MAAuB;AAAA,EACrB;AAAA,EAEA,YAAY,GAA0B;AAEpC,SAAK,gBAAgB,IAAI,EAAM,GAAkB,IAAI;AAAA,MACnD,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,OAAO,MAAqB;AACtC,QAAI;AACF,YAAM,IAAO,WAAW,CAAA;AACxB,aAAO,KAAK,eAAe,IAAI,CAAI,EAAE,KAAA,CAAM,MAAS,EAAK,MAAM,KAAK,CAAC;AAAA,IACvE,SAAS,GAAO;AACd,qBAAQ,MAAM,0BAA0B,CAAK,GACtC;AAAA,IACT;AAAA,EACF;AACF"}
1
+ {"version":3,"file":"BannerApi.es.js","names":[],"sources":["../../../src/core/api/BannerApi.ts"],"sourcesContent":["import { Fetch } from '../utils'\nimport { ApiEndpoints } from '../constants'\n\nexport class BannerApi {\n fetchInstance: Fetch | null\n\n constructor(bullseyeEndpoint: string) {\n // Override headers without MD-Session-Token to avoid CORS error in bullseye\n this.fetchInstance = new Fetch(bullseyeEndpoint, '', {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n })\n }\n\n getBanner = async (userGuid: string) => {\n try {\n const path = `/banner/${userGuid}/account_widget_banner`\n return this.fetchInstance?.get(path).then((data) => data.banner) ?? {}\n } catch (error) {\n console.error('Error fetching banner:', error)\n return null\n }\n }\n\n // Records a banner click server-side. The deep-link path needs this because it\n // never hits `redirect_url`, which is what records the click for external\n // banners. Rejections propagate so AppDataStore can report them via its\n // captureException handler instead of being silently swallowed here.\n markClicked = async (guid: string) =>\n this.fetchInstance?.put(`/${ApiEndpoints.OFFERS}/${encodeURIComponent(guid)}/clicked`, {})\n}\n"],"mappings":";;AAGA,IAAa,IAAb,MAAuB;AAAA,EACrB;AAAA,EAEA,YAAY,GAA0B;AAEpC,SAAK,gBAAgB,IAAI,EAAM,GAAkB,IAAI;AAAA,MACnD,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,OAAO,MAAqB;AACtC,QAAI;AACF,YAAM,IAAO,WAAW,CAAA;AACxB,aAAO,KAAK,eAAe,IAAI,CAAI,EAAE,KAAA,CAAM,MAAS,EAAK,MAAM,KAAK,CAAC;AAAA,IACvE,SAAS,GAAO;AACd,qBAAQ,MAAM,0BAA0B,CAAK,GACtC;AAAA,IACT;AAAA,EACF;AAAA,EAMA,cAAc,OAAO,MACnB,KAAK,eAAe,IAAI,IAAI,EAAa,MAAA,IAAU,mBAAmB,CAAI,CAAA,YAAa,CAAC,CAAC;AAC7F"}
@@ -18,6 +18,7 @@ export declare class AppDataStore {
18
18
  setAppData: (appData: AppData) => void;
19
19
  loadAppData: () => Promise<void>;
20
20
  loadBanner: () => Promise<void>;
21
+ markBannerClicked: (guid: string) => Promise<void>;
21
22
  setUser: (user: User) => User;
22
23
  setUserCommunicationProfile: (profile: UserCommunicationProfile) => UserCommunicationProfile;
23
24
  setUserProfile: (userProfile: UserProfile) => UserProfile;
@@ -1,7 +1,7 @@
1
1
  import { AppDataApi as a } from "../api/AppDataApi.es.js";
2
2
  import { BannerApi as e } from "../api/BannerApi.es.js";
3
3
  import { makeAutoObservable as i, runInAction as o } from "mobx";
4
- var l = class {
4
+ var c = class {
5
5
  globalStore;
6
6
  api = new a("/", "");
7
7
  bannerApi = new e("/");
@@ -50,12 +50,19 @@ var l = class {
50
50
  console.error("Error loading banner:", t), this.globalStore.captureException(t, { store: "AppDataStore" });
51
51
  }
52
52
  };
53
+ markBannerClicked = async (t) => {
54
+ try {
55
+ await this.bannerApi.markClicked(t);
56
+ } catch (r) {
57
+ console.error("Error marking banner clicked:", r), this.globalStore.captureException(r, { store: "AppDataStore" });
58
+ }
59
+ };
53
60
  setUser = (t) => this.appData.user = t;
54
61
  setUserCommunicationProfile = (t) => this.appData.user_communication_profile = t;
55
62
  setUserProfile = (t) => this.appData.user_profile = t;
56
63
  };
57
64
  export {
58
- l as AppDataStore
65
+ c as AppDataStore
59
66
  };
60
67
 
61
68
  //# sourceMappingURL=AppDataStore.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppDataStore.es.js","names":[],"sources":["../../../src/core/stores/AppDataStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AppDataApi, BannerApi } from '../api'\nimport type {\n AppConfig,\n AppData,\n Banner,\n User,\n UserCommunicationProfile,\n UserProfile,\n} from '../types'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AppDataStore {\n globalStore: GlobalStore\n api: AppDataApi = new AppDataApi('/', '')\n bannerApi: BannerApi = new BannerApi('/')\n\n appData: AppData = {} as AppData\n isAppDataLoaded: boolean = false\n banner: Banner = {}\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new AppDataApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get appConfig(): AppConfig {\n return this.globalStore.appConfig\n }\n\n get clientCommunicationProfile() {\n return this.appData.client_communication_profile\n }\n\n get clientInsightProfile() {\n return this.appData.client_insight_profile\n }\n\n get user() {\n return this.appData.user\n }\n\n get userCommunicationProfile() {\n return this.appData.user_communication_profile\n }\n\n get userProfile() {\n return this.appData.user_profile\n }\n\n setAppData = (appData: AppData) => {\n this.appData = appData\n this.bannerApi = new BannerApi(appData.address?.bullseye || '/')\n this.isAppDataLoaded = true\n }\n\n loadAppData = async () => {\n try {\n const appData = await this.api.getAppData()\n this.setAppData(appData)\n } catch (error) {\n console.error('Error loading app data:', error)\n this.globalStore.captureException(error, { store: 'AppDataStore' })\n }\n }\n\n loadBanner = async () => {\n try {\n const userGuid = this.user?.guid ?? null\n const banner = userGuid ? await this.bannerApi.getBanner(userGuid) : {}\n\n runInAction(() => {\n this.banner = banner\n })\n } catch (error) {\n console.error('Error loading banner:', error)\n this.globalStore.captureException(error, { store: 'AppDataStore' })\n }\n }\n\n setUser = (user: User) => (this.appData.user = user)\n\n setUserCommunicationProfile = (profile: UserCommunicationProfile) =>\n (this.appData.user_communication_profile = profile)\n\n setUserProfile = (userProfile: UserProfile) => (this.appData.user_profile = userProfile)\n}\n"],"mappings":";;;AAcA,IAAa,IAAb,MAA0B;AAAA,EACxB;AAAA,EACA,MAAkB,IAAI,EAAW,KAAK,EAAE;AAAA,EACxC,YAAuB,IAAI,EAAU,GAAG;AAAA,EAExC,UAAmB,CAAC;AAAA,EACpB,kBAA2B;AAAA,EAC3B,SAAiB,CAAC;AAAA,EAElB,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAW,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE7F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,IAAI,YAAuB;AACzB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,6BAA6B;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,uBAAuB;AACzB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,2BAA2B;AAC7B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,aAAA,CAAc,MAAqB;AACjC,SAAK,UAAU,GACf,KAAK,YAAY,IAAI,EAAU,EAAQ,SAAS,YAAY,GAAG,GAC/D,KAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,cAAc,YAAY;AACxB,QAAI;AACF,YAAM,IAAU,MAAM,KAAK,IAAI,WAAW;AAC1C,WAAK,WAAW,CAAO;AAAA,IACzB,SAAS,GAAO;AACd,cAAQ,MAAM,2BAA2B,CAAK,GAC9C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,aAAa,YAAY;AACvB,QAAI;AACF,YAAM,IAAW,KAAK,MAAM,QAAQ,MAC9B,IAAS,IAAW,MAAM,KAAK,UAAU,UAAU,CAAQ,IAAI,CAAC;AAEtE,MAAA,EAAA,MAAkB;AAChB,aAAK,SAAS;AAAA,MAChB,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,yBAAyB,CAAK,GAC5C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,UAAA,CAAW,MAAgB,KAAK,QAAQ,OAAO;AAAA,EAE/C,8BAAA,CAA+B,MAC5B,KAAK,QAAQ,6BAA6B;AAAA,EAE7C,iBAAA,CAAkB,MAA8B,KAAK,QAAQ,eAAe;AAC9E"}
1
+ {"version":3,"file":"AppDataStore.es.js","names":[],"sources":["../../../src/core/stores/AppDataStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { AppDataApi, BannerApi } from '../api'\nimport type {\n AppConfig,\n AppData,\n Banner,\n User,\n UserCommunicationProfile,\n UserProfile,\n} from '../types'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class AppDataStore {\n globalStore: GlobalStore\n api: AppDataApi = new AppDataApi('/', '')\n bannerApi: BannerApi = new BannerApi('/')\n\n appData: AppData = {} as AppData\n isAppDataLoaded: boolean = false\n banner: Banner = {}\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new AppDataApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get appConfig(): AppConfig {\n return this.globalStore.appConfig\n }\n\n get clientCommunicationProfile() {\n return this.appData.client_communication_profile\n }\n\n get clientInsightProfile() {\n return this.appData.client_insight_profile\n }\n\n get user() {\n return this.appData.user\n }\n\n get userCommunicationProfile() {\n return this.appData.user_communication_profile\n }\n\n get userProfile() {\n return this.appData.user_profile\n }\n\n setAppData = (appData: AppData) => {\n this.appData = appData\n this.bannerApi = new BannerApi(appData.address?.bullseye || '/')\n this.isAppDataLoaded = true\n }\n\n loadAppData = async () => {\n try {\n const appData = await this.api.getAppData()\n this.setAppData(appData)\n } catch (error) {\n console.error('Error loading app data:', error)\n this.globalStore.captureException(error, { store: 'AppDataStore' })\n }\n }\n\n loadBanner = async () => {\n try {\n const userGuid = this.user?.guid ?? null\n const banner = userGuid ? await this.bannerApi.getBanner(userGuid) : {}\n\n runInAction(() => {\n this.banner = banner\n })\n } catch (error) {\n console.error('Error loading banner:', error)\n this.globalStore.captureException(error, { store: 'AppDataStore' })\n }\n }\n\n // Fire-and-forget click receipt for the deep-link banner path (see BannerApi).\n markBannerClicked = async (guid: string) => {\n try {\n await this.bannerApi.markClicked(guid)\n } catch (error) {\n console.error('Error marking banner clicked:', error)\n this.globalStore.captureException(error, { store: 'AppDataStore' })\n }\n }\n\n setUser = (user: User) => (this.appData.user = user)\n\n setUserCommunicationProfile = (profile: UserCommunicationProfile) =>\n (this.appData.user_communication_profile = profile)\n\n setUserProfile = (userProfile: UserProfile) => (this.appData.user_profile = userProfile)\n}\n"],"mappings":";;;AAcA,IAAa,IAAb,MAA0B;AAAA,EACxB;AAAA,EACA,MAAkB,IAAI,EAAW,KAAK,EAAE;AAAA,EACxC,YAAuB,IAAI,EAAU,GAAG;AAAA,EAExC,UAAmB,CAAC;AAAA,EACpB,kBAA2B;AAAA,EAC3B,SAAiB,CAAC;AAAA,EAElB,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAW,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE7F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,IAAI,YAAuB;AACzB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,6BAA6B;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,uBAAuB;AACzB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,2BAA2B;AAC7B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,aAAA,CAAc,MAAqB;AACjC,SAAK,UAAU,GACf,KAAK,YAAY,IAAI,EAAU,EAAQ,SAAS,YAAY,GAAG,GAC/D,KAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,cAAc,YAAY;AACxB,QAAI;AACF,YAAM,IAAU,MAAM,KAAK,IAAI,WAAW;AAC1C,WAAK,WAAW,CAAO;AAAA,IACzB,SAAS,GAAO;AACd,cAAQ,MAAM,2BAA2B,CAAK,GAC9C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,aAAa,YAAY;AACvB,QAAI;AACF,YAAM,IAAW,KAAK,MAAM,QAAQ,MAC9B,IAAS,IAAW,MAAM,KAAK,UAAU,UAAU,CAAQ,IAAI,CAAC;AAEtE,MAAA,EAAA,MAAkB;AAChB,aAAK,SAAS;AAAA,MAChB,CAAC;AAAA,IACH,SAAS,GAAO;AACd,cAAQ,MAAM,yBAAyB,CAAK,GAC5C,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAGA,oBAAoB,OAAO,MAAiB;AAC1C,QAAI;AACF,YAAM,KAAK,UAAU,YAAY,CAAI;AAAA,IACvC,SAAS,GAAO;AACd,cAAQ,MAAM,iCAAiC,CAAK,GACpD,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,UAAA,CAAW,MAAgB,KAAK,QAAQ,OAAO;AAAA,EAE/C,8BAAA,CAA+B,MAC5B,KAAK,QAAQ,6BAA6B;AAAA,EAE7C,iBAAA,CAAkB,MAA8B,KAAK,QAAQ,eAAe;AAC9E"}
@@ -27,8 +27,10 @@ export interface AppConfig {
27
27
  userFeatures: UserFeature[];
28
28
  }
29
29
  export interface Banner {
30
+ guid?: string;
30
31
  image_url?: string;
31
32
  redirect_url?: string;
33
+ deep_link_type?: number | null;
32
34
  }
33
35
  interface TransactionConfig {
34
36
  selected_account_guid?: string;
@@ -86,7 +86,7 @@ export interface DismissInsightCopy {
86
86
  export interface TransactionHistoryBlock {
87
87
  category_spend_drawer_title: string;
88
88
  monthly_spend_comparison_drawer_title: string;
89
- savings_account_balances_summary_drawer_title: string;
89
+ account_balance_drawer_title: string;
90
90
  upcoming_bill_drawer_title: string;
91
91
  monthly_spend_to_income_drawer_title: string;
92
92
  monthly_debt_to_income_drawer_title: string;
@@ -2,15 +2,15 @@ var e = {
2
2
  SAVE_ENOUGH_TO_LIVE_ON: "SaveEnoughToLiveOn",
3
3
  SAVE_AN_EXTRA_100: "SaveAnExtra100"
4
4
  }, t = {
5
- save_enough_to_live_on: e.SAVE_ENOUGH_TO_LIVE_ON,
6
- save_an_extra_100: e.SAVE_AN_EXTRA_100
7
- }, n = (_) => t[_ ?? ""] ?? e.SAVE_AN_EXTRA_100, E = (_, a) => {
5
+ save_enough: e.SAVE_ENOUGH_TO_LIVE_ON,
6
+ save_extra: e.SAVE_AN_EXTRA_100
7
+ }, E = (_) => t[_ ?? ""] ?? e.SAVE_AN_EXTRA_100, n = (_, a) => {
8
8
  const r = a.insights_feed?.make_transfer;
9
- return r ? n(_) === e.SAVE_ENOUGH_TO_LIVE_ON ? r.save_enough_title : r.save_extra_title : "";
9
+ return r ? E(_) === e.SAVE_ENOUGH_TO_LIVE_ON ? r.save_enough_title : r.save_extra_title : "";
10
10
  }, A = (_) => _ == null || _ === "" ? void 0 : Number(_);
11
11
  export {
12
- E as getMakeTransferDrawerTitle,
13
- n as resolveMakeTransferVariant,
12
+ n as getMakeTransferDrawerTitle,
13
+ E as resolveMakeTransferVariant,
14
14
  A as toNumber,
15
15
  e as variants
16
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/MakeTransferActionBlock/layout.ts"],"sourcesContent":["import type { GlobalCopy, MakeTransferCopy } from '../../../core'\nimport type { SaveExtraBlockData } from '../../../core/types/InsightsInstanceSlotData'\n\n/**\n * MakeTransfer drilldown variants. The block uses the VALUE (e.g. \"SaveAnExtra100\"),\n * which is also the key each variant registers under (see ./index).\n */\nexport const variants = {\n SAVE_ENOUGH_TO_LIVE_ON: 'SaveEnoughToLiveOn',\n SAVE_AN_EXTRA_100: 'SaveAnExtra100',\n} as const\n\nexport type MakeTransferVariant = (typeof variants)[keyof typeof variants]\n\n// The beat payload sends the variant as a snake_case key; map it to the value.\nconst VARIANT_BY_KEY: Record<string, MakeTransferVariant> = {\n save_enough_to_live_on: variants.SAVE_ENOUGH_TO_LIVE_ON,\n save_an_extra_100: variants.SAVE_AN_EXTRA_100,\n}\n\n/** Props shared by every MakeTransfer variant. Each variant reads the fields it\n * needs directly off `slotData` — no per-variant key indirection. */\nexport interface MakeTransferVariantProps {\n slotData?: SaveExtraBlockData\n copy: MakeTransferCopy\n}\n\n/** Maps the payload variant key to the block's variant VALUE (defaults to save-extra). */\nexport const resolveMakeTransferVariant = (variant?: string | null): MakeTransferVariant =>\n VARIANT_BY_KEY[variant ?? ''] ?? variants.SAVE_AN_EXTRA_100\n\n/** Variant-specific, localized drawer title from `insights_feed.make_transfer`. */\nexport const getMakeTransferDrawerTitle = (\n variant: string | null | undefined,\n copy: GlobalCopy,\n): string => {\n const makeTransfer = copy.insights_feed?.make_transfer\n if (!makeTransfer) return ''\n return resolveMakeTransferVariant(variant) === variants.SAVE_ENOUGH_TO_LIVE_ON\n ? makeTransfer.save_enough_title\n : makeTransfer.save_extra_title\n}\n\n/** Coerce a payload figure (number or numeric string) to a number, else undefined. */\nexport const toNumber = (value?: string | number): number | undefined =>\n value === undefined || value === null || value === '' ? undefined : Number(value)\n"],"mappings":"AAOA,IAAa,IAAW;AAAA,EACtB,wBAAwB;AAAA,EACxB,mBAAmB;AACrB,GAKM,IAAsD;AAAA,EAC1D,wBAAwB,EAAS;AAAA,EACjC,mBAAmB,EAAS;AAC9B,GAUa,IAAA,CAA8B,MACzC,EAAe,KAAW,EAAA,KAAO,EAAS,mBAG/B,IAAA,CACX,GACA,MACW;AACX,QAAM,IAAe,EAAK,eAAe;AACzC,SAAK,IACE,EAA2B,CAAO,MAAM,EAAS,yBACpD,EAAa,oBACb,EAAa,mBAHS;AAI5B,GAGa,IAAA,CAAY,MACA,KAAU,QAAQ,MAAU,KAAK,SAAY,OAAO,CAAK"}
1
+ {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/MakeTransferActionBlock/layout.ts"],"sourcesContent":["import type { GlobalCopy, MakeTransferCopy } from '../../../core'\nimport type { SaveExtraBlockData } from '../../../core/types/InsightsInstanceSlotData'\n\n/**\n * MakeTransfer drilldown variants. The block uses the VALUE (e.g. \"SaveAnExtra100\"),\n * which is also the key each variant registers under (see ./index).\n */\nexport const variants = {\n SAVE_ENOUGH_TO_LIVE_ON: 'SaveEnoughToLiveOn',\n SAVE_AN_EXTRA_100: 'SaveAnExtra100',\n} as const\n\nexport type MakeTransferVariant = (typeof variants)[keyof typeof variants]\n\n// The beat payload sends the variant as a snake_case key; map it to the value. The keys are\n// behavior-named (aligning with the `save_enough_title` / `save_extra_title` copy), not beat-named.\nconst VARIANT_BY_KEY: Record<string, MakeTransferVariant> = {\n save_enough: variants.SAVE_ENOUGH_TO_LIVE_ON,\n save_extra: variants.SAVE_AN_EXTRA_100,\n}\n\n/** Props shared by every MakeTransfer variant. Each variant reads the fields it\n * needs directly off `slotData` — no per-variant key indirection. */\nexport interface MakeTransferVariantProps {\n slotData?: SaveExtraBlockData\n copy: MakeTransferCopy\n}\n\n/** Maps the payload variant key to the block's variant VALUE (defaults to save-extra). */\nexport const resolveMakeTransferVariant = (variant?: string | null): MakeTransferVariant =>\n VARIANT_BY_KEY[variant ?? ''] ?? variants.SAVE_AN_EXTRA_100\n\n/** Variant-specific, localized drawer title from `insights_feed.make_transfer`. */\nexport const getMakeTransferDrawerTitle = (\n variant: string | null | undefined,\n copy: GlobalCopy,\n): string => {\n const makeTransfer = copy.insights_feed?.make_transfer\n if (!makeTransfer) return ''\n return resolveMakeTransferVariant(variant) === variants.SAVE_ENOUGH_TO_LIVE_ON\n ? makeTransfer.save_enough_title\n : makeTransfer.save_extra_title\n}\n\n/** Coerce a payload figure (number or numeric string) to a number, else undefined. */\nexport const toNumber = (value?: string | number): number | undefined =>\n value === undefined || value === null || value === '' ? undefined : Number(value)\n"],"mappings":"AAOA,IAAa,IAAW;AAAA,EACtB,wBAAwB;AAAA,EACxB,mBAAmB;AACrB,GAMM,IAAsD;AAAA,EAC1D,aAAa,EAAS;AAAA,EACtB,YAAY,EAAS;AACvB,GAUa,IAAA,CAA8B,MACzC,EAAe,KAAW,EAAA,KAAO,EAAS,mBAG/B,IAAA,CACX,GACA,MACW;AACX,QAAM,IAAe,EAAK,eAAe;AACzC,SAAK,IACE,EAA2B,CAAO,MAAM,EAAS,yBACpD,EAAa,oBACb,EAAa,mBAHS;AAI5B,GAGa,IAAA,CAAY,MACA,KAAU,QAAQ,MAAU,KAAK,SAAY,OAAO,CAAK"}
@@ -17,10 +17,10 @@ export interface DrillDownHeaderContext {
17
17
  selectedDate?: string | Date;
18
18
  }
19
19
  export declare const DRILLDOWN_VARIANTS: {
20
- readonly TRANSACTION: "bill_amount_not_standard";
20
+ readonly TRANSACTION: "not_standard_amount";
21
21
  readonly CATEGORY_SPEND: "category_spend";
22
22
  readonly MONTHLY_SPEND: "monthly_spend_comparison";
23
- readonly ACCOUNT_BALANCE: "savings_account_balances_summary";
23
+ readonly ACCOUNT_BALANCE: "account_balance";
24
24
  readonly UPCOMING_BILL: "upcoming_bill";
25
25
  readonly SPEND_TO_INCOME: "monthly_spend_to_income";
26
26
  readonly SAVINGS_TO_INCOME: "monthly_savings_to_income";
@@ -1,15 +1,15 @@
1
- import { buildDynamicCopy as u } from "../../../core/utils/Localization.es.js";
2
- import { DATE_FORMATS_INTL as p, formatDate as y } from "../../../core/constants/DateFormats.es.js";
3
- import { getCategoryColor as N } from "../../../core/utils/CategoryUtil.es.js";
1
+ import { buildDynamicCopy as p } from "../../../core/utils/Localization.es.js";
2
+ import { DATE_FORMATS_INTL as u, formatDate as N } from "../../../core/constants/DateFormats.es.js";
3
+ import { getCategoryColor as y } from "../../../core/utils/CategoryUtil.es.js";
4
4
  import { MerchantLogo as S } from "@mxenabled/mxui";
5
5
  import { Icon as O } from "@mxenabled/mx-icons";
6
6
  import { jsx as c } from "react/jsx-runtime";
7
7
  import { endOfMonth as T, startOfMonth as f } from "date-fns";
8
8
  var i = {
9
- TRANSACTION: "bill_amount_not_standard",
9
+ TRANSACTION: "not_standard_amount",
10
10
  CATEGORY_SPEND: "category_spend",
11
11
  MONTHLY_SPEND: "monthly_spend_comparison",
12
- ACCOUNT_BALANCE: "savings_account_balances_summary",
12
+ ACCOUNT_BALANCE: "account_balance",
13
13
  UPCOMING_BILL: "upcoming_bill",
14
14
  SPEND_TO_INCOME: "monthly_spend_to_income",
15
15
  SAVINGS_TO_INCOME: "monthly_savings_to_income",
@@ -17,34 +17,34 @@ var i = {
17
17
  COST_OF_LIVING: "cost_living_to_income",
18
18
  NON_ESSENTIAL_CATEGORY: "non_essential_category_summary",
19
19
  DEPOSIT_SUMMARY: "monthly_deposit_summary"
20
- }, _ = (e, t) => t && N(t, e) || e.palette.primary.main, l = (e) => ({
20
+ }, _ = (e, t) => t && y(t, e) || e.palette.primary.main, l = (e) => ({
21
21
  start: f(new Date(e ?? NaN)),
22
22
  end: T(new Date(e ?? NaN))
23
23
  }), d = (e) => e?.length ? { accounts: e } : {}, g = ({ beatTransactions: e, dataSeries: t, selectedIndex: o }) => {
24
- const r = t[o], a = r?.guid, s = e.find((n) => n.guid === a)?.has_been_split;
24
+ const r = t[o], a = r?.guid, n = e.find((s) => s.guid === a)?.has_been_split;
25
25
  return {
26
- custom: (n) => n.guid === a,
26
+ custom: (s) => s.guid === a,
27
27
  dateRange: l(r?.date),
28
- showSplits: !s
28
+ showSplits: !n
29
29
  };
30
30
  }, C = ({ dataSeries: e, selectedIndex: t, instanceSlotData: o }) => {
31
31
  const r = e[t], a = o.category_guid ?? r?.guid;
32
32
  return {
33
- custom: (s) => s.category_guid === a || s.top_level_category_guid === a,
33
+ custom: (n) => n.category_guid === a || n.top_level_category_guid === a,
34
34
  dateRange: l(r?.date)
35
35
  };
36
36
  }, I = ({ dataSeries: e, selectedIndex: t, spendCategoryGuids: o, instanceSlotData: r }) => {
37
37
  const a = e[t];
38
38
  return {
39
- custom: (s) => !!s.top_level_category_guid && o.includes(s.top_level_category_guid),
39
+ custom: (n) => !!n.top_level_category_guid && o.includes(n.top_level_category_guid),
40
40
  dateRange: l(a?.date),
41
41
  ...d(r.account_guids)
42
42
  };
43
43
  }, h = ({ beat: e, dataSeries: t, selectedIndex: o, isLastTab: r, instanceSlotData: a }) => {
44
- const s = t[o], { start: n, end: m } = l(s?.date);
44
+ const n = t[o], { start: s, end: m } = l(n?.date);
45
45
  return {
46
46
  dateRange: {
47
- start: n,
47
+ start: s,
48
48
  end: r && e.created_at ? new Date(e.created_at) : m
49
49
  },
50
50
  ...d(a.account_guids)
@@ -70,7 +70,7 @@ var i = {
70
70
  };
71
71
  },
72
72
  tipSection: (e, t, o = "") => ({
73
- message: u(t.general.tip_section_message, /* @__PURE__ */ c("strong", { children: t.general.tip_section_title }), /* @__PURE__ */ c("strong", { children: o })),
73
+ message: p(t.general.tip_section_message, /* @__PURE__ */ c("strong", { children: t.general.tip_section_title }), /* @__PURE__ */ c("strong", { children: o })),
74
74
  onDismiss: () => e(!0)
75
75
  })
76
76
  },
@@ -82,7 +82,7 @@ var i = {
82
82
  colors: (e, t) => [_(e, t)],
83
83
  header: (e) => ({
84
84
  heading: e.categoryName,
85
- subHeadingText: e.selectedDate && y(e.selectedDate, p.MONTH_LONG) || "",
85
+ subHeadingText: e.selectedDate && N(e.selectedDate, u.MONTH_LONG) || "",
86
86
  icon: /* @__PURE__ */ c(O, {
87
87
  name: "calendar_month",
88
88
  size: 16
@@ -1 +1 @@
1
- {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionHistoryBlock/layout.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type { Theme } from '@mui/material/styles'\nimport { endOfMonth, startOfMonth } from 'date-fns'\nimport { getCategoryColor } from '../../../core/utils/CategoryUtil'\nimport {\n type Beat,\n type InsightsFeedCopy,\n type Subtitle,\n type Transaction,\n buildDynamicCopy,\n} from '../../../core'\nimport type { TransactionFilter } from '../../../core/stores/TransactionStore'\nimport type { InsightsInstanceSlotData } from '../../../core/types/InsightsInstanceSlotData'\nimport { MerchantLogo } from '@mxenabled/mxui'\nimport { DATE_FORMATS_INTL, formatDate } from '../../../core/constants'\nimport { Icon } from '@mxenabled/mx-icons'\nimport type { ChartDataSeriesItem } from '../../blocks/ChartBlocks/BarchartBlock/utils'\nimport type { TipSectionProps } from '../../../insights/components/shared/ChartDrawerTemplate/TipSection'\n\nexport interface DrillDownHeader {\n heading?: string\n subHeadingText?: string\n icon?: ReactNode\n}\n\nexport interface DrillDownHeaderContext {\n title?: string\n subHeader?: Subtitle\n categoryName: string\n selectedDate?: string | Date\n}\n\nexport const DRILLDOWN_VARIANTS = {\n TRANSACTION: 'bill_amount_not_standard',\n CATEGORY_SPEND: 'category_spend',\n MONTHLY_SPEND: 'monthly_spend_comparison',\n ACCOUNT_BALANCE: 'savings_account_balances_summary',\n UPCOMING_BILL: 'upcoming_bill',\n SPEND_TO_INCOME: 'monthly_spend_to_income',\n SAVINGS_TO_INCOME: 'monthly_savings_to_income',\n DEBT_TO_INCOME: 'monthly_debt_to_income',\n COST_OF_LIVING: 'cost_living_to_income',\n NON_ESSENTIAL_CATEGORY: 'non_essential_category_summary',\n DEPOSIT_SUMMARY: 'monthly_deposit_summary',\n} as const\n\nexport type DrillDownVariant = (typeof DRILLDOWN_VARIANTS)[keyof typeof DRILLDOWN_VARIANTS]\n\n/**\n * One row of the flattened data_series a filterStrategy indexes into: a single-bar monthly total or a\n * synthesized upcoming-bill bar. Fields are optional because the backend keys each row dynamically\n * from data_series.names and not every variant carries a guid/category. Double-bar comparison rows\n * will extend this in the next MR.\n */\n\n// Resolves the top-chart palette from the theme (and the beat's category, when relevant).\nexport type ColorKind = (theme: Theme, categoryGuid?: string) => string[]\n\n// Resolves the dynamic drawer header (heading/sub-heading/icon JSX) from the selection context.\nexport type HeaderKind = (ctx: DrillDownHeaderContext) => DrillDownHeader\n\n/**\n * Everything a filterStrategy needs to turn the currently-selected bar/sub-tab into a\n * TransactionFilter. Data-only so strategies stay pure and testable.\n */\nexport interface FilterContext {\n beat: Beat\n beatTransactions: Transaction[]\n dataSeries: ChartDataSeriesItem[]\n selectedIndex: number\n subIndex: number\n isLastTab: boolean\n instanceSlotData: InsightsInstanceSlotData\n spendCategoryGuids: string[]\n displayedDateRange: { start: Date; end: Date }\n}\n\n// Resolves the current selection into a TransactionFilter. Carried on each config row so behavior\n// lives next to the variant it belongs to (no separate strategy registry to chase).\nexport type FilterStrategy = (ctx: FilterContext) => TransactionFilter\n\nexport interface DrillDownVariantConfig {\n top: 'singleBar' | 'upcomingBill' | 'doubleBar' | 'tabsOnly'\n filterStrategy: FilterStrategy\n colors: ColorKind\n header?: HeaderKind\n tipSection?: (\n setCloseTipSection: (flag: boolean) => void,\n copy: InsightsFeedCopy,\n merchantName?: string,\n ) => TipSectionProps\n scope: 'store' | 'beat'\n filterMode: 'store' | 'local'\n}\nconst categoryColor = (theme: Theme, categoryGuid?: string): string =>\n (categoryGuid && getCategoryColor(categoryGuid, theme)) || theme.palette.primary.main\n\nconst monthRange = (date: string | number | Date | undefined) => ({\n start: startOfMonth(new Date(date ?? NaN)),\n end: endOfMonth(new Date(date ?? NaN)),\n})\n\n// Scopes a filter to the beat's accounts when the beat carries account_guids; otherwise leaves\n// accounts unset so the store default (all accounts) applies.\nconst accountScope = (accountGuids?: string[]): Pick<TransactionFilter, 'accounts'> =>\n accountGuids?.length ? { accounts: accountGuids } : {}\n\n// ── Single-bar filter strategies (this MR) ────────────────────────────────────────────────────\n\n// BillAmountNotStandard / UpcomingBill — the series carries a transaction (TRN) guid; match a single\n// transaction by guid within its month.\nconst transactionGuidStrategy: FilterStrategy = ({\n beatTransactions,\n dataSeries,\n selectedIndex,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n const seriesGuid = seriesItem?.guid\n const hasBeenSplit = beatTransactions.find((trn) => trn.guid === seriesGuid)?.has_been_split\n\n return {\n custom: (trn) => trn.guid === seriesGuid,\n dateRange: monthRange(seriesItem?.date),\n showSplits: !hasBeenSplit,\n }\n}\n\n// CategorySpendingV2 — match transactions in the beat's category (or whose top-level category is that\n// guid) within the month.\nconst categoryStrategy: FilterStrategy = ({ dataSeries, selectedIndex, instanceSlotData }) => {\n const seriesItem = dataSeries[selectedIndex]\n const categoryGuid = instanceSlotData.category_guid ?? seriesItem?.guid\n\n return {\n custom: (trn) =>\n trn.category_guid === categoryGuid || trn.top_level_category_guid === categoryGuid,\n dateRange: monthRange(seriesItem?.date),\n }\n}\n\n// MonthlySpendComparisonV2 — no per-bar guid; show all spending-category transactions\n// (income/transfers/investments excluded via spendCategoryGuids) within the month.\nconst spendCategoriesStrategy: FilterStrategy = ({\n dataSeries,\n selectedIndex,\n spendCategoryGuids,\n instanceSlotData,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n\n return {\n custom: (trn) =>\n !!trn.top_level_category_guid && spendCategoryGuids.includes(trn.top_level_category_guid),\n dateRange: monthRange(seriesItem?.date),\n ...accountScope(instanceSlotData.account_guids),\n }\n}\n\n// SavingsAccountBalancesSummary — balances, not categorized spend. Filter by month only; the most\n// recent month is capped at the beat's creation time to match the snapshot the balance was computed\n// from.\nconst accountDateStrategy: FilterStrategy = ({\n beat,\n dataSeries,\n selectedIndex,\n isLastTab,\n instanceSlotData,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n const { start, end } = monthRange(seriesItem?.date)\n\n return {\n dateRange: {\n start,\n end: isLastTab && beat.created_at ? new Date(beat.created_at) : end,\n },\n ...accountScope(instanceSlotData.account_guids),\n }\n}\n\n// ── Double-bar + tabsOnly strategies (NEXT MR) ───────────────────────────────────────────────────\n// TODO(next MR — double bar): comparisonAggregatedGuidsStrategy — month × sub-tab membership over the\n// comparison bars' precomputed subGuids. Needs comparisonBars in FilterContext.\n// TODO(next MR — tabsOnly): aggregatedGuids / depositSummary strategies for the donut-drawer beats.\n\nexport const layout: Partial<Record<DrillDownVariant, DrillDownVariantConfig>> = {\n [DRILLDOWN_VARIANTS.TRANSACTION]: {\n top: 'singleBar',\n scope: 'store',\n filterMode: 'store',\n filterStrategy: transactionGuidStrategy,\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n header: (ctx: DrillDownHeaderContext) => {\n const { title, subHeader } = ctx\n return {\n heading: title,\n subHeadingText: subHeader?.text || undefined,\n icon: (\n <MerchantLogo\n alt={subHeader?.text}\n categoryGuid={subHeader?.logo?.category_guid || ''}\n merchantGuid={subHeader?.logo?.merchant_guid || ''}\n size={16}\n />\n ),\n }\n },\n tipSection: (setCloseTipSection, copy, merchantName = '') => {\n return {\n message: buildDynamicCopy(\n copy.general.tip_section_message,\n <strong>{copy.general.tip_section_title}</strong>,\n <strong>{merchantName}</strong>,\n ),\n onDismiss: () => setCloseTipSection(true),\n } as TipSectionProps\n },\n },\n [DRILLDOWN_VARIANTS.CATEGORY_SPEND]: {\n top: 'singleBar',\n filterStrategy: categoryStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n header: (ctx: DrillDownHeaderContext) => {\n return {\n heading: ctx.categoryName,\n subHeadingText: ctx.selectedDate\n ? formatDate(ctx.selectedDate, DATE_FORMATS_INTL.MONTH_LONG) || ''\n : '',\n icon: <Icon name=\"calendar_month\" size={16} />,\n }\n },\n },\n [DRILLDOWN_VARIANTS.MONTHLY_SPEND]: {\n top: 'singleBar',\n filterStrategy: spendCategoriesStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme) => [theme.palette.chart.chart2 ?? theme.palette.primary.main],\n },\n [DRILLDOWN_VARIANTS.ACCOUNT_BALANCE]: {\n top: 'singleBar',\n filterStrategy: accountDateStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme) => [theme.palette.success.main],\n },\n [DRILLDOWN_VARIANTS.UPCOMING_BILL]: {\n top: 'upcomingBill',\n filterStrategy: transactionGuidStrategy,\n scope: 'beat',\n filterMode: 'local',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n },\n\n // ── NEXT MR: double-bar comparison beats (month tabs + spend/income sub-tabs) ────────────────\n // [DRILLDOWN_VARIANTS.SPEND_TO_INCOME]: comparison('spendVsIncome'),\n // [DRILLDOWN_VARIANTS.SAVINGS_TO_INCOME]: comparison('savingsVsIncome'),\n // [DRILLDOWN_VARIANTS.DEBT_TO_INCOME]: comparison('debtVsIncome'),\n // [DRILLDOWN_VARIANTS.COST_OF_LIVING]: comparison('costOfLiving'),\n //\n // ── NEXT MR: tabsOnly donut-drawer beats (no top chart) ───────────────────────────────────\n // [DRILLDOWN_VARIANTS.NON_ESSENTIAL_CATEGORY]: { top: 'tabsOnly', ... },\n // [DRILLDOWN_VARIANTS.DEPOSIT_SUMMARY]: { top: 'tabsOnly', ... },\n}\n\n// Fallback for a missing/typo'd backend variant: a single-bar, store-scoped drawer filtered by the\n// beat's transaction guid and colored by category, so the drawer still renders instead of crashing.\nexport const FALLBACK: DrillDownVariantConfig = {\n top: 'singleBar',\n filterStrategy: transactionGuidStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionHistoryBlock/layout.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type { Theme } from '@mui/material/styles'\nimport { endOfMonth, startOfMonth } from 'date-fns'\nimport { getCategoryColor } from '../../../core/utils/CategoryUtil'\nimport {\n type Beat,\n type InsightsFeedCopy,\n type Subtitle,\n type Transaction,\n buildDynamicCopy,\n} from '../../../core'\nimport type { TransactionFilter } from '../../../core/stores/TransactionStore'\nimport type { InsightsInstanceSlotData } from '../../../core/types/InsightsInstanceSlotData'\nimport { MerchantLogo } from '@mxenabled/mxui'\nimport { DATE_FORMATS_INTL, formatDate } from '../../../core/constants'\nimport { Icon } from '@mxenabled/mx-icons'\nimport type { ChartDataSeriesItem } from '../../blocks/ChartBlocks/BarchartBlock/utils'\nimport type { TipSectionProps } from '../../../insights/components/shared/ChartDrawerTemplate/TipSection'\n\nexport interface DrillDownHeader {\n heading?: string\n subHeadingText?: string\n icon?: ReactNode\n}\n\nexport interface DrillDownHeaderContext {\n title?: string\n subHeader?: Subtitle\n categoryName: string\n selectedDate?: string | Date\n}\n\nexport const DRILLDOWN_VARIANTS = {\n TRANSACTION: 'not_standard_amount',\n CATEGORY_SPEND: 'category_spend',\n MONTHLY_SPEND: 'monthly_spend_comparison',\n ACCOUNT_BALANCE: 'account_balance',\n UPCOMING_BILL: 'upcoming_bill',\n SPEND_TO_INCOME: 'monthly_spend_to_income',\n SAVINGS_TO_INCOME: 'monthly_savings_to_income',\n DEBT_TO_INCOME: 'monthly_debt_to_income',\n COST_OF_LIVING: 'cost_living_to_income',\n NON_ESSENTIAL_CATEGORY: 'non_essential_category_summary',\n DEPOSIT_SUMMARY: 'monthly_deposit_summary',\n} as const\n\nexport type DrillDownVariant = (typeof DRILLDOWN_VARIANTS)[keyof typeof DRILLDOWN_VARIANTS]\n\n/**\n * One row of the flattened data_series a filterStrategy indexes into: a single-bar monthly total or a\n * synthesized upcoming-bill bar. Fields are optional because the backend keys each row dynamically\n * from data_series.names and not every variant carries a guid/category. Double-bar comparison rows\n * will extend this in the next MR.\n */\n\n// Resolves the top-chart palette from the theme (and the beat's category, when relevant).\nexport type ColorKind = (theme: Theme, categoryGuid?: string) => string[]\n\n// Resolves the dynamic drawer header (heading/sub-heading/icon JSX) from the selection context.\nexport type HeaderKind = (ctx: DrillDownHeaderContext) => DrillDownHeader\n\n/**\n * Everything a filterStrategy needs to turn the currently-selected bar/sub-tab into a\n * TransactionFilter. Data-only so strategies stay pure and testable.\n */\nexport interface FilterContext {\n beat: Beat\n beatTransactions: Transaction[]\n dataSeries: ChartDataSeriesItem[]\n selectedIndex: number\n subIndex: number\n isLastTab: boolean\n instanceSlotData: InsightsInstanceSlotData\n spendCategoryGuids: string[]\n displayedDateRange: { start: Date; end: Date }\n}\n\n// Resolves the current selection into a TransactionFilter. Carried on each config row so behavior\n// lives next to the variant it belongs to (no separate strategy registry to chase).\nexport type FilterStrategy = (ctx: FilterContext) => TransactionFilter\n\nexport interface DrillDownVariantConfig {\n top: 'singleBar' | 'upcomingBill' | 'doubleBar' | 'tabsOnly'\n filterStrategy: FilterStrategy\n colors: ColorKind\n header?: HeaderKind\n tipSection?: (\n setCloseTipSection: (flag: boolean) => void,\n copy: InsightsFeedCopy,\n merchantName?: string,\n ) => TipSectionProps\n scope: 'store' | 'beat'\n filterMode: 'store' | 'local'\n}\nconst categoryColor = (theme: Theme, categoryGuid?: string): string =>\n (categoryGuid && getCategoryColor(categoryGuid, theme)) || theme.palette.primary.main\n\nconst monthRange = (date: string | number | Date | undefined) => ({\n start: startOfMonth(new Date(date ?? NaN)),\n end: endOfMonth(new Date(date ?? NaN)),\n})\n\n// Scopes a filter to the beat's accounts when the beat carries account_guids; otherwise leaves\n// accounts unset so the store default (all accounts) applies.\nconst accountScope = (accountGuids?: string[]): Pick<TransactionFilter, 'accounts'> =>\n accountGuids?.length ? { accounts: accountGuids } : {}\n\n// ── Single-bar filter strategies (this MR) ────────────────────────────────────────────────────\n\n// BillAmountNotStandard / UpcomingBill — the series carries a transaction (TRN) guid; match a single\n// transaction by guid within its month.\nconst transactionGuidStrategy: FilterStrategy = ({\n beatTransactions,\n dataSeries,\n selectedIndex,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n const seriesGuid = seriesItem?.guid\n const hasBeenSplit = beatTransactions.find((trn) => trn.guid === seriesGuid)?.has_been_split\n\n return {\n custom: (trn) => trn.guid === seriesGuid,\n dateRange: monthRange(seriesItem?.date),\n showSplits: !hasBeenSplit,\n }\n}\n\n// CategorySpendingV2 — match transactions in the beat's category (or whose top-level category is that\n// guid) within the month.\nconst categoryStrategy: FilterStrategy = ({ dataSeries, selectedIndex, instanceSlotData }) => {\n const seriesItem = dataSeries[selectedIndex]\n const categoryGuid = instanceSlotData.category_guid ?? seriesItem?.guid\n\n return {\n custom: (trn) =>\n trn.category_guid === categoryGuid || trn.top_level_category_guid === categoryGuid,\n dateRange: monthRange(seriesItem?.date),\n }\n}\n\n// MonthlySpendComparisonV2 — no per-bar guid; show all spending-category transactions\n// (income/transfers/investments excluded via spendCategoryGuids) within the month.\nconst spendCategoriesStrategy: FilterStrategy = ({\n dataSeries,\n selectedIndex,\n spendCategoryGuids,\n instanceSlotData,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n\n return {\n custom: (trn) =>\n !!trn.top_level_category_guid && spendCategoryGuids.includes(trn.top_level_category_guid),\n dateRange: monthRange(seriesItem?.date),\n ...accountScope(instanceSlotData.account_guids),\n }\n}\n\n// SavingsAccountBalancesSummary — balances, not categorized spend. Filter by month only; the most\n// recent month is capped at the beat's creation time to match the snapshot the balance was computed\n// from.\nconst accountDateStrategy: FilterStrategy = ({\n beat,\n dataSeries,\n selectedIndex,\n isLastTab,\n instanceSlotData,\n}) => {\n const seriesItem = dataSeries[selectedIndex]\n const { start, end } = monthRange(seriesItem?.date)\n\n return {\n dateRange: {\n start,\n end: isLastTab && beat.created_at ? new Date(beat.created_at) : end,\n },\n ...accountScope(instanceSlotData.account_guids),\n }\n}\n\n// ── Double-bar + tabsOnly strategies (NEXT MR) ───────────────────────────────────────────────────\n// TODO(next MR — double bar): comparisonAggregatedGuidsStrategy — month × sub-tab membership over the\n// comparison bars' precomputed subGuids. Needs comparisonBars in FilterContext.\n// TODO(next MR — tabsOnly): aggregatedGuids / depositSummary strategies for the donut-drawer beats.\n\nexport const layout: Partial<Record<DrillDownVariant, DrillDownVariantConfig>> = {\n [DRILLDOWN_VARIANTS.TRANSACTION]: {\n top: 'singleBar',\n scope: 'store',\n filterMode: 'store',\n filterStrategy: transactionGuidStrategy,\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n header: (ctx: DrillDownHeaderContext) => {\n const { title, subHeader } = ctx\n return {\n heading: title,\n subHeadingText: subHeader?.text || undefined,\n icon: (\n <MerchantLogo\n alt={subHeader?.text}\n categoryGuid={subHeader?.logo?.category_guid || ''}\n merchantGuid={subHeader?.logo?.merchant_guid || ''}\n size={16}\n />\n ),\n }\n },\n tipSection: (setCloseTipSection, copy, merchantName = '') => {\n return {\n message: buildDynamicCopy(\n copy.general.tip_section_message,\n <strong>{copy.general.tip_section_title}</strong>,\n <strong>{merchantName}</strong>,\n ),\n onDismiss: () => setCloseTipSection(true),\n } as TipSectionProps\n },\n },\n [DRILLDOWN_VARIANTS.CATEGORY_SPEND]: {\n top: 'singleBar',\n filterStrategy: categoryStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n header: (ctx: DrillDownHeaderContext) => {\n return {\n heading: ctx.categoryName,\n subHeadingText: ctx.selectedDate\n ? formatDate(ctx.selectedDate, DATE_FORMATS_INTL.MONTH_LONG) || ''\n : '',\n icon: <Icon name=\"calendar_month\" size={16} />,\n }\n },\n },\n [DRILLDOWN_VARIANTS.MONTHLY_SPEND]: {\n top: 'singleBar',\n filterStrategy: spendCategoriesStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme) => [theme.palette.chart.chart2 ?? theme.palette.primary.main],\n },\n [DRILLDOWN_VARIANTS.ACCOUNT_BALANCE]: {\n top: 'singleBar',\n filterStrategy: accountDateStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme) => [theme.palette.success.main],\n },\n [DRILLDOWN_VARIANTS.UPCOMING_BILL]: {\n top: 'upcomingBill',\n filterStrategy: transactionGuidStrategy,\n scope: 'beat',\n filterMode: 'local',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n },\n\n // ── NEXT MR: double-bar comparison beats (month tabs + spend/income sub-tabs) ────────────────\n // [DRILLDOWN_VARIANTS.SPEND_TO_INCOME]: comparison('spendVsIncome'),\n // [DRILLDOWN_VARIANTS.SAVINGS_TO_INCOME]: comparison('savingsVsIncome'),\n // [DRILLDOWN_VARIANTS.DEBT_TO_INCOME]: comparison('debtVsIncome'),\n // [DRILLDOWN_VARIANTS.COST_OF_LIVING]: comparison('costOfLiving'),\n //\n // ── NEXT MR: tabsOnly donut-drawer beats (no top chart) ───────────────────────────────────\n // [DRILLDOWN_VARIANTS.NON_ESSENTIAL_CATEGORY]: { top: 'tabsOnly', ... },\n // [DRILLDOWN_VARIANTS.DEPOSIT_SUMMARY]: { top: 'tabsOnly', ... },\n}\n\n// Fallback for a missing/typo'd backend variant: a single-bar, store-scoped drawer filtered by the\n// beat's transaction guid and colored by category, so the drawer still renders instead of crashing.\nexport const FALLBACK: DrillDownVariantConfig = {\n top: 'singleBar',\n filterStrategy: transactionGuidStrategy,\n scope: 'store',\n filterMode: 'store',\n colors: (theme: Theme, categoryGuid?: string) => [categoryColor(theme, categoryGuid)],\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Theme } from '@mui/material/styles';
2
2
  export declare const getLayoutConfig: (theme: Theme) => {
3
- savings_account_balances_summary: {
3
+ account_balance: {
4
4
  color: string;
5
5
  };
6
6
  monthly_spend_comparison: {
@@ -1,5 +1,5 @@
1
1
  var o = (a) => ({
2
- savings_account_balances_summary: { color: a.palette.success.main },
2
+ account_balance: { color: a.palette.success.main },
3
3
  monthly_spend_comparison: { color: a.palette.chart.chart2 }
4
4
  });
5
5
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/BarchartBlock/layout.ts"],"sourcesContent":["import { type Theme } from '@mui/material/styles'\nexport const getLayoutConfig = (theme: Theme) => {\n return {\n savings_account_balances_summary: {\n color: theme.palette.success.main,\n },\n monthly_spend_comparison: {\n color: theme.palette.chart.chart2,\n },\n }\n}\n"],"mappings":"AACA,IAAa,IAAA,CAAmB,OACvB;AAAA,EACL,kCAAkC,EAChC,OAAO,EAAM,QAAQ,QAAQ,KAC/B;AAAA,EACA,0BAA0B,EACxB,OAAO,EAAM,QAAQ,MAAM,OAC7B;AACF"}
1
+ {"version":3,"file":"layout.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/BarchartBlock/layout.ts"],"sourcesContent":["import { type Theme } from '@mui/material/styles'\nexport const getLayoutConfig = (theme: Theme) => {\n return {\n account_balance: {\n color: theme.palette.success.main,\n },\n monthly_spend_comparison: {\n color: theme.palette.chart.chart2,\n },\n }\n}\n"],"mappings":"AACA,IAAa,IAAA,CAAmB,OACvB;AAAA,EACL,iBAAiB,EACf,OAAO,EAAM,QAAQ,QAAQ,KAC/B;AAAA,EACA,0BAA0B,EACxB,OAAO,EAAM,QAAQ,MAAM,OAC7B;AACF"}
@@ -4,7 +4,7 @@ import { DataSeries, InstanceSlot } from '../../../../core';
4
4
  import { InsightsInstanceSlotData } from '../../../../core/types/InsightsInstanceSlotData';
5
5
  export declare const BAR_CHART_VARIANTS: {
6
6
  CATEGORY_COLOR: string;
7
- SAVINGS_ACCOUNT_BALANCES_SUMMARY: string;
7
+ ACCOUNT_BALANCE: string;
8
8
  MONTHLY_SPEND_COMPARISON: string;
9
9
  };
10
10
  export interface ChartDataSeriesItem {