@mx-cartographer/experiences 9.7.105 → 9.7.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [9.7.107] - 11-05-2026
2
+
3
+ - **FIXED** - The Savings Account Balance Summary "Savings Contributions" drawer reads its bars, trend and accounts from the beat's `drilldown_data` (`resolveSavingsContributionsSlotData`) instead of `instance_slot.data` and the beat, and fails closed: a beat whose `drilldown_data` names no savings account lists no transactions instead of every account (WEC-2023)
4
+ - **FIXED** - A Transaction History chart drawer with no bars lists no transactions instead of keeping the store's default (every account) or a previous drawer's filter (WEC-2023)
5
+
6
+ ## [9.7.106] - 11-05-2026
7
+
8
+ - **ADDED** - Micro Deposits on Insights 2.0: the deposits as green credits, and a Deposit History drawer (WEC-2109)
9
+
1
10
  ## [9.7.105] - 11-04-2026
2
11
 
3
12
  - **REMOVED** - Unused dead code from the account filter utilities (MEW-4188)
@@ -133,6 +133,9 @@ export interface TransactionHistoryBlock {
133
133
  */
134
134
  upcoming_bill_tip_message?: string;
135
135
  }
136
+ export interface TransactionListBlockCopy {
137
+ deposit_history_drawer_title?: string;
138
+ }
136
139
  export interface HiddenConfirmationCopy {
137
140
  title: string;
138
141
  description: string;
@@ -445,6 +448,8 @@ export interface InsightsFeedCopy {
445
448
  emergency_savings?: EmergencySavingsCopy;
446
449
  overflow_menu: OverflowMenuCopy;
447
450
  transaction_history_block: TransactionHistoryBlock;
451
+ /** Optional until the localized-content service ships it. */
452
+ transaction_list_block?: TransactionListBlockCopy;
448
453
  hidden_confirmation: HiddenConfirmationCopy;
449
454
  hide_feedback: HideFeedbackCopy;
450
455
  feedback: FeedbackCopy;
@@ -19,7 +19,7 @@ import { observer as Pt } from "mobx-react-lite";
19
19
  import { Fragment as Vt, jsx as r, jsxs as zt } from "react/jsx-runtime";
20
20
  import { useTheme as Ut } from "@mui/material/styles";
21
21
  var pe = Pt(({ beat: s }) => {
22
- const D = Ut(), { actionDrawer: B, setActionContext: S } = yt(), { insights_payload: c } = s, V = Rt(B, c?.primary_cta, c?.secondary_cta, c?.in_description_cta)?.variant, { top: e, filterMode: u, header: z, colors: U, filterStrategy: W, tipSection: L, subTabAriaLabels: Y, slotData: $, beatTransactions: q, hideListHeader: J } = Ft(V ?? ""), { instanceSlotData: a, beatTransactions: g, spendCategoryGuids: v, allAccountGuids: I, categoryName: Q, displayedDateRange: f, transactionStore: X } = Nt(s, {
22
+ const D = Ut(), { actionDrawer: B, setActionContext: S } = yt(), { insights_payload: c } = s, V = Rt(B, c?.primary_cta, c?.secondary_cta, c?.in_description_cta)?.variant, { top: e, filterMode: u, header: z, colors: U, filterStrategy: W, tipSection: L, subTabAriaLabels: Y, slotData: $, beatTransactions: q, hideListHeader: J } = Ft(V ?? ""), { instanceSlotData: a, beatTransactions: g, spendCategoryGuids: v, allAccountGuids: I, categoryName: Q, displayedDateRange: h, transactionStore: X } = Nt(s, {
23
23
  slotData: $,
24
24
  beatTransactions: q
25
25
  }), { common: Z, insights_feed: n } = Tt(), { isCopyLoaded: tt } = Ct(), [et, x] = m(!1), [ot, at] = m(!1), E = It(), { dataSeries: p, chartData: b, comparisonBars: i } = Gt({
@@ -44,11 +44,16 @@ var pe = Pt(({ beat: s }) => {
44
44
  isLastTab: t === l.length - 1,
45
45
  instanceSlotData: a,
46
46
  spendCategoryGuids: v,
47
- displayedDateRange: f
47
+ displayedDateRange: h
48
48
  }), lt = g.map((t) => t.guid).join(","), ct = v.join(","), dt = I.join(","), mt = e === "list" || e === "tabsOnly" || e === "monthTabs" || p.length > 0, j = () => {
49
- u !== "store" || !mt || X.setFilter(kt(C(o), {
49
+ if (u !== "store") return;
50
+ const t = mt ? C(o) : {
51
+ accounts: [],
52
+ custom: () => !1
53
+ };
54
+ X.setFilter(kt(t, {
50
55
  allAccountGuids: I,
51
- displayedDateRange: f
56
+ displayedDateRange: h
52
57
  }));
53
58
  };
54
59
  Mt(() => {
@@ -60,7 +65,7 @@ var pe = Pt(({ beat: s }) => {
60
65
  u,
61
66
  p.length,
62
67
  a,
63
- f,
68
+ h,
64
69
  ct,
65
70
  dt,
66
71
  lt,
@@ -76,9 +81,9 @@ var pe = Pt(({ beat: s }) => {
76
81
  const [H, w] = a?.legends ?? [], ut = u === "local" ? (t) => C(t).custom ?? (() => !0) : void 0, { transactions: gt, projectedTransaction: A } = wt(g), pt = u === "local" ? gt : void 0, k = n.general.projected_amount, bt = A && k && C(o).custom?.(A) ? {
77
82
  heading: k,
78
83
  transaction: A
79
- } : void 0, N = (t, h) => {
80
- E(P.DRAWER_CHART_BAR_CLICKED), _(t), h !== void 0 && O(h);
81
- }, ht = (t) => {
84
+ } : void 0, N = (t, f) => {
85
+ E(P.DRAWER_CHART_BAR_CLICKED), _(t), f !== void 0 && O(f);
86
+ }, ft = (t) => {
82
87
  E(P.TAB_SELECTED), _(t);
83
88
  }, K = d ? Et([{
84
89
  ...H,
@@ -86,9 +91,9 @@ var pe = Pt(({ beat: s }) => {
86
91
  }, {
87
92
  ...w,
88
93
  value: i[o]?.comparison
89
- }]) : void 0, ft = Y?.(n) ?? [], M = d ? (K ?? []).map((t, h) => ({
94
+ }]) : void 0, ht = Y?.(n) ?? [], M = d ? (K ?? []).map((t, f) => ({
90
95
  label: t.label,
91
- ariaLabel: ft[h]
96
+ ariaLabel: ht[f]
92
97
  })) : nt ? p.flatMap((t) => t.localized_label ? [{ label: t.localized_label }] : []) : [], _t = d || e === "singleBar" || e === "upcomingBill" ? l.length ? d ? /* @__PURE__ */ r(xt, {
93
98
  bars: i,
94
99
  colors: G,
@@ -122,7 +127,7 @@ var pe = Pt(({ beat: s }) => {
122
127
  projectedRow: bt,
123
128
  heading: y?.heading,
124
129
  icon: y?.icon,
125
- onSelectionChange: ht,
130
+ onSelectionChange: ft,
126
131
  selectedIndex: o,
127
132
  subHeadingText: y?.subHeadingText,
128
133
  tabs: l,
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionHistoryBlock.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionHistoryBlock/TransactionHistoryBlock.tsx"],"sourcesContent":["import { useLayoutEffect, useState } from 'react'\n\nimport { useTheme } from '@mui/material/styles'\nimport { observer } from 'mobx-react-lite'\n\nimport type { Beat, DataSeries, Transaction } from '../../../core'\nimport { formatCurrency } from '../../../core/utils/NumberFormatting'\nimport { ANALYTICS_EVENTS_CONFIG, useAnalyticsEvent } from '../../analytics'\nimport { BarChartV2 } from '../../components/chartblocks/BarchartV2'\nimport { DoubleBarChart } from '../../components/chartblocks/DoubleBarChart'\nimport { EmptyBarChart } from '../../components/chartblocks/EmptyBarChart'\nimport { BAR_ARIA_LABEL } from '../../blocks/ChartBlocks/BarchartBlock/utils'\nimport {\n COMPARISON_BAR_ARIA_LABEL,\n toLegendItems,\n} from '../../blocks/ChartBlocks/DoubleBarChartBlock/comparisonUtils'\n\nimport { TransactionDrillDown } from './TransactionDrillDown'\nimport { useTransactionHistory } from './useTransactionHistory'\nimport {\n getDefaultSelection,\n getDrillDownConfig,\n getFlattenedDataSeries,\n resolveDrillDownSubHeader,\n splitProjectedTransaction,\n toStoreFilter,\n} from './utils'\nimport {\n Drawer,\n useInsightsV2Store,\n useGlobalCopyStore,\n useGlobalUiStore,\n Loader,\n} from '../../../common'\nimport { TransactionDetailsBlock } from '../TransactionDetailsBlock'\nimport { getDynamicCtaBasedOnTriggers } from '../util'\n\ninterface TransactionHistoryProp {\n beat: Beat\n}\n\nexport const TransactionHistoryBlock = observer(({ beat }: TransactionHistoryProp) => {\n const theme = useTheme()\n\n const { actionDrawer, setActionContext } = useInsightsV2Store()\n\n const { insights_payload } = beat\n\n const dynamicCtaVariant = getDynamicCtaBasedOnTriggers(\n actionDrawer,\n insights_payload?.primary_cta,\n insights_payload?.secondary_cta,\n insights_payload?.in_description_cta,\n )?.variant\n\n const {\n top,\n filterMode,\n header,\n colors,\n filterStrategy,\n tipSection,\n subTabAriaLabels,\n slotData,\n beatTransactions: resolveBeatTransactions,\n hideListHeader,\n } = getDrillDownConfig(dynamicCtaVariant ?? '')\n\n const {\n instanceSlotData,\n beatTransactions,\n spendCategoryGuids,\n allAccountGuids,\n categoryName,\n displayedDateRange,\n transactionStore,\n } = useTransactionHistory(beat, { slotData, beatTransactions: resolveBeatTransactions })\n\n const { common: commonCopy, insights_feed: insightsCopy } = useGlobalCopyStore()\n\n const { isCopyLoaded } = useGlobalUiStore()\n\n const [isTransactionDetailsOpen, setIsTransactionDetailsOpen] = useState(false)\n\n const [closeTipSection, setCloseTipSection] = useState(false)\n\n const fireAnalyticsEvent = useAnalyticsEvent()\n\n // `getFlattenedDataSeries` runs ahead of the copy-loaded guard below, hence the literal fallback.\n const { dataSeries, chartData, comparisonBars } = getFlattenedDataSeries({\n data: instanceSlotData?.data_series as DataSeries,\n ariaLabel:\n top === 'doubleBar'\n ? (insightsCopy?.general?.in_month_you_had_a_category_of_amount ??\n COMPARISON_BAR_ARIA_LABEL)\n : BAR_ARIA_LABEL,\n top,\n beatTransactions,\n })\n\n const isDoubleBar = top === 'doubleBar'\n const isTabsOnly = top === 'tabsOnly'\n // The drawer's columns (and tabs): the double bar's month pairs, or the single bar's bars.\n const bars = isDoubleBar ? comparisonBars : chartData\n\n const { chartBarIndex, subTabIndex } = getDefaultSelection({\n chartTabCount: chartData.length,\n comparisonTabCount: comparisonBars.length,\n actionDrawer,\n beatGuid: beat.guid,\n })\n\n const [selectedIndex, setSelectedIndex] = useState(chartBarIndex)\n // The double-bar drawer's series tab (0 = main, e.g. Spend; 1 = comparison, e.g. Income).\n const [subIndex, setSubIndex] = useState(subTabIndex)\n\n // Bars built from the transaction store (Upcoming Bill's paid bills) can arrive after the drawer\n // opens: re-select the default when the bar count changes. Payload-built bars never change count.\n const [defaultedTabCount, setDefaultedTabCount] = useState(bars.length)\n if (bars.length !== defaultedTabCount) {\n setDefaultedTabCount(bars.length)\n setSelectedIndex(chartBarIndex)\n }\n\n const resolveFilter = (index: number) =>\n filterStrategy({\n beat,\n beatTransactions,\n dataSeries,\n comparisonBars,\n selectedIndex: index,\n subIndex,\n isLastTab: index === bars.length - 1,\n instanceSlotData,\n spendCategoryGuids,\n displayedDateRange,\n })\n\n // Apply the current selection's filter. Store variants route through the store filter; local\n // (upcomingBill) variants filter beatTransactions directly and only backfill the cache when the\n // Stable primitive keys for the collections below: beatTransactions/spendCategoryGuids/\n // allAccountGuids are recomputed (new array identity) every render, so depending on them directly\n // re-fires the effect each render (REVIEW.md MEW-3732). Key on content instead.\n const beatTransactionGuidsKey = beatTransactions.map((transaction) => transaction.guid).join(',')\n const spendCategoryGuidsKey = spendCategoryGuids.join(',')\n const allAccountGuidsKey = allAccountGuids.join(',')\n\n // Re-applies the current selection's filter to the shared transactionStore. Called both by the\n // effect below (on selection change) and when the nested TransactionDetailsBlock drawer closes:\n // AddMerchantBudgetAction (opened from within that drawer) overwrites transactionStore.filter\n // with a merchant_guid-only filter while its own drawer is open, and never restores it — leaving\n // the row list stuck showing only that one merchant's transactions after backing all the way out.\n // Re-running this on close re-derives the filter fresh instead of relying on whatever the nested\n // drawers left behind.\n // A `list`, `tabsOnly` or `monthTabs` drawer applies its filter even with no bars or rows.\n const canApplyFilter =\n top === 'list' || top === 'tabsOnly' || top === 'monthTabs' || dataSeries.length > 0\n const applyCurrentSelectionFilter = () => {\n if (filterMode !== 'store' || !canApplyFilter) return\n transactionStore.setFilter(\n toStoreFilter(resolveFilter(selectedIndex), { allAccountGuids, displayedDateRange }),\n )\n }\n\n // store variants route the selection through the shared store filter; local (upcomingBill) variants\n // filter beatTransactions directly, so there's nothing to push to the store for them.\n useLayoutEffect(() => {\n applyCurrentSelectionFilter()\n }, [\n beat.guid,\n selectedIndex,\n subIndex,\n filterMode,\n dataSeries.length,\n instanceSlotData,\n displayedDateRange,\n spendCategoryGuidsKey,\n allAccountGuidsKey,\n beatTransactionGuidsKey,\n top,\n ])\n\n const subHeader = resolveDrillDownSubHeader(insights_payload)\n\n const headerContent = header?.({\n title: insights_payload?.title,\n subHeader,\n categoryName,\n selectedDate: chartData[selectedIndex]?.date ?? undefined,\n })\n\n const barColors = colors(theme, instanceSlotData?.category_guid)\n\n if (!isCopyLoaded) return <Loader />\n\n // `legends` is the block's additional_data ([0] main, [1] second series), as BarchartBlock reads it.\n const [mainLegend, comparisonLegend] = instanceSlotData?.legends ?? []\n\n const transactionFilter =\n filterMode === 'local'\n ? (index: number) => resolveFilter(index).custom ?? (() => true)\n : undefined\n\n // A variant's `beatTransactions` resolver may append a synthesized projected bill (Upcoming Bill's)\n // last: it draws the last bar but is never a list row or a CSV line. Its tab (the one whose filter\n // matches it) shows it as its own row under the copy service's \"Projected amount\"; no row without\n // that copy.\n const { transactions: listTransactions, projectedTransaction } =\n splitProjectedTransaction(beatTransactions)\n\n const baseTransactions: Transaction[] | undefined =\n filterMode === 'local' ? listTransactions : undefined\n\n const projectedHeading = insightsCopy.general.projected_amount\n const projectedRow =\n projectedTransaction &&\n projectedHeading &&\n resolveFilter(selectedIndex).custom?.(projectedTransaction)\n ? { heading: projectedHeading, transaction: projectedTransaction }\n : undefined\n\n // A chart bar click selects its column (and, on the double bar, its series); a month tab change\n // selects the month. MUI Tabs only fires onChange on real user selection, not on mount. The\n // series (Spend / Income) tab fires its own analytics via the shared SubTabs component.\n const selectBar = (index: number, seriesIndex?: number) => {\n fireAnalyticsEvent(ANALYTICS_EVENTS_CONFIG.DRAWER_CHART_BAR_CLICKED)\n setSelectedIndex(index)\n if (seriesIndex !== undefined) setSubIndex(seriesIndex)\n }\n const selectMonth = (index: number) => {\n fireAnalyticsEvent(ANALYTICS_EVENTS_CONFIG.TAB_SELECTED)\n setSelectedIndex(index)\n }\n\n // Double bar: the Spend / Income labels come from copy (additional_data); the legend carries the\n // selected month's two totals, and its labels name the series tabs.\n const doubleBarLegends = isDoubleBar\n ? toLegendItems([\n { ...mainLegend, value: comparisonBars[selectedIndex]?.main },\n { ...comparisonLegend, value: comparisonBars[selectedIndex]?.comparison },\n ])\n : undefined\n\n // Legacy pulse named these tabs \"Spend transactions\" / \"Income transactions\" for screen readers.\n const seriesAriaLabels = subTabAriaLabels?.(insightsCopy) ?? []\n\n // The second tab row: the double bar's two series, or a tabs-only drawer's sides (one per\n // data_series row, labelled by the row's pre-localized label).\n const sideTabs = isDoubleBar\n ? (doubleBarLegends ?? []).map((legend, index) => ({\n label: legend.label,\n ariaLabel: seriesAriaLabels[index],\n }))\n : isTabsOnly\n ? dataSeries.flatMap((row) => (row.localized_label ? [{ label: row.localized_label }] : []))\n : []\n\n const renderChart = () => {\n if (!bars.length) return <EmptyBarChart />\n\n return isDoubleBar ? (\n <DoubleBarChart\n bars={comparisonBars}\n colors={barColors}\n legendPosition=\"top\"\n legends={doubleBarLegends}\n onBarClick={selectBar}\n selectedIndex={selectedIndex}\n />\n ) : (\n <BarChartV2\n amounts={{\n average: instanceSlotData?.average_amount,\n formattedAverage: formatCurrency(instanceSlotData?.average_amount ?? 0, '0,0.00'),\n }}\n color={barColors[0] ?? theme.palette.primary.main}\n data={chartData}\n legendPosition=\"top\"\n // Figma's chart drawer: 172px of bars under the 24px legend, 200px in all.\n heightOverride={172}\n margin={{\n bottom: 8,\n top: 24,\n left: 24,\n right: 24,\n }}\n // TODO: Temporary fallback while the backend doesn't always send `legends` on every\n // beat/variant. Remove this once the backend guarantees `legends` on the payload.\n monthlyAmountLabel={mainLegend?.label ?? insightsCopy.general.monthly_amount}\n onBarClick={selectBar}\n selectedTabIndex={selectedIndex}\n trendAmountLabel={comparisonLegend?.label ?? insightsCopy.general.trend}\n />\n )\n }\n\n // `list` (Low Account Balance), `tabsOnly` (Non-Essential Category Summary) and `monthTabs`\n // (Monthly Subscription Aggregate) drawers have no chart above their transaction list.\n const chartTop =\n isDoubleBar || top === 'singleBar' || top === 'upcomingBill' ? renderChart() : null\n\n return (\n <>\n <TransactionDrillDown\n baseTransactions={baseTransactions}\n hideListHeader={hideListHeader}\n projectedRow={projectedRow}\n heading={headerContent?.heading}\n icon={headerContent?.icon}\n onSelectionChange={selectMonth}\n selectedIndex={selectedIndex}\n subHeadingText={headerContent?.subHeadingText}\n tabs={bars}\n top={chartTop}\n {...(sideTabs.length > 0 && {\n subTabs: { tabs: sideTabs, selectedIndex: subIndex, onChange: setSubIndex },\n })}\n {...(tipSection && {\n tipSection:\n !closeTipSection &&\n (tipSection(setCloseTipSection, insightsCopy, subHeader?.text, instanceSlotData) ??\n false),\n })}\n transactionFilter={transactionFilter}\n onEachRowClick={(guid) => {\n setActionContext({ transaction_guid: guid })\n setIsTransactionDetailsOpen(true)\n }}\n />\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isTransactionDetailsOpen}\n onClose={() => {\n setIsTransactionDetailsOpen(false)\n // Clear only the key this nested drawer owns — setActionContext merges, so an\n // explicit `{}` would be a no-op and leave transaction_guid stuck in the shared\n // context, and the outer drawer's own context (e.g. chartBarIndex) must survive.\n setActionContext({ transaction_guid: undefined })\n // Re-apply this block's own filter: a further-nested AddMerchantBudgetAction drawer may\n // have overwritten transactionStore.filter (merchant_guid-only) without restoring it.\n applyCurrentSelectionFilter()\n }}\n title={insightsCopy.general.transaction_details_title}\n >\n <TransactionDetailsBlock beat={beat} />\n </Drawer>\n </>\n )\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"TransactionHistoryBlock.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionHistoryBlock/TransactionHistoryBlock.tsx"],"sourcesContent":["import { useLayoutEffect, useState } from 'react'\n\nimport { useTheme } from '@mui/material/styles'\nimport { observer } from 'mobx-react-lite'\n\nimport type { Beat, DataSeries, Transaction } from '../../../core'\nimport { formatCurrency } from '../../../core/utils/NumberFormatting'\nimport { ANALYTICS_EVENTS_CONFIG, useAnalyticsEvent } from '../../analytics'\nimport { BarChartV2 } from '../../components/chartblocks/BarchartV2'\nimport { DoubleBarChart } from '../../components/chartblocks/DoubleBarChart'\nimport { EmptyBarChart } from '../../components/chartblocks/EmptyBarChart'\nimport { BAR_ARIA_LABEL } from '../../blocks/ChartBlocks/BarchartBlock/utils'\nimport {\n COMPARISON_BAR_ARIA_LABEL,\n toLegendItems,\n} from '../../blocks/ChartBlocks/DoubleBarChartBlock/comparisonUtils'\n\nimport { TransactionDrillDown } from './TransactionDrillDown'\nimport { useTransactionHistory } from './useTransactionHistory'\nimport {\n getDefaultSelection,\n getDrillDownConfig,\n getFlattenedDataSeries,\n resolveDrillDownSubHeader,\n splitProjectedTransaction,\n toStoreFilter,\n} from './utils'\nimport {\n Drawer,\n useInsightsV2Store,\n useGlobalCopyStore,\n useGlobalUiStore,\n Loader,\n} from '../../../common'\nimport { TransactionDetailsBlock } from '../TransactionDetailsBlock'\nimport { getDynamicCtaBasedOnTriggers } from '../util'\n\ninterface TransactionHistoryProp {\n beat: Beat\n}\n\nexport const TransactionHistoryBlock = observer(({ beat }: TransactionHistoryProp) => {\n const theme = useTheme()\n\n const { actionDrawer, setActionContext } = useInsightsV2Store()\n\n const { insights_payload } = beat\n\n const dynamicCtaVariant = getDynamicCtaBasedOnTriggers(\n actionDrawer,\n insights_payload?.primary_cta,\n insights_payload?.secondary_cta,\n insights_payload?.in_description_cta,\n )?.variant\n\n const {\n top,\n filterMode,\n header,\n colors,\n filterStrategy,\n tipSection,\n subTabAriaLabels,\n slotData,\n beatTransactions: resolveBeatTransactions,\n hideListHeader,\n } = getDrillDownConfig(dynamicCtaVariant ?? '')\n\n const {\n instanceSlotData,\n beatTransactions,\n spendCategoryGuids,\n allAccountGuids,\n categoryName,\n displayedDateRange,\n transactionStore,\n } = useTransactionHistory(beat, { slotData, beatTransactions: resolveBeatTransactions })\n\n const { common: commonCopy, insights_feed: insightsCopy } = useGlobalCopyStore()\n\n const { isCopyLoaded } = useGlobalUiStore()\n\n const [isTransactionDetailsOpen, setIsTransactionDetailsOpen] = useState(false)\n\n const [closeTipSection, setCloseTipSection] = useState(false)\n\n const fireAnalyticsEvent = useAnalyticsEvent()\n\n // `getFlattenedDataSeries` runs ahead of the copy-loaded guard below, hence the literal fallback.\n const { dataSeries, chartData, comparisonBars } = getFlattenedDataSeries({\n data: instanceSlotData?.data_series as DataSeries,\n ariaLabel:\n top === 'doubleBar'\n ? (insightsCopy?.general?.in_month_you_had_a_category_of_amount ??\n COMPARISON_BAR_ARIA_LABEL)\n : BAR_ARIA_LABEL,\n top,\n beatTransactions,\n })\n\n const isDoubleBar = top === 'doubleBar'\n const isTabsOnly = top === 'tabsOnly'\n // The drawer's columns (and tabs): the double bar's month pairs, or the single bar's bars.\n const bars = isDoubleBar ? comparisonBars : chartData\n\n const { chartBarIndex, subTabIndex } = getDefaultSelection({\n chartTabCount: chartData.length,\n comparisonTabCount: comparisonBars.length,\n actionDrawer,\n beatGuid: beat.guid,\n })\n\n const [selectedIndex, setSelectedIndex] = useState(chartBarIndex)\n // The double-bar drawer's series tab (0 = main, e.g. Spend; 1 = comparison, e.g. Income).\n const [subIndex, setSubIndex] = useState(subTabIndex)\n\n // Bars built from the transaction store (Upcoming Bill's paid bills) can arrive after the drawer\n // opens: re-select the default when the bar count changes. Payload-built bars never change count.\n const [defaultedTabCount, setDefaultedTabCount] = useState(bars.length)\n if (bars.length !== defaultedTabCount) {\n setDefaultedTabCount(bars.length)\n setSelectedIndex(chartBarIndex)\n }\n\n const resolveFilter = (index: number) =>\n filterStrategy({\n beat,\n beatTransactions,\n dataSeries,\n comparisonBars,\n selectedIndex: index,\n subIndex,\n isLastTab: index === bars.length - 1,\n instanceSlotData,\n spendCategoryGuids,\n displayedDateRange,\n })\n\n // Apply the current selection's filter. Store variants route through the store filter; local\n // (upcomingBill) variants filter beatTransactions directly and only backfill the cache when the\n // Stable primitive keys for the collections below: beatTransactions/spendCategoryGuids/\n // allAccountGuids are recomputed (new array identity) every render, so depending on them directly\n // re-fires the effect each render (REVIEW.md MEW-3732). Key on content instead.\n const beatTransactionGuidsKey = beatTransactions.map((transaction) => transaction.guid).join(',')\n const spendCategoryGuidsKey = spendCategoryGuids.join(',')\n const allAccountGuidsKey = allAccountGuids.join(',')\n\n // Re-applies the current selection's filter to the shared transactionStore. Called both by the\n // effect below (on selection change) and when the nested TransactionDetailsBlock drawer closes:\n // AddMerchantBudgetAction (opened from within that drawer) overwrites transactionStore.filter\n // with a merchant_guid-only filter while its own drawer is open, and never restores it — leaving\n // the row list stuck showing only that one merchant's transactions after backing all the way out.\n // Re-running this on close re-derives the filter fresh instead of relying on whatever the nested\n // drawers left behind.\n // A `list`, `tabsOnly` or `monthTabs` drawer applies its filter even with no bars or rows.\n const canApplyFilter =\n top === 'list' || top === 'tabsOnly' || top === 'monthTabs' || dataSeries.length > 0\n const applyCurrentSelectionFilter = () => {\n if (filterMode !== 'store') return\n // A chart drawer with no bars can name no rows: fail closed rather than keep the store's default\n // (every account) or a previous drawer's filter.\n const filter = canApplyFilter\n ? resolveFilter(selectedIndex)\n : { accounts: [], custom: () => false }\n transactionStore.setFilter(toStoreFilter(filter, { allAccountGuids, displayedDateRange }))\n }\n\n // store variants route the selection through the shared store filter; local (upcomingBill) variants\n // filter beatTransactions directly, so there's nothing to push to the store for them.\n useLayoutEffect(() => {\n applyCurrentSelectionFilter()\n }, [\n beat.guid,\n selectedIndex,\n subIndex,\n filterMode,\n dataSeries.length,\n instanceSlotData,\n displayedDateRange,\n spendCategoryGuidsKey,\n allAccountGuidsKey,\n beatTransactionGuidsKey,\n top,\n ])\n\n const subHeader = resolveDrillDownSubHeader(insights_payload)\n\n const headerContent = header?.({\n title: insights_payload?.title,\n subHeader,\n categoryName,\n selectedDate: chartData[selectedIndex]?.date ?? undefined,\n })\n\n const barColors = colors(theme, instanceSlotData?.category_guid)\n\n if (!isCopyLoaded) return <Loader />\n\n // `legends` is the block's additional_data ([0] main, [1] second series), as BarchartBlock reads it.\n const [mainLegend, comparisonLegend] = instanceSlotData?.legends ?? []\n\n const transactionFilter =\n filterMode === 'local'\n ? (index: number) => resolveFilter(index).custom ?? (() => true)\n : undefined\n\n // A variant's `beatTransactions` resolver may append a synthesized projected bill (Upcoming Bill's)\n // last: it draws the last bar but is never a list row or a CSV line. Its tab (the one whose filter\n // matches it) shows it as its own row under the copy service's \"Projected amount\"; no row without\n // that copy.\n const { transactions: listTransactions, projectedTransaction } =\n splitProjectedTransaction(beatTransactions)\n\n const baseTransactions: Transaction[] | undefined =\n filterMode === 'local' ? listTransactions : undefined\n\n const projectedHeading = insightsCopy.general.projected_amount\n const projectedRow =\n projectedTransaction &&\n projectedHeading &&\n resolveFilter(selectedIndex).custom?.(projectedTransaction)\n ? { heading: projectedHeading, transaction: projectedTransaction }\n : undefined\n\n // A chart bar click selects its column (and, on the double bar, its series); a month tab change\n // selects the month. MUI Tabs only fires onChange on real user selection, not on mount. The\n // series (Spend / Income) tab fires its own analytics via the shared SubTabs component.\n const selectBar = (index: number, seriesIndex?: number) => {\n fireAnalyticsEvent(ANALYTICS_EVENTS_CONFIG.DRAWER_CHART_BAR_CLICKED)\n setSelectedIndex(index)\n if (seriesIndex !== undefined) setSubIndex(seriesIndex)\n }\n const selectMonth = (index: number) => {\n fireAnalyticsEvent(ANALYTICS_EVENTS_CONFIG.TAB_SELECTED)\n setSelectedIndex(index)\n }\n\n // Double bar: the Spend / Income labels come from copy (additional_data); the legend carries the\n // selected month's two totals, and its labels name the series tabs.\n const doubleBarLegends = isDoubleBar\n ? toLegendItems([\n { ...mainLegend, value: comparisonBars[selectedIndex]?.main },\n { ...comparisonLegend, value: comparisonBars[selectedIndex]?.comparison },\n ])\n : undefined\n\n // Legacy pulse named these tabs \"Spend transactions\" / \"Income transactions\" for screen readers.\n const seriesAriaLabels = subTabAriaLabels?.(insightsCopy) ?? []\n\n // The second tab row: the double bar's two series, or a tabs-only drawer's sides (one per\n // data_series row, labelled by the row's pre-localized label).\n const sideTabs = isDoubleBar\n ? (doubleBarLegends ?? []).map((legend, index) => ({\n label: legend.label,\n ariaLabel: seriesAriaLabels[index],\n }))\n : isTabsOnly\n ? dataSeries.flatMap((row) => (row.localized_label ? [{ label: row.localized_label }] : []))\n : []\n\n const renderChart = () => {\n if (!bars.length) return <EmptyBarChart />\n\n return isDoubleBar ? (\n <DoubleBarChart\n bars={comparisonBars}\n colors={barColors}\n legendPosition=\"top\"\n legends={doubleBarLegends}\n onBarClick={selectBar}\n selectedIndex={selectedIndex}\n />\n ) : (\n <BarChartV2\n amounts={{\n average: instanceSlotData?.average_amount,\n formattedAverage: formatCurrency(instanceSlotData?.average_amount ?? 0, '0,0.00'),\n }}\n color={barColors[0] ?? theme.palette.primary.main}\n data={chartData}\n legendPosition=\"top\"\n // Figma's chart drawer: 172px of bars under the 24px legend, 200px in all.\n heightOverride={172}\n margin={{\n bottom: 8,\n top: 24,\n left: 24,\n right: 24,\n }}\n // TODO: Temporary fallback while the backend doesn't always send `legends` on every\n // beat/variant. Remove this once the backend guarantees `legends` on the payload.\n monthlyAmountLabel={mainLegend?.label ?? insightsCopy.general.monthly_amount}\n onBarClick={selectBar}\n selectedTabIndex={selectedIndex}\n trendAmountLabel={comparisonLegend?.label ?? insightsCopy.general.trend}\n />\n )\n }\n\n // `list` (Low Account Balance), `tabsOnly` (Non-Essential Category Summary) and `monthTabs`\n // (Monthly Subscription Aggregate) drawers have no chart above their transaction list.\n const chartTop =\n isDoubleBar || top === 'singleBar' || top === 'upcomingBill' ? renderChart() : null\n\n return (\n <>\n <TransactionDrillDown\n baseTransactions={baseTransactions}\n hideListHeader={hideListHeader}\n projectedRow={projectedRow}\n heading={headerContent?.heading}\n icon={headerContent?.icon}\n onSelectionChange={selectMonth}\n selectedIndex={selectedIndex}\n subHeadingText={headerContent?.subHeadingText}\n tabs={bars}\n top={chartTop}\n {...(sideTabs.length > 0 && {\n subTabs: { tabs: sideTabs, selectedIndex: subIndex, onChange: setSubIndex },\n })}\n {...(tipSection && {\n tipSection:\n !closeTipSection &&\n (tipSection(setCloseTipSection, insightsCopy, subHeader?.text, instanceSlotData) ??\n false),\n })}\n transactionFilter={transactionFilter}\n onEachRowClick={(guid) => {\n setActionContext({ transaction_guid: guid })\n setIsTransactionDetailsOpen(true)\n }}\n />\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isTransactionDetailsOpen}\n onClose={() => {\n setIsTransactionDetailsOpen(false)\n // Clear only the key this nested drawer owns — setActionContext merges, so an\n // explicit `{}` would be a no-op and leave transaction_guid stuck in the shared\n // context, and the outer drawer's own context (e.g. chartBarIndex) must survive.\n setActionContext({ transaction_guid: undefined })\n // Re-apply this block's own filter: a further-nested AddMerchantBudgetAction drawer may\n // have overwritten transactionStore.filter (merchant_guid-only) without restoring it.\n applyCurrentSelectionFilter()\n }}\n title={insightsCopy.general.transaction_details_title}\n >\n <TransactionDetailsBlock beat={beat} />\n </Drawer>\n </>\n )\n})\n"],"mappings":"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"}
@@ -76,6 +76,7 @@ export interface DrillDownVariantConfig {
76
76
  hideListHeader?: boolean;
77
77
  }
78
78
  export declare const resolveUpcomingBillSlotData: SlotDataResolver;
79
+ export declare const resolveSavingsContributionsSlotData: SlotDataResolver;
79
80
  export declare const resolveUpcomingBillTransactions: BeatTransactionsResolver;
80
81
  export declare const layout: Partial<Record<DrillDownVariant, DrillDownVariantConfig>>;
81
82
  export declare const FALLBACK: DrillDownVariantConfig;
@@ -1,14 +1,14 @@
1
- import { buildDynamicCopy as h } from "../../../core/utils/Localization.es.js";
2
- import { DATE_FORMATS_INTL as A, formatDate as v } from "../../../core/constants/DateFormats.es.js";
3
- import { TransactionStatus as L } from "../../../core/types/Transaction.es.js";
4
- import { fromUnixUTC as S } from "../../../core/utils/DateUtil.es.js";
5
- import { getCategoryColor as b } from "../../../core/utils/CategoryUtil.es.js";
6
- import { getLayoutConfig as M } from "../../blocks/ChartBlocks/DoubleBarChartBlock/layout.es.js";
7
- import { buildProjectedBillTransaction as D, calendarDateOf as G, finiteNumberOf as N, guidListOf as B, nonEmptyStringOf as T } from "./utils.es.js";
8
- import { MerchantLogo as R } from "@mxenabled/mxui";
9
- import { Icon as P } from "@mxenabled/mx-icons";
1
+ import { buildDynamicCopy as v } from "../../../core/utils/Localization.es.js";
2
+ import { DATE_FORMATS_INTL as A, formatDate as C } from "../../../core/constants/DateFormats.es.js";
3
+ import { TransactionStatus as D } from "../../../core/types/Transaction.es.js";
4
+ import { fromUnixUTC as O } from "../../../core/utils/DateUtil.es.js";
5
+ import { getCategoryColor as G } from "../../../core/utils/CategoryUtil.es.js";
6
+ import { getLayoutConfig as B } from "../../blocks/ChartBlocks/DoubleBarChartBlock/layout.es.js";
7
+ import { buildProjectedBillTransaction as R, calendarDateOf as P, finiteNumberOf as u, guidListOf as b, nonEmptyStringOf as T } from "./utils.es.js";
8
+ import { MerchantLogo as U } from "@mxenabled/mxui";
9
+ import { Icon as w } from "@mxenabled/mx-icons";
10
10
  import { jsx as c } from "react/jsx-runtime";
11
- import { endOfMonth as C, fromUnixTime as U, isValid as E, parseISO as l, startOfMonth as I } from "date-fns";
11
+ import { endOfMonth as E, fromUnixTime as H, isValid as I, parseISO as d, startOfMonth as L } from "date-fns";
12
12
  var n = {
13
13
  TRANSACTION: "not_standard_amount",
14
14
  CATEGORY_SPEND: "category_spend",
@@ -23,125 +23,139 @@ var n = {
23
23
  DEPOSIT_SUMMARY: "monthly_deposit_summary",
24
24
  LOW_BALANCE: "low_balance",
25
25
  SUBSCRIPTION_AGGREGATE: "monthly_subscription_aggregate"
26
- }, g = (t, e) => e && b(e, t) || t.palette.primary.main, u = (t) => typeof t == "string" ? l(t) : new Date(t ?? NaN), d = (t) => ({
27
- start: I(u(t)),
28
- end: C(u(t))
29
- }), p = (t) => t?.length ? { accounts: t } : {}, w = ({ beat: t }) => {
30
- const { account_guid: e, from_date: o, to_date: a } = t.insights_payload?.drilldown_data ?? {};
31
- return typeof e != "string" || typeof o != "number" || typeof a != "number" || !Number.isFinite(o) || !Number.isFinite(a) || a <= o ? {
26
+ }, l = (t, e) => e && G(e, t) || t.palette.primary.main, m = (t) => typeof t == "string" ? d(t) : new Date(t ?? NaN), g = (t) => ({
27
+ start: L(m(t)),
28
+ end: E(m(t))
29
+ }), M = (t) => t?.length ? { accounts: t } : {}, Y = ({ beat: t }) => {
30
+ const { account_guid: e, from_date: a, to_date: o } = t.insights_payload?.drilldown_data ?? {};
31
+ return typeof e != "string" || typeof a != "number" || typeof o != "number" || !Number.isFinite(a) || !Number.isFinite(o) || o <= a ? {
32
32
  accounts: [],
33
33
  custom: () => !1
34
34
  } : {
35
35
  accounts: [e],
36
- custom: (r) => !r.is_hidden && r.feed_status !== L.PENDING,
36
+ custom: (r) => !r.is_hidden && r.feed_status !== D.PENDING,
37
37
  showSplits: !0,
38
38
  dateRange: {
39
- start: S(o),
40
- end: S(a - 1)
39
+ start: O(a),
40
+ end: O(o - 1)
41
41
  }
42
42
  };
43
- }, H = (t) => {
43
+ }, F = (t) => {
44
44
  const e = t?.drilldown_data ?? {};
45
45
  return {
46
- transaction_guids: B(e.transaction_guids),
47
- date: G(e.due_date),
48
- amount: N(e.amount),
46
+ transaction_guids: b(e.transaction_guids),
47
+ date: P(e.due_date),
48
+ amount: u(e.amount),
49
49
  category_guid: T(e.category_guid),
50
- average_amount: N(e.average_amount),
50
+ average_amount: u(e.average_amount),
51
51
  merchant_name: T(e.merchant_name)
52
52
  };
53
- }, Y = (t, e) => {
54
- const o = D(t, e);
55
- return o ? [...t, o] : t;
56
- }, F = (t, e, o, a) => {
57
- const r = a?.merchant_name, i = a?.date;
58
- if (!r || !i) return;
59
- const s = e.transaction_history_block?.upcoming_bill_tip_message;
60
- if (s)
53
+ }, V = (t) => {
54
+ const e = t;
55
+ return Array.isArray(e?.names) && Array.isArray(e?.data) ? e : void 0;
56
+ }, W = (t) => {
57
+ const e = t?.drilldown_data ?? {};
58
+ return {
59
+ account_guids: b(e.account_guids),
60
+ data_series: V(e.data_series),
61
+ average_amount: u(e.average_amount)
62
+ };
63
+ }, x = (t, e) => {
64
+ const a = R(t, e);
65
+ return a ? [...t, a] : t;
66
+ }, j = (t, e, a, o) => {
67
+ const r = o?.merchant_name, s = o?.date;
68
+ if (!r || !s) return;
69
+ const i = e.transaction_history_block?.upcoming_bill_tip_message;
70
+ if (i)
61
71
  return {
62
- message: h(s, /* @__PURE__ */ c("strong", { children: e.general.tip_section_title }), r, v(l(i), A.FULL_MONTH_DAY)),
72
+ message: v(i, /* @__PURE__ */ c("strong", { children: e.general.tip_section_title }), r, C(d(s), A.FULL_MONTH_DAY)),
63
73
  onDismiss: () => t(!0)
64
74
  };
65
- }, m = ({ beatTransactions: t, dataSeries: e, selectedIndex: o }) => {
66
- const a = e[o], r = a?.guid, i = t.find((s) => s.guid === r)?.has_been_split;
75
+ }, p = ({ beatTransactions: t, dataSeries: e, selectedIndex: a }) => {
76
+ const o = e[a], r = o?.guid, s = t.find((i) => i.guid === r)?.has_been_split;
67
77
  return {
68
- custom: (s) => s.guid === r,
69
- dateRange: d(a?.date),
70
- showSplits: !i
78
+ custom: (i) => i.guid === r,
79
+ dateRange: g(o?.date),
80
+ showSplits: !s
71
81
  };
72
- }, V = ({ dataSeries: t, selectedIndex: e, instanceSlotData: o }) => {
73
- const a = t[e], r = o.category_guid ?? a?.guid;
82
+ }, z = ({ dataSeries: t, selectedIndex: e, instanceSlotData: a }) => {
83
+ const o = t[e], r = a.category_guid ?? o?.guid;
74
84
  return {
75
- custom: (i) => i.category_guid === r || i.top_level_category_guid === r,
76
- dateRange: d(a?.date)
85
+ custom: (s) => s.category_guid === r || s.top_level_category_guid === r,
86
+ dateRange: g(o?.date)
77
87
  };
78
- }, W = ({ dataSeries: t, selectedIndex: e, spendCategoryGuids: o, instanceSlotData: a }) => {
88
+ }, k = ({ dataSeries: t, selectedIndex: e, spendCategoryGuids: a, instanceSlotData: o }) => {
79
89
  const r = t[e];
80
90
  return {
81
- custom: (i) => !!i.top_level_category_guid && o.includes(i.top_level_category_guid),
82
- dateRange: d(r?.date),
83
- ...p(a.account_guids)
91
+ custom: (s) => !!s.top_level_category_guid && a.includes(s.top_level_category_guid),
92
+ dateRange: g(r?.date),
93
+ ...M(o.account_guids)
84
94
  };
85
- }, x = (t) => typeof t == "number" ? U(t) : l(t ?? ""), j = ({ beat: t, dataSeries: e, selectedIndex: o, isLastTab: a, instanceSlotData: r }) => {
86
- const i = e[o], { start: s, end: f } = d(i?.date), _ = x(t.created_at);
87
- return {
88
- dateRange: {
89
- start: s,
90
- end: a && E(_) && _ < f ? _ : f
91
- },
92
- ...p(t.account_guids?.length ? t.account_guids : r.account_guids)
95
+ }, K = (t) => typeof t == "number" ? H(t) : d(t ?? ""), $ = ({ beat: t, dataSeries: e, selectedIndex: a, isLastTab: o, instanceSlotData: r }) => {
96
+ const s = e[a], { start: i, end: f } = g(s?.date), _ = K(t.created_at), S = r.account_guids, N = {
97
+ start: i,
98
+ end: o && I(_) && _ < f ? _ : f
99
+ };
100
+ return S?.length ? {
101
+ dateRange: N,
102
+ accounts: S
103
+ } : {
104
+ dateRange: N,
105
+ accounts: [],
106
+ custom: () => !1
93
107
  };
94
- }, y = (t, e, o) => {
95
- const a = new Set(t), r = l(e ?? "");
96
- return !a.size || !E(r) ? {
108
+ }, y = (t, e, a) => {
109
+ const o = new Set(t), r = d(e ?? "");
110
+ return !o.size || !I(r) ? {
97
111
  accounts: [],
98
112
  custom: () => !1
99
113
  } : {
100
- custom: (i) => a.has(i.guid),
114
+ custom: (s) => o.has(s.guid),
101
115
  dateRange: {
102
- start: I(r),
103
- end: C(r)
116
+ start: L(r),
117
+ end: E(r)
104
118
  },
105
- ...p(o)
119
+ ...M(a)
106
120
  };
107
- }, z = ({ beat: t, dataSeries: e, selectedIndex: o }) => y(e[o]?.aggregated_guids, e[o]?.date, t.account_guids), O = ({ beat: t, comparisonBars: e, selectedIndex: o, subIndex: a }) => {
108
- const r = e[o];
109
- return y(a === 1 ? r?.comparisonGuids : r?.mainGuids, r?.date, t.account_guids);
110
- }, k = ({ beat: t, dataSeries: e, subIndex: o }) => y(e[o]?.aggregated_guids, e[o]?.date, t.account_guids), at = {
121
+ }, q = ({ beat: t, dataSeries: e, selectedIndex: a }) => y(e[a]?.aggregated_guids, e[a]?.date, t.account_guids), h = ({ beat: t, comparisonBars: e, selectedIndex: a, subIndex: o }) => {
122
+ const r = e[a];
123
+ return y(o === 1 ? r?.comparisonGuids : r?.mainGuids, r?.date, t.account_guids);
124
+ }, J = ({ beat: t, dataSeries: e, subIndex: a }) => y(e[a]?.aggregated_guids, e[a]?.date, t.account_guids), ct = {
111
125
  [n.TRANSACTION]: {
112
126
  top: "singleBar",
113
127
  scope: "store",
114
128
  filterMode: "store",
115
- filterStrategy: m,
116
- colors: (t, e) => [g(t, e)],
129
+ filterStrategy: p,
130
+ colors: (t, e) => [l(t, e)],
117
131
  header: (t) => {
118
- const { title: e, subHeader: o } = t;
132
+ const { title: e, subHeader: a } = t;
119
133
  return {
120
134
  heading: e,
121
- subHeadingText: o?.text || void 0,
122
- icon: /* @__PURE__ */ c(R, {
123
- alt: o?.text,
124
- categoryGuid: o?.logo?.category_guid || "",
125
- merchantGuid: o?.logo?.merchant_guid || "",
135
+ subHeadingText: a?.text || void 0,
136
+ icon: /* @__PURE__ */ c(U, {
137
+ alt: a?.text,
138
+ categoryGuid: a?.logo?.category_guid || "",
139
+ merchantGuid: a?.logo?.merchant_guid || "",
126
140
  size: 16
127
141
  })
128
142
  };
129
143
  },
130
- tipSection: (t, e, o = "") => ({
131
- message: h(e.general.tip_section_message, /* @__PURE__ */ c("strong", { children: e.general.tip_section_title }), /* @__PURE__ */ c("strong", { children: o })),
144
+ tipSection: (t, e, a = "") => ({
145
+ message: v(e.general.tip_section_message, /* @__PURE__ */ c("strong", { children: e.general.tip_section_title }), /* @__PURE__ */ c("strong", { children: a })),
132
146
  onDismiss: () => t(!0)
133
147
  })
134
148
  },
135
149
  [n.CATEGORY_SPEND]: {
136
150
  top: "singleBar",
137
- filterStrategy: V,
151
+ filterStrategy: z,
138
152
  scope: "store",
139
153
  filterMode: "store",
140
- colors: (t, e) => [g(t, e)],
154
+ colors: (t, e) => [l(t, e)],
141
155
  header: (t) => ({
142
156
  heading: t.categoryName,
143
- subHeadingText: t.selectedDate && v(u(t.selectedDate), A.MONTH_LONG) || "",
144
- icon: /* @__PURE__ */ c(P, {
157
+ subHeadingText: t.selectedDate && C(m(t.selectedDate), A.MONTH_LONG) || "",
158
+ icon: /* @__PURE__ */ c(w, {
145
159
  name: "calendar_month",
146
160
  size: 16
147
161
  })
@@ -149,32 +163,33 @@ var n = {
149
163
  },
150
164
  [n.MONTHLY_SPEND]: {
151
165
  top: "singleBar",
152
- filterStrategy: W,
166
+ filterStrategy: k,
153
167
  scope: "store",
154
168
  filterMode: "store",
155
169
  colors: (t) => [t.palette.chart.chart2 ?? t.palette.primary.main]
156
170
  },
157
171
  [n.ACCOUNT_BALANCE]: {
158
172
  top: "singleBar",
159
- filterStrategy: j,
173
+ filterStrategy: $,
174
+ slotData: W,
160
175
  scope: "store",
161
176
  filterMode: "store",
162
177
  colors: (t) => [t.palette.success.main]
163
178
  },
164
179
  [n.UPCOMING_BILL]: {
165
180
  top: "upcomingBill",
166
- filterStrategy: m,
181
+ filterStrategy: p,
167
182
  scope: "beat",
168
183
  filterMode: "local",
169
- colors: (t, e) => [g(t, e)],
170
- slotData: H,
171
- beatTransactions: Y,
184
+ colors: (t, e) => [l(t, e)],
185
+ slotData: F,
186
+ beatTransactions: x,
172
187
  fetchMissingTransactions: (t) => t.insights_payload?.drilldown_data?.transaction_guids,
173
- tipSection: F
188
+ tipSection: j
174
189
  },
175
190
  [n.LOW_BALANCE]: {
176
191
  top: "list",
177
- filterStrategy: w,
192
+ filterStrategy: Y,
178
193
  scope: "store",
179
194
  filterMode: "store",
180
195
  colors: (t) => [t.palette.primary.main],
@@ -182,47 +197,48 @@ var n = {
182
197
  },
183
198
  [n.SUBSCRIPTION_AGGREGATE]: {
184
199
  top: "monthTabs",
185
- filterStrategy: z,
200
+ filterStrategy: q,
186
201
  scope: "store",
187
202
  filterMode: "store",
188
203
  colors: (t) => [t.palette.primary.main]
189
204
  },
190
205
  [n.SPEND_TO_INCOME]: {
191
206
  top: "doubleBar",
192
- filterStrategy: O,
207
+ filterStrategy: h,
193
208
  scope: "store",
194
209
  filterMode: "store",
195
- colors: (t) => M(t, "spend_to_income")?.color ?? [],
210
+ colors: (t) => B(t, "spend_to_income")?.color ?? [],
196
211
  subTabAriaLabels: (t) => [t.general.spend_transactions, t.general.income_transactions]
197
212
  },
198
213
  [n.COST_OF_LIVING]: {
199
214
  top: "doubleBar",
200
- filterStrategy: O,
215
+ filterStrategy: h,
201
216
  scope: "store",
202
217
  filterMode: "store",
203
- colors: (t, e) => [g(t, e), t.palette.chart.chart4 ?? t.palette.primary.main],
218
+ colors: (t, e) => [l(t, e), t.palette.chart.chart4 ?? t.palette.primary.main],
204
219
  subTabAriaLabels: (t) => [void 0, t.general.income_transactions]
205
220
  },
206
221
  [n.NON_ESSENTIAL_CATEGORY]: {
207
222
  top: "tabsOnly",
208
- filterStrategy: k,
223
+ filterStrategy: J,
209
224
  scope: "store",
210
225
  filterMode: "store",
211
226
  colors: (t) => [t.palette.primary.main]
212
227
  }
213
- }, it = {
228
+ }, lt = {
214
229
  top: "singleBar",
215
- filterStrategy: m,
230
+ filterStrategy: p,
216
231
  scope: "store",
217
232
  filterMode: "store",
218
- colors: (t, e) => [g(t, e)]
233
+ colors: (t, e) => [l(t, e)]
219
234
  };
220
235
  export {
221
236
  n as DRILLDOWN_VARIANTS,
222
- it as FALLBACK,
223
- at as layout,
224
- H as resolveUpcomingBillSlotData,
225
- Y as resolveUpcomingBillTransactions
237
+ lt as FALLBACK,
238
+ ct as layout,
239
+ W as resolveSavingsContributionsSlotData,
240
+ F as resolveUpcomingBillSlotData,
241
+ x as resolveUpcomingBillTransactions
226
242
  };
227
243
 
228
244
  //# sourceMappingURL=layout.es.js.map